Merge branch 'master' into xbox

This commit is contained in:
espes 2012-10-23 13:59:11 +11:00
commit a282385882
165 changed files with 3875 additions and 2633 deletions

View File

@ -641,7 +641,7 @@ F: monitor.c
Network device layer
M: Anthony Liguori <aliguori@us.ibm.com>
M: Stefan Hajnoczi <stefanha@gmail.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Maintained
F: net/
T: git git://github.com/stefanha/qemu.git net
@ -661,7 +661,7 @@ F: slirp/
T: git git://git.kiszka.org/qemu.git queues/slirp
Tracing
M: Stefan Hajnoczi <stefanha@gmail.com>
M: Stefan Hajnoczi <stefanha@redhat.com>
S: Maintained
F: trace/
F: scripts/tracetool.py

View File

@ -14,9 +14,11 @@ config-host.mak: $(SRC_PATH)/configure
@sed -n "/.*Configured with/s/[^:]*: //p" $@ | sh
else
config-host.mak:
ifneq ($(filter-out %clean,$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
@echo "Please call configure before running make!"
@exit 1
endif
endif
GENERATED_HEADERS = config-host.h trace.h qemu-options.def
ifeq ($(TRACE_BACKEND),dtrace)
@ -403,7 +405,9 @@ qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \
# Add a dependency on the generated files, so that they are always
# rebuilt before other object files
ifneq ($(filter-out %clean,$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
Makefile: $(GENERATED_HEADERS)
endif
# Include automatically generated dependency files
# Dependencies in Makefile.objs files come from our recursive subdir rules

View File

@ -31,6 +31,8 @@
#include "config.h"
#include "monitor.h"
#include "sysemu.h"
#include "bitops.h"
#include "bitmap.h"
#include "arch_init.h"
#include "audio/audio.h"
#include "hw/pc.h"
@ -45,6 +47,7 @@
#include "hw/pcspk.h"
#include "qemu/page_cache.h"
#include "qmp-commands.h"
#include "trace.h"
#ifdef DEBUG_ARCH_INIT
#define DPRINTF(fmt, ...) \
@ -330,6 +333,78 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
static RAMBlock *last_block;
static ram_addr_t last_offset;
static unsigned long *migration_bitmap;
static uint64_t migration_dirty_pages;
static inline bool migration_bitmap_test_and_reset_dirty(MemoryRegion *mr,
ram_addr_t offset)
{
bool ret;
int nr = (mr->ram_addr + offset) >> TARGET_PAGE_BITS;
ret = test_and_clear_bit(nr, migration_bitmap);
if (ret) {
migration_dirty_pages--;
}
return ret;
}
static inline bool migration_bitmap_set_dirty(MemoryRegion *mr,
ram_addr_t offset)
{
bool ret;
int nr = (mr->ram_addr + offset) >> TARGET_PAGE_BITS;
ret = test_and_set_bit(nr, migration_bitmap);
if (!ret) {
migration_dirty_pages++;
}
return ret;
}
static void migration_bitmap_sync(void)
{
RAMBlock *block;
ram_addr_t addr;
uint64_t num_dirty_pages_init = migration_dirty_pages;
MigrationState *s = migrate_get_current();
static int64_t start_time;
static int64_t num_dirty_pages_period;
int64_t end_time;
if (!start_time) {
start_time = qemu_get_clock_ms(rt_clock);
}
trace_migration_bitmap_sync_start();
memory_global_sync_dirty_bitmap(get_system_memory());
QLIST_FOREACH(block, &ram_list.blocks, next) {
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
if (memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
DIRTY_MEMORY_MIGRATION)) {
migration_bitmap_set_dirty(block->mr, addr);
}
}
memory_region_reset_dirty(block->mr, 0, block->length,
DIRTY_MEMORY_MIGRATION);
}
trace_migration_bitmap_sync_end(migration_dirty_pages
- num_dirty_pages_init);
num_dirty_pages_period += migration_dirty_pages - num_dirty_pages_init;
end_time = qemu_get_clock_ms(rt_clock);
/* more than 1 second = 1000 millisecons */
if (end_time > start_time + 1000) {
s->dirty_pages_rate = num_dirty_pages_period * 1000
/ (end_time - start_time);
start_time = end_time;
num_dirty_pages_period = 0;
}
}
/*
* ram_save_block: Writes a page of memory to the stream f
@ -352,14 +427,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
do {
mr = block->mr;
if (memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE,
DIRTY_MEMORY_MIGRATION)) {
if (migration_bitmap_test_and_reset_dirty(mr, offset)) {
uint8_t *p;
int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;
memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE,
DIRTY_MEMORY_MIGRATION);
p = memory_region_get_ram_ptr(mr) + offset;
if (is_dup_page(p)) {
@ -409,7 +480,7 @@ static uint64_t bytes_transferred;
static ram_addr_t ram_save_remaining(void)
{
return ram_list.dirty_pages;
return migration_dirty_pages;
}
uint64_t ram_bytes_remaining(void)
@ -481,17 +552,27 @@ static void ram_migration_cancel(void *opaque)
migration_end();
}
static void reset_ram_globals(void)
{
last_block = NULL;
last_offset = 0;
sort_ram_list();
}
#define MAX_WAIT 50 /* ms, half buffered_file limit */
static int ram_save_setup(QEMUFile *f, void *opaque)
{
ram_addr_t addr;
RAMBlock *block;
int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
migration_bitmap = bitmap_new(ram_pages);
bitmap_set(migration_bitmap, 1, ram_pages);
migration_dirty_pages = ram_pages;
bytes_transferred = 0;
last_block = NULL;
last_offset = 0;
sort_ram_list();
reset_ram_globals();
if (migrate_use_xbzrle()) {
XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
@ -506,17 +587,8 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
acct_clear();
}
/* Make sure all dirty bits are set */
QLIST_FOREACH(block, &ram_list.blocks, next) {
for (addr = 0; addr < block->length; addr += TARGET_PAGE_SIZE) {
if (!memory_region_get_dirty(block->mr, addr, TARGET_PAGE_SIZE,
DIRTY_MEMORY_MIGRATION)) {
memory_region_set_dirty(block->mr, addr, TARGET_PAGE_SIZE);
}
}
}
memory_global_dirty_log_start();
migration_bitmap_sync();
qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
@ -537,7 +609,8 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
double bwidth = 0;
int ret;
int i;
uint64_t expected_time;
uint64_t expected_downtime;
MigrationState *s = migrate_get_current();
bytes_transferred_last = bytes_transferred;
bwidth = qemu_get_clock_ns(rt_clock);
@ -576,31 +649,32 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
bwidth = qemu_get_clock_ns(rt_clock) - bwidth;
bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
/* if we haven't transferred anything this round, force expected_time to a
* a very high value, but without crashing */
/* if we haven't transferred anything this round, force
* expected_downtime to a very high value, but without
* crashing */
if (bwidth == 0) {
bwidth = 0.000001;
}
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
expected_downtime = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
DPRINTF("ram_save_live: expected(%" PRIu64 ") <= max(" PRIu64 ")?\n",
expected_downtime, migrate_max_downtime());
DPRINTF("ram_save_live: expected(%" PRIu64 ") <= max(%" PRIu64 ")?\n",
expected_time, migrate_max_downtime());
if (expected_downtime <= migrate_max_downtime()) {
migration_bitmap_sync();
expected_downtime = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
s->expected_downtime = expected_downtime / 1000000; /* ns -> ms */
if (expected_time <= migrate_max_downtime()) {
memory_global_sync_dirty_bitmap(get_system_memory());
expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
return expected_time <= migrate_max_downtime();
return expected_downtime <= migrate_max_downtime();
}
return 0;
}
static int ram_save_complete(QEMUFile *f, void *opaque)
{
memory_global_sync_dirty_bitmap(get_system_memory());
migration_bitmap_sync();
/* try transferring iterative blocks of memory */
@ -619,6 +693,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
g_free(migration_bitmap);
migration_bitmap = NULL;
return 0;
}

View File

@ -423,20 +423,23 @@ static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds,
error:
DPRINTF("Error reading sector %" PRId64 "\n", sector);
qemu_file_set_error(f, ret);
g_free(blk->buf);
g_free(blk);
return 0;
return ret;
}
/* return value:
* 0: too much data for max_downtime
* 1: few enough data for max_downtime
*/
static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
{
BlkMigDevState *bmds;
int ret = 0;
int ret = 1;
QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {
if (mig_save_device_dirty(f, bmds, is_async) == 0) {
ret = 1;
ret = mig_save_device_dirty(f, bmds, is_async);
if (ret <= 0) {
break;
}
}
@ -444,9 +447,10 @@ static int blk_mig_save_dirty_block(QEMUFile *f, int is_async)
return ret;
}
static void flush_blks(QEMUFile* f)
static int flush_blks(QEMUFile *f)
{
BlkMigBlock *blk;
int ret = 0;
DPRINTF("%s Enter submitted %d read_done %d transferred %d\n",
__FUNCTION__, block_mig_state.submitted, block_mig_state.read_done,
@ -457,7 +461,7 @@ static void flush_blks(QEMUFile* f)
break;
}
if (blk->ret < 0) {
qemu_file_set_error(f, blk->ret);
ret = blk->ret;
break;
}
blk_send(f, blk);
@ -474,6 +478,7 @@ static void flush_blks(QEMUFile* f)
DPRINTF("%s Exit submitted %d read_done %d transferred %d\n", __FUNCTION__,
block_mig_state.submitted, block_mig_state.read_done,
block_mig_state.transferred);
return ret;
}
static int64_t get_remaining_dirty(void)
@ -555,9 +560,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
/* start track dirty blocks */
set_dirty_tracking(1);
flush_blks(f);
ret = qemu_file_get_error(f);
ret = flush_blks(f);
if (ret) {
blk_mig_cleanup();
return ret;
@ -577,9 +580,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
flush_blks(f);
ret = qemu_file_get_error(f);
ret = flush_blks(f);
if (ret) {
blk_mig_cleanup();
return ret;
@ -598,16 +599,19 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
block_mig_state.bulk_completed = 1;
}
} else {
if (blk_mig_save_dirty_block(f, 1) == 0) {
ret = blk_mig_save_dirty_block(f, 1);
if (ret != 0) {
/* no more dirty blocks */
break;
}
}
}
if (ret) {
blk_mig_cleanup();
return ret;
}
flush_blks(f);
ret = qemu_file_get_error(f);
ret = flush_blks(f);
if (ret) {
blk_mig_cleanup();
return ret;
@ -625,9 +629,7 @@ static int block_save_complete(QEMUFile *f, void *opaque)
DPRINTF("Enter save live complete submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
flush_blks(f);
ret = qemu_file_get_error(f);
ret = flush_blks(f);
if (ret) {
blk_mig_cleanup();
return ret;
@ -639,18 +641,16 @@ static int block_save_complete(QEMUFile *f, void *opaque)
all async read completed */
assert(block_mig_state.submitted == 0);
while (blk_mig_save_dirty_block(f, 0) != 0) {
/* Do nothing */
}
do {
ret = blk_mig_save_dirty_block(f, 0);
} while (ret == 0);
blk_mig_cleanup();
/* report completion */
qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);
ret = qemu_file_get_error(f);
if (ret) {
return ret;
}
/* report completion */
qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS);
DPRINTF("Block migration completed\n");

View File

@ -23,11 +23,7 @@
typedef struct QEMUFileBuffered
{
BufferedPutFunc *put_buffer;
BufferedPutReadyFunc *put_ready;
BufferedWaitForUnfreezeFunc *wait_for_unfreeze;
BufferedCloseFunc *close;
void *opaque;
MigrationState *migration_state;
QEMUFile *file;
int freeze_output;
size_t bytes_xfer;
@ -50,70 +46,60 @@ static void buffered_append(QEMUFileBuffered *s,
const uint8_t *buf, size_t size)
{
if (size > (s->buffer_capacity - s->buffer_size)) {
void *tmp;
DPRINTF("increasing buffer capacity from %zu by %zu\n",
s->buffer_capacity, size + 1024);
s->buffer_capacity += size + 1024;
tmp = g_realloc(s->buffer, s->buffer_capacity);
if (tmp == NULL) {
fprintf(stderr, "qemu file buffer expansion failed\n");
exit(1);
}
s->buffer = tmp;
s->buffer = g_realloc(s->buffer, s->buffer_capacity);
}
memcpy(s->buffer + s->buffer_size, buf, size);
s->buffer_size += size;
}
static void buffered_flush(QEMUFileBuffered *s)
static ssize_t buffered_flush(QEMUFileBuffered *s)
{
size_t offset = 0;
int error;
error = qemu_file_get_error(s->file);
if (error != 0) {
DPRINTF("flush when error, bailing: %s\n", strerror(-error));
return;
}
ssize_t ret = 0;
DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size);
while (offset < s->buffer_size) {
ssize_t ret;
while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) {
ret = s->put_buffer(s->opaque, s->buffer + offset,
s->buffer_size - offset);
ret = migrate_fd_put_buffer(s->migration_state, s->buffer + offset,
s->buffer_size - offset);
if (ret == -EAGAIN) {
DPRINTF("backend not ready, freezing\n");
ret = 0;
s->freeze_output = 1;
break;
}
if (ret <= 0) {
DPRINTF("error flushing data, %zd\n", ret);
qemu_file_set_error(s->file, ret);
break;
} else {
DPRINTF("flushed %zd byte(s)\n", ret);
offset += ret;
s->bytes_xfer += ret;
}
}
DPRINTF("flushed %zu of %zu byte(s)\n", offset, s->buffer_size);
memmove(s->buffer, s->buffer + offset, s->buffer_size - offset);
s->buffer_size -= offset;
if (ret < 0) {
return ret;
}
return offset;
}
static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, int size)
{
QEMUFileBuffered *s = opaque;
int offset = 0, error;
ssize_t ret;
ssize_t error;
DPRINTF("putting %d bytes at %" PRId64 "\n", size, pos);
@ -126,65 +112,54 @@ static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, in
DPRINTF("unfreezing output\n");
s->freeze_output = 0;
buffered_flush(s);
while (!s->freeze_output && offset < size) {
if (s->bytes_xfer > s->xfer_limit) {
DPRINTF("transfer limit exceeded when putting\n");
break;
}
ret = s->put_buffer(s->opaque, buf + offset, size - offset);
if (ret == -EAGAIN) {
DPRINTF("backend not ready, freezing\n");
s->freeze_output = 1;
break;
}
if (ret <= 0) {
DPRINTF("error putting\n");
qemu_file_set_error(s->file, ret);
offset = -EINVAL;
break;
}
DPRINTF("put %zd byte(s)\n", ret);
offset += ret;
s->bytes_xfer += ret;
if (size > 0) {
DPRINTF("buffering %d bytes\n", size - offset);
buffered_append(s, buf, size);
}
if (offset >= 0) {
DPRINTF("buffering %d bytes\n", size - offset);
buffered_append(s, buf + offset, size - offset);
offset = size;
error = buffered_flush(s);
if (error < 0) {
DPRINTF("buffered flush error. bailing: %s\n", strerror(-error));
return error;
}
if (pos == 0 && size == 0) {
DPRINTF("file is ready\n");
if (s->bytes_xfer <= s->xfer_limit) {
if (!s->freeze_output && s->bytes_xfer < s->xfer_limit) {
DPRINTF("notifying client\n");
s->put_ready(s->opaque);
migrate_fd_put_ready(s->migration_state);
}
}
return offset;
return size;
}
static int buffered_close(void *opaque)
{
QEMUFileBuffered *s = opaque;
int ret;
ssize_t ret = 0;
int ret2;
DPRINTF("closing\n");
s->xfer_limit = INT_MAX;
while (!qemu_file_get_error(s->file) && s->buffer_size) {
buffered_flush(s);
if (s->freeze_output)
s->wait_for_unfreeze(s->opaque);
ret = buffered_flush(s);
if (ret < 0) {
break;
}
if (s->freeze_output) {
ret = migrate_fd_wait_for_unfreeze(s->migration_state);
if (ret < 0) {
break;
}
}
}
ret = s->close(s->opaque);
ret2 = migrate_fd_close(s->migration_state);
if (ret >= 0) {
ret = ret2;
}
qemu_del_timer(s->timer);
qemu_free_timer(s->timer);
g_free(s->buffer);
@ -256,29 +231,17 @@ static void buffered_rate_tick(void *opaque)
s->bytes_xfer = 0;
buffered_flush(s);
/* Add some checks around this */
s->put_ready(s->opaque);
buffered_put_buffer(s, NULL, 0, 0);
}
QEMUFile *qemu_fopen_ops_buffered(void *opaque,
size_t bytes_per_sec,
BufferedPutFunc *put_buffer,
BufferedPutReadyFunc *put_ready,
BufferedWaitForUnfreezeFunc *wait_for_unfreeze,
BufferedCloseFunc *close)
QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state)
{
QEMUFileBuffered *s;
s = g_malloc0(sizeof(*s));
s->opaque = opaque;
s->xfer_limit = bytes_per_sec / 10;
s->put_buffer = put_buffer;
s->put_ready = put_ready;
s->wait_for_unfreeze = wait_for_unfreeze;
s->close = close;
s->migration_state = migration_state;
s->xfer_limit = migration_state->bandwidth_limit / 10;
s->file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
buffered_close, buffered_rate_limit,

View File

@ -15,16 +15,8 @@
#define QEMU_BUFFERED_FILE_H
#include "hw/hw.h"
#include "migration.h"
typedef ssize_t (BufferedPutFunc)(void *opaque, const void *data, size_t size);
typedef void (BufferedPutReadyFunc)(void *opaque);
typedef void (BufferedWaitForUnfreezeFunc)(void *opaque);
typedef int (BufferedCloseFunc)(void *opaque);
QEMUFile *qemu_fopen_ops_buffered(void *opaque, size_t xfer_limit,
BufferedPutFunc *put_buffer,
BufferedPutReadyFunc *put_ready,
BufferedWaitForUnfreezeFunc *wait_for_unfreeze,
BufferedCloseFunc *close);
QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state);
#endif

37
configure vendored
View File

@ -199,7 +199,7 @@ cocoa="no"
softmmu="yes"
linux_user="no"
bsd_user="no"
guest_base=""
guest_base="yes"
uname_release=""
mixemu="no"
aix="no"
@ -871,63 +871,36 @@ for opt do
esac
done
host_guest_base="no"
case "$cpu" in
sparc)
LDFLAGS="-m32 $LDFLAGS"
QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
host_guest_base="yes"
;;
sparc64)
LDFLAGS="-m64 $LDFLAGS"
QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
host_guest_base="yes"
;;
s390)
QEMU_CFLAGS="-m31 -march=z990 $QEMU_CFLAGS"
LDFLAGS="-m31 $LDFLAGS"
host_guest_base="yes"
;;
s390x)
QEMU_CFLAGS="-m64 -march=z990 $QEMU_CFLAGS"
LDFLAGS="-m64 $LDFLAGS"
host_guest_base="yes"
;;
i386)
QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
LDFLAGS="-m32 $LDFLAGS"
cc_i386='$(CC) -m32'
host_guest_base="yes"
;;
x86_64)
QEMU_CFLAGS="-m64 $QEMU_CFLAGS"
LDFLAGS="-m64 $LDFLAGS"
cc_i386='$(CC) -m32'
host_guest_base="yes"
;;
arm*)
host_guest_base="yes"
;;
ppc*)
host_guest_base="yes"
;;
mips*)
host_guest_base="yes"
;;
ia64*)
host_guest_base="yes"
;;
hppa*)
host_guest_base="yes"
;;
unicore32*)
host_guest_base="yes"
;;
# No special flags required for other host CPUs
esac
[ -z "$guest_base" ] && guest_base="$host_guest_base"
default_target_list=""
# these targets are portable
@ -1323,7 +1296,7 @@ if test -z "$cross_prefix" ; then
# big/little endian test
cat > $TMPC << EOF
#include <inttypes.h>
int main(int argc, char ** argv){
int main(void) {
volatile uint32_t i=0x01234567;
return (*((uint8_t*)(&i))) == 0x67;
}
@ -2896,7 +2869,7 @@ static int sfaa(int *ptr)
return __sync_fetch_and_and(ptr, 0);
}
int main(int argc, char **argv)
int main(void)
{
int val = 42;
sfaa(&val);
@ -3227,7 +3200,7 @@ echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
echo "CONFIG_QEMU_HELPERDIR=\"$libexecdir\"" >> $config_host_mak
echo "qemu_helperdir=$libexecdir" >> $config_host_mak
echo "ARCH=$ARCH" >> $config_host_mak
if test "$debug_tcg" = "yes" ; then

View File

@ -500,7 +500,6 @@ typedef struct RAMBlock {
typedef struct RAMList {
uint8_t *phys_dirty;
QLIST_HEAD(, RAMBlock) blocks;
uint64_t dirty_pages;
} RAMList;
extern RAMList ram_list;
@ -518,6 +517,7 @@ extern int mem_prealloc;
#define TLB_MMIO (1 << 5)
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
ram_addr_t last_ram_offset(void);
#endif /* !CONFIG_USER_ONLY */
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,

9
cpus.c
View File

@ -898,6 +898,11 @@ int qemu_cpu_is_self(void *_env)
return qemu_thread_is_self(cpu->thread);
}
static bool qemu_in_vcpu_thread(void)
{
return cpu_single_env && qemu_cpu_is_self(cpu_single_env);
}
void qemu_mutex_lock_iothread(void)
{
if (!tcg_enabled()) {
@ -943,7 +948,7 @@ void pause_all_vcpus(void)
penv = penv->next_cpu;
}
if (!qemu_thread_is_self(&io_thread)) {
if (qemu_in_vcpu_thread()) {
cpu_stop_current();
if (!kvm_enabled()) {
while (penv) {
@ -1060,7 +1065,7 @@ void cpu_stop_current(void)
void vm_stop(RunState state)
{
if (!qemu_thread_is_self(&io_thread)) {
if (qemu_in_vcpu_thread()) {
qemu_system_vmstop_request(state);
/*
* FIXME: should not return to device code in case

View File

@ -21,11 +21,11 @@
#include "cpu.h"
#include "exec-all.h"
#include "memory.h"
#include "exec-memory.h"
#include "cputlb.h"
#define WANT_EXEC_OBSOLETE
#include "exec-obsolete.h"
#include "memory-internal.h"
//#define DEBUG_TLB
//#define DEBUG_TLB_CHECK
@ -252,7 +252,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
if (size != TARGET_PAGE_SIZE) {
tlb_add_large_page(env, vaddr, size);
}
section = phys_page_find(paddr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS);
#if defined(DEBUG_TLB)
printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
" prot=%x idx=%d pd=0x%08lx\n",

View File

@ -26,7 +26,8 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
target_ulong vaddr);
void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
uintptr_t length);
MemoryRegionSection *phys_page_find(target_phys_addr_t index);
MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d,
target_phys_addr_t index);
void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length);
void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
extern int tlb_flush_count;

View File

@ -19,3 +19,5 @@ CONFIG_IDE_PCI=y
CONFIG_AHCI=y
CONFIG_ESP=y
CONFIG_ESP_PCI=y
CONFIG_SERIAL=y
CONFIG_SERIAL_PCI=y

View File

@ -14,7 +14,8 @@
/* #define DEBUG_IOMMU */
static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
static void do_dma_memory_set(AddressSpace *as,
dma_addr_t addr, uint8_t c, dma_addr_t len)
{
#define FILLBUF_SIZE 512
uint8_t fillbuf[FILLBUF_SIZE];
@ -23,7 +24,7 @@ static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
memset(fillbuf, c, FILLBUF_SIZE);
while (len > 0) {
l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE;
cpu_physical_memory_rw(addr, fillbuf, l, true);
address_space_rw(as, addr, fillbuf, l, true);
len -= l;
addr += l;
}
@ -36,7 +37,7 @@ int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
if (dma_has_iommu(dma)) {
return iommu_dma_memory_set(dma, addr, c, len);
}
do_dma_memory_set(addr, c, len);
do_dma_memory_set(dma->as, addr, c, len);
return 0;
}
@ -332,8 +333,7 @@ int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr,
plen = len;
}
cpu_physical_memory_rw(paddr, buf, plen,
dir == DMA_DIRECTION_FROM_DEVICE);
address_space_rw(dma->as, paddr, buf, plen, dir == DMA_DIRECTION_FROM_DEVICE);
len -= plen;
addr += plen;
@ -366,7 +366,7 @@ int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c,
plen = len;
}
do_dma_memory_set(paddr, c, plen);
do_dma_memory_set(dma->as, paddr, c, plen);
len -= plen;
addr += plen;
@ -375,13 +375,14 @@ int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c,
return 0;
}
void dma_context_init(DMAContext *dma, DMATranslateFunc translate,
void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate,
DMAMapFunc map, DMAUnmapFunc unmap)
{
#ifdef DEBUG_IOMMU
fprintf(stderr, "dma_context_init(%p, %p, %p, %p)\n",
dma, translate, map, unmap);
#endif
dma->as = as;
dma->translate = translate;
dma->map = map;
dma->unmap = unmap;
@ -407,14 +408,13 @@ void *iommu_dma_memory_map(DMAContext *dma, dma_addr_t addr, dma_addr_t *len,
/*
* If this is true, the virtual region is contiguous,
* but the translated physical region isn't. We just
* clamp *len, much like cpu_physical_memory_map() does.
* clamp *len, much like address_space_map() does.
*/
if (plen < *len) {
*len = plen;
}
buf = cpu_physical_memory_map(paddr, &plen,
dir == DMA_DIRECTION_FROM_DEVICE);
buf = address_space_map(dma->as, paddr, &plen, dir == DMA_DIRECTION_FROM_DEVICE);
*len = plen;
return buf;
@ -428,8 +428,7 @@ void iommu_dma_memory_unmap(DMAContext *dma, void *buffer, dma_addr_t len,
return;
}
cpu_physical_memory_unmap(buffer, len,
dir == DMA_DIRECTION_FROM_DEVICE,
access_len);
address_space_unmap(dma->as, buffer, len, dir == DMA_DIRECTION_FROM_DEVICE,
access_len);
}

17
dma.h
View File

@ -11,6 +11,7 @@
#define DMA_H
#include <stdio.h>
#include "memory.h"
#include "hw/hw.h"
#include "block.h"
#include "kvm.h"
@ -61,6 +62,7 @@ typedef void DMAUnmapFunc(DMAContext *dma,
dma_addr_t access_len);
struct DMAContext {
AddressSpace *as;
DMATranslateFunc *translate;
DMAMapFunc *map;
DMAUnmapFunc *unmap;
@ -93,7 +95,7 @@ static inline void dma_barrier(DMAContext *dma, DMADirection dir)
static inline bool dma_has_iommu(DMAContext *dma)
{
return !!dma;
return dma && dma->translate;
}
/* Checks that the given range of addresses is valid for DMA. This is
@ -120,8 +122,7 @@ static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr,
{
if (!dma_has_iommu(dma)) {
/* Fast-path for no IOMMU */
cpu_physical_memory_rw(addr, buf, len,
dir == DMA_DIRECTION_FROM_DEVICE);
address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
return 0;
} else {
return iommu_dma_memory_rw(dma, addr, buf, len, dir);
@ -179,8 +180,7 @@ static inline void *dma_memory_map(DMAContext *dma,
target_phys_addr_t xlen = *len;
void *p;
p = cpu_physical_memory_map(addr, &xlen,
dir == DMA_DIRECTION_FROM_DEVICE);
p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
*len = xlen;
return p;
} else {
@ -196,9 +196,8 @@ static inline void dma_memory_unmap(DMAContext *dma,
DMADirection dir, dma_addr_t access_len)
{
if (!dma_has_iommu(dma)) {
cpu_physical_memory_unmap(buffer, (target_phys_addr_t)len,
dir == DMA_DIRECTION_FROM_DEVICE,
access_len);
address_space_unmap(dma->as, buffer, (target_phys_addr_t)len,
dir == DMA_DIRECTION_FROM_DEVICE, access_len);
} else {
iommu_dma_memory_unmap(dma, buffer, len, dir, access_len);
}
@ -242,7 +241,7 @@ DEFINE_LDST_DMA(q, q, 64, be);
#undef DEFINE_LDST_DMA
void dma_context_init(DMAContext *dma, DMATranslateFunc translate,
void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate,
DMAMapFunc map, DMAUnmapFunc unmap);
struct ScatterGatherEntry {

109
docs/qemupciserial.inf Normal file
View File

@ -0,0 +1,109 @@
; qemupciserial.inf for QEMU, based on MSPORTS.INF
; The driver itself is shipped with Windows (serial.sys). This is
; just a inf file to tell windows which pci id the serial pci card
; emulated by qemu has, and to apply a name tag to it which windows
; will show in the device manager.
; Installing the driver: Go to device manager. You should find a "pci
; serial card" tagged with a yellow question mark. Open properties.
; Pick "update driver". Then "select driver manually". Pick "Ports
; (Com+Lpt)" from the list. Click "Have a disk". Select this file.
; Procedure may vary a bit depending on the windows version.
; FIXME: This file covers the single port version only.
[Version]
Signature="$CHICAGO$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%QEMU%
DriverVer=09/24/2012,1.3.0
[SourceDisksNames]
3426=windows cd
[SourceDisksFiles]
serial.sys = 3426
serenum.sys = 3426
[DestinationDirs]
DefaultDestDir = 11 ;LDID_SYS
ComPort.NT.Copy = 12 ;DIRID_DRIVERS
SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS
; Drivers
;----------------------------------------------------------
[Manufacturer]
%QEMU%=QEMU,NTx86
[QEMU.NTx86]
%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, "PCI\VEN_1b36&DEV_0002&CC_0700"
; COM sections
;----------------------------------------------------------
[ComPort.AddReg]
HKR,,PortSubClass,1,01
[ComPort.NT]
AddReg=ComPort.AddReg, ComPort.NT.AddReg
LogConfig=caa
SyssetupPnPFlags = 1
[ComPort.NT.HW]
AddReg=ComPort.NT.HW.AddReg
[ComPort.NT.AddReg]
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[ComPort.NT.HW.AddReg]
HKR,,"UpperFilters",0x00010000,"serenum"
;-------------- Service installation
; Port Driver (function driver for this device)
[ComPort.NT.Services]
AddService = Serial, 0x00000002, Serial_Service_Inst, Serial_EventLog_Inst
AddService = Serenum,,Serenum_Service_Inst
; -------------- Serial Port Driver install sections
[Serial_Service_Inst]
DisplayName = %Serial.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 1 ; SERVICE_SYSTEM_START (this driver may do detection)
ErrorControl = 0 ; SERVICE_ERROR_IGNORE
ServiceBinary = %12%\serial.sys
LoadOrderGroup = Extended base
; -------------- Serenum Driver install section
[Serenum_Service_Inst]
DisplayName = %Serenum.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\serenum.sys
LoadOrderGroup = PNP Filter
[Serial_EventLog_Inst]
AddReg = Serial_EventLog_AddReg
[Serial_EventLog_AddReg]
HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys"
HKR,,TypesSupported,0x00010001,7
; The following sections are COM port resource configs.
; Section name format means:
; Char 1 = c (COM port)
; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any)
; Char 3 = IRQ config: #, a (any)
[caa] ; Any base, any IRQ
ConfigPriority=HARDRECONFIG
IOConfig=8@100-ffff%fff8(3ff::)
IRQConfig=S:3,4,5,7,9,10,11,12,14,15
[Strings]
QEMU="QEMU"
QEMU-PCI_SERIAL.DeviceDesc="QEMU Serial PCI Card"
Serial.SVCDESC = "Serial port driver"
Serenum.SVCDESC = "Serenum Filter Driver"

34
docs/specs/pci-serial.txt Normal file
View File

@ -0,0 +1,34 @@
QEMU pci serial devices
=======================
There is one single-port variant and two muliport-variants. Linux
guests out-of-the box with all cards. There is a Windows inf file
(docs/qemupciserial.inf) to setup the single-port card in Windows
guests.
single-port card
----------------
Name: pci-serial
PCI ID: 1b36:0002
PCI Region 0:
IO bar, 8 bytes long, with the 16550 uart mapped to it.
Interrupt is wired to pin A.
multiport cards
---------------
Name: pci-serial-2x
PCI ID: 1b36:0003
Name: pci-serial-4x
PCI ID: 1b36:0004
PCI Region 0:
IO bar, with two/four 16550 uart mapped after each other.
The first is at offset 0, second at offset 8, ...
Interrupt is wired to pin A.

View File

@ -0,0 +1,64 @@
QEMU Standard VGA
=================
Exists in two variants, for isa and pci.
command line switches:
-vga std [ picks isa for -M isapc, otherwise pci ]
-device VGA [ pci variant ]
-device isa-vga [ isa variant ]
PCI spec
--------
Applies to the pci variant only for obvious reasons.
PCI ID: 1234:1111
PCI Region 0:
Framebuffer memory, 16 MB in size (by default).
Size is tunable via vga_mem_mb property.
PCI Region 1:
Reserved (so we have the option to make the framebuffer bar 64bit).
PCI Region 2:
MMIO bar, 4096 bytes in size (qemu 1.3+)
PCI ROM Region:
Holds the vgabios (qemu 0.14+).
IO ports used
-------------
03c0 - 03df : standard vga ports
01ce : bochs vbe interface index port
01cf : bochs vbe interface data port
Memory regions used
-------------------
0xe0000000 : Framebuffer memory, isa variant only.
The pci variant used to mirror the framebuffer bar here, qemu 0.14+
stops doing that (except when in -M pc-$old compat mode).
MMIO area spec
--------------
Likewise applies to the pci variant only for obvious reasons.
0000 - 03ff : reserved, for possible virtio extension.
0400 - 041f : vga ioports (0x3c0 -> 0x3df), remapped 1:1.
word access is supported, bytes are written
in little endia order (aka index port first),
so indexed registers can be updated with a
single mmio write (and thus only one vmexit).
0500 - 0515 : bochs dispi interface registers, mapped flat
without index/data ports. Use (index << 1)
as offset for (16bit) register access.

View File

@ -121,8 +121,6 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
#define CODE_GEN_PHYS_HASH_BITS 15
#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS)
#define MIN_CODE_GEN_BUFFER_SIZE (1024 * 1024)
/* estimated block size for TB allocation */
/* XXX: use a per code average code fragment size and modulate it
according to the host CPU */
@ -296,7 +294,8 @@ extern int tb_invalidated_flag;
#if defined(CONFIG_TCG_INTERPRETER)
/* Alpha and SH4 user mode emulations and Softmmu call GETPC().
For all others, GETPC remains undefined (which makes TCI a little faster. */
# if defined(CONFIG_SOFTMMU) || defined(TARGET_ALPHA) || defined(TARGET_SH4)
# if defined(CONFIG_SOFTMMU) || defined(TARGET_ALPHA) || defined(TARGET_SH4) \
|| defined(TARGET_SPARC)
extern uintptr_t tci_tb_ptr;
# define GETPC() tci_tb_ptr
# endif

View File

@ -33,11 +33,8 @@ MemoryRegion *get_system_memory(void);
*/
MemoryRegion *get_system_io(void);
/* Set the root memory region. This region is the system memory map. */
void set_system_memory_map(MemoryRegion *mr);
/* Set the I/O memory region. This region is the I/O memory map. */
void set_system_io_map(MemoryRegion *mr);
extern AddressSpace address_space_memory;
extern AddressSpace address_space_io;
#endif

564
exec.c
View File

@ -59,8 +59,7 @@
#include "cputlb.h"
#define WANT_EXEC_OBSOLETE
#include "exec-obsolete.h"
#include "memory-internal.h"
//#define DEBUG_TB_INVALIDATE
//#define DEBUG_FLUSH
@ -86,26 +85,11 @@ static int nb_tbs;
/* any access to the tbs or the page table must use this lock */
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
#if defined(__arm__) || defined(__sparc__)
/* The prologue must be reachable with a direct jump. ARM and Sparc64
have limited branch ranges (possibly also PPC) so place it in a
section close to code segment. */
#define code_gen_section \
__attribute__((__section__(".gen_code"))) \
__attribute__((aligned (32)))
#elif defined(_WIN32) && !defined(_WIN64)
#define code_gen_section \
__attribute__((aligned (16)))
#else
#define code_gen_section \
__attribute__((aligned (32)))
#endif
uint8_t code_gen_prologue[1024] code_gen_section;
uint8_t *code_gen_prologue;
static uint8_t *code_gen_buffer;
static unsigned long code_gen_buffer_size;
static size_t code_gen_buffer_size;
/* threshold to flush the translated code buffer */
static unsigned long code_gen_buffer_max_size;
static size_t code_gen_buffer_max_size;
static uint8_t *code_gen_ptr;
#if !defined(CONFIG_USER_ONLY)
@ -117,6 +101,9 @@ RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
static MemoryRegion *system_memory;
static MemoryRegion *system_io;
AddressSpace address_space_io;
AddressSpace address_space_memory;
MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
static MemoryRegion io_mem_subpage_ram;
@ -185,7 +172,6 @@ uintptr_t qemu_host_page_mask;
static void *l1_map[V_L1_SIZE];
#if !defined(CONFIG_USER_ONLY)
typedef struct PhysPageEntry PhysPageEntry;
static MemoryRegionSection *phys_sections;
static unsigned phys_sections_nb, phys_sections_nb_alloc;
@ -194,22 +180,12 @@ static uint16_t phys_section_notdirty;
static uint16_t phys_section_rom;
static uint16_t phys_section_watch;
struct PhysPageEntry {
uint16_t is_leaf : 1;
/* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
uint16_t ptr : 15;
};
/* Simple allocator for PhysPageEntry nodes */
static PhysPageEntry (*phys_map_nodes)[L2_SIZE];
static unsigned phys_map_nodes_nb, phys_map_nodes_nb_alloc;
#define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
/* This is a multi-level map on the physical address space.
The bottom level has pointers to MemoryRegionSections. */
static PhysPageEntry phys_map = { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
static void io_mem_init(void);
static void memory_map_init(void);
@ -221,7 +197,7 @@ static int tb_flush_count;
static int tb_phys_invalidate_count;
#ifdef _WIN32
static void map_exec(void *addr, long size)
static inline void map_exec(void *addr, long size)
{
DWORD old_protect;
VirtualProtect(addr, size,
@ -229,7 +205,7 @@ static void map_exec(void *addr, long size)
}
#else
static void map_exec(void *addr, long size)
static inline void map_exec(void *addr, long size)
{
unsigned long start, end, page_size;
@ -457,18 +433,19 @@ static void phys_page_set_level(PhysPageEntry *lp, target_phys_addr_t *index,
}
}
static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb,
static void phys_page_set(AddressSpaceDispatch *d,
target_phys_addr_t index, target_phys_addr_t nb,
uint16_t leaf)
{
/* Wildly overreserve - it doesn't matter much. */
phys_map_node_reserve(3 * P_L2_LEVELS);
phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
}
MemoryRegionSection *phys_page_find(target_phys_addr_t index)
MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, target_phys_addr_t index)
{
PhysPageEntry lp = phys_map;
PhysPageEntry lp = d->phys_map;
PhysPageEntry *p;
int i;
uint16_t s_index = phys_section_unassigned;
@ -497,111 +474,142 @@ bool memory_region_is_unassigned(MemoryRegion *mr)
#define mmap_unlock() do { } while(0)
#endif
#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
#if defined(CONFIG_USER_ONLY)
/* Currently it is not recommended to allocate big chunks of data in
user mode. It will change when a dedicated libc will be used */
user mode. It will change when a dedicated libc will be used. */
/* ??? 64-bit hosts ought to have no problem mmaping data outside the
region in which the guest needs to run. Revisit this. */
#define USE_STATIC_CODE_GEN_BUFFER
#endif
/* ??? Should configure for this, not list operating systems here. */
#if (defined(__linux__) \
|| defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
|| defined(__DragonFly__) || defined(__OpenBSD__) \
|| defined(__NetBSD__))
# define USE_MMAP
#endif
/* Minimum size of the code gen buffer. This number is randomly chosen,
but not so small that we can't have a fair number of TB's live. */
#define MIN_CODE_GEN_BUFFER_SIZE (1024u * 1024)
/* Maximum size of the code gen buffer we'd like to use. Unless otherwise
indicated, this is constrained by the range of direct branches on the
host cpu, as used by the TCG implementation of goto_tb. */
#if defined(__x86_64__)
# define MAX_CODE_GEN_BUFFER_SIZE (2ul * 1024 * 1024 * 1024)
#elif defined(__sparc__)
# define MAX_CODE_GEN_BUFFER_SIZE (2ul * 1024 * 1024 * 1024)
#elif defined(__arm__)
# define MAX_CODE_GEN_BUFFER_SIZE (16u * 1024 * 1024)
#elif defined(__s390x__)
/* We have a +- 4GB range on the branches; leave some slop. */
# define MAX_CODE_GEN_BUFFER_SIZE (3ul * 1024 * 1024 * 1024)
#else
# define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
#endif
#define DEFAULT_CODE_GEN_BUFFER_SIZE_1 (32u * 1024 * 1024)
#define DEFAULT_CODE_GEN_BUFFER_SIZE \
(DEFAULT_CODE_GEN_BUFFER_SIZE_1 < MAX_CODE_GEN_BUFFER_SIZE \
? DEFAULT_CODE_GEN_BUFFER_SIZE_1 : MAX_CODE_GEN_BUFFER_SIZE)
static inline size_t size_code_gen_buffer(size_t tb_size)
{
/* Size the buffer. */
if (tb_size == 0) {
#ifdef USE_STATIC_CODE_GEN_BUFFER
tb_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
#else
/* ??? Needs adjustments. */
/* ??? If we relax the requirement that CONFIG_USER_ONLY use the
static buffer, we could size this on RESERVED_VA, on the text
segment size of the executable, or continue to use the default. */
tb_size = (unsigned long)(ram_size / 4);
#endif
}
if (tb_size < MIN_CODE_GEN_BUFFER_SIZE) {
tb_size = MIN_CODE_GEN_BUFFER_SIZE;
}
if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
tb_size = MAX_CODE_GEN_BUFFER_SIZE;
}
code_gen_buffer_size = tb_size;
return tb_size;
}
#ifdef USE_STATIC_CODE_GEN_BUFFER
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
__attribute__((aligned (CODE_GEN_ALIGN)));
#endif
__attribute__((aligned(CODE_GEN_ALIGN)));
static void code_gen_alloc(unsigned long tb_size)
static inline void *alloc_code_gen_buffer(void)
{
#ifdef USE_STATIC_CODE_GEN_BUFFER
code_gen_buffer = static_code_gen_buffer;
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
map_exec(code_gen_buffer, code_gen_buffer_size);
#else
code_gen_buffer_size = tb_size;
if (code_gen_buffer_size == 0) {
#if defined(CONFIG_USER_ONLY)
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
#else
/* XXX: needs adjustments */
code_gen_buffer_size = (unsigned long)(ram_size / 4);
#endif
}
if (code_gen_buffer_size < MIN_CODE_GEN_BUFFER_SIZE)
code_gen_buffer_size = MIN_CODE_GEN_BUFFER_SIZE;
/* The code gen buffer location may have constraints depending on
the host cpu and OS */
#if defined(__linux__)
{
int flags;
void *start = NULL;
map_exec(static_code_gen_buffer, code_gen_buffer_size);
return static_code_gen_buffer;
}
#elif defined(USE_MMAP)
static inline void *alloc_code_gen_buffer(void)
{
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
uintptr_t start = 0;
void *buf;
flags = MAP_PRIVATE | MAP_ANONYMOUS;
#if defined(__x86_64__)
flags |= MAP_32BIT;
/* Cannot map more than that */
if (code_gen_buffer_size > (800 * 1024 * 1024))
code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc__) && HOST_LONG_BITS == 64
// Map the buffer below 2G, so we can use direct calls and branches
start = (void *) 0x40000000UL;
if (code_gen_buffer_size > (512 * 1024 * 1024))
code_gen_buffer_size = (512 * 1024 * 1024);
#elif defined(__arm__)
/* Keep the buffer no bigger than 16MB to branch between blocks */
if (code_gen_buffer_size > 16 * 1024 * 1024)
code_gen_buffer_size = 16 * 1024 * 1024;
#elif defined(__s390x__)
/* Map the buffer so that we can use direct calls and branches. */
/* We have a +- 4GB range on the branches; leave some slop. */
if (code_gen_buffer_size > (3ul * 1024 * 1024 * 1024)) {
code_gen_buffer_size = 3ul * 1024 * 1024 * 1024;
}
start = (void *)0x90000000UL;
#endif
code_gen_buffer = mmap(start, code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC,
flags, -1, 0);
if (code_gen_buffer == MAP_FAILED) {
fprintf(stderr, "Could not allocate dynamic translator buffer\n");
exit(1);
}
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
|| defined(__DragonFly__) || defined(__OpenBSD__) \
|| defined(__NetBSD__)
{
int flags;
void *addr = NULL;
flags = MAP_PRIVATE | MAP_ANONYMOUS;
#if defined(__x86_64__)
/* FreeBSD doesn't have MAP_32BIT, use MAP_FIXED and assume
* 0x40000000 is free */
flags |= MAP_FIXED;
addr = (void *)0x40000000;
/* Cannot map more than that */
if (code_gen_buffer_size > (800 * 1024 * 1024))
code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc__) && HOST_LONG_BITS == 64
// Map the buffer below 2G, so we can use direct calls and branches
addr = (void *) 0x40000000UL;
if (code_gen_buffer_size > (512 * 1024 * 1024)) {
code_gen_buffer_size = (512 * 1024 * 1024);
}
#endif
code_gen_buffer = mmap(addr, code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC,
flags, -1, 0);
if (code_gen_buffer == MAP_FAILED) {
fprintf(stderr, "Could not allocate dynamic translator buffer\n");
exit(1);
}
/* Constrain the position of the buffer based on the host cpu.
Note that these addresses are chosen in concert with the
addresses assigned in the relevant linker script file. */
# if defined(__PIE__) || defined(__PIC__)
/* Don't bother setting a preferred location if we're building
a position-independent executable. We're more likely to get
an address near the main executable if we let the kernel
choose the address. */
# elif defined(__x86_64__) && defined(MAP_32BIT)
/* Force the memory down into low memory with the executable.
Leave the choice of exact location with the kernel. */
flags |= MAP_32BIT;
/* Cannot expect to map more than 800MB in low memory. */
if (code_gen_buffer_size > 800u * 1024 * 1024) {
code_gen_buffer_size = 800u * 1024 * 1024;
}
# elif defined(__sparc__)
start = 0x40000000ul;
# elif defined(__s390x__)
start = 0x90000000ul;
# endif
buf = mmap((void *)start, code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0);
return buf == MAP_FAILED ? NULL : buf;
}
#else
code_gen_buffer = g_malloc(code_gen_buffer_size);
map_exec(code_gen_buffer, code_gen_buffer_size);
#endif
#endif /* !USE_STATIC_CODE_GEN_BUFFER */
map_exec(code_gen_prologue, sizeof(code_gen_prologue));
static inline void *alloc_code_gen_buffer(void)
{
void *buf = g_malloc(code_gen_buffer_size);
if (buf) {
map_exec(buf, code_gen_buffer_size);
}
return buf;
}
#endif /* USE_STATIC_CODE_GEN_BUFFER, USE_MMAP */
static inline void code_gen_alloc(size_t tb_size)
{
code_gen_buffer_size = size_code_gen_buffer(tb_size);
code_gen_buffer = alloc_code_gen_buffer();
if (code_gen_buffer == NULL) {
fprintf(stderr, "Could not allocate dynamic translator buffer\n");
exit(1);
}
/* Steal room for the prologue at the end of the buffer. This ensures
(via the MAX_CODE_GEN_BUFFER_SIZE limits above) that direct branches
from TB's to the prologue are going to be in range. It also means
that we don't need to mark (additional) portions of the data segment
as executable. */
code_gen_prologue = code_gen_buffer + code_gen_buffer_size - 1024;
code_gen_buffer_size -= 1024;
code_gen_buffer_max_size = code_gen_buffer_size -
(TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
@ -1470,7 +1478,7 @@ void tb_invalidate_phys_addr(target_phys_addr_t addr)
ram_addr_t ram_addr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr)
|| (section->mr->rom_device && section->mr->readable))) {
return;
@ -2208,9 +2216,9 @@ static void destroy_l2_mapping(PhysPageEntry *lp, unsigned level)
lp->ptr = PHYS_MAP_NODE_NIL;
}
static void destroy_all_mappings(void)
static void destroy_all_mappings(AddressSpaceDispatch *d)
{
destroy_l2_mapping(&phys_map, P_L2_LEVELS - 1);
destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
phys_map_nodes_reset();
}
@ -2230,12 +2238,12 @@ static void phys_sections_clear(void)
phys_sections_nb = 0;
}
static void register_subpage(MemoryRegionSection *section)
static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
{
subpage_t *subpage;
target_phys_addr_t base = section->offset_within_address_space
& TARGET_PAGE_MASK;
MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);
MemoryRegionSection *existing = phys_page_find(d, base >> TARGET_PAGE_BITS);
MemoryRegionSection subsection = {
.offset_within_address_space = base,
.size = TARGET_PAGE_SIZE,
@ -2247,7 +2255,7 @@ static void register_subpage(MemoryRegionSection *section)
if (!(existing->mr->subpage)) {
subpage = subpage_init(base);
subsection.mr = &subpage->iomem;
phys_page_set(base >> TARGET_PAGE_BITS, 1,
phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
phys_section_add(&subsection));
} else {
subpage = container_of(existing->mr, subpage_t, iomem);
@ -2258,7 +2266,7 @@ static void register_subpage(MemoryRegionSection *section)
}
static void register_multipage(MemoryRegionSection *section)
static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *section)
{
target_phys_addr_t start_addr = section->offset_within_address_space;
ram_addr_t size = section->size;
@ -2268,13 +2276,13 @@ static void register_multipage(MemoryRegionSection *section)
assert(size);
addr = start_addr;
phys_page_set(addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
phys_page_set(d, addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS,
section_index);
}
void cpu_register_physical_memory_log(MemoryRegionSection *section,
bool readonly)
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
{
AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
MemoryRegionSection now = *section, remain = *section;
if ((now.offset_within_address_space & ~TARGET_PAGE_MASK)
@ -2282,7 +2290,7 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
now.size = MIN(TARGET_PAGE_ALIGN(now.offset_within_address_space)
- now.offset_within_address_space,
now.size);
register_subpage(&now);
register_subpage(d, &now);
remain.size -= now.size;
remain.offset_within_address_space += now.size;
remain.offset_within_region += now.size;
@ -2291,10 +2299,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
now = remain;
if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
now.size = TARGET_PAGE_SIZE;
register_subpage(&now);
register_subpage(d, &now);
} else {
now.size &= TARGET_PAGE_MASK;
register_multipage(&now);
register_multipage(d, &now);
}
remain.size -= now.size;
remain.offset_within_address_space += now.size;
@ -2302,23 +2310,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section,
}
now = remain;
if (now.size) {
register_subpage(&now);
register_subpage(d, &now);
}
}
void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
{
if (kvm_enabled())
kvm_coalesce_mmio_region(addr, size);
}
void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
{
if (kvm_enabled())
kvm_uncoalesce_mmio_region(addr, size);
}
void qemu_flush_coalesced_mmio_buffer(void)
{
if (kvm_enabled())
@ -2454,7 +2449,7 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
return offset;
}
static ram_addr_t last_ram_offset(void)
ram_addr_t last_ram_offset(void)
{
RAMBlock *block;
ram_addr_t last = 0;
@ -2576,6 +2571,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);
qemu_ram_setup_dump(new_block->host, size);
qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
if (kvm_enabled())
kvm_setup_guest_memory(new_block->host, size);
@ -3166,18 +3162,24 @@ static void io_mem_init(void)
"watch", UINT64_MAX);
}
static void mem_begin(MemoryListener *listener)
{
AddressSpaceDispatch *d = container_of(listener, AddressSpaceDispatch, listener);
destroy_all_mappings(d);
d->phys_map.ptr = PHYS_MAP_NODE_NIL;
}
static void core_begin(MemoryListener *listener)
{
destroy_all_mappings();
phys_sections_clear();
phys_map.ptr = PHYS_MAP_NODE_NIL;
phys_section_unassigned = dummy_section(&io_mem_unassigned);
phys_section_notdirty = dummy_section(&io_mem_notdirty);
phys_section_rom = dummy_section(&io_mem_rom);
phys_section_watch = dummy_section(&io_mem_watch);
}
static void core_commit(MemoryListener *listener)
static void tcg_commit(MemoryListener *listener)
{
CPUArchState *env;
@ -3189,38 +3191,6 @@ static void core_commit(MemoryListener *listener)
}
}
static void core_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
cpu_register_physical_memory_log(section, section->readonly);
}
static void core_region_del(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void core_region_nop(MemoryListener *listener,
MemoryRegionSection *section)
{
cpu_register_physical_memory_log(section, section->readonly);
}
static void core_log_start(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void core_log_stop(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void core_log_sync(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void core_log_global_start(MemoryListener *listener)
{
cpu_physical_memory_set_dirty_tracking(1);
@ -3231,26 +3201,6 @@ static void core_log_global_stop(MemoryListener *listener)
cpu_physical_memory_set_dirty_tracking(0);
}
static void core_eventfd_add(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e)
{
}
static void core_eventfd_del(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e)
{
}
static void io_begin(MemoryListener *listener)
{
}
static void io_commit(MemoryListener *listener)
{
}
static void io_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
@ -3269,90 +3219,63 @@ static void io_region_del(MemoryListener *listener,
isa_unassign_ioport(section->offset_within_address_space, section->size);
}
static void io_region_nop(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void io_log_start(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void io_log_stop(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void io_log_sync(MemoryListener *listener,
MemoryRegionSection *section)
{
}
static void io_log_global_start(MemoryListener *listener)
{
}
static void io_log_global_stop(MemoryListener *listener)
{
}
static void io_eventfd_add(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e)
{
}
static void io_eventfd_del(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data, EventNotifier *e)
{
}
static MemoryListener core_memory_listener = {
.begin = core_begin,
.commit = core_commit,
.region_add = core_region_add,
.region_del = core_region_del,
.region_nop = core_region_nop,
.log_start = core_log_start,
.log_stop = core_log_stop,
.log_sync = core_log_sync,
.log_global_start = core_log_global_start,
.log_global_stop = core_log_global_stop,
.eventfd_add = core_eventfd_add,
.eventfd_del = core_eventfd_del,
.priority = 0,
.priority = 1,
};
static MemoryListener io_memory_listener = {
.begin = io_begin,
.commit = io_commit,
.region_add = io_region_add,
.region_del = io_region_del,
.region_nop = io_region_nop,
.log_start = io_log_start,
.log_stop = io_log_stop,
.log_sync = io_log_sync,
.log_global_start = io_log_global_start,
.log_global_stop = io_log_global_stop,
.eventfd_add = io_eventfd_add,
.eventfd_del = io_eventfd_del,
.priority = 0,
};
static MemoryListener tcg_memory_listener = {
.commit = tcg_commit,
};
void address_space_init_dispatch(AddressSpace *as)
{
AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
d->listener = (MemoryListener) {
.begin = mem_begin,
.region_add = mem_add,
.region_nop = mem_add,
.priority = 0,
};
as->dispatch = d;
memory_listener_register(&d->listener, as);
}
void address_space_destroy_dispatch(AddressSpace *as)
{
AddressSpaceDispatch *d = as->dispatch;
memory_listener_unregister(&d->listener);
destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
g_free(d);
as->dispatch = NULL;
}
static void memory_map_init(void)
{
system_memory = g_malloc(sizeof(*system_memory));
memory_region_init(system_memory, "system", INT64_MAX);
set_system_memory_map(system_memory);
address_space_init(&address_space_memory, system_memory);
address_space_memory.name = "memory";
system_io = g_malloc(sizeof(*system_io));
memory_region_init(system_io, "io", 65536);
set_system_io_map(system_io);
address_space_init(&address_space_io, system_io);
address_space_io.name = "I/O";
memory_listener_register(&core_memory_listener, system_memory);
memory_listener_register(&io_memory_listener, system_io);
memory_listener_register(&core_memory_listener, &address_space_memory);
memory_listener_register(&io_memory_listener, &address_space_io);
memory_listener_register(&tcg_memory_listener, &address_space_memory);
}
MemoryRegion *get_system_memory(void)
@ -3422,9 +3345,10 @@ static void invalidate_and_set_dirty(target_phys_addr_t addr,
xen_modified_memory(addr, length);
}
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
int len, bool is_write)
{
AddressSpaceDispatch *d = as->dispatch;
int l;
uint8_t *ptr;
uint32_t val;
@ -3436,7 +3360,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
section = phys_page_find(page >> TARGET_PAGE_BITS);
section = phys_page_find(d, page >> TARGET_PAGE_BITS);
if (is_write) {
if (!memory_region_is_ram(section->mr)) {
@ -3507,10 +3431,36 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
}
}
void address_space_write(AddressSpace *as, target_phys_addr_t addr,
const uint8_t *buf, int len)
{
address_space_rw(as, addr, (uint8_t *)buf, len, true);
}
/**
* address_space_read: read from an address space.
*
* @as: #AddressSpace to be accessed
* @addr: address within that address space
* @buf: buffer with the data transferred
*/
void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len)
{
address_space_rw(as, addr, buf, len, false);
}
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
return address_space_rw(&address_space_memory, addr, buf, len, is_write);
}
/* used for ROM loading : can write in RAM and ROM */
void cpu_physical_memory_write_rom(target_phys_addr_t addr,
const uint8_t *buf, int len)
{
AddressSpaceDispatch *d = address_space_memory.dispatch;
int l;
uint8_t *ptr;
target_phys_addr_t page;
@ -3521,7 +3471,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
section = phys_page_find(page >> TARGET_PAGE_BITS);
section = phys_page_find(d, page >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
@ -3595,10 +3545,12 @@ static void cpu_notify_map_clients(void)
* Use cpu_register_map_client() to know when retrying the map operation is
* likely to succeed.
*/
void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t *plen,
int is_write)
void *address_space_map(AddressSpace *as,
target_phys_addr_t addr,
target_phys_addr_t *plen,
bool is_write)
{
AddressSpaceDispatch *d = as->dispatch;
target_phys_addr_t len = *plen;
target_phys_addr_t todo = 0;
int l;
@ -3613,7 +3565,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
section = phys_page_find(page >> TARGET_PAGE_BITS);
section = phys_page_find(d, page >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
if (todo || bounce.buffer) {
@ -3623,7 +3575,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
bounce.addr = addr;
bounce.len = l;
if (!is_write) {
cpu_physical_memory_read(addr, bounce.buffer, l);
address_space_read(as, addr, bounce.buffer, l);
}
*plen = l;
@ -3644,12 +3596,12 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
return ret;
}
/* Unmaps a memory region previously mapped by cpu_physical_memory_map().
/* Unmaps a memory region previously mapped by address_space_map().
* Will also mark the memory as dirty if is_write == 1. access_len gives
* the amount of memory that was actually read or written by the caller.
*/
void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
int is_write, target_phys_addr_t access_len)
void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
int is_write, target_phys_addr_t access_len)
{
if (buffer != bounce.buffer) {
if (is_write) {
@ -3670,13 +3622,26 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
return;
}
if (is_write) {
cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len);
address_space_write(as, bounce.addr, bounce.buffer, access_len);
}
qemu_vfree(bounce.buffer);
bounce.buffer = NULL;
cpu_notify_map_clients();
}
void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t *plen,
int is_write)
{
return address_space_map(&address_space_memory, addr, plen, is_write);
}
void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
int is_write, target_phys_addr_t access_len)
{
return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len);
}
/* warning: addr must be aligned */
static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
enum device_endian endian)
@ -3685,7 +3650,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
uint32_t val;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
@ -3744,7 +3709,7 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
uint64_t val;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
@ -3811,7 +3776,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
uint64_t val;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
@ -3870,7 +3835,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
addr = memory_region_section_addr(section, addr);
@ -3902,7 +3867,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
addr = memory_region_section_addr(section, addr);
@ -3931,7 +3896,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
addr = memory_region_section_addr(section, addr);
@ -3998,7 +3963,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
addr = memory_region_section_addr(section, addr);
@ -4188,7 +4153,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
}
/* XXX: avoid using doubles ? */
cpu_fprintf(f, "Translation buffer state:\n");
cpu_fprintf(f, "gen code size %td/%ld\n",
cpu_fprintf(f, "gen code size %td/%zd\n",
code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
cpu_fprintf(f, "TB count %d/%d\n",
nb_tbs, code_gen_max_blocks);
@ -4234,7 +4199,8 @@ bool cpu_physical_memory_is_io(target_phys_addr_t phys_addr)
{
MemoryRegionSection *section;
section = phys_page_find(phys_addr >> TARGET_PAGE_BITS);
section = phys_page_find(address_space_memory.dispatch,
phys_addr >> TARGET_PAGE_BITS);
return !(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr));

12
hmp.c
View File

@ -152,6 +152,14 @@ void hmp_info_migrate(Monitor *mon)
monitor_printf(mon, "Migration status: %s\n", info->status);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->total_time);
if (info->has_expected_downtime) {
monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n",
info->expected_downtime);
}
if (info->has_downtime) {
monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n",
info->downtime);
}
}
if (info->has_ram) {
@ -167,6 +175,10 @@ void hmp_info_migrate(Monitor *mon)
info->ram->normal);
monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
info->ram->normal_bytes >> 10);
if (info->ram->dirty_pages_rate) {
monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
info->ram->dirty_pages_rate);
}
}
if (info->has_disk) {

View File

@ -20,7 +20,8 @@ common-obj-$(CONFIG_M48T59) += m48t59.o
common-obj-$(CONFIG_ESCC) += escc.o
common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_SERIAL) += serial.o
common-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
common-obj-$(CONFIG_PARALLEL) += parallel.o
common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
common-obj-$(CONFIG_PCSPK) += pcspk.o

View File

@ -15,6 +15,7 @@
#include "mc146818rtc.h"
#include "ide.h"
#include "i8254.h"
#include "serial.h"
#define MAX_IDE_BUS 2
@ -42,13 +43,13 @@ static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
return (slot + 1) * 4 + irq_num;
}
static void clipper_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void clipper_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
CPUAlphaState *cpus[4];
PCIBus *pci_bus;
ISABus *isa_bus;

View File

@ -19,11 +19,11 @@
/* Board init. */
static void an5206_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void an5206_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
CPUM68KState *env;
int kernel_size;
uint64_t elf_entry;

View File

@ -242,11 +242,12 @@ static const MemoryRegionOps gpio_ops = {
static struct cris_load_info li;
static
void axisdev88_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
void axisdev88_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
CRISCPU *cpu;
CPUCRISState *env;
DeviceState *dev;

View File

@ -5,12 +5,16 @@
#include "qdev.h"
typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model);
typedef struct QEMUMachineInitArgs {
ram_addr_t ram_size;
const char *boot_device;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
const char *cpu_model;
} QEMUMachineInitArgs;
typedef void QEMUMachineInitFunc(QEMUMachineInitArgs *args);
typedef void QEMUMachineResetFunc(void);

View File

@ -23,11 +23,12 @@ static struct arm_boot_info collie_binfo = {
.ram_size = 0x20000000,
};
static void collie_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void collie_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
StrongARMState *s;
DriveInfo *dinfo;
MemoryRegion *sysmem = get_system_memory();

View File

@ -16,11 +16,11 @@
/* Board init. */
static void dummy_m68k_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void dummy_m68k_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
CPUM68KState *env;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -130,22 +130,22 @@ static Exynos4210State *exynos4_boards_init_common(
exynos4_board_ram_size[board_type]);
}
static void nuri_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void nuri_init(QEMUMachineInitArgs *args)
{
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
exynos4_boards_init_common(kernel_filename, kernel_cmdline,
initrd_filename, EXYNOS4_BOARD_NURI);
arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
}
static void smdkc210_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void smdkc210_init(QEMUMachineInitArgs *args)
{
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
Exynos4210State *s = exynos4_boards_init_common(kernel_filename,
kernel_cmdline, initrd_filename, EXYNOS4_BOARD_SMDKC210);

View File

@ -45,10 +45,7 @@
static const int sector_len = 128 * 1024;
static void connex_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void connex_init(QEMUMachineInitArgs *args)
{
PXA2xxState *cpu;
DriveInfo *dinfo;
@ -84,11 +81,9 @@ static void connex_init(ram_addr_t ram_size,
qdev_get_gpio_in(cpu->gpio, 36));
}
static void verdex_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void verdex_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
PXA2xxState *cpu;
DriveInfo *dinfo;
int be;

View File

@ -187,11 +187,13 @@ static struct arm_boot_info highbank_binfo;
* 32-bit host, set the reg value of memory to 0xf7ff00000 in the
* device tree and pass -m 2047 to QEMU.
*/
static void highbank_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void highbank_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
DeviceState *dev;
SysBusDevice *busdev;
qemu_irq *irqp;

View File

@ -12,6 +12,7 @@
#include "irq.h"
#include "qemu-file.h"
#include "vmstate.h"
#include "qemu-log.h"
#ifdef NEED_CPU_H
#if TARGET_LONG_BITS == 64

View File

@ -438,11 +438,13 @@ static struct arm_boot_info integrator_binfo = {
.board_id = 0x113,
};
static void integratorcp_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void integratorcp_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -21,7 +21,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
#include "pc.h" /* for the FPGA UART that emulates a 16550 */
#include "serial.h"
#include "imx.h"
/* Memory map for Kzm Emulation Baseboard:
@ -70,11 +70,13 @@ static struct arm_boot_info kzm_binfo = {
.board_id = 1722,
};
static void kzm_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void kzm_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ARMCPU *cpu;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -94,13 +94,11 @@ static void leon3_set_pil_in(void *opaque, uint32_t pil_in)
}
}
static void leon3_generic_hw_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void leon3_generic_hw_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
SPARCCPU *cpu;
CPUSPARCState *env;
MemoryRegion *address_space_mem = get_system_memory();

View File

@ -69,12 +69,10 @@ static void main_cpu_reset(void *opaque)
env->deba = reset_info->flash_base;
}
static void lm32_evr_init(ram_addr_t ram_size_not_used,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void lm32_evr_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
LM32CPU *cpu;
CPULM32State *env;
DriveInfo *dinfo;
@ -159,12 +157,12 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
qemu_register_reset(main_cpu_reset, reset_info);
}
static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void lm32_uclinux_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
LM32CPU *cpu;
CPULM32State *env;
DriveInfo *dinfo;

View File

@ -171,11 +171,13 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
arm_load_kernel(mpu->cpu, &mainstone_binfo);
}
static void mainstone_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void mainstone_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
mainstone_common_init(get_system_memory(), ram_size, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
}

View File

@ -187,11 +187,11 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
}
}
static void mcf5208evb_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void mcf5208evb_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
CPUM68KState *env;
int kernel_size;
uint64_t elf_entry;

View File

@ -73,12 +73,12 @@ static void main_cpu_reset(void *opaque)
}
static void
milkymist_init(ram_addr_t ram_size_not_used,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
milkymist_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
LM32CPU *cpu;
CPULM32State *env;
int kernel_size;

View File

@ -20,6 +20,7 @@
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"
@ -256,10 +257,13 @@ static void cpu_request_exit(void *opaque, int irq, int level)
}
}
static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void mips_fulong2e_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
char *filename;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -26,6 +26,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "fdc.h"
#include "sysemu.h"
@ -302,21 +303,19 @@ static void mips_jazz_init(MemoryRegion *address_space,
}
static
void mips_magnum_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
void mips_magnum_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
mips_jazz_init(get_system_memory(), get_system_io(),
ram_size, cpu_model, JAZZ_MAGNUM);
}
static
void mips_pica61_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
void mips_pica61_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
mips_jazz_init(get_system_memory(), get_system_io(),
ram_size, cpu_model, JAZZ_PICA61);
}

View File

@ -24,6 +24,7 @@
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "boards.h"
@ -775,11 +776,13 @@ static void cpu_request_exit(void *opaque, int irq, int level)
}
static
void mips_malta_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
void mips_malta_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
char *filename;
pflash_t *fl;
MemoryRegion *system_memory = get_system_memory();

View File

@ -27,7 +27,7 @@
#include "hw.h"
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"
@ -131,11 +131,13 @@ static void mipsnet_init(int base, qemu_irq irq, NICInfo *nd)
}
static void
mips_mipssim_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
mips_mipssim_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
char *filename;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -11,6 +11,7 @@
#include "mips.h"
#include "mips_cpudevs.h"
#include "pc.h"
#include "serial.h"
#include "isa.h"
#include "net.h"
#include "sysemu.h"
@ -151,11 +152,13 @@ static void main_cpu_reset(void *opaque)
static const int sector_len = 32 * 1024;
static
void mips_r4k_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
void mips_r4k_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
char *filename;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

View File

@ -15,7 +15,7 @@
#include "net.h"
#include "sysemu.h"
#include "boards.h"
#include "pc.h"
#include "serial.h"
#include "qemu-timer.h"
#include "ptimer.h"
#include "block.h"
@ -1508,11 +1508,12 @@ static struct arm_boot_info musicpal_binfo = {
.board_id = 0x20e,
};
static void musicpal_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void musicpal_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
ARMCPU *cpu;
qemu_irq *cpu_pic;
qemu_irq pic[32];

View File

@ -1397,21 +1397,27 @@ static struct arm_boot_info n810_binfo = {
.atag_board = n810_atag_setup,
};
static void n800_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void n800_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
return n8x0_init(ram_size, boot_device,
kernel_filename, kernel_cmdline, initrd_filename,
cpu_model, &n800_binfo, 800);
}
static void n810_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void n810_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
return n8x0_init(ram_size, boot_device,
kernel_filename, kernel_cmdline, initrd_filename,
cpu_model, &n810_binfo, 810);

View File

@ -15,12 +15,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
static void machine_none_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void machine_none_init(QEMUMachineInitArgs *args)
{
}

View File

@ -209,20 +209,26 @@ static void sx1_init(ram_addr_t ram_size,
//~ qemu_console_resize(ds, 640, 480);
}
static void sx1_init_v1(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void sx1_init_v1(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sx1_init(ram_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, 1);
}
static void sx1_init_v2(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void sx1_init_v2(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sx1_init(ram_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, 2);
}

View File

@ -20,8 +20,7 @@
#include "qemu-char.h"
#include "hw.h"
#include "omap.h"
/* We use pc-style serial ports. */
#include "pc.h"
#include "serial.h"
#include "exec-memory.h"
/* UARTs */

View File

@ -21,7 +21,8 @@
#include "hw.h"
#include "boards.h"
#include "elf.h"
#include "pc.h"
#include "serial.h"
#include "net.h"
#include "loader.h"
#include "exec-memory.h"
#include "sysemu.h"
@ -90,13 +91,11 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
cpu->env.pc = entry;
}
static void openrisc_sim_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void openrisc_sim_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
OpenRISCCPU *cpu = NULL;
MemoryRegion *ram;
int n;

View File

@ -190,11 +190,12 @@ static struct arm_boot_info palmte_binfo = {
.board_id = 0x331,
};
static void palmte_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void palmte_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
MemoryRegion *address_space_mem = get_system_memory();
struct omap_mpu_state_s *mpu;
int flash_size = 0x00800000;

View File

@ -23,6 +23,7 @@
*/
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "apic.h"
#include "fdc.h"
#include "ide.h"

27
hw/pc.h
View File

@ -12,33 +12,6 @@
/* PC-style peripherals (also used by other machines). */
/* serial.c */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr);
SerialState *serial_mm_init(MemoryRegion *address_space,
target_phys_addr_t base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, enum device_endian);
static inline bool serial_isa_init(ISABus *bus, int index,
CharDriverState *chr)
{
ISADevice *dev;
dev = isa_try_create(bus, "isa-serial");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "index", index);
qdev_prop_set_chr(&dev->qdev, "chardev", chr);
if (qdev_init(&dev->qdev) < 0) {
return false;
}
return true;
}
void serial_set_frequency(SerialState *s, uint32_t frequency);
/* parallel.c */
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
{

View File

@ -287,13 +287,14 @@ static void pc_init1(MemoryRegion *system_memory,
}
}
static void pc_init_pci(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void pc_init_pci(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
pc_init1(get_system_memory(),
get_system_io(),
ram_size, boot_device,
@ -301,13 +302,14 @@ static void pc_init_pci(ram_addr_t ram_size,
initrd_filename, cpu_model, 1, 1);
}
static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
pc_init1(get_system_memory(),
get_system_io(),
ram_size, boot_device,
@ -315,13 +317,14 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
initrd_filename, cpu_model, 1, 0);
}
static void pc_init_isa(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void pc_init_isa(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
if (cpu_model == NULL)
cpu_model = "486";
pc_init1(get_system_memory(),
@ -332,19 +335,12 @@ static void pc_init_isa(ram_addr_t ram_size,
}
#ifdef CONFIG_XEN
static void pc_xen_hvm_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
{
if (xen_hvm_init() != 0) {
hw_error("xen hardware virtual machine initialisation failed");
}
pc_init_pci_no_kvmclock(ram_size, boot_device,
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model);
pc_init_pci_no_kvmclock(args);
xen_vcpu_init();
}
#endif
@ -379,6 +375,10 @@ static QEMUMachine pc_machine_v1_3 = {
.driver = "qxl-vga",\
.property = "revision",\
.value = stringify(3),\
},{\
.driver = "VGA",\
.property = "mmio",\
.value = "off",\
}
static QEMUMachine pc_machine_v1_2 = {

View File

@ -33,6 +33,7 @@
#include "qmp-commands.h"
#include "msi.h"
#include "msix.h"
#include "exec-memory.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@ -777,6 +778,17 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
pci_dev->bus = bus;
if (bus->dma_context_fn) {
pci_dev->dma = bus->dma_context_fn(bus, bus->dma_context_opaque, devfn);
} else {
/* FIXME: Make dma_context_fn use MemoryRegions instead, so this path is
* taken unconditionally */
/* FIXME: inherit memory region from bus creator */
memory_region_init_alias(&pci_dev->bus_master_enable_region, "bus master",
get_system_memory(), 0,
memory_region_size(get_system_memory()));
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region);
pci_dev->dma = g_new(DMAContext, 1);
dma_context_init(pci_dev->dma, &pci_dev->bus_master_as, NULL, NULL, NULL);
}
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
@ -830,6 +842,13 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
qemu_free_irqs(pci_dev->irq);
pci_dev->bus->devices[pci_dev->devfn] = NULL;
pci_config_free(pci_dev);
if (!pci_dev->bus->dma_context_fn) {
address_space_destroy(&pci_dev->bus_master_as);
memory_region_destroy(&pci_dev->bus_master_enable_region);
g_free(pci_dev->dma);
pci_dev->dma = NULL;
}
}
static void pci_unregister_io_regions(PCIDevice *pci_dev)
@ -1051,8 +1070,12 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
if (range_covers_byte(addr, l, PCI_COMMAND))
if (range_covers_byte(addr, l, PCI_COMMAND)) {
pci_update_irq_disabled(d, was_irq_disabled);
memory_region_set_enabled(&d->bus_master_enable_region,
pci_get_word(d->config + PCI_COMMAND)
& PCI_COMMAND_MASTER);
}
msi_write_config(d, addr, val, l);
msix_write_config(d, addr, val, l);

View File

@ -211,6 +211,8 @@ struct PCIDevice {
int32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
AddressSpace bus_master_as;
MemoryRegion bus_master_enable_region;
DMAContext *dma;
/* do not access the following fields */

View File

@ -39,6 +39,7 @@
#define PCI_CLASS_BRIDGE_PCI 0x0604
#define PCI_CLASS_BRIDGE_OTHER 0x0680
#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
#define PCI_CLASS_PROCESSOR_CO 0x0b40

View File

@ -34,7 +34,7 @@
#include "boards.h"
#include "xilinx.h"
#include "blockdev.h"
#include "pc.h"
#include "serial.h"
#include "exec-memory.h"
#include "ssi.h"
@ -73,12 +73,10 @@ static void machine_cpu_reset(MicroBlazeCPU *cpu)
}
static void
petalogix_ml605_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
petalogix_ml605_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
MemoryRegion *address_space_mem = get_system_memory();
DeviceState *dev, *dma, *eth0;
MicroBlazeCPU *cpu;

View File

@ -57,12 +57,10 @@ static void machine_cpu_reset(MicroBlazeCPU *cpu)
}
static void
petalogix_s3adsp1800_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
DeviceState *dev;
MicroBlazeCPU *cpu;
CPUMBState *env;

View File

@ -107,7 +107,8 @@ static uint64_t pl011_read(void *opaque, target_phys_addr_t offset,
case 18: /* UARTDMACR */
return s->dmacr;
default:
hw_error("pl011_read: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl011_read: Bad offset %x\n", (int)offset);
return 0;
}
}
@ -178,11 +179,13 @@ static void pl011_write(void *opaque, target_phys_addr_t offset,
break;
case 18: /* UARTDMACR */
s->dmacr = value;
if (value & 3)
hw_error("PL011: DMA not implemented\n");
if (value & 3) {
qemu_log_mask(LOG_UNIMP, "pl011: DMA not implemented\n");
}
break;
default:
hw_error("pl011_write: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl011_write: Bad offset %x\n", (int)offset);
}
}

View File

@ -168,7 +168,8 @@ static uint64_t pl022_read(void *opaque, target_phys_addr_t offset,
/* Not implemented. */
return 0;
default:
hw_error("pl022_read: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl022_read: Bad offset %x\n", (int)offset);
return 0;
}
}
@ -211,11 +212,12 @@ static void pl022_write(void *opaque, target_phys_addr_t offset,
break;
case 0x20: /* DMACR */
if (value) {
hw_error("pl022: DMA not implemented\n");
qemu_log_mask(LOG_UNIMP, "pl022: DMA not implemented\n");
}
break;
default:
hw_error("pl022_write: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl022_write: Bad offset %x\n", (int)offset);
}
}

View File

@ -120,11 +120,13 @@ static uint64_t pl031_read(void *opaque, target_phys_addr_t offset,
case RTC_MIS:
return s->is & s->im;
case RTC_ICR:
fprintf(stderr, "qemu: pl031_read: Unexpected offset 0x%x\n",
(int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl031: read of write-only register at offset 0x%x\n",
(int)offset);
break;
default:
hw_error("pl031_read: Bad offset 0x%x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl031_read: Bad offset 0x%x\n", (int)offset);
break;
}
@ -167,12 +169,14 @@ static void pl031_write(void * opaque, target_phys_addr_t offset,
case RTC_DR:
case RTC_MIS:
case RTC_RIS:
fprintf(stderr, "qemu: pl031_write: Unexpected offset 0x%x\n",
(int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl031: write to read-only register at offset 0x%x\n",
(int)offset);
break;
default:
hw_error("pl031_write: Bad offset 0x%x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl031_write: Bad offset 0x%x\n", (int)offset);
break;
}
}

View File

@ -536,8 +536,9 @@ static int pl041_init(SysBusDevice *dev)
default:
/* NC FIFO depth of 16 is not allowed because its id bits in
AACIPERIPHID3 overlap with the id for the default NC FIFO depth */
fprintf(stderr, "pl041: unsupported non-compact fifo depth [%i]\n",
s->fifo_depth);
qemu_log_mask(LOG_UNIMP,
"pl041: unsupported non-compact fifo depth [%i]\n",
s->fifo_depth);
return -1;
}

View File

@ -352,7 +352,7 @@ static uint64_t pl181_read(void *opaque, target_phys_addr_t offset,
case 0xa0: case 0xa4: case 0xa8: case 0xac:
case 0xb0: case 0xb4: case 0xb8: case 0xbc:
if (s->fifo_len == 0) {
fprintf(stderr, "pl181: Unexpected FIFO read\n");
qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n");
return 0;
} else {
uint32_t value;
@ -363,7 +363,8 @@ static uint64_t pl181_read(void *opaque, target_phys_addr_t offset,
return value;
}
default:
hw_error("pl181_read: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl181_read: Bad offset %x\n", (int)offset);
return 0;
}
}
@ -387,11 +388,11 @@ static void pl181_write(void *opaque, target_phys_addr_t offset,
s->cmd = value;
if (s->cmd & PL181_CMD_ENABLE) {
if (s->cmd & PL181_CMD_INTERRUPT) {
fprintf(stderr, "pl181: Interrupt mode not implemented\n");
abort();
qemu_log_mask(LOG_UNIMP,
"pl181: Interrupt mode not implemented\n");
} if (s->cmd & PL181_CMD_PENDING) {
fprintf(stderr, "pl181: Pending commands not implemented\n");
abort();
qemu_log_mask(LOG_UNIMP,
"pl181: Pending commands not implemented\n");
} else {
pl181_send_command(s);
pl181_fifo_run(s);
@ -427,14 +428,15 @@ static void pl181_write(void *opaque, target_phys_addr_t offset,
case 0xa0: case 0xa4: case 0xa8: case 0xac:
case 0xb0: case 0xb4: case 0xb8: case 0xbc:
if (s->datacnt == 0) {
fprintf(stderr, "pl181: Unexpected FIFO write\n");
qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n");
} else {
pl181_fifo_push(s, value);
pl181_fifo_run(s);
}
break;
default:
hw_error("pl181_write: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl181_write: Bad offset %x\n", (int)offset);
}
pl181_update(s);
}

View File

@ -143,7 +143,8 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
case 13: /* DEFVECTADDR */
return s->vect_addr[16];
default:
hw_error("pl190_read: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl190_read: Bad offset %x\n", (int)offset);
return 0;
}
}
@ -202,7 +203,8 @@ static void pl190_write(void *opaque, target_phys_addr_t offset,
}
break;
default:
hw_error("pl190_write: Bad offset %x\n", (int)offset);
qemu_log_mask(LOG_GUEST_ERROR,
"pl190_write: Bad offset %x\n", (int)offset);
return;
}
pl190_update(s);

View File

@ -19,7 +19,7 @@
#include "e500.h"
#include "net.h"
#include "hw/hw.h"
#include "hw/pc.h"
#include "hw/serial.h"
#include "hw/pci.h"
#include "hw/boards.h"
#include "sysemu.h"

View File

@ -25,13 +25,14 @@ static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
sizeof(compatible));
}
static void e500plat_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void e500plat_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *boot_device = args->boot_device;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
PPCE500Params params = {
.ram_size = ram_size,
.boot_device = boot_device,

View File

@ -25,13 +25,14 @@ static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
sizeof(compatible));
}
static void mpc8544ds_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void mpc8544ds_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *boot_device = args->boot_device;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
PPCE500Params params = {
.ram_size = ram_size,
.boot_device = boot_device,

View File

@ -158,7 +158,7 @@ static void ref405ep_fpga_reset (void *opaque)
fpga->reg1 = 0x0F;
}
static void ref405ep_fpga_init (MemoryRegion *sysmem, uint32_t base)
static void ref405ep_fpga_init(MemoryRegion *sysmem, uint32_t base)
{
ref405ep_fpga_t *fpga;
MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
@ -170,13 +170,12 @@ static void ref405ep_fpga_init (MemoryRegion *sysmem, uint32_t base)
qemu_register_reset(&ref405ep_fpga_reset, fpga);
}
static void ref405ep_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void ref405ep_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
char *filename;
ppc4xx_bd_info_t bd;
CPUPPCState *env;
@ -484,7 +483,7 @@ static void taihu_cpld_reset (void *opaque)
cpld->reg1 = 0x80;
}
static void taihu_cpld_init (MemoryRegion *sysmem, uint32_t base)
static void taihu_cpld_init(MemoryRegion *sysmem, uint32_t base)
{
taihu_cpld_t *cpld;
MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
@ -495,13 +494,11 @@ static void taihu_cpld_init (MemoryRegion *sysmem, uint32_t base)
qemu_register_reset(&taihu_cpld_reset, cpld);
}
static void taihu_405ep_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void taihu_405ep_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *kernel_filename = args->kernel_filename;
const char *initrd_filename = args->initrd_filename;
char *filename;
qemu_irq *pic;
MemoryRegion *sysmem = get_system_memory();

View File

@ -24,7 +24,7 @@
#include "hw.h"
#include "ppc.h"
#include "ppc405.h"
#include "pc.h"
#include "serial.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "qemu-log.h"

View File

@ -23,7 +23,7 @@
#include "loader.h"
#include "elf.h"
#include "exec-memory.h"
#include "pc.h"
#include "serial.h"
#include "ppc.h"
#include "ppc405.h"
#include "sysemu.h"
@ -157,13 +157,13 @@ static void main_cpu_reset(void *opaque)
mmubooke_create_initial_mapping(env, 0, 0);
}
static void bamboo_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void bamboo_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *ram_memories

View File

@ -128,13 +128,14 @@ static void ppc_core99_reset(void *opaque)
}
/* PowerPC Mac99 hardware initialisation */
static void ppc_core99_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void ppc_core99_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;
char *filename;

View File

@ -71,13 +71,14 @@ static void ppc_heathrow_reset(void *opaque)
cpu_reset(CPU(cpu));
}
static void ppc_heathrow_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void ppc_heathrow_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
MemoryRegion *sysmem = get_system_memory();
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;

View File

@ -24,6 +24,7 @@
#include "hw.h"
#include "nvram.h"
#include "pc.h"
#include "serial.h"
#include "fdc.h"
#include "net.h"
#include "sysemu.h"
@ -447,13 +448,14 @@ static void ppc_prep_reset(void *opaque)
}
/* PowerPC PREP hardware initialisation */
static void ppc_prep_init (ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void ppc_prep_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
MemoryRegion *sysmem = get_system_memory();
PowerPCCPU *cpu = NULL;
CPUPPCState *env = NULL;

View File

@ -91,10 +91,12 @@ static void puv3_load_kernel(const char *kernel_filename)
graphic_console_init(NULL, NULL, NULL, NULL, NULL);
}
static void puv3_init(ram_addr_t ram_size, const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void puv3_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *initrd_filename = args->initrd_filename;
CPUUniCore32State *env;
if (initrd_filename) {

View File

@ -10,7 +10,7 @@
#include "sysbus.h"
#include "pxa.h"
#include "sysemu.h"
#include "pc.h"
#include "serial.h"
#include "i2c.h"
#include "ssi.h"
#include "qemu-char.h"

View File

@ -219,11 +219,12 @@ static struct QEMU_PACKED
char kernel_cmdline[256];
} boot_params;
static void r2d_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void r2d_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
SuperHCPU *cpu;
CPUSH4State *env;
ResetData *reset_info;

View File

@ -330,11 +330,14 @@ static void realview_init(ram_addr_t ram_size,
arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo);
}
static void realview_eb_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void realview_eb_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
if (!cpu_model) {
cpu_model = "arm926";
}
@ -342,11 +345,14 @@ static void realview_eb_init(ram_addr_t ram_size,
initrd_filename, cpu_model, BOARD_EB);
}
static void realview_eb_mpcore_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void realview_eb_mpcore_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
if (!cpu_model) {
cpu_model = "arm11mpcore";
}
@ -354,11 +360,14 @@ static void realview_eb_mpcore_init(ram_addr_t ram_size,
initrd_filename, cpu_model, BOARD_EB_MPCORE);
}
static void realview_pb_a8_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void realview_pb_a8_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
if (!cpu_model) {
cpu_model = "cortex-a8";
}
@ -366,11 +375,14 @@ static void realview_pb_a8_init(ram_addr_t ram_size,
initrd_filename, cpu_model, BOARD_PB_A8);
}
static void realview_pbx_a9_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void realview_pbx_a9_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
if (!cpu_model) {
cpu_model = "cortex-a9";
}

View File

@ -151,13 +151,14 @@ unsigned s390_del_running_cpu(CPUS390XState *env)
}
/* PC hardware initialisation */
static void s390_init(ram_addr_t my_ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void s390_init(QEMUMachineInitArgs *args)
{
ram_addr_t my_ram_size = args->ram_size;
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
CPUS390XState *env = NULL;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);

130
hw/serial-isa.c Normal file
View File

@ -0,0 +1,130 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "serial.h"
#include "isa.h"
typedef struct ISASerialState {
ISADevice dev;
uint32_t index;
uint32_t iobase;
uint32_t isairq;
SerialState state;
} ISASerialState;
static const int isa_serial_io[MAX_SERIAL_PORTS] = {
0x3f8, 0x2f8, 0x3e8, 0x2e8
};
static const int isa_serial_irq[MAX_SERIAL_PORTS] = {
4, 3, 4, 3
};
static int serial_isa_initfn(ISADevice *dev)
{
static int index;
ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
SerialState *s = &isa->state;
if (isa->index == -1) {
isa->index = index;
}
if (isa->index >= MAX_SERIAL_PORTS) {
return -1;
}
if (isa->iobase == -1) {
isa->iobase = isa_serial_io[isa->index];
}
if (isa->isairq == -1) {
isa->isairq = isa_serial_irq[isa->index];
}
index++;
s->baudbase = 115200;
isa_init_irq(dev, &s->irq, isa->isairq);
serial_init_core(s);
qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
isa_register_ioport(dev, &s->io, isa->iobase);
return 0;
}
static const VMStateDescription vmstate_isa_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
}
};
static Property serial_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
ic->init = serial_isa_initfn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
}
static TypeInfo serial_isa_info = {
.name = "isa-serial",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASerialState),
.class_init = serial_isa_class_initfn,
};
static void serial_register_types(void)
{
type_register_static(&serial_isa_info);
}
type_init(serial_register_types)
bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr)
{
ISADevice *dev;
dev = isa_try_create(bus, "isa-serial");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "index", index);
qdev_prop_set_chr(&dev->qdev, "chardev", chr);
if (qdev_init(&dev->qdev) < 0) {
return false;
}
return true;
}

252
hw/serial-pci.c Normal file
View File

@ -0,0 +1,252 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* see docs/specs/pci-serial.txt */
#include "serial.h"
#include "pci.h"
#define PCI_SERIAL_MAX_PORTS 4
typedef struct PCISerialState {
PCIDevice dev;
SerialState state;
} PCISerialState;
typedef struct PCIMultiSerialState {
PCIDevice dev;
MemoryRegion iobar;
uint32_t ports;
char *name[PCI_SERIAL_MAX_PORTS];
SerialState state[PCI_SERIAL_MAX_PORTS];
uint32_t level[PCI_SERIAL_MAX_PORTS];
qemu_irq *irqs;
} PCIMultiSerialState;
static int serial_pci_init(PCIDevice *dev)
{
PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
SerialState *s = &pci->state;
s->baudbase = 115200;
serial_init_core(s);
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
s->irq = pci->dev.irq[0];
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
return 0;
}
static void multi_serial_irq_mux(void *opaque, int n, int level)
{
PCIMultiSerialState *pci = opaque;
int i, pending = 0;
pci->level[n] = level;
for (i = 0; i < pci->ports; i++) {
if (pci->level[i]) {
pending = 1;
}
}
qemu_set_irq(pci->dev.irq[0], pending);
}
static int multi_serial_pci_init(PCIDevice *dev)
{
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
SerialState *s;
int i;
switch (pc->device_id) {
case 0x0003:
pci->ports = 2;
break;
case 0x0004:
pci->ports = 4;
break;
}
assert(pci->ports > 0);
assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
memory_region_init(&pci->iobar, "multiserial", 8 * pci->ports);
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci,
pci->ports);
for (i = 0; i < pci->ports; i++) {
s = pci->state + i;
s->baudbase = 115200;
serial_init_core(s);
s->irq = pci->irqs[i];
pci->name[i] = g_strdup_printf("uart #%d", i+1);
memory_region_init_io(&s->io, &serial_io_ops, s, pci->name[i], 8);
memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
}
return 0;
}
static void serial_pci_exit(PCIDevice *dev)
{
PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
SerialState *s = &pci->state;
serial_exit_core(s);
memory_region_destroy(&s->io);
}
static void multi_serial_pci_exit(PCIDevice *dev)
{
PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
SerialState *s;
int i;
for (i = 0; i < pci->ports; i++) {
s = pci->state + i;
serial_exit_core(s);
memory_region_destroy(&s->io);
g_free(pci->name[i]);
}
memory_region_destroy(&pci->iobar);
qemu_free_irqs(pci->irqs);
}
static const VMStateDescription vmstate_pci_serial = {
.name = "pci-serial",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PCISerialState),
VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_pci_multi_serial = {
.name = "pci-serial-multi",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
0, vmstate_serial, SerialState),
VMSTATE_UINT32_ARRAY(level, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS),
VMSTATE_END_OF_LIST()
}
};
static Property serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
DEFINE_PROP_END_OF_LIST(),
};
static Property multi_2x_serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
DEFINE_PROP_END_OF_LIST(),
};
static Property multi_4x_serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = serial_pci_init;
pc->exit = serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0002;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_serial;
dc->props = serial_pci_properties;
}
static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = multi_serial_pci_init;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0003;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
dc->props = multi_2x_serial_pci_properties;
}
static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
pc->init = multi_serial_pci_init;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = 0x1b36; /* Red Hat */
pc->device_id = 0x0004;
pc->revision = 1;
pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL;
dc->vmsd = &vmstate_pci_multi_serial;
dc->props = multi_4x_serial_pci_properties;
}
static TypeInfo serial_pci_info = {
.name = "pci-serial",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCISerialState),
.class_init = serial_pci_class_initfn,
};
static TypeInfo multi_2x_serial_pci_info = {
.name = "pci-serial-2x",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIMultiSerialState),
.class_init = multi_2x_serial_pci_class_initfn,
};
static TypeInfo multi_4x_serial_pci_info = {
.name = "pci-serial-4x",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIMultiSerialState),
.class_init = multi_4x_serial_pci_class_initfn,
};
static void serial_pci_register_types(void)
{
type_register_static(&serial_pci_info);
type_register_static(&multi_2x_serial_pci_info);
type_register_static(&multi_4x_serial_pci_info);
}
type_init(serial_pci_register_types)

View File

@ -22,12 +22,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "serial.h"
#include "qemu-char.h"
#include "isa.h"
#include "pc.h"
#include "qemu-timer.h"
#include "sysemu.h"
//#define DEBUG_SERIAL
@ -93,8 +91,6 @@
#define UART_FCR_RFR 0x02 /* RCVR Fifo Reset */
#define UART_FCR_FE 0x01 /* FIFO Enable */
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
#define XMIT_FIFO 0
#define RECV_FIFO 1
#define MAX_XMIT_RETRY 4
@ -107,64 +103,6 @@ do { fprintf(stderr, "serial: " fmt , ## __VA_ARGS__); } while (0)
do {} while (0)
#endif
typedef struct SerialFIFO {
uint8_t data[UART_FIFO_LENGTH];
uint8_t count;
uint8_t itl; /* Interrupt Trigger Level */
uint8_t tail;
uint8_t head;
} SerialFIFO;
struct SerialState {
uint16_t divider;
uint8_t rbr; /* receive register */
uint8_t thr; /* transmit holding register */
uint8_t tsr; /* transmit shift register */
uint8_t ier;
uint8_t iir; /* read only */
uint8_t lcr;
uint8_t mcr;
uint8_t lsr; /* read only */
uint8_t msr; /* read only */
uint8_t scr;
uint8_t fcr;
uint8_t fcr_vmstate; /* we can't write directly this value
it has side effects */
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
int it_shift;
int baudbase;
int tsr_retry;
uint32_t wakeup;
uint64_t last_xmit_ts; /* Time when the last byte was successfully sent out of the tsr */
SerialFIFO recv_fifo;
SerialFIFO xmit_fifo;
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
struct QEMUTimer *transmit_timer;
uint64_t char_transmit_time; /* time to transmit a char in ticks*/
int poll_msl;
struct QEMUTimer *modem_status_poll;
MemoryRegion io;
};
typedef struct ISASerialState {
ISADevice dev;
uint32_t index;
uint32_t iobase;
uint32_t isairq;
SerialState state;
} ISASerialState;
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
static void fifo_clear(SerialState *s, int fifo)
@ -687,7 +625,7 @@ static int serial_post_load(void *opaque, int version_id)
return 0;
}
static const VMStateDescription vmstate_serial = {
const VMStateDescription vmstate_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
@ -736,7 +674,7 @@ static void serial_reset(void *opaque)
qemu_irq_lower(s->irq);
}
static void serial_init_core(SerialState *s)
void serial_init_core(SerialState *s)
{
if (!s->chr) {
fprintf(stderr, "Can't create serial device, empty char device\n");
@ -754,6 +692,12 @@ static void serial_init_core(SerialState *s)
serial_event, s);
}
void serial_exit_core(SerialState *s)
{
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
qemu_unregister_reset(serial_reset, s);
}
/* Change the main reference oscillator frequency. */
void serial_set_frequency(SerialState *s, uint32_t frequency)
{
@ -761,54 +705,15 @@ void serial_set_frequency(SerialState *s, uint32_t frequency)
serial_update_parameters(s);
}
static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
static const MemoryRegionPortio serial_portio[] = {
{ 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write },
PORTIO_END_OF_LIST()
};
static const MemoryRegionOps serial_io_ops = {
const MemoryRegionOps serial_io_ops = {
.old_portio = serial_portio
};
static int serial_isa_initfn(ISADevice *dev)
{
static int index;
ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev);
SerialState *s = &isa->state;
if (isa->index == -1)
isa->index = index;
if (isa->index >= MAX_SERIAL_PORTS)
return -1;
if (isa->iobase == -1)
isa->iobase = isa_serial_io[isa->index];
if (isa->isairq == -1)
isa->isairq = isa_serial_irq[isa->index];
index++;
s->baudbase = 115200;
isa_init_irq(dev, &s->irq, isa->isairq);
serial_init_core(s);
qdev_set_legacy_instance_id(&dev->qdev, isa->iobase, 3);
memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8);
isa_register_ioport(dev, &s->io, isa->iobase);
return 0;
}
static const VMStateDescription vmstate_isa_serial = {
.name = "serial",
.version_id = 3,
.minimum_version_id = 2,
.fields = (VMStateField []) {
VMSTATE_STRUCT(state, ISASerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
}
};
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr)
{
@ -886,35 +791,3 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
serial_update_msl(s);
return s;
}
static Property serial_isa_properties[] = {
DEFINE_PROP_UINT32("index", ISASerialState, index, -1),
DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1),
DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1),
DEFINE_PROP_CHR("chardev", ISASerialState, state.chr),
DEFINE_PROP_UINT32("wakeup", ISASerialState, state.wakeup, 0),
DEFINE_PROP_END_OF_LIST(),
};
static void serial_isa_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ISADeviceClass *ic = ISA_DEVICE_CLASS(klass);
ic->init = serial_isa_initfn;
dc->vmsd = &vmstate_isa_serial;
dc->props = serial_isa_properties;
}
static TypeInfo serial_isa_info = {
.name = "isa-serial",
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISASerialState),
.class_init = serial_isa_class_initfn,
};
static void serial_register_types(void)
{
type_register_static(&serial_isa_info);
}
type_init(serial_register_types)

99
hw/serial.h Normal file
View File

@ -0,0 +1,99 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw.h"
#include "sysemu.h"
#include "memory.h"
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
typedef struct SerialFIFO {
uint8_t data[UART_FIFO_LENGTH];
uint8_t count;
uint8_t itl; /* Interrupt Trigger Level */
uint8_t tail;
uint8_t head;
} SerialFIFO;
struct SerialState {
uint16_t divider;
uint8_t rbr; /* receive register */
uint8_t thr; /* transmit holding register */
uint8_t tsr; /* transmit shift register */
uint8_t ier;
uint8_t iir; /* read only */
uint8_t lcr;
uint8_t mcr;
uint8_t lsr; /* read only */
uint8_t msr; /* read only */
uint8_t scr;
uint8_t fcr;
uint8_t fcr_vmstate; /* we can't write directly this value
it has side effects */
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
int it_shift;
int baudbase;
int tsr_retry;
uint32_t wakeup;
/* Time when the last byte was successfully sent out of the tsr */
uint64_t last_xmit_ts;
SerialFIFO recv_fifo;
SerialFIFO xmit_fifo;
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
struct QEMUTimer *transmit_timer;
uint64_t char_transmit_time; /* time to transmit a char in ticks */
int poll_msl;
struct QEMUTimer *modem_status_poll;
MemoryRegion io;
};
extern const VMStateDescription vmstate_serial;
extern const MemoryRegionOps serial_io_ops;
void serial_init_core(SerialState *s);
void serial_exit_core(SerialState *s);
void serial_set_frequency(SerialState *s, uint32_t frequency);
/* legacy pre qom */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr);
SerialState *serial_mm_init(MemoryRegion *address_space,
target_phys_addr_t base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, enum device_endian end);
/* serial-isa.c */
bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr);

View File

@ -37,11 +37,9 @@
#define BIOS_FILENAME "shix_bios.bin"
#define BIOS_ADDRESS 0xA0000000
static void shix_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void shix_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
int ret;
CPUSH4State *env;
struct SH7750State *s;

View File

@ -24,7 +24,7 @@
#include <stdio.h>
#include "hw.h"
#include "pc.h"
#include "serial.h"
#include "console.h"
#include "devices.h"
#include "sysbus.h"

View File

@ -665,13 +665,14 @@ static int spapr_vga_init(PCIBus *pci_bus)
}
/* pSeries LPAR / sPAPR hardware init */
static void ppc_spapr_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void ppc_spapr_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
PowerPCCPU *cpu;
CPUPPCState *env;
PCIHostState *phb;

View File

@ -21,6 +21,7 @@
#include "qdev.h"
#include "kvm_ppc.h"
#include "dma.h"
#include "exec-memory.h"
#include "hw/spapr.h"
@ -124,7 +125,7 @@ DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size)
}
tcet = g_malloc0(sizeof(*tcet));
dma_context_init(&tcet->dma, spapr_tce_translate, NULL, NULL);
dma_context_init(&tcet->dma, &address_space_memory, spapr_tce_translate, NULL, NULL);
tcet->liobn = liobn;
tcet->window_size = window_size;

View File

@ -936,38 +936,46 @@ static void spitz_common_init(ram_addr_t ram_size,
sl_bootparam_write(SL_PXA_PARAM_BASE);
}
static void spitz_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void spitz_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
spitz_common_init(ram_size, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9);
}
static void borzoi_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void borzoi_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
spitz_common_init(ram_size, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f);
}
static void akita_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void akita_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
spitz_common_init(ram_size, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8);
}
static void terrier_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void terrier_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
spitz_common_init(ram_size, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, terrier, 0x33f);
}

View File

@ -1313,19 +1313,17 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
}
/* FIXME: Figure out how to generate these from stellaris_boards. */
static void lm3s811evb_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void lm3s811evb_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
}
static void lm3s6965evb_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void lm3s6965evb_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
}

View File

@ -1306,92 +1306,118 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
};
/* SPARCstation 5 hardware initialisation */
static void ss5_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss5_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCstation 10 hardware initialisation */
static void ss10_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss10_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCserver 600MP hardware initialisation */
static void ss600mp_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss600mp_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCstation 20 hardware initialisation */
static void ss20_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss20_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCstation Voyager hardware initialisation */
static void vger_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void vger_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCstation LX hardware initialisation */
static void ss_lx_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss_lx_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCstation 4 hardware initialisation */
static void ss4_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss4_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCClassic hardware initialisation */
static void scls_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void scls_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCbook hardware initialisation */
static void sbook_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void sbook_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
@ -1654,21 +1680,27 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
}
/* SPARCserver 1000 hardware initialisation */
static void ss1000_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss1000_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
/* SPARCcenter 2000 hardware initialisation */
static void ss2000_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss2000_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
@ -1848,11 +1880,14 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
}
/* SPARCstation 2 hardware initialisation */
static void ss2_init(ram_addr_t RAM_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void ss2_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}

View File

@ -25,6 +25,7 @@
#include "pci.h"
#include "apb_pci.h"
#include "pc.h"
#include "serial.h"
#include "nvram.h"
#include "fdc.h"
#include "net.h"
@ -933,31 +934,40 @@ static const struct hwdef hwdefs[] = {
};
/* Sun4u hardware initialisation */
static void sun4u_init(ram_addr_t RAM_size,
const char *boot_devices,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void sun4u_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_devices = args->boot_device;
sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
}
/* Sun4v hardware initialisation */
static void sun4v_init(ram_addr_t RAM_size,
const char *boot_devices,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void sun4v_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_devices = args->boot_device;
sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
}
/* Niagara hardware initialisation */
static void niagara_init(ram_addr_t RAM_size,
const char *boot_devices,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void niagara_init(QEMUMachineInitArgs *args)
{
ram_addr_t RAM_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_devices = args->boot_device;
sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
}

View File

@ -205,11 +205,12 @@ static struct arm_boot_info tosa_binfo = {
.ram_size = 0x04000000,
};
static void tosa_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void tosa_init(QEMUMachineInitArgs *args)
{
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
PXA2xxState *mpu;

View File

@ -421,12 +421,16 @@ static void usb_serial_handle_destroy(USBDevice *dev)
{
USBSerialState *s = (USBSerialState *)dev;
qemu_chr_delete(s->cs);
qemu_chr_add_handlers(s->cs, NULL, NULL, NULL, NULL);
}
static int usb_serial_can_read(void *opaque)
{
USBSerialState *s = opaque;
if (!s->dev.attached) {
return 0;
}
return RECV_BUF - s->recv_used;
}
@ -469,8 +473,14 @@ static void usb_serial_event(void *opaque, int event)
case CHR_EVENT_FOCUS:
break;
case CHR_EVENT_OPENED:
usb_serial_reset(s);
/* TODO: Reset USB port */
if (!s->dev.attached) {
usb_device_attach(&s->dev);
}
break;
case CHR_EVENT_CLOSED:
if (s->dev.attached) {
usb_device_detach(&s->dev);
}
break;
}
}
@ -481,6 +491,7 @@ static int usb_serial_initfn(USBDevice *dev)
usb_desc_create_serial(dev);
usb_desc_init(dev);
dev->auto_attach = 0;
if (!s->cs) {
error_report("Property chardev is required");
@ -490,6 +501,10 @@ static int usb_serial_initfn(USBDevice *dev)
qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
usb_serial_event, s);
usb_serial_handle_reset(dev);
if (s->cs->opened && !dev->attached) {
usb_device_attach(dev);
}
return 0;
}

View File

@ -348,22 +348,28 @@ static void versatile_init(ram_addr_t ram_size,
arm_load_kernel(cpu, &versatile_binfo);
}
static void vpb_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void vpb_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
versatile_init(ram_size,
boot_device,
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model, 0x183);
}
static void vab_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename, const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
static void vab_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
versatile_init(ram_size,
boot_device,
kernel_filename, kernel_cmdline,

View File

@ -467,25 +467,27 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
}
static void vexpress_a9_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void vexpress_a9_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
vexpress_common_init(&a9_daughterboard,
ram_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);
}
static void vexpress_a15_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
static void vexpress_a15_init(QEMUMachineInitArgs *args)
{
ram_addr_t ram_size = args->ram_size;
const char *cpu_model = args->cpu_model;
const char *kernel_filename = args->kernel_filename;
const char *kernel_cmdline = args->kernel_cmdline;
const char *initrd_filename = args->initrd_filename;
const char *boot_device = args->boot_device;
vexpress_common_init(&a15_daughterboard,
ram_size, boot_device, kernel_filename,
kernel_cmdline, initrd_filename, cpu_model);

View File

@ -930,25 +930,6 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
return -errno;
}
static void vfio_listener_dummy1(MemoryListener *listener)
{
/* We don't do batching (begin/commit) or care about logging */
}
static void vfio_listener_dummy2(MemoryListener *listener,
MemoryRegionSection *section)
{
/* We don't do logging or care about nops */
}
static void vfio_listener_dummy3(MemoryListener *listener,
MemoryRegionSection *section,
bool match_data, uint64_t data,
EventNotifier *e)
{
/* We don't care about eventfds */
}
static bool vfio_listener_skipped_section(MemoryRegionSection *section)
{
return !memory_region_is_ram(section->mr);
@ -1040,18 +1021,8 @@ static void vfio_listener_region_del(MemoryListener *listener,
}
static MemoryListener vfio_memory_listener = {
.begin = vfio_listener_dummy1,
.commit = vfio_listener_dummy1,
.region_add = vfio_listener_region_add,
.region_del = vfio_listener_region_del,
.region_nop = vfio_listener_dummy2,
.log_start = vfio_listener_dummy2,
.log_stop = vfio_listener_dummy2,
.log_sync = vfio_listener_dummy2,
.log_global_start = vfio_listener_dummy1,
.log_global_stop = vfio_listener_dummy1,
.eventfd_add = vfio_listener_dummy3,
.eventfd_del = vfio_listener_dummy3,
};
static void vfio_listener_release(VFIOContainer *container)
@ -1536,8 +1507,7 @@ static int vfio_connect_container(VFIOGroup *group)
container->iommu_data.listener = vfio_memory_listener;
container->iommu_data.release = vfio_listener_release;
memory_listener_register(&container->iommu_data.listener,
get_system_memory());
memory_listener_register(&container->iommu_data.listener, &address_space_memory);
} else {
error_report("vfio: No available IOMMU models\n");
g_free(container);

View File

@ -1,6 +1,8 @@
/*
* QEMU ISA VGA Emulator.
*
* see docs/specs/standard-vga.txt for virtual hardware specs.
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -1,6 +1,8 @@
/*
* QEMU PCI VGA Emulator.
*
* see docs/specs/standard-vga.txt for virtual hardware specs.
*
* Copyright (c) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@ -29,9 +31,23 @@
#include "qemu-timer.h"
#include "loader.h"
#define PCI_VGA_IOPORT_OFFSET 0x400
#define PCI_VGA_IOPORT_SIZE (0x3e0 - 0x3c0)
#define PCI_VGA_BOCHS_OFFSET 0x500
#define PCI_VGA_BOCHS_SIZE (0x0b * 2)
#define PCI_VGA_MMIO_SIZE 0x1000
enum vga_pci_flags {
PCI_VGA_FLAG_ENABLE_MMIO = 1,
};
typedef struct PCIVGAState {
PCIDevice dev;
VGACommonState vga;
uint32_t flags;
MemoryRegion mmio;
MemoryRegion ioport;
MemoryRegion bochs;
} PCIVGAState;
static const VMStateDescription vmstate_vga_pci = {
@ -46,31 +62,125 @@ static const VMStateDescription vmstate_vga_pci = {
}
};
static uint64_t pci_vga_ioport_read(void *ptr, target_phys_addr_t addr,
unsigned size)
{
PCIVGAState *d = ptr;
uint64_t ret = 0;
switch (size) {
case 1:
ret = vga_ioport_read(&d->vga, addr);
break;
case 2:
ret = vga_ioport_read(&d->vga, addr);
ret |= vga_ioport_read(&d->vga, addr+1) << 8;
break;
}
return ret;
}
static void pci_vga_ioport_write(void *ptr, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIVGAState *d = ptr;
switch (size) {
case 1:
vga_ioport_write(&d->vga, addr, val);
break;
case 2:
/*
* Update bytes in little endian order. Allows to update
* indexed registers with a single word write because the
* index byte is updated first.
*/
vga_ioport_write(&d->vga, addr, val & 0xff);
vga_ioport_write(&d->vga, addr+1, (val >> 8) & 0xff);
break;
}
}
static const MemoryRegionOps pci_vga_ioport_ops = {
.read = pci_vga_ioport_read,
.write = pci_vga_ioport_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 1,
.impl.max_access_size = 2,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static uint64_t pci_vga_bochs_read(void *ptr, target_phys_addr_t addr,
unsigned size)
{
PCIVGAState *d = ptr;
int index = addr >> 1;
vbe_ioport_write_index(&d->vga, 0, index);
return vbe_ioport_read_data(&d->vga, 0);
}
static void pci_vga_bochs_write(void *ptr, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIVGAState *d = ptr;
int index = addr >> 1;
vbe_ioport_write_index(&d->vga, 0, index);
vbe_ioport_write_data(&d->vga, 0, val);
}
static const MemoryRegionOps pci_vga_bochs_ops = {
.read = pci_vga_bochs_read,
.write = pci_vga_bochs_write,
.valid.min_access_size = 1,
.valid.max_access_size = 4,
.impl.min_access_size = 2,
.impl.max_access_size = 2,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static int pci_std_vga_initfn(PCIDevice *dev)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
VGACommonState *s = &d->vga;
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
VGACommonState *s = &d->vga;
// vga + console init
vga_common_init(s);
vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
/* vga + console init */
vga_common_init(s);
vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
vga_init_vbe(s, pci_address_space(dev));
}
/* mmio bar for vga register access */
if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_MMIO)) {
memory_region_init(&d->mmio, "vga.mmio", 4096);
memory_region_init_io(&d->ioport, &pci_vga_ioport_ops, d,
"vga ioports remapped", PCI_VGA_IOPORT_SIZE);
memory_region_init_io(&d->bochs, &pci_vga_bochs_ops, d,
"bochs dispi interface", PCI_VGA_BOCHS_SIZE);
return 0;
memory_region_add_subregion(&d->mmio, PCI_VGA_IOPORT_OFFSET,
&d->ioport);
memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
&d->bochs);
pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
}
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
vga_init_vbe(s, pci_address_space(dev));
}
return 0;
}
static Property vga_pci_properties[] = {
DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -582,7 +582,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
}
}
#ifdef CONFIG_BOCHS_VBE
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
{
VGACommonState *s = opaque;
@ -591,7 +590,7 @@ static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
return val;
}
static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
{
VGACommonState *s = opaque;
uint32_t val;
@ -627,13 +626,13 @@ static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
return val;
}
static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
{
VGACommonState *s = opaque;
s->vbe_index = val;
}
static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
{
VGACommonState *s = opaque;
@ -784,7 +783,6 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
}
}
}
#endif
/* called for accesses between 0xa0000 and 0xc0000 */
uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
@ -1129,14 +1127,12 @@ static void vga_get_offsets(VGACommonState *s,
uint32_t *pline_compare)
{
uint32_t start_addr, line_offset, line_compare;
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
line_offset = s->vbe_line_offset;
start_addr = s->vbe_start_addr;
line_compare = 65535;
} else
#endif
{
} else {
/* compute line_offset in bytes */
line_offset = s->cr[VGA_CRTC_OFFSET];
line_offset <<= 3;
@ -1572,12 +1568,10 @@ static vga_draw_line_func * const vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_
static int vga_get_bpp(VGACommonState *s)
{
int ret;
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
} else
#endif
{
} else {
ret = 0;
}
return ret;
@ -1587,13 +1581,10 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
{
int width, height;
#ifdef CONFIG_BOCHS_VBE
if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
} else
#endif
{
} else {
width = (s->cr[VGA_CRTC_H_DISP] + 1) * 8;
height = s->cr[VGA_CRTC_V_DISP_END] |
((s->cr[VGA_CRTC_OVERFLOW] & 0x02) << 7) |
@ -1948,14 +1939,12 @@ void vga_common_reset(VGACommonState *s)
s->dac_8bit = 0;
memset(s->palette, '\0', sizeof(s->palette));
s->bank_offset = 0;
#ifdef CONFIG_BOCHS_VBE
s->vbe_index = 0;
memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));
s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
s->vbe_start_addr = 0;
s->vbe_line_offset = 0;
s->vbe_bank_mask = (s->vram_size >> 16) - 1;
#endif
memset(s->font_offsets, '\0', sizeof(s->font_offsets));
s->graphic_mode = -1; /* force full update */
s->shift_control = 0;
@ -2229,13 +2218,11 @@ const VMStateDescription vmstate_vga_common = {
VMSTATE_INT32(bank_offset, VGACommonState),
VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
#ifdef CONFIG_BOCHS_VBE
VMSTATE_UINT16(vbe_index, VGACommonState),
VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
VMSTATE_UINT32(vbe_start_addr, VGACommonState),
VMSTATE_UINT32(vbe_line_offset, VGACommonState),
VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
#endif
VMSTATE_END_OF_LIST()
}
};
@ -2275,11 +2262,7 @@ void vga_common_init(VGACommonState *s)
}
s->vram_size_mb = s->vram_size >> 20;
#ifdef CONFIG_BOCHS_VBE
s->is_vbe_vmstate = 1;
#else
s->is_vbe_vmstate = 0;
#endif
memory_region_init_ram(&s->vram, "vga.vram", s->vram_size);
vmstate_register_ram_global(&s->vram);
xen_register_framebuffer(&s->vram);
@ -2314,7 +2297,6 @@ static const MemoryRegionPortio vga_portio_list[] = {
PORTIO_END_OF_LIST(),
};
#ifdef CONFIG_BOCHS_VBE
static const MemoryRegionPortio vbe_portio_list[] = {
{ 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
# ifdef TARGET_I386
@ -2324,7 +2306,6 @@ static const MemoryRegionPortio vbe_portio_list[] = {
# endif
PORTIO_END_OF_LIST(),
};
#endif /* CONFIG_BOCHS_VBE */
/* Used by both ISA and PCI */
MemoryRegion *vga_init_io(VGACommonState *s,
@ -2334,10 +2315,7 @@ MemoryRegion *vga_init_io(VGACommonState *s,
MemoryRegion *vga_mem;
*vga_ports = vga_portio_list;
*vbe_ports = NULL;
#ifdef CONFIG_BOCHS_VBE
*vbe_ports = vbe_portio_list;
#endif
vga_mem = g_malloc(sizeof(*vga_mem));
memory_region_init_io(vga_mem, &vga_mem_ops, s,
@ -2379,7 +2357,6 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space,
void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
{
#ifdef CONFIG_BOCHS_VBE
/* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
* so use an alias to avoid double-mapping the same region.
*/
@ -2390,7 +2367,6 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
VBE_DISPI_LFB_PHYSICAL_ADDRESS,
&s->vram_vbe);
s->vbe_mapped = 1;
#endif
}
/********************************************************/
/* vga screen dump */

View File

@ -29,9 +29,6 @@
#define ST01_V_RETRACE 0x08
#define ST01_DISP_ENABLE 0x01
/* bochs VBE support */
#define CONFIG_BOCHS_VBE
#define VBE_DISPI_MAX_XRES 16000
#define VBE_DISPI_MAX_YRES 12000
#define VBE_DISPI_MAX_BPP 32
@ -65,21 +62,6 @@
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000
#ifdef CONFIG_BOCHS_VBE
#define VGA_STATE_COMMON_BOCHS_VBE \
uint16_t vbe_index; \
uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \
uint32_t vbe_start_addr; \
uint32_t vbe_line_offset; \
uint32_t vbe_bank_mask; \
int vbe_mapped;
#else
#define VGA_STATE_COMMON_BOCHS_VBE
#endif /* !CONFIG_BOCHS_VBE */
#define CH_ATTR_SIZE (160 * 100)
#define VGA_MAX_HEIGHT 2048
@ -140,7 +122,13 @@ typedef struct VGACommonState {
void (*get_resolution)(struct VGACommonState *s,
int *pwidth,
int *pheight);
VGA_STATE_COMMON_BOCHS_VBE
/* bochs vbe state */
uint16_t vbe_index;
uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
uint32_t vbe_start_addr;
uint32_t vbe_line_offset;
uint32_t vbe_bank_mask;
int vbe_mapped;
/* display refresh support */
DisplayState *ds;
uint32_t font_offsets[2];
@ -208,7 +196,11 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space);
uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr);
void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val);
void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val);
extern const uint8_t sr_mask[8];
extern const uint8_t gr_mask[16];

Some files were not shown because too many files have changed in this diff Show More