mirror of https://github.com/xemu-project/xemu.git
Merge branch 'master' into xbox
This commit is contained in:
commit
a282385882
|
@ -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
|
||||
|
|
4
Makefile
4
Makefile
|
@ -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
|
||||
|
|
141
arch_init.c
141
arch_init.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
129
buffered_file.c
129
buffered_file.c
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
9
cpus.c
|
@ -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
|
||||
|
|
6
cputlb.c
6
cputlb.c
|
@ -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",
|
||||
|
|
3
cputlb.h
3
cputlb.h
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
17
dma.h
|
@ -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 {
|
||||
|
|
|
@ -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"
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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
564
exec.c
|
@ -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
12
hmp.c
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
16
hw/boards.h
16
hw/boards.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
11
hw/gumstix.c
11
hw/gumstix.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
1
hw/hw.h
1
hw/hw.h
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
12
hw/kzm.c
12
hw/kzm.c
|
@ -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);
|
||||
|
|
10
hw/leon3.c
10
hw/leon3.c
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
22
hw/nseries.c
22
hw/nseries.c
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
1
hw/pc.c
1
hw/pc.c
|
@ -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
27
hw/pc.h
|
@ -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)
|
||||
{
|
||||
|
|
54
hw/pc_piix.c
54
hw/pc_piix.c
|
@ -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 = {
|
||||
|
|
25
hw/pci.c
25
hw/pci.c
|
@ -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);
|
||||
|
|
2
hw/pci.h
2
hw/pci.h
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
11
hw/pl011.c
11
hw/pl011.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
hw/pl031.c
16
hw/pl031.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
18
hw/pl181.c
18
hw/pl181.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
9
hw/r2d.c
9
hw/r2d.c
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
149
hw/serial.c
149
hw/serial.c
|
@ -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)
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
13
hw/spapr.c
13
hw/spapr.c
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
40
hw/spitz.c
40
hw/spitz.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
133
hw/sun4m.c
133
hw/sun4m.c
|
@ -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);
|
||||
}
|
||||
|
|
34
hw/sun4u.c
34
hw/sun4u.c
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
138
hw/vga-pci.c
138
hw/vga-pci.c
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
40
hw/vga.c
40
hw/vga.c
|
@ -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 */
|
||||
|
|
30
hw/vga_int.h
30
hw/vga_int.h
|
@ -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
Loading…
Reference in New Issue