diff --git a/Binary Artifacts/Support Files/bios.bin b/Binary Artifacts/Support Files/bios.bin
index 6c8bc9f6..e4323c05 100644
Binary files a/Binary Artifacts/Support Files/bios.bin and b/Binary Artifacts/Support Files/bios.bin differ
diff --git a/TESTFILES/WinQemu.dll b/TESTFILES/WinQemu.dll
index 1787d9c8..a1d0b963 100644
Binary files a/TESTFILES/WinQemu.dll and b/TESTFILES/WinQemu.dll differ
diff --git a/TESTFILES/WinQemu.pdb b/TESTFILES/WinQemu.pdb
index aab4fe34..68ef7e54 100644
Binary files a/TESTFILES/WinQemu.pdb and b/TESTFILES/WinQemu.pdb differ
diff --git a/TESTFILES/bios.bin b/TESTFILES/bios.bin
index 8aa5b713..e4323c05 100644
Binary files a/TESTFILES/bios.bin and b/TESTFILES/bios.bin differ
diff --git a/WinQemu.vcxproj b/WinQemu.vcxproj
index bdac325a..54092dc1 100644
--- a/WinQemu.vcxproj
+++ b/WinQemu.vcxproj
@@ -196,6 +196,8 @@
true
+
+
@@ -1107,6 +1109,7 @@
+
diff --git a/WinQemu.vcxproj.filters b/WinQemu.vcxproj.filters
index 2977366a..3a3ad81f 100644
--- a/WinQemu.vcxproj.filters
+++ b/WinQemu.vcxproj.filters
@@ -1134,9 +1134,6 @@
qemu\block\src
-
- qemu\src
-
qemu\src
@@ -1191,6 +1188,15 @@
qemu\src
+
+ qemu\hw\src
+
+
+ qemu\hw\src
+
+
+ qemu\hw\src
+
@@ -1796,6 +1802,9 @@
qemu\inc
+
+ qemu\hw\inc
+
diff --git a/qemu/Makefile b/qemu/Makefile
index caf85309..a3ae99fd 100644
--- a/qemu/Makefile
+++ b/qemu/Makefile
@@ -108,7 +108,7 @@ obj-y += bt-hci-csr.o
obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
obj-y += qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
obj-y += msmouse.o ps2.o
-obj-y += qdev.o ssi.o
+obj-y += qdev.o qdev-properties.o ssi.o
obj-$(CONFIG_BRLAPI) += baum.o
diff --git a/qemu/Makefile.hw b/qemu/Makefile.hw
index f7a9507e..571e5184 100644
--- a/qemu/Makefile.hw
+++ b/qemu/Makefile.hw
@@ -26,7 +26,7 @@ obj-y += m48t59.o escc.o
# SCSI layer
obj-y += lsi53c895a.o esp.o
-obj-y += dma-helpers.o sysbus.o
+obj-y += dma-helpers.o sysbus.o qdev-addr.o
all: $(HWLIB)
# Dummy command so that make thinks it has done something
diff --git a/qemu/block.c b/qemu/block.c
index e8b689db..bdbf3863 100644
--- a/qemu/block.c
+++ b/qemu/block.c
@@ -1183,24 +1183,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return drv->bdrv_get_info(bs, bdi);
}
-int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
+int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
+ int64_t pos, int size)
{
BlockDriver *drv = bs->drv;
if (!drv)
return -ENOMEDIUM;
- if (!drv->bdrv_put_buffer)
+ if (!drv->bdrv_save_vmstate)
return -ENOTSUP;
- return drv->bdrv_put_buffer(bs, buf, pos, size);
+ return drv->bdrv_save_vmstate(bs, buf, pos, size);
}
-int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
+int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+ int64_t pos, int size)
{
BlockDriver *drv = bs->drv;
if (!drv)
return -ENOMEDIUM;
- if (!drv->bdrv_get_buffer)
+ if (!drv->bdrv_load_vmstate)
return -ENOTSUP;
- return drv->bdrv_get_buffer(bs, buf, pos, size);
+ return drv->bdrv_load_vmstate(bs, buf, pos, size);
}
/**************************************************************/
@@ -1399,6 +1401,7 @@ static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
{
BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
qemu_bh_delete(acb->bh);
+ acb->bh = NULL;
qemu_aio_release(acb);
}
@@ -1416,6 +1419,7 @@ static void bdrv_aio_bh_cb(void *opaque)
qemu_vfree(acb->bounce);
acb->common.cb(acb->common.opaque, acb->ret);
qemu_bh_delete(acb->bh);
+ acb->bh = NULL;
qemu_aio_release(acb);
}
diff --git a/qemu/block.h b/qemu/block.h
index 406a1994..ccd4c1e7 100644
--- a/qemu/block.h
+++ b/qemu/block.h
@@ -159,9 +159,10 @@ void path_combine(char *dest, int dest_size,
const char *base_path,
const char *filename);
-int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
- int64_t pos, int size);
+int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
+ int64_t pos, int size);
-int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
+int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
+ int64_t pos, int size);
#endif
diff --git a/qemu/block/qcow.c b/qemu/block/qcow.c
index 329b364b..7fc85ae5 100644
--- a/qemu/block/qcow.c
+++ b/qemu/block/qcow.c
@@ -723,7 +723,7 @@ static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs,
s->cluster_cache_offset = -1; /* disable compressed cache */
- acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
+ acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
if (!acb)
return NULL;
@@ -909,9 +909,21 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
static QEMUOptionParameter qcow_create_options[] = {
- { BLOCK_OPT_SIZE, OPT_SIZE },
- { BLOCK_OPT_BACKING_FILE, OPT_STRING },
- { BLOCK_OPT_ENCRYPT, OPT_FLAG },
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ {
+ .name = BLOCK_OPT_BACKING_FILE,
+ .type = OPT_STRING,
+ .help = "File name of a base image"
+ },
+ {
+ .name = BLOCK_OPT_ENCRYPT,
+ .type = OPT_FLAG,
+ .help = "Encrypt the image"
+ },
{ NULL }
};
diff --git a/qemu/block/qcow2-cluster.c b/qemu/block/qcow2-cluster.c
index d349655d..057dac57 100644
--- a/qemu/block/qcow2-cluster.c
+++ b/qemu/block/qcow2-cluster.c
@@ -47,7 +47,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
#endif
new_l1_size2 = sizeof(uint64_t) * new_l1_size;
- new_l1_table = qemu_mallocz(new_l1_size2);
+ new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
/* write new table (align to cluster) */
diff --git a/qemu/block/qcow2-refcount.c b/qemu/block/qcow2-refcount.c
index d42c6e64..e6c857e0 100644
--- a/qemu/block/qcow2-refcount.c
+++ b/qemu/block/qcow2-refcount.c
@@ -513,7 +513,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
l1_size2 = l1_size * sizeof(uint64_t);
l1_allocated = 0;
if (l1_table_offset != s->l1_table_offset) {
- l1_table = qemu_malloc(l1_size2);
+ l1_table = qemu_mallocz(align_offset(l1_size2, 512));
l1_allocated = 1;
if (bdrv_pread(s->hd, l1_table_offset,
l1_table, l1_size2) != l1_size2)
diff --git a/qemu/block/qcow2.c b/qemu/block/qcow2.c
index 9a7c666e..a5bf2052 100644
--- a/qemu/block/qcow2.c
+++ b/qemu/block/qcow2.c
@@ -200,7 +200,8 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
if (s->l1_size < s->l1_vm_state_index)
goto fail;
s->l1_table_offset = header.l1_table_offset;
- s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
+ s->l1_table = qemu_mallocz(
+ align_offset(s->l1_size * sizeof(uint64_t), 512));
if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
s->l1_size * sizeof(uint64_t))
goto fail;
@@ -889,12 +890,16 @@ static void qcow_flush(BlockDriverState *bs)
bdrv_flush(s->hd);
}
+static int64_t qcow_vm_state_offset(BDRVQcowState *s)
+{
+ return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
+}
+
static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
{
BDRVQcowState *s = bs->opaque;
bdi->cluster_size = s->cluster_size;
- bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
- (s->cluster_bits + s->l2_bits);
+ bdi->vm_state_offset = qcow_vm_state_offset(s);
return 0;
}
@@ -924,26 +929,28 @@ static void dump_refcounts(BlockDriverState *bs)
}
#endif
-static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
+static int qcow_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
int64_t pos, int size)
{
+ BDRVQcowState *s = bs->opaque;
int growable = bs->growable;
bs->growable = 1;
- bdrv_pwrite(bs, pos, buf, size);
+ bdrv_pwrite(bs, qcow_vm_state_offset(s) + pos, buf, size);
bs->growable = growable;
return size;
}
-static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
+static int qcow_load_vmstate(BlockDriverState *bs, uint8_t *buf,
int64_t pos, int size)
{
+ BDRVQcowState *s = bs->opaque;
int growable = bs->growable;
int ret;
bs->growable = 1;
- ret = bdrv_pread(bs, pos, buf, size);
+ ret = bdrv_pread(bs, qcow_vm_state_offset(s) + pos, buf, size);
bs->growable = growable;
return ret;
@@ -1000,8 +1007,8 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_snapshot_list = qcow2_snapshot_list,
.bdrv_get_info = qcow_get_info,
- .bdrv_put_buffer = qcow_put_buffer,
- .bdrv_get_buffer = qcow_get_buffer,
+ .bdrv_save_vmstate = qcow_save_vmstate,
+ .bdrv_load_vmstate = qcow_load_vmstate,
.create_options = qcow_create_options,
.bdrv_check = qcow_check,
diff --git a/qemu/block/raw-posix.c b/qemu/block/raw-posix.c
index fa4f83e8..389903e4 100644
--- a/qemu/block/raw-posix.c
+++ b/qemu/block/raw-posix.c
@@ -852,6 +852,7 @@ static int64_t raw_getlength(BlockDriverState *bs)
static int raw_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
+ int result = 0;
int64_t total_size = 0;
/* Read out options */
@@ -864,11 +865,17 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
- if (fd < 0)
- return -EIO;
- ftruncate(fd, total_size * 512);
- close(fd);
- return 0;
+ if (fd < 0) {
+ result = -errno;
+ } else {
+ if (ftruncate(fd, total_size * 512) != 0) {
+ result = -errno;
+ }
+ if (close(fd) != 0) {
+ result = -errno;
+ }
+ }
+ return result;
}
static void raw_flush(BlockDriverState *bs)
diff --git a/qemu/block_int.h b/qemu/block_int.h
index 830b7e9c..8898d91f 100644
--- a/qemu/block_int.h
+++ b/qemu/block_int.h
@@ -84,10 +84,10 @@ struct BlockDriver {
QEMUSnapshotInfo **psn_info);
int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
- int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
- int64_t pos, int size);
- int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
- int64_t pos, int size);
+ int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
+ int64_t pos, int size);
+ int (*bdrv_load_vmstate)(BlockDriverState *bs, uint8_t *buf,
+ int64_t pos, int size);
/* removable device specific */
int (*bdrv_is_inserted)(BlockDriverState *bs);
diff --git a/qemu/configure b/qemu/configure
index a55dbc5e..cba0c08a 100644
--- a/qemu/configure
+++ b/qemu/configure
@@ -34,6 +34,8 @@ ar="ar"
make="make"
install="install"
strip="strip"
+objcopy="objcopy"
+ld="ld"
# parse CC options first
for opt do
@@ -53,6 +55,8 @@ done
cc="${cross_prefix}${cc}"
ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}"
+objcopy="${cross_prefix}${objcopy}"
+ld="${cross_prefix}${ld}"
# check that the C compiler works.
cat > $TMPC <> $config_mak
echo "CC=$cc" >> $config_mak
echo "HOST_CC=$host_cc" >> $config_mak
echo "AR=$ar" >> $config_mak
+echo "OBJCOPY=$objcopy" >> $config_mak
+echo "LD=$ld" >> $config_mak
# XXX: only use CFLAGS and LDFLAGS ?
# XXX: should export HOST_CFLAGS and HOST_LDFLAGS for cross
# compilation of dyngen tool (useful for win32 build on Linux host)
diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c
index f21169b9..64322a05 100644
--- a/qemu/cpu-exec.c
+++ b/qemu/cpu-exec.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/*
@@ -421,7 +420,7 @@ int cpu_exec(CPUState *env1)
env->hflags2 |= HF2_NMI_MASK;
do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
next_tb = 0;
- } else if (interrupt_request & CPU_INTERRUPT_MCE) {
+ } else if (interrupt_request & CPU_INTERRUPT_MCE) {
env->interrupt_request &= ~CPU_INTERRUPT_MCE;
do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
next_tb = 0;
@@ -496,7 +495,7 @@ int cpu_exec(CPUState *env1)
}
#elif defined(TARGET_SPARC)
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->psret != 0)) {
+ cpu_interrupts_enabled(env)) {
int pil = env->interrupt_index & 15;
int type = env->interrupt_index & 0xf0;
@@ -507,7 +506,7 @@ int cpu_exec(CPUState *env1)
env->exception_index = env->interrupt_index;
do_interrupt(env);
env->interrupt_index = 0;
-#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
cpu_check_irqs(env);
#endif
next_tb = 0;
diff --git a/qemu/exec.c b/qemu/exec.c
index e591a099..b4458b96 100644
--- a/qemu/exec.c
+++ b/qemu/exec.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include "config.h"
#ifdef _WIN32
@@ -1508,7 +1507,6 @@ void cpu_single_step(CPUState *env, int enabled)
}
}
-
/* enable or disable low levels log */
void cpu_set_log(int log_flags)
{
@@ -1770,6 +1768,13 @@ static inline void tlb_flush_jmp_cache(CPUState *env, target_ulong addr)
TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
}
+static CPUTLBEntry s_cputlb_empty_entry = {
+ .addr_read = -1,
+ .addr_write = -1,
+ .addr_code = -1,
+ .addend = -1,
+};
+
/* NOTE: if flush_global is true, also flush global entries (not
implemented yet) */
void tlb_flush(CPUState *env, int flush_global)
@@ -1786,9 +1791,7 @@ void tlb_flush(CPUState *env, int flush_global)
for(i = 0; i < CPU_TLB_SIZE; i++) {
int mmu_idx;
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
- env->tlb_table[mmu_idx][i].addr_read = -1;
- env->tlb_table[mmu_idx][i].addr_write = -1;
- env->tlb_table[mmu_idx][i].addr_code = -1;
+ env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry;
}
}
@@ -1810,9 +1813,7 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
(TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
addr == (tlb_entry->addr_code &
(TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
- tlb_entry->addr_read = -1;
- tlb_entry->addr_write = -1;
- tlb_entry->addr_code = -1;
+ *tlb_entry = s_cputlb_empty_entry;
}
}
diff --git a/qemu/gdb-xml/power-core.xml b/qemu/gdb-xml/power-core.xml
index dae13a67..0c69e8c8 100644
--- a/qemu/gdb-xml/power-core.xml
+++ b/qemu/gdb-xml/power-core.xml
@@ -46,13 +46,4 @@
-
-
diff --git a/qemu/gdb-xml/power-fpu.xml b/qemu/gdb-xml/power-fpu.xml
index d1ca3a3d..38705515 100644
--- a/qemu/gdb-xml/power-fpu.xml
+++ b/qemu/gdb-xml/power-fpu.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/qemu/gdb-xml/power-spe.xml b/qemu/gdb-xml/power-spe.xml
index 1ec15d66..57740cc5 100644
--- a/qemu/gdb-xml/power-spe.xml
+++ b/qemu/gdb-xml/power-spe.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/qemu/gdb-xml/power64-core.xml b/qemu/gdb-xml/power64-core.xml
index fef42e41..6cc15312 100644
--- a/qemu/gdb-xml/power64-core.xml
+++ b/qemu/gdb-xml/power64-core.xml
@@ -46,13 +46,4 @@
-
-
diff --git a/qemu/gdbstub.c b/qemu/gdbstub.c
index 5549bcc2..157e031a 100644
--- a/qemu/gdbstub.c
+++ b/qemu/gdbstub.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include "config.h"
#include "qemu-common.h"
@@ -511,112 +510,136 @@ static const int gpr_map[8] = {0, 1, 2, 3, 4, 5, 6, 7};
#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
+#define IDX_IP_REG CPU_NB_REGS
+#define IDX_FLAGS_REG (IDX_IP_REG + 1)
+#define IDX_SEG_REGS (IDX_FLAGS_REG + 1)
+#define IDX_FP_REGS (IDX_SEG_REGS + 6)
+#define IDX_XMM_REGS (IDX_FP_REGS + 16)
+#define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS)
+
static int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
{
if (n < CPU_NB_REGS) {
GET_REGL(env->regs[gpr_map[n]]);
- } else if (n >= CPU_NB_REGS + 8 && n < CPU_NB_REGS + 16) {
- /* FIXME: byteswap float values. */
+ } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
#ifdef USE_X86LDOUBLE
- memcpy(mem_buf, &env->fpregs[n - (CPU_NB_REGS + 8)], 10);
+ /* FIXME: byteswap float values - after fixing fpregs layout. */
+ memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10);
#else
memset(mem_buf, 0, 10);
#endif
return 10;
- } else if (n >= CPU_NB_REGS + 24) {
- n -= CPU_NB_REGS + 24;
- if (n < CPU_NB_REGS) {
- stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
- stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
- return 16;
- } else if (n == CPU_NB_REGS) {
- GET_REG32(env->mxcsr);
- }
+ } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
+ n -= IDX_XMM_REGS;
+ stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
+ stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
+ return 16;
} else {
- n -= CPU_NB_REGS;
switch (n) {
- case 0: GET_REGL(env->eip);
- case 1: GET_REG32(env->eflags);
- case 2: GET_REG32(env->segs[R_CS].selector);
- case 3: GET_REG32(env->segs[R_SS].selector);
- case 4: GET_REG32(env->segs[R_DS].selector);
- case 5: GET_REG32(env->segs[R_ES].selector);
- case 6: GET_REG32(env->segs[R_FS].selector);
- case 7: GET_REG32(env->segs[R_GS].selector);
- /* 8...15 x87 regs. */
- case 16: GET_REG32(env->fpuc);
- case 17: GET_REG32((env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11);
- case 18: GET_REG32(0); /* ftag */
- case 19: GET_REG32(0); /* fiseg */
- case 20: GET_REG32(0); /* fioff */
- case 21: GET_REG32(0); /* foseg */
- case 22: GET_REG32(0); /* fooff */
- case 23: GET_REG32(0); /* fop */
- /* 24+ xmm regs. */
+ case IDX_IP_REG: GET_REGL(env->eip);
+ case IDX_FLAGS_REG: GET_REG32(env->eflags);
+
+ case IDX_SEG_REGS: GET_REG32(env->segs[R_CS].selector);
+ case IDX_SEG_REGS + 1: GET_REG32(env->segs[R_SS].selector);
+ case IDX_SEG_REGS + 2: GET_REG32(env->segs[R_DS].selector);
+ case IDX_SEG_REGS + 3: GET_REG32(env->segs[R_ES].selector);
+ case IDX_SEG_REGS + 4: GET_REG32(env->segs[R_FS].selector);
+ case IDX_SEG_REGS + 5: GET_REG32(env->segs[R_GS].selector);
+
+ case IDX_FP_REGS + 8: GET_REG32(env->fpuc);
+ case IDX_FP_REGS + 9: GET_REG32((env->fpus & ~0x3800) |
+ (env->fpstt & 0x7) << 11);
+ case IDX_FP_REGS + 10: GET_REG32(0); /* ftag */
+ case IDX_FP_REGS + 11: GET_REG32(0); /* fiseg */
+ case IDX_FP_REGS + 12: GET_REG32(0); /* fioff */
+ case IDX_FP_REGS + 13: GET_REG32(0); /* foseg */
+ case IDX_FP_REGS + 14: GET_REG32(0); /* fooff */
+ case IDX_FP_REGS + 15: GET_REG32(0); /* fop */
+
+ case IDX_MXCSR_REG: GET_REG32(env->mxcsr);
}
}
return 0;
}
-static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int i)
+static int cpu_x86_gdb_load_seg(CPUState *env, int sreg, uint8_t *mem_buf)
+{
+ uint16_t selector = ldl_p(mem_buf);
+
+ if (selector != env->segs[sreg].selector) {
+#if defined(CONFIG_USER_ONLY)
+ cpu_x86_load_seg(env, sreg, selector);
+#else
+ unsigned int limit, flags;
+ target_ulong base;
+
+ if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
+ base = selector << 4;
+ limit = 0xffff;
+ flags = 0;
+ } else {
+ if (!cpu_x86_get_descr_debug(env, selector, &base, &limit, &flags))
+ return 4;
+ }
+ cpu_x86_load_seg_cache(env, sreg, selector, base, limit, flags);
+#endif
+ }
+ return 4;
+}
+
+static int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
{
uint32_t tmp;
- if (i < CPU_NB_REGS) {
- env->regs[gpr_map[i]] = ldtul_p(mem_buf);
+ if (n < CPU_NB_REGS) {
+ env->regs[gpr_map[n]] = ldtul_p(mem_buf);
return sizeof(target_ulong);
- } else if (i >= CPU_NB_REGS + 8 && i < CPU_NB_REGS + 16) {
- i -= CPU_NB_REGS + 8;
+ } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) {
#ifdef USE_X86LDOUBLE
- memcpy(&env->fpregs[i], mem_buf, 10);
+ /* FIXME: byteswap float values - after fixing fpregs layout. */
+ memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10);
#endif
return 10;
- } else if (i >= CPU_NB_REGS + 24) {
- i -= CPU_NB_REGS + 24;
- if (i < CPU_NB_REGS) {
- env->xmm_regs[i].XMM_Q(0) = ldq_p(mem_buf);
- env->xmm_regs[i].XMM_Q(1) = ldq_p(mem_buf + 8);
- return 16;
- } else if (i == CPU_NB_REGS) {
+ } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) {
+ n -= IDX_XMM_REGS;
+ env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf);
+ env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8);
+ return 16;
+ } else {
+ switch (n) {
+ case IDX_IP_REG:
+ env->eip = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case IDX_FLAGS_REG:
+ env->eflags = ldl_p(mem_buf);
+ return 4;
+
+ case IDX_SEG_REGS: return cpu_x86_gdb_load_seg(env, R_CS, mem_buf);
+ case IDX_SEG_REGS + 1: return cpu_x86_gdb_load_seg(env, R_SS, mem_buf);
+ case IDX_SEG_REGS + 2: return cpu_x86_gdb_load_seg(env, R_DS, mem_buf);
+ case IDX_SEG_REGS + 3: return cpu_x86_gdb_load_seg(env, R_ES, mem_buf);
+ case IDX_SEG_REGS + 4: return cpu_x86_gdb_load_seg(env, R_FS, mem_buf);
+ case IDX_SEG_REGS + 5: return cpu_x86_gdb_load_seg(env, R_GS, mem_buf);
+
+ case IDX_FP_REGS + 8:
+ env->fpuc = ldl_p(mem_buf);
+ return 4;
+ case IDX_FP_REGS + 9:
+ tmp = ldl_p(mem_buf);
+ env->fpstt = (tmp >> 11) & 7;
+ env->fpus = tmp & ~0x3800;
+ return 4;
+ case IDX_FP_REGS + 10: /* ftag */ return 4;
+ case IDX_FP_REGS + 11: /* fiseg */ return 4;
+ case IDX_FP_REGS + 12: /* fioff */ return 4;
+ case IDX_FP_REGS + 13: /* foseg */ return 4;
+ case IDX_FP_REGS + 14: /* fooff */ return 4;
+ case IDX_FP_REGS + 15: /* fop */ return 4;
+
+ case IDX_MXCSR_REG:
env->mxcsr = ldl_p(mem_buf);
return 4;
}
- } else {
- i -= CPU_NB_REGS;
- switch (i) {
- case 0: env->eip = ldtul_p(mem_buf); return sizeof(target_ulong);
- case 1: env->eflags = ldl_p(mem_buf); return 4;
-#if defined(CONFIG_USER_ONLY)
-#define LOAD_SEG(index, sreg)\
- tmp = ldl_p(mem_buf);\
- if (tmp != env->segs[sreg].selector)\
- cpu_x86_load_seg(env, sreg, tmp);
-#else
-/* FIXME: Honor segment registers. Needs to avoid raising an exception
- when the selector is invalid. */
-#define LOAD_SEG(index, sreg) do {} while(0)
-#endif
- case 2: LOAD_SEG(10, R_CS); return 4;
- case 3: LOAD_SEG(11, R_SS); return 4;
- case 4: LOAD_SEG(12, R_DS); return 4;
- case 5: LOAD_SEG(13, R_ES); return 4;
- case 6: LOAD_SEG(14, R_FS); return 4;
- case 7: LOAD_SEG(15, R_GS); return 4;
- /* 8...15 x87 regs. */
- case 16: env->fpuc = ldl_p(mem_buf); return 4;
- case 17:
- tmp = ldl_p(mem_buf);
- env->fpstt = (tmp >> 11) & 7;
- env->fpus = tmp & ~0x3800;
- return 4;
- case 18: /* ftag */ return 4;
- case 19: /* fiseg */ return 4;
- case 20: /* fioff */ return 4;
- case 21: /* foseg */ return 4;
- case 22: /* fooff */ return 4;
- case 23: /* fop */ return 4;
- /* 24+ xmm regs. */
- }
}
/* Unrecognised register. */
return 0;
@@ -1634,6 +1657,64 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
s->signal = 0;
gdb_continue(s);
return RS_IDLE;
+ case 'v':
+ if (strncmp(p, "Cont", 4) == 0) {
+ int res_signal, res_thread;
+
+ p += 4;
+ if (*p == '?') {
+ put_packet(s, "vCont;c;C;s;S");
+ break;
+ }
+ res = 0;
+ res_signal = 0;
+ res_thread = 0;
+ while (*p) {
+ int action, signal;
+
+ if (*p++ != ';') {
+ res = 0;
+ break;
+ }
+ action = *p++;
+ signal = 0;
+ if (action == 'C' || action == 'S') {
+ signal = strtoul(p, (char **)&p, 16);
+ } else if (action != 'c' && action != 's') {
+ res = 0;
+ break;
+ }
+ thread = 0;
+ if (*p == ':') {
+ thread = strtoull(p+1, (char **)&p, 16);
+ }
+ action = tolower(action);
+ if (res == 0 || (res == 'c' && action == 's')) {
+ res = action;
+ res_signal = signal;
+ res_thread = thread;
+ }
+ }
+ if (res) {
+ if (res_thread != -1 && res_thread != 0) {
+ env = find_cpu(res_thread);
+ if (env == NULL) {
+ put_packet(s, "E22");
+ break;
+ }
+ s->c_cpu = env;
+ }
+ if (res == 's') {
+ cpu_single_step(s->c_cpu, sstep_flags);
+ }
+ s->signal = res_signal;
+ gdb_continue(s);
+ return RS_IDLE;
+ }
+ break;
+ } else {
+ goto unknown_command;
+ }
case 'k':
/* Kill the target */
fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
diff --git a/qemu/hw/ac97.c b/qemu/hw/ac97.c
index 37aca9e8..f18fa524 100644
--- a/qemu/hw/ac97.c
+++ b/qemu/hw/ac97.c
@@ -1308,9 +1308,9 @@ static void ac97_on_reset (void *opaque)
mixer_reset (s);
}
-static void ac97_initfn(PCIDevice *dev)
+static void ac97_initfn (PCIDevice *dev)
{
- PCIAC97LinkState *d = DO_UPCAST(PCIAC97LinkState, dev, dev);
+ PCIAC97LinkState *d = DO_UPCAST (PCIAC97LinkState, dev, dev);
AC97LinkState *s = &d->ac97;
uint8_t *c = d->dev.config;
@@ -1360,19 +1360,19 @@ static void ac97_initfn(PCIDevice *dev)
int ac97_init (PCIBus *bus)
{
- pci_create_simple(bus, -1, "AC97");
+ pci_create_simple (bus, -1, "AC97");
return 0;
}
static PCIDeviceInfo ac97_info = {
.qdev.name = "AC97",
- .qdev.size = sizeof(PCIAC97LinkState),
+ .qdev.size = sizeof (PCIAC97LinkState),
.init = ac97_initfn,
};
-static void ac97_register(void)
+static void ac97_register (void)
{
- pci_qdev_register(&ac97_info);
+ pci_qdev_register (&ac97_info);
}
-device_init(ac97_register);
+device_init (ac97_register);
diff --git a/qemu/hw/apb_pci.c b/qemu/hw/apb_pci.c
index 5f411aa0..9f2a44d5 100644
--- a/qemu/hw/apb_pci.c
+++ b/qemu/hw/apb_pci.c
@@ -263,7 +263,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
d->config[0x09] = 0x00; // programming i/f
pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
d->config[0x0D] = 0x10; // latency_timer
- d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_BRIDGE; // header_type
+ d->config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
/* APB secondary busses */
*bus2 = pci_bridge_init(s->bus, 8, PCI_VENDOR_ID_SUN,
diff --git a/qemu/hw/arm_sysctl.c b/qemu/hw/arm_sysctl.c
index c9d1e3ff..bb005c80 100644
--- a/qemu/hw/arm_sysctl.c
+++ b/qemu/hw/arm_sysctl.c
@@ -194,7 +194,6 @@ static void arm_sysctl_init1(SysBusDevice *dev)
arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev);
int iomemtype;
- s->sys_id = qdev_get_prop_int(&dev->qdev, "sys_id", 0);
/* The MPcore bootloader uses these flags to start secondary CPUs.
We don't use a bootloader, so do this here. */
s->flags = 3;
@@ -210,15 +209,28 @@ void arm_sysctl_init(uint32_t base, uint32_t sys_id)
DeviceState *dev;
dev = qdev_create(NULL, "realview_sysctl");
- qdev_set_prop_int(dev, "sys_id", sys_id);
+ qdev_prop_set_uint32(dev, "sys_id", sys_id);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
}
+static SysBusDeviceInfo arm_sysctl_info = {
+ .init = arm_sysctl_init1,
+ .qdev.name = "realview_sysctl",
+ .qdev.size = sizeof(arm_sysctl_state),
+ .qdev.props = (Property[]) {
+ {
+ .name = "sys_id",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(arm_sysctl_state, sys_id),
+ },
+ {/* end of list */}
+ }
+};
+
static void arm_sysctl_register_devices(void)
{
- sysbus_register_dev("realview_sysctl", sizeof(arm_sysctl_state),
- arm_sysctl_init1);
+ sysbus_register_withprop(&arm_sysctl_info);
}
device_init(arm_sysctl_register_devices)
diff --git a/qemu/hw/armv7m.c b/qemu/hw/armv7m.c
index 297a3e1f..2e66d7e9 100644
--- a/qemu/hw/armv7m.c
+++ b/qemu/hw/armv7m.c
@@ -127,7 +127,6 @@ static void bitband_init(SysBusDevice *dev)
BitBandState *s = FROM_SYSBUS(BitBandState, dev);
int iomemtype;
- s->base = qdev_get_prop_int(&dev->qdev, "base", 0);
iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn,
&s->base);
sysbus_init_mmio(dev, 0x02000000, iomemtype);
@@ -138,12 +137,12 @@ static void armv7m_bitband_init(void)
DeviceState *dev;
dev = qdev_create(NULL, "ARM,bitband-memory");
- qdev_set_prop_int(dev, "base", 0x20000000);
+ qdev_prop_set_uint32(dev, "base", 0x20000000);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x22000000);
dev = qdev_create(NULL, "ARM,bitband-memory");
- qdev_set_prop_int(dev, "base", 0x40000000);
+ qdev_prop_set_uint32(dev, "base", 0x40000000);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0x42000000);
}
@@ -238,10 +237,23 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
return pic;
}
+static SysBusDeviceInfo bitband_info = {
+ .init = bitband_init,
+ .qdev.name = "ARM,bitband-memory",
+ .qdev.size = sizeof(BitBandState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "base",
+ .info = &qdev_prop_hex32,
+ .offset = offsetof(BitBandState, base),
+ },
+ {/* end of list */}
+ }
+};
+
static void armv7m_register_devices(void)
{
- sysbus_register_dev("ARM,bitband-memory", sizeof(BitBandState),
- bitband_init);
+ sysbus_register_withprop(&bitband_info);
}
device_init(armv7m_register_devices)
diff --git a/qemu/hw/axis_dev88.c b/qemu/hw/axis_dev88.c
index 79a4d710..f93f4314 100644
--- a/qemu/hw/axis_dev88.c
+++ b/qemu/hw/axis_dev88.c
@@ -297,7 +297,7 @@ void axisdev88_init (ram_addr_t ram_size,
cpu_irq = cris_pic_init_cpu(env);
dev = qdev_create(NULL, "etraxfs,pic");
/* FIXME: Is there a proper way to signal vectors to the CPU core? */
- qdev_set_prop_ptr(dev, "interrupt_vector", &env->interrupt_vector);
+ qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector);
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0x3001c000);
diff --git a/qemu/hw/boards.h b/qemu/hw/boards.h
index f6733b7c..11acb89f 100644
--- a/qemu/hw/boards.h
+++ b/qemu/hw/boards.h
@@ -3,6 +3,8 @@
#ifndef HW_BOARDS_H
#define HW_BOARDS_H
+#include "qdev.h"
+
typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
@@ -17,6 +19,7 @@ typedef struct QEMUMachine {
int use_scsi;
int max_cpus;
int is_default;
+ CompatProperty *compat_props;
struct QEMUMachine *next;
} QEMUMachine;
diff --git a/qemu/hw/cs4231.c b/qemu/hw/cs4231.c
index a981b094..da841027 100644
--- a/qemu/hw/cs4231.c
+++ b/qemu/hw/cs4231.c
@@ -21,8 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
+#include "sysbus.h"
/* debug CS4231 */
//#define DEBUG_CS
@@ -36,9 +37,10 @@
#define CS_MAXDREG (CS_DREGS - 1)
typedef struct CSState {
+ SysBusDevice busdev;
+ qemu_irq irq;
uint32_t regs[CS_REGS];
uint8_t dregs[CS_DREGS];
- void *intctl;
} CSState;
#define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
@@ -165,16 +167,32 @@ static int cs_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void cs_init(target_phys_addr_t base, int irq, void *intctl)
+static void cs4231_init1(SysBusDevice *dev)
{
- int cs_io_memory;
- CSState *s;
+ int io;
+ CSState *s = FROM_SYSBUS(CSState, dev);
- s = qemu_mallocz(sizeof(CSState));
+ io = cpu_register_io_memory(cs_mem_read, cs_mem_write, s);
+ sysbus_init_mmio(dev, CS_SIZE, io);
+ sysbus_init_irq(dev, &s->irq);
- cs_io_memory = cpu_register_io_memory(cs_mem_read, cs_mem_write, s);
- cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
- register_savevm("cs4231", base, 1, cs_save, cs_load, s);
+ register_savevm("cs4231", -1, 1, cs_save, cs_load, s);
qemu_register_reset(cs_reset, s);
cs_reset(s);
}
+
+static SysBusDeviceInfo cs4231_info = {
+ .init = cs4231_init1,
+ .qdev.name = "SUNW,CS4231",
+ .qdev.size = sizeof(CSState),
+ .qdev.props = (Property[]) {
+ {.name = NULL}
+ }
+};
+
+static void cs4231_register_devices(void)
+{
+ sysbus_register_withprop(&cs4231_info);
+}
+
+device_init(cs4231_register_devices);
diff --git a/qemu/hw/eccmemctl.c b/qemu/hw/eccmemctl.c
index 3430481c..193248c4 100644
--- a/qemu/hw/eccmemctl.c
+++ b/qemu/hw/eccmemctl.c
@@ -21,9 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
-#include "sysemu.h"
+#include "sysbus.h"
//#define DEBUG_ECC
@@ -126,6 +126,7 @@
#define ECC_DIAG_MASK (ECC_DIAG_SIZE - 1)
typedef struct ECCState {
+ SysBusDevice busdev;
qemu_irq irq;
uint32_t regs[ECC_NREGS];
uint8_t diag[ECC_DIAG_SIZE];
@@ -314,27 +315,61 @@ static void ecc_reset(void *opaque)
s->regs[ECC_ECR1] = 0;
}
-void * ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version)
+static void ecc_init1(SysBusDevice *dev)
{
int ecc_io_memory;
- ECCState *s;
-
- s = qemu_mallocz(sizeof(ECCState));
-
- s->version = version;
- s->regs[0] = version;
- s->irq = irq;
+ ECCState *s = FROM_SYSBUS(ECCState, dev);
+ sysbus_init_irq(dev, &s->irq);
+ s->regs[0] = s->version;
ecc_io_memory = cpu_register_io_memory(ecc_mem_read, ecc_mem_write, s);
- cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory);
- if (version == ECC_MCC) { // SS-600MP only
+ sysbus_init_mmio(dev, ECC_SIZE, ecc_io_memory);
+
+ if (s->version == ECC_MCC) { // SS-600MP only
ecc_io_memory = cpu_register_io_memory(ecc_diag_mem_read,
ecc_diag_mem_write, s);
- cpu_register_physical_memory(base + 0x1000, ECC_DIAG_SIZE,
- ecc_io_memory);
+ sysbus_init_mmio(dev, ECC_DIAG_SIZE, ecc_io_memory);
}
- register_savevm("ECC", base, 3, ecc_save, ecc_load, s);
+ register_savevm("ECC", -1, 3, ecc_save, ecc_load, s);
qemu_register_reset(ecc_reset, s);
ecc_reset(s);
- return s;
}
+
+void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, "eccmemctl");
+ qdev_prop_set_uint32(dev, "version", version);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_mmio_map(s, 0, base);
+ if (version == ECC_MCC) { // SS-600MP only
+ sysbus_mmio_map(s, 1, base + 0x1000);
+ }
+}
+
+static SysBusDeviceInfo ecc_info = {
+ .init = ecc_init1,
+ .qdev.name = "eccmemctl",
+ .qdev.size = sizeof(ECCState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "version",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(ECCState, version),
+ .defval = (uint32_t[]) { -1 },
+ },
+ {/* end of list */}
+ }
+};
+
+
+static void ecc_register_devices(void)
+{
+ sysbus_register_withprop(&ecc_info);
+}
+
+device_init(ecc_register_devices);
diff --git a/qemu/hw/es1370.c b/qemu/hw/es1370.c
index 9e860f9b..8d5a9f98 100644
--- a/qemu/hw/es1370.c
+++ b/qemu/hw/es1370.c
@@ -1054,13 +1054,13 @@ int es1370_init (PCIBus *bus)
static PCIDeviceInfo es1370_info = {
.qdev.name = "ES1370",
- .qdev.size = sizeof(PCIES1370State),
+ .qdev.size = sizeof (PCIES1370State),
.init = es1370_initfn,
};
static void es1370_register(void)
{
- pci_qdev_register(&es1370_info);
+ pci_qdev_register (&es1370_info);
}
-device_init(es1370_register);
+device_init (es1370_register);
diff --git a/qemu/hw/escc.c b/qemu/hw/escc.c
index fe5655d0..34ca2240 100644
--- a/qemu/hw/escc.c
+++ b/qemu/hw/escc.c
@@ -21,7 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include "hw.h"
+#include "sysbus.h"
#include "escc.h"
#include "qemu-char.h"
#include "console.h"
@@ -124,8 +126,12 @@ typedef struct ChannelState {
} ChannelState;
struct SerialState {
+ SysBusDevice busdev;
struct ChannelState chn[2];
int it_shift;
+ int mmio_index;
+ uint32_t disabled;
+ uint32_t frequency;
};
#define SERIAL_CTRL 0
@@ -750,44 +756,28 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
CharDriverState *chrA, CharDriverState *chrB,
int clock, int it_shift)
{
- int escc_io_memory, i;
- SerialState *s;
-
- s = qemu_mallocz(sizeof(SerialState));
-
- escc_io_memory = cpu_register_io_memory(escc_mem_read,
- escc_mem_write,
- s);
- if (base)
- cpu_register_physical_memory(base, ESCC_SIZE << it_shift,
- escc_io_memory);
-
- s->it_shift = it_shift;
- s->chn[0].chr = chrB;
- s->chn[1].chr = chrA;
- s->chn[0].disabled = 0;
- s->chn[1].disabled = 0;
- s->chn[0].irq = irqB;
- s->chn[1].irq = irqA;
-
- for (i = 0; i < 2; i++) {
- s->chn[i].chn = 1 - i;
- s->chn[i].type = ser;
- s->chn[i].clock = clock / 2;
- if (s->chn[i].chr) {
- qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
- serial_receive1, serial_event, &s->chn[i]);
- }
+ DeviceState *dev;
+ SysBusDevice *s;
+ SerialState *d;
+
+ dev = qdev_create(NULL, "escc");
+ qdev_prop_set_uint32(dev, "disabled", 0);
+ qdev_prop_set_uint32(dev, "frequency", clock);
+ qdev_prop_set_uint32(dev, "it_shift", it_shift);
+ qdev_prop_set_ptr(dev, "chrB", chrB);
+ qdev_prop_set_ptr(dev, "chrA", chrA);
+ qdev_prop_set_uint32(dev, "chnBtype", ser);
+ qdev_prop_set_uint32(dev, "chnAtype", ser);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irqA);
+ sysbus_connect_irq(s, 1, irqB);
+ if (base) {
+ sysbus_mmio_map(s, 0, base);
}
- s->chn[0].otherchn = &s->chn[1];
- s->chn[1].otherchn = &s->chn[0];
- if (base)
- register_savevm("escc", base, 2, escc_save, escc_load, s);
- else
- register_savevm("escc", -1, 2, escc_save, escc_load, s);
- qemu_register_reset(escc_reset, s);
- escc_reset(s);
- return escc_io_memory;
+
+ d = FROM_SYSBUS(SerialState, s);
+ return d->mmio_index;
}
static const uint8_t keycodes[128] = {
@@ -930,35 +920,107 @@ static void sunmouse_event(void *opaque,
void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
int disabled, int clock, int it_shift)
{
- int slavio_serial_io_memory, i;
- SerialState *s;
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, "escc");
+ qdev_prop_set_uint32(dev, "disabled", disabled);
+ qdev_prop_set_uint32(dev, "frequency", clock);
+ qdev_prop_set_uint32(dev, "it_shift", it_shift);
+ qdev_prop_set_ptr(dev, "chrB", NULL);
+ qdev_prop_set_ptr(dev, "chrA", NULL);
+ qdev_prop_set_uint32(dev, "chnBtype", mouse);
+ qdev_prop_set_uint32(dev, "chnAtype", kbd);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_connect_irq(s, 1, irq);
+ sysbus_mmio_map(s, 0, base);
+}
- s = qemu_mallocz(sizeof(SerialState));
+static void escc_init1(SysBusDevice *dev)
+{
+ SerialState *s = FROM_SYSBUS(SerialState, dev);
+ int io;
+ unsigned int i;
- s->it_shift = it_shift;
+ s->chn[0].disabled = s->disabled;
+ s->chn[1].disabled = s->disabled;
for (i = 0; i < 2; i++) {
- s->chn[i].irq = irq;
+ sysbus_init_irq(dev, &s->chn[i].irq);
s->chn[i].chn = 1 - i;
- s->chn[i].chr = NULL;
- s->chn[i].clock = clock / 2;
+ s->chn[i].clock = s->frequency / 2;
+ if (s->chn[i].chr) {
+ qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
+ serial_receive1, serial_event, &s->chn[i]);
+ }
}
s->chn[0].otherchn = &s->chn[1];
s->chn[1].otherchn = &s->chn[0];
- s->chn[0].type = mouse;
- s->chn[1].type = kbd;
- s->chn[0].disabled = disabled;
- s->chn[1].disabled = disabled;
-
- slavio_serial_io_memory = cpu_register_io_memory(escc_mem_read,
- escc_mem_write,
- s);
- cpu_register_physical_memory(base, ESCC_SIZE << it_shift,
- slavio_serial_io_memory);
-
- qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
- "QEMU Sun Mouse");
- qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
- register_savevm("slavio_serial_mouse", base, 2, escc_save, escc_load, s);
+
+ io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s);
+ sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
+ s->mmio_index = io;
+
+ if (s->chn[0].type == mouse) {
+ qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
+ "QEMU Sun Mouse");
+ }
+ if (s->chn[1].type == kbd) {
+ qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+ }
+ register_savevm("escc", -1, 2, escc_save, escc_load, s);
qemu_register_reset(escc_reset, s);
escc_reset(s);
}
+
+static SysBusDeviceInfo escc_info = {
+ .init = escc_init1,
+ .qdev.name = "escc",
+ .qdev.size = sizeof(SerialState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "frequency",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SerialState, frequency),
+ },
+ {
+ .name = "it_shift",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SerialState, it_shift),
+ },
+ {
+ .name = "disabled",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SerialState, disabled),
+ },
+ {
+ .name = "chrB",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SerialState, chn[1].chr),
+ },
+ {
+ .name = "chrA",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SerialState, chn[0].chr),
+ },
+ {
+ .name = "chnBtype",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SerialState, chn[1].type),
+ },
+ {
+ .name = "chnAtype",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SerialState, chn[0].type),
+ },
+ {/* end of list */}
+ }
+};
+
+static void escc_register_devices(void)
+{
+ sysbus_register_withprop(&escc_info);
+}
+
+device_init(escc_register_devices);
diff --git a/qemu/hw/esp.c b/qemu/hw/esp.c
index 469acc10..207570a4 100644
--- a/qemu/hw/esp.c
+++ b/qemu/hw/esp.c
@@ -678,12 +678,14 @@ void esp_init(target_phys_addr_t espaddr, int it_shift,
{
DeviceState *dev;
SysBusDevice *s;
+ ESPState *esp;
dev = qdev_create(NULL, "esp");
- qdev_set_prop_ptr(dev, "dma_memory_read", dma_memory_read);
- qdev_set_prop_ptr(dev, "dma_memory_write", dma_memory_write);
- qdev_set_prop_ptr(dev, "dma_opaque", dma_opaque);
- qdev_set_prop_int(dev, "it_shift", it_shift);
+ esp = DO_UPCAST(ESPState, busdev.qdev, dev);
+ esp->dma_memory_read = dma_memory_read;
+ esp->dma_memory_write = dma_memory_write;
+ esp->dma_opaque = dma_opaque;
+ esp->it_shift = it_shift;
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_connect_irq(s, 0, irq);
@@ -696,11 +698,7 @@ static void esp_init1(SysBusDevice *dev)
int esp_io_memory;
sysbus_init_irq(dev, &s->irq);
- s->it_shift = qdev_get_prop_int(&dev->qdev, "it_shift", -1);
assert(s->it_shift != -1);
- s->dma_memory_read = qdev_get_prop_ptr(&dev->qdev, "dma_memory_read");
- s->dma_memory_write = qdev_get_prop_ptr(&dev->qdev, "dma_memory_write");
- s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma_opaque");
esp_io_memory = cpu_register_io_memory(esp_mem_read, esp_mem_write, s);
sysbus_init_mmio(dev, ESP_REGS << s->it_shift, esp_io_memory);
diff --git a/qemu/hw/etraxfs.c b/qemu/hw/etraxfs.c
index 94cd6bc8..c2eca527 100644
--- a/qemu/hw/etraxfs.c
+++ b/qemu/hw/etraxfs.c
@@ -88,7 +88,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
cpu_irq = cris_pic_init_cpu(env);
dev = qdev_create(NULL, "etraxfs,pic");
/* FIXME: Is there a proper way to signal vectors to the CPU core? */
- qdev_set_prop_ptr(dev, "interrupt_vector", &env->interrupt_vector);
+ qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector);
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0x3001c000);
diff --git a/qemu/hw/etraxfs_pic.c b/qemu/hw/etraxfs_pic.c
index 1c674279..e6272189 100644
--- a/qemu/hw/etraxfs_pic.c
+++ b/qemu/hw/etraxfs_pic.c
@@ -140,7 +140,6 @@ static void etraxfs_pic_init(SysBusDevice *dev)
struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev);
int intr_vect_regs;
- s->interrupt_vector = qdev_get_prop_ptr(&dev->qdev, "interrupt_vector");
qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
sysbus_init_irq(dev, &s->parent_irq);
sysbus_init_irq(dev, &s->parent_nmi);
@@ -149,10 +148,23 @@ static void etraxfs_pic_init(SysBusDevice *dev)
sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs);
}
+static SysBusDeviceInfo etraxfs_pic_info = {
+ .init = etraxfs_pic_init,
+ .qdev.name = "etraxfs,pic",
+ .qdev.size = sizeof(struct etrax_pic),
+ .qdev.props = (Property[]) {
+ {
+ .name = "interrupt_vector",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(struct etrax_pic, interrupt_vector),
+ },
+ {/* end of list */}
+ }
+};
+
static void etraxfs_pic_register(void)
{
- sysbus_register_dev("etraxfs,pic", sizeof (struct etrax_pic),
- etraxfs_pic_init);
+ sysbus_register_withprop(&etraxfs_pic_info);
}
device_init(etraxfs_pic_register)
diff --git a/qemu/hw/fdc.c b/qemu/hw/fdc.c
index 311e7cb7..e8177d97 100644
--- a/qemu/hw/fdc.c
+++ b/qemu/hw/fdc.c
@@ -26,11 +26,13 @@
* The controller is used in Sun4m systems in a slightly different
* way. There are changes in DOR register and DMA is not available.
*/
+
#include "hw.h"
#include "fdc.h"
#include "block.h"
#include "qemu-timer.h"
#include "isa.h"
+#include "sysbus.h"
/********************************************************/
/* debug Floppy devices */
@@ -468,6 +470,7 @@ enum {
#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
struct fdctrl_t {
+ SysBusDevice busdev;
/* Controller's identification */
uint8_t version;
/* HW */
@@ -508,6 +511,8 @@ struct fdctrl_t {
/* Floppy drives */
fdrive_t drives[MAX_FD];
int reset_sensei;
+ uint32_t strict_io;
+ uint32_t mem_mapped;
};
static uint32_t fdctrl_read (void *opaque, uint32_t reg)
@@ -1849,11 +1854,10 @@ static void fdctrl_result_timer(void *opaque)
}
/* Init functions */
-static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann,
- target_phys_addr_t io_base,
- BlockDriverState **fds)
+static void fdctrl_init_common (fdctrl_t *fdctrl, int dma_chann,
+ target_phys_addr_t io_base,
+ BlockDriverState **fds)
{
- fdctrl_t *fdctrl;
int i, j;
/* Fill 'command_to_handler' lookup table */
@@ -1865,13 +1869,11 @@ static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann,
}
FLOPPY_DPRINTF("init controller\n");
- fdctrl = qemu_mallocz(sizeof(fdctrl_t));
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
fdctrl->result_timer = qemu_new_timer(vm_clock,
fdctrl_result_timer, fdctrl);
fdctrl->version = 0x90; /* Intel 82078 controller */
- fdctrl->irq = irq;
fdctrl->dma_chann = dma_chann;
fdctrl->io_base = io_base;
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
@@ -1887,24 +1889,26 @@ static fdctrl_t *fdctrl_init_common (qemu_irq irq, int dma_chann,
for (i = 0; i < MAX_FD; i++) {
fd_revalidate(&fdctrl->drives[i]);
}
-
- return fdctrl;
}
fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
target_phys_addr_t io_base,
BlockDriverState **fds)
{
+ DeviceState *dev;
+ SysBusDevice *s;
fdctrl_t *fdctrl;
- int io_mem;
-
- fdctrl = fdctrl_init_common(irq, dma_chann, io_base, fds);
- fdctrl->sun4m = 0;
+ dev = qdev_create(NULL, "fdc");
+ qdev_prop_set_uint32(dev, "strict_io", 0);
+ qdev_prop_set_uint32(dev, "mem_mapped", mem_mapped);
+ qdev_prop_set_uint32(dev, "sun4m", 0);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ fdctrl = FROM_SYSBUS(fdctrl_t, s);
if (mem_mapped) {
- io_mem = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write,
- fdctrl);
- cpu_register_physical_memory(io_base, 0x08, io_mem);
+ sysbus_mmio_map(s, 0, io_base);
} else {
register_ioport_read((uint32_t)io_base + 0x01, 5, 1,
&fdctrl_read_port, fdctrl);
@@ -1916,22 +1920,83 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
&fdctrl_write_port, fdctrl);
}
+ fdctrl_init_common(fdctrl, dma_chann, io_base, fds);
+
return fdctrl;
}
fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
BlockDriverState **fds, qemu_irq *fdc_tc)
{
+ DeviceState *dev;
+ SysBusDevice *s;
fdctrl_t *fdctrl;
- int io_mem;
- fdctrl = fdctrl_init_common(irq, -1, io_base, fds);
- fdctrl->sun4m = 1;
- io_mem = cpu_register_io_memory(fdctrl_mem_read_strict,
- fdctrl_mem_write_strict,
- fdctrl);
- cpu_register_physical_memory(io_base, 0x08, io_mem);
- *fdc_tc = *qemu_allocate_irqs(fdctrl_handle_tc, fdctrl, 1);
+ dev = qdev_create(NULL, "fdc");
+ qdev_prop_set_uint32(dev, "strict_io", 1);
+ qdev_prop_set_uint32(dev, "mem_mapped", 1);
+ qdev_prop_set_uint32(dev, "sun4m", 1);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_mmio_map(s, 0, io_base);
+ *fdc_tc = qdev_get_gpio_in(dev, 0);
+
+ fdctrl = FROM_SYSBUS(fdctrl_t, s);
+ fdctrl_init_common(fdctrl, -1, io_base, fds);
return fdctrl;
}
+
+static void fdc_init1(SysBusDevice *dev)
+{
+ fdctrl_t *s = FROM_SYSBUS(fdctrl_t, dev);
+ int io;
+
+ sysbus_init_irq(dev, &s->irq);
+ qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1);
+ if (s->strict_io) {
+ io = cpu_register_io_memory(fdctrl_mem_read_strict,
+ fdctrl_mem_write_strict, s);
+ } else {
+ io = cpu_register_io_memory(fdctrl_mem_read, fdctrl_mem_write, s);
+ }
+ sysbus_init_mmio(dev, 0x08, io);
+}
+
+
+static SysBusDeviceInfo fdc_info = {
+ .init = fdc_init1,
+ .qdev.name = "fdc",
+ .qdev.size = sizeof(fdctrl_t),
+ .qdev.props = (Property[]) {
+ {
+ .name = "io_base",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(fdctrl_t, io_base),
+ },
+ {
+ .name = "strict_io",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(fdctrl_t, strict_io),
+ },
+ {
+ .name = "mem_mapped",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(fdctrl_t, mem_mapped),
+ },
+ {
+ .name = "sun4m",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(fdctrl_t, sun4m),
+ },
+ {/* end of properties */}
+ }
+};
+
+static void fdc_register_devices(void)
+{
+ sysbus_register_withprop(&fdc_info);
+}
+
+device_init(fdc_register_devices);
diff --git a/qemu/hw/fw_cfg.c b/qemu/hw/fw_cfg.c
index ce57de7d..d75cce46 100644
--- a/qemu/hw/fw_cfg.c
+++ b/qemu/hw/fw_cfg.c
@@ -279,6 +279,7 @@ void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
+ fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
register_savevm("fw_cfg", -1, 1, fw_cfg_save, fw_cfg_load, s);
qemu_register_reset(fw_cfg_reset, s);
diff --git a/qemu/hw/fw_cfg.h b/qemu/hw/fw_cfg.h
index f616ed2f..9fee1810 100644
--- a/qemu/hw/fw_cfg.h
+++ b/qemu/hw/fw_cfg.h
@@ -15,6 +15,7 @@
#define FW_CFG_INITRD_SIZE 0x0b
#define FW_CFG_BOOT_DEVICE 0x0c
#define FW_CFG_NUMA 0x0d
+#define FW_CFG_BOOT_MENU 0x0e
#define FW_CFG_MAX_ENTRY 0x10
#define FW_CFG_WRITE_CHANNEL 0x4000
diff --git a/qemu/hw/hpet.c b/qemu/hw/hpet.c
index 186d6715..24aee6a2 100644
--- a/qemu/hw/hpet.c
+++ b/qemu/hw/hpet.c
@@ -17,8 +17,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*
* *****************************************************************
*
@@ -554,6 +553,7 @@ static void hpet_reset(void *opaque) {
/* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
s->capability = 0x8086a201ULL;
s->capability |= ((HPET_CLK_PERIOD) << 32);
+ s->config = 0ULL;
if (count > 0)
/* we don't enable pit when hpet_reset is first called (by hpet_init)
* because hpet is taking over for pit here. On subsequent invocations,
diff --git a/qemu/hw/hw.h b/qemu/hw/hw.h
index a424d28f..1e5783d9 100644
--- a/qemu/hw/hw.h
+++ b/qemu/hw/hw.h
@@ -261,10 +261,12 @@ void unregister_savevm(const char *idstr, void *opaque);
typedef void QEMUResetHandler(void *opaque);
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
-/* handler to set the boot_device for a specific type of QEMUMachine */
+/* handler to set the boot_device order for a specific type of QEMUMachine */
/* return 0 if success */
-typedef int QEMUBootSetHandler(void *opaque, const char *boot_device);
+typedef int QEMUBootSetHandler(void *opaque, const char *boot_devices);
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
+int qemu_boot_set(const char *boot_devices);
#endif
diff --git a/qemu/hw/i2c.c b/qemu/hw/i2c.c
index 98aa7fcd..42a5d7a6 100644
--- a/qemu/hw/i2c.c
+++ b/qemu/hw/i2c.c
@@ -20,6 +20,14 @@ struct i2c_bus
static struct BusInfo i2c_bus_info = {
.name = "I2C",
.size = sizeof(i2c_bus),
+ .props = (Property[]) {
+ {
+ .name = "address",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct i2c_slave, address),
+ },
+ {/* end of list */}
+ }
};
static void i2c_bus_save(QEMUFile *f, void *opaque)
@@ -151,7 +159,6 @@ static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev);
s->info = info;
- s->address = qdev_get_prop_int(dev, "address", 0);
info->init(s);
}
@@ -169,7 +176,7 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr)
DeviceState *dev;
dev = qdev_create(&bus->qbus, name);
- qdev_set_prop_int(dev, "address", addr);
+ qdev_prop_set_uint32(dev, "address", addr);
qdev_init(dev);
return dev;
}
diff --git a/qemu/hw/i2c.h b/qemu/hw/i2c.h
index c4df3998..479ff4b9 100644
--- a/qemu/hw/i2c.h
+++ b/qemu/hw/i2c.h
@@ -40,7 +40,7 @@ struct i2c_slave
I2CSlaveInfo *info;
/* Remaining fields for internal use by the I2C code. */
- int address;
+ uint32_t address;
};
i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
diff --git a/qemu/hw/integratorcp.c b/qemu/hw/integratorcp.c
index 50eae0c3..ddc8d855 100644
--- a/qemu/hw/integratorcp.c
+++ b/qemu/hw/integratorcp.c
@@ -17,6 +17,7 @@
typedef struct {
SysBusDevice busdev;
+ uint32_t memsz;
uint32_t flash_offset;
uint32_t cm_osc;
uint32_t cm_ctrl;
@@ -230,23 +231,21 @@ static void integratorcm_init(SysBusDevice *dev)
{
int iomemtype;
integratorcm_state *s = FROM_SYSBUS(integratorcm_state, dev);
- int memsz;
- memsz = qdev_get_prop_int(&dev->qdev, "memsz", 0);
s->cm_osc = 0x01000048;
/* ??? What should the high bits of this value be? */
s->cm_auxosc = 0x0007feff;
s->cm_sdram = 0x00011122;
- if (memsz >= 256) {
+ if (s->memsz >= 256) {
integrator_spd[31] = 64;
s->cm_sdram |= 0x10;
- } else if (memsz >= 128) {
+ } else if (s->memsz >= 128) {
integrator_spd[31] = 32;
s->cm_sdram |= 0x0c;
- } else if (memsz >= 64) {
+ } else if (s->memsz >= 64) {
integrator_spd[31] = 16;
s->cm_sdram |= 0x08;
- } else if (memsz >= 32) {
+ } else if (s->memsz >= 32) {
integrator_spd[31] = 4;
s->cm_sdram |= 0x04;
} else {
@@ -475,7 +474,7 @@ static void integratorcp_init(ram_addr_t ram_size,
cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
dev = qdev_create(NULL, "integrator_core");
- qdev_set_prop_int(dev, "memsz", ram_size >> 20);
+ qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
qdev_init(dev);
sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
@@ -522,11 +521,24 @@ static void integratorcp_machine_init(void)
machine_init(integratorcp_machine_init);
+static SysBusDeviceInfo core_info = {
+ .init = integratorcm_init,
+ .qdev.name = "integrator_core",
+ .qdev.size = sizeof(integratorcm_state),
+ .qdev.props = (Property[]) {
+ {
+ .name = "memsz",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(integratorcm_state, memsz),
+ },
+ {/* end of list */}
+ }
+};
+
static void integratorcp_register_devices(void)
{
sysbus_register_dev("integrator_pic", sizeof(icp_pic_state), icp_pic_init);
- sysbus_register_dev("integrator_core", sizeof(integratorcm_state),
- integratorcm_init);
+ sysbus_register_withprop(&core_info);
}
device_init(integratorcp_register_devices)
diff --git a/qemu/hw/iommu.c b/qemu/hw/iommu.c
index 0af6d32a..b172f152 100644
--- a/qemu/hw/iommu.c
+++ b/qemu/hw/iommu.c
@@ -21,8 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
+#include "sysbus.h"
/* debug iommu */
//#define DEBUG_IOMMU
@@ -127,6 +128,7 @@
#define IOMMU_PAGE_MASK ~(IOMMU_PAGE_SIZE - 1)
typedef struct IOMMUState {
+ SysBusDevice busdev;
uint32_t regs[IOMMU_NREGS];
target_phys_addr_t iostart;
uint32_t version;
@@ -366,20 +368,54 @@ static void iommu_reset(void *opaque)
void *iommu_init(target_phys_addr_t addr, uint32_t version, qemu_irq irq)
{
- IOMMUState *s;
- int iommu_io_memory;
+ DeviceState *dev;
+ SysBusDevice *s;
+ IOMMUState *d;
+
+ dev = qdev_create(NULL, "iommu");
+ qdev_prop_set_uint32(dev, "version", version);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_mmio_map(s, 0, addr);
- s = qemu_mallocz(sizeof(IOMMUState));
+ d = FROM_SYSBUS(IOMMUState, s);
- s->version = version;
- s->irq = irq;
+ return d;
+}
- iommu_io_memory = cpu_register_io_memory(iommu_mem_read,
- iommu_mem_write, s);
- cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory);
+static void iommu_init1(SysBusDevice *dev)
+{
+ IOMMUState *s = FROM_SYSBUS(IOMMUState, dev);
+ int io;
- register_savevm("iommu", addr, 2, iommu_save, iommu_load, s);
+ sysbus_init_irq(dev, &s->irq);
+
+ io = cpu_register_io_memory(iommu_mem_read, iommu_mem_write, s);
+ sysbus_init_mmio(dev, IOMMU_NREGS * sizeof(uint32_t), io);
+
+ register_savevm("iommu", -1, 2, iommu_save, iommu_load, s);
qemu_register_reset(iommu_reset, s);
iommu_reset(s);
- return s;
}
+
+static SysBusDeviceInfo iommu_info = {
+ .init = iommu_init1,
+ .qdev.name = "iommu",
+ .qdev.size = sizeof(IOMMUState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "version",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(IOMMUState, version),
+ },
+ {/* end of property list */}
+ }
+};
+
+static void iommu_register_devices(void)
+{
+ sysbus_register_withprop(&iommu_info);
+}
+
+device_init(iommu_register_devices);
diff --git a/qemu/hw/m48t59.c b/qemu/hw/m48t59.c
index f5de4c10..d2c65f8f 100644
--- a/qemu/hw/m48t59.c
+++ b/qemu/hw/m48t59.c
@@ -23,9 +23,9 @@
*/
#include "hw.h"
#include "nvram.h"
-#include "isa.h"
#include "qemu-timer.h"
#include "sysemu.h"
+#include "sysbus.h"
//#define DEBUG_NVRAM
@@ -41,13 +41,13 @@
* PPC platform there is also a nvram lock function.
*/
struct m48t59_t {
+ SysBusDevice busdev;
/* Model parameters */
- int type; // 2 = m48t02, 8 = m48t08, 59 = m48t59
+ uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59
/* Hardware parameters */
qemu_irq IRQ;
- int mem_index;
uint32_t io_base;
- uint16_t size;
+ uint32_t size;
/* RTC management */
time_t time_offset;
time_t stop_time;
@@ -618,32 +618,78 @@ m48t59_t *m48t59_init (qemu_irq IRQ, target_phys_addr_t mem_base,
uint32_t io_base, uint16_t size,
int type)
{
- m48t59_t *s;
- target_phys_addr_t save_base;
-
- s = qemu_mallocz(sizeof(m48t59_t));
- s->buffer = qemu_mallocz(size);
- s->IRQ = IRQ;
- s->size = size;
- s->io_base = io_base;
- s->type = type;
+ DeviceState *dev;
+ SysBusDevice *s;
+ m48t59_t *d;
+
+ dev = qdev_create(NULL, "m48t59");
+ qdev_prop_set_uint32(dev, "type", type);
+ qdev_prop_set_uint32(dev, "size", size);
+ qdev_prop_set_uint32(dev, "io_base", io_base);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, IRQ);
if (io_base != 0) {
register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
}
if (mem_base != 0) {
- s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s);
- cpu_register_physical_memory(mem_base, size, s->mem_index);
+ sysbus_mmio_map(s, 0, mem_base);
}
- if (type == 59) {
+
+ d = FROM_SYSBUS(m48t59_t, s);
+
+ return d;
+}
+
+static void m48t59_init1(SysBusDevice *dev)
+{
+ m48t59_t *s = FROM_SYSBUS(m48t59_t, dev);
+ int mem_index;
+
+ s->buffer = qemu_mallocz(s->size);
+ sysbus_init_irq(dev, &s->IRQ);
+
+ mem_index = cpu_register_io_memory(nvram_read, nvram_write, s);
+ sysbus_init_mmio(dev, s->size, mem_index);
+
+ if (s->type == 59) {
s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
}
qemu_get_timedate(&s->alarm, 0);
qemu_register_reset(m48t59_reset, s);
- save_base = mem_base ? mem_base : io_base;
- register_savevm("m48t59", save_base, 1, m48t59_save, m48t59_load, s);
+ register_savevm("m48t59", -1, 1, m48t59_save, m48t59_load, s);
+}
+
+static SysBusDeviceInfo m48t59_info = {
+ .init = m48t59_init1,
+ .qdev.name = "m48t59",
+ .qdev.size = sizeof(m48t59_t),
+ .qdev.props = (Property[]) {
+ {
+ .name = "size",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(m48t59_t, size),
+ .defval = (uint32_t[]) { -1 },
+ },{
+ .name = "type",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(m48t59_t, type),
+ .defval = (uint32_t[]) { -1 },
+ },{
+ .name = "io_base",
+ .info = &qdev_prop_hex32,
+ .offset = offsetof(m48t59_t, io_base),
+ },
+ {/* end of list */}
+ }
+};
- return s;
+static void m48t59_register_devices(void)
+{
+ sysbus_register_withprop(&m48t59_info);
}
+
+device_init(m48t59_register_devices);
diff --git a/qemu/hw/mips_malta.c b/qemu/hw/mips_malta.c
index 853ec2b8..7728e58c 100644
--- a/qemu/hw/mips_malta.c
+++ b/qemu/hw/mips_malta.c
@@ -914,8 +914,8 @@ void mips_malta_init (ram_addr_t ram_size,
/* TODO: Populate SPD eeprom data. */
DeviceState *eeprom;
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
- qdev_set_prop_int(eeprom, "address", 0x50 + i);
- qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
+ qdev_prop_set_uint32(eeprom, "address", 0x50 + i);
+ qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
qdev_init(eeprom);
}
pit = pit_init(0x40, i8259[0]);
diff --git a/qemu/hw/msix.c b/qemu/hw/msix.c
index e1308572..3420ce9b 100644
--- a/qemu/hw/msix.c
+++ b/qemu/hw/msix.c
@@ -286,8 +286,9 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
{
unsigned n = dev->msix_entries_nr;
- if (!dev->cap_present & QEMU_PCI_CAP_MSIX)
+ if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) {
return;
+ }
qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
@@ -302,6 +303,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
return;
}
+ msix_free_irq_entries(dev);
qemu_get_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
}
diff --git a/qemu/hw/musicpal.c b/qemu/hw/musicpal.c
index 10be69be..e6367919 100644
--- a/qemu/hw/musicpal.c
+++ b/qemu/hw/musicpal.c
@@ -1578,7 +1578,7 @@ static void musicpal_init(ram_addr_t ram_size,
qemu_check_nic_model(&nd_table[0], "mv88w8618");
dev = qdev_create(NULL, "mv88w8618_eth");
- qdev_set_netdev(dev, &nd_table[0]);
+ dev->nd = &nd_table[0];
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, MP_ETH_BASE);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[MP_ETH_IRQ]);
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 553ba5c8..8a1582c2 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -825,6 +825,7 @@ static void load_linux(void *fw_cfg,
uint8_t header[8192];
target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr = 0;
FILE *f, *fi;
+ char *vmode;
/* Align to 16 bytes as a paranoia measure */
cmdline_size = (strlen(kernel_cmdline)+16) & ~15;
@@ -900,6 +901,24 @@ static void load_linux(void *fw_cfg,
stw_p(header+0x22, cmdline_addr-real_addr);
}
+ /* handle vga= parameter */
+ vmode = strstr(kernel_cmdline, "vga=");
+ if (vmode) {
+ unsigned int video_mode;
+ /* skip "vga=" */
+ vmode += 4;
+ if (!strncmp(vmode, "normal", 6)) {
+ video_mode = 0xffff;
+ } else if (!strncmp(vmode, "ext", 3)) {
+ video_mode = 0xfffe;
+ } else if (!strncmp(vmode, "ask", 3)) {
+ video_mode = 0xfffd;
+ } else {
+ video_mode = strtol(vmode, NULL, 0);
+ }
+ stw_p(header+0x1fa, video_mode);
+ }
+
/* loader type */
/* High nybble = B reserved for Qemu; low nybble is revision number.
If this code is substantially changed, you may want to consider
@@ -1081,12 +1100,20 @@ static CPUState *pc_new_cpu(const char *cpu_model)
return env;
}
+enum {
+ COMPAT_DEFAULT = 0,
+ COMPAT_0_10, /* compatible with qemu 0.10.x */
+};
+
/* PC hardware initialisation */
static void pc_init1(ram_addr_t ram_size,
const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
const char *initrd_filename,
- int pci_enabled, const char *cpu_model)
+ const char *cpu_model,
+ int pci_enabled,
+ int compat_level)
{
char *filename;
int ret, linux_boot, i;
@@ -1104,6 +1131,7 @@ static void pc_init1(ram_addr_t ram_size,
BlockDriverState *fd[MAX_FD];
int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
void *fw_cfg;
+ const char *virtio_blk_name, *virtio_console_name;
if (ram_size >= 0xe0000000 ) {
above_4g_mem_size = ram_size - 0xe0000000;
@@ -1374,8 +1402,8 @@ static void pc_init1(ram_addr_t ram_size,
for (i = 0; i < 8; i++) {
DeviceState *eeprom;
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
- qdev_set_prop_int(eeprom, "address", 0x50 + i);
- qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256));
+ qdev_prop_set_uint32(eeprom, "address", 0x50 + i);
+ qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
qdev_init(eeprom);
}
}
@@ -1394,13 +1422,26 @@ static void pc_init1(ram_addr_t ram_size,
}
}
+ switch (compat_level) {
+ case COMPAT_DEFAULT:
+ default:
+ virtio_blk_name = "virtio-blk-pci";
+ virtio_console_name = "virtio-console-pci";
+ break;
+
+ case COMPAT_0_10:
+ virtio_blk_name = "virtio-blk-pci-0-10";
+ virtio_console_name = "virtio-console-pci-0-10";
+ break;
+ }
+
/* Add virtio block devices */
if (pci_enabled) {
int index;
int unit_id = 0;
while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
- pci_dev = pci_create("virtio-blk-pci",
+ pci_dev = pci_create(virtio_blk_name,
drives_table[index].devaddr);
qdev_init(&pci_dev->qdev);
unit_id++;
@@ -1417,7 +1458,7 @@ static void pc_init1(ram_addr_t ram_size,
if (pci_enabled) {
for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
if (virtcon_hds[i]) {
- pci_create_simple(pci_bus, -1, "virtio-console-pci");
+ pci_create_simple(pci_bus, -1, virtio_console_name);
}
}
}
@@ -1432,7 +1473,8 @@ static void pc_init_pci(ram_addr_t ram_size,
{
pc_init1(ram_size, boot_device,
kernel_filename, kernel_cmdline,
- initrd_filename, 1, cpu_model);
+ initrd_filename, cpu_model,
+ 1, COMPAT_DEFAULT);
}
static void pc_init_isa(ram_addr_t ram_size,
@@ -1444,7 +1486,21 @@ static void pc_init_isa(ram_addr_t ram_size,
{
pc_init1(ram_size, boot_device,
kernel_filename, kernel_cmdline,
- initrd_filename, 0, cpu_model);
+ initrd_filename, cpu_model,
+ 0, COMPAT_DEFAULT);
+}
+
+static void pc_init_pci_0_10(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)
+{
+ pc_init1(ram_size, boot_device,
+ kernel_filename, kernel_cmdline,
+ initrd_filename, cpu_model,
+ 1, COMPAT_0_10);
}
/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
@@ -1463,6 +1519,25 @@ static QEMUMachine pc_machine = {
.is_default = 1,
};
+static QEMUMachine pc_machine_v0_10 = {
+ .name = "pc-0.10",
+ .desc = "Standard PC, qemu 0.10",
+ .init = pc_init_pci,
+ .max_cpus = 255,
+ .compat_props = (CompatProperty[]) {
+ {
+ .driver = "virtio-blk-pci",
+ .property = "class",
+ .value = stringify(PCI_CLASS_STORAGE_OTHER),
+ },{
+ .driver = "virtio-console-pci",
+ .property = "class",
+ .value = stringify(PCI_CLASS_DISPLAY_OTHER),
+ },
+ { /* end of list */ }
+ },
+};
+
static QEMUMachine isapc_machine = {
.name = "isapc",
.desc = "ISA-only PC",
@@ -1470,10 +1545,21 @@ static QEMUMachine isapc_machine = {
.max_cpus = 1,
};
+static QEMUMachine pc_0_10_machine = {
+ .name = "pc-0-10",
+ .desc = "Standard PC compatible with qemu 0.10.x",
+ .init = pc_init_pci_0_10,
+ .max_cpus = 255,
+};
+
static void pc_machine_init(void)
{
qemu_register_machine(&pc_machine);
+ qemu_register_machine(&pc_machine_v0_10);
qemu_register_machine(&isapc_machine);
+
+ /* For compatibility with 0.10.x */
+ qemu_register_machine(&pc_0_10_machine);
}
machine_init(pc_machine_init);
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 71d9227a..3b5a9477 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -28,6 +28,11 @@
#include "sysemu.h"
//#define DEBUG_PCI
+#ifdef DEBUG_PCI
+# define PCI_DPRINTF(format, ...) printf(format, __VA_ARGS__)
+#else
+# define PCI_DPRINTF(format, ...) do { } while (0)
+#endif
struct PCIBus {
BusState qbus;
@@ -54,6 +59,15 @@ static struct BusInfo pci_bus_info = {
.name = "PCI",
.size = sizeof(PCIBus),
.print_dev = pcibus_dev_print,
+ .props = (Property[]) {
+ {
+ .name = "devfn",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(PCIDevice, devfn),
+ .defval = (uint32_t[]) { -1 },
+ },
+ {/* end of list */}
+ }
};
static void pci_update_mappings(PCIDevice *d);
@@ -123,7 +137,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
bus->irq_opaque = pic;
bus->devfn_min = devfn_min;
bus->nirq = nirq;
- bus->irq_count = qemu_malloc(nirq * sizeof(bus->irq_count[0]));
+ bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
bus->next = first_bus;
first_bus = bus;
register_savevm("PCIBUS", nbus++, 1, pcibus_save, pcibus_load, bus);
@@ -135,7 +149,7 @@ static PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq
{
PCIBus *bus;
- bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, NULL));
+ bus = qemu_mallocz(sizeof(PCIBus));
bus->map_irq = map_irq;
bus->parent_dev = dev;
bus->next = dev->bus->next;
@@ -548,9 +562,9 @@ void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
PCIDevice *pci_dev;
int config_addr, bus_num;
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_write: addr=%08x val=%08x len=%d\n",
- addr, val, len);
+#if 0
+ PCI_DPRINTF("pci_data_write: addr=%08x val=%08x len=%d\n",
+ addr, val, len);
#endif
bus_num = (addr >> 16) & 0xff;
while (s && s->bus_num != bus_num)
@@ -561,10 +575,8 @@ void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len)
if (!pci_dev)
return;
config_addr = addr & 0xff;
-#if defined(DEBUG_PCI)
- printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
+ PCI_DPRINTF("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
+ pci_dev->name, config_addr, val, len);
pci_dev->config_write(pci_dev, config_addr, val, len);
}
@@ -599,14 +611,12 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
}
config_addr = addr & 0xff;
val = pci_dev->config_read(pci_dev, config_addr, len);
-#if defined(DEBUG_PCI)
- printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
- pci_dev->name, config_addr, val, len);
-#endif
+ PCI_DPRINTF("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
+ pci_dev->name, config_addr, val, len);
the_end:
-#if defined(DEBUG_PCI) && 0
- printf("pci_data_read: addr=%08x val=%08x len=%d\n",
- addr, val, len);
+#if 0
+ PCI_DPRINTF("pci_data_read: addr=%08x val=%08x len=%d\n",
+ addr, val, len);
#endif
return val;
}
@@ -728,6 +738,7 @@ static void pci_info_device(PCIDevice *d)
}
}
}
+ monitor_printf(mon, " id \"%s\"\n", d->qdev.id ? d->qdev.id : "");
if (class == 0x0604 && d->config[0x19] != 0) {
pci_for_each_device(d->config[0x19], pci_info_device);
}
@@ -769,7 +780,7 @@ PCIDevice *pci_create(const char *name, const char *devaddr)
}
dev = qdev_create(&bus->qbus, name);
- qdev_set_prop_int(dev, "devfn", devfn);
+ qdev_prop_set_uint32(dev, "devfn", devfn);
return (PCIDevice *)dev;
}
@@ -812,7 +823,9 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
if (strcmp(nd->model, pci_nic_models[i]) == 0) {
pci_dev = pci_create(pci_nic_names[i], devaddr);
dev = &pci_dev->qdev;
- qdev_set_netdev(dev, nd);
+ if (nd->id)
+ dev->id = qemu_strdup(nd->id);
+ dev->nd = nd;
qdev_init(dev);
nd->private = dev;
return pci_dev;
@@ -890,7 +903,7 @@ static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
int devfn;
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
- devfn = qdev_get_prop_int(qdev, "devfn", -1);
+ devfn = pci_dev->devfn;
pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
info->config_read, info->config_write);
assert(pci_dev);
@@ -917,7 +930,7 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
DeviceState *dev;
dev = qdev_create(&bus->qbus, name);
- qdev_set_prop_int(dev, "devfn", devfn);
+ qdev_prop_set_uint32(dev, "devfn", devfn);
qdev_init(dev);
return (PCIDevice *)dev;
diff --git a/qemu/hw/pci_ids.h b/qemu/hw/pci_ids.h
index 3afe6748..2fe60eeb 100644
--- a/qemu/hw/pci_ids.h
+++ b/qemu/hw/pci_ids.h
@@ -35,6 +35,9 @@
#define PCI_CLASS_BRIDGE_PCI 0x0604
#define PCI_CLASS_BRIDGE_OTHER 0x0680
+#define PCI_CLASS_SERIAL_OTHER 0x0780
+
+#define PCI_CLASS_PROCESSOR_CO 0x0b40
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
#define PCI_CLASS_PROCESSOR_CO 0x0b40
diff --git a/qemu/hw/pcnet.c b/qemu/hw/pcnet.c
index e3365f59..b313b432 100644
--- a/qemu/hw/pcnet.c
+++ b/qemu/hw/pcnet.c
@@ -2128,8 +2128,6 @@ static void lance_init(SysBusDevice *dev)
s->mmio_index =
cpu_register_io_memory(lance_mem_read, lance_mem_write, d);
- s->dma_opaque = qdev_get_prop_ptr(&dev->qdev, "dma");
-
qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
sysbus_init_mmio(dev, 4, s->mmio_index);
@@ -2141,6 +2139,21 @@ static void lance_init(SysBusDevice *dev)
pcnet_common_init(&dev->qdev, s, lance_cleanup);
}
+
+static SysBusDeviceInfo lance_info = {
+ .init = lance_init,
+ .qdev.name = "lance",
+ .qdev.size = sizeof(SysBusPCNetState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "dma",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SysBusPCNetState, state.dma_opaque),
+ },
+ {/* end of list */}
+ }
+};
+
#endif /* TARGET_SPARC */
static PCIDeviceInfo pcnet_info = {
@@ -2153,7 +2166,7 @@ static void pcnet_register_devices(void)
{
pci_qdev_register(&pcnet_info);
#if defined (TARGET_SPARC) && !defined(TARGET_SPARC64)
- sysbus_register_dev("lance", sizeof(SysBusPCNetState), lance_init);
+ sysbus_register_withprop(&lance_info);
#endif
}
diff --git a/qemu/hw/ppc.c b/qemu/hw/ppc.c
index e9f1724c..c23a02d2 100644
--- a/qemu/hw/ppc.c
+++ b/qemu/hw/ppc.c
@@ -551,13 +551,13 @@ static void cpu_ppc_tb_start (CPUState *env)
}
static always_inline uint32_t _cpu_ppc_load_decr (CPUState *env,
- uint64_t *next)
+ uint64_t next)
{
ppc_tb_t *tb_env = env->tb_env;
uint32_t decr;
int64_t diff;
- diff = tb_env->decr_next - qemu_get_clock(vm_clock);
+ diff = next - qemu_get_clock(vm_clock);
if (diff >= 0)
decr = muldiv64(diff, tb_env->decr_freq, ticks_per_sec);
else
@@ -571,14 +571,14 @@ uint32_t cpu_ppc_load_decr (CPUState *env)
{
ppc_tb_t *tb_env = env->tb_env;
- return _cpu_ppc_load_decr(env, &tb_env->decr_next);
+ return _cpu_ppc_load_decr(env, tb_env->decr_next);
}
uint32_t cpu_ppc_load_hdecr (CPUState *env)
{
ppc_tb_t *tb_env = env->tb_env;
- return _cpu_ppc_load_decr(env, &tb_env->hdecr_next);
+ return _cpu_ppc_load_decr(env, tb_env->hdecr_next);
}
uint64_t cpu_ppc_load_purr (CPUState *env)
diff --git a/qemu/hw/ps2.c b/qemu/hw/ps2.c
index fb770052..0915b9fa 100644
--- a/qemu/hw/ps2.c
+++ b/qemu/hw/ps2.c
@@ -488,9 +488,8 @@ void ps2_write_mouse(void *opaque, int val)
}
}
-static void ps2_reset(void *opaque)
+static void ps2_common_reset(PS2State *s)
{
- PS2State *s = (PS2State *)opaque;
PS2Queue *q;
s->write_cmd = -1;
q = &s->queue;
@@ -500,6 +499,33 @@ static void ps2_reset(void *opaque)
s->update_irq(s->update_arg, 0);
}
+static void ps2_kbd_reset(void *opaque)
+{
+ PS2KbdState *s = (PS2KbdState *) opaque;
+
+ ps2_common_reset(&s->common);
+ s->scan_enabled = 0;
+ s->translate = 0;
+ s->scancode_set = 0;
+}
+
+static void ps2_mouse_reset(void *opaque)
+{
+ PS2MouseState *s = (PS2MouseState *) opaque;
+
+ ps2_common_reset(&s->common);
+ s->mouse_status = 0;
+ s->mouse_resolution = 0;
+ s->mouse_sample_rate = 0;
+ s->mouse_wrap = 0;
+ s->mouse_type = 0;
+ s->mouse_detect_state = 0;
+ s->mouse_dx = 0;
+ s->mouse_dy = 0;
+ s->mouse_dz = 0;
+ s->mouse_buttons = 0;
+}
+
static void ps2_common_save (QEMUFile *f, PS2State *s)
{
qemu_put_be32 (f, s->write_cmd);
@@ -590,10 +616,10 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_irq = update_irq;
s->common.update_arg = update_arg;
s->scancode_set = 2;
- ps2_reset(&s->common);
+ ps2_kbd_reset(s);
register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
qemu_add_kbd_event_handler(ps2_put_keycode, s);
- qemu_register_reset(ps2_reset, &s->common);
+ qemu_register_reset(ps2_kbd_reset, s);
return s;
}
@@ -603,9 +629,9 @@ void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
s->common.update_irq = update_irq;
s->common.update_arg = update_arg;
- ps2_reset(&s->common);
+ ps2_mouse_reset(s);
register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
- qemu_register_reset(ps2_reset, &s->common);
+ qemu_register_reset(ps2_mouse_reset, s);
return s;
}
diff --git a/qemu/hw/qdev-addr.c b/qemu/hw/qdev-addr.c
new file mode 100644
index 00000000..305c2d37
--- /dev/null
+++ b/qemu/hw/qdev-addr.c
@@ -0,0 +1,32 @@
+#include "qdev.h"
+#include "qdev-addr.h"
+#include "targphys.h"
+
+/* --- target physical address --- */
+
+static int parse_taddr(DeviceState *dev, Property *prop, const char *str)
+{
+ target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ *ptr = strtoull(str, NULL, 16);
+ return 0;
+}
+
+static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "0x" TARGET_FMT_plx, *ptr);
+}
+
+PropertyInfo qdev_prop_taddr = {
+ .name = "taddr",
+ .type = PROP_TYPE_TADDR,
+ .size = sizeof(target_phys_addr_t),
+ .parse = parse_taddr,
+ .print = print_taddr,
+};
+
+void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value)
+{
+ qdev_prop_set(dev, name, &value, PROP_TYPE_TADDR);
+}
diff --git a/qemu/hw/qdev-addr.h b/qemu/hw/qdev-addr.h
new file mode 100644
index 00000000..f02bd7af
--- /dev/null
+++ b/qemu/hw/qdev-addr.h
@@ -0,0 +1,2 @@
+extern PropertyInfo qdev_prop_taddr;
+void qdev_prop_set_taddr(DeviceState *dev, const char *name, target_phys_addr_t value);
diff --git a/qemu/hw/qdev-properties.c b/qemu/hw/qdev-properties.c
new file mode 100644
index 00000000..c7a167b6
--- /dev/null
+++ b/qemu/hw/qdev-properties.c
@@ -0,0 +1,269 @@
+#include "qdev.h"
+
+void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
+{
+ void *ptr = dev;
+ (char*)ptr += prop->offset;
+ return ptr;
+}
+
+/* --- 16bit integer --- */
+
+static int parse_uint16(DeviceState *dev, Property *prop, const char *str)
+{
+ uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ const char *fmt;
+
+ /* accept both hex and decimal */
+ fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx16 : "%" PRIu16;
+ if (sscanf(str, fmt, ptr) != 1)
+ return -1;
+ return 0;
+}
+
+static int print_uint16(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint16_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "%" PRIu16, *ptr);
+}
+
+PropertyInfo qdev_prop_uint16 = {
+ .name = "uint16",
+ .type = PROP_TYPE_UINT16,
+ .size = sizeof(uint16_t),
+ .parse = parse_uint16,
+ .print = print_uint16,
+};
+
+/* --- 32bit integer --- */
+
+static int parse_uint32(DeviceState *dev, Property *prop, const char *str)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ const char *fmt;
+
+ /* accept both hex and decimal */
+ fmt = strncasecmp(str, "0x",2) == 0 ? "%" PRIx32 : "%" PRIu32;
+ if (sscanf(str, fmt, ptr) != 1)
+ return -1;
+ return 0;
+}
+
+static int print_uint32(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "%" PRIu32, *ptr);
+}
+
+PropertyInfo qdev_prop_uint32 = {
+ .name = "uint32",
+ .type = PROP_TYPE_UINT32,
+ .size = sizeof(uint32_t),
+ .parse = parse_uint32,
+ .print = print_uint32,
+};
+
+/* --- 32bit hex value --- */
+
+static int parse_hex32(DeviceState *dev, Property *prop, const char *str)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (sscanf(str, "%" PRIx32, ptr) != 1)
+ return -1;
+ return 0;
+}
+
+static int print_hex32(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint32_t *ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "0x%" PRIx32, *ptr);
+}
+
+PropertyInfo qdev_prop_hex32 = {
+ .name = "hex32",
+ .type = PROP_TYPE_UINT32,
+ .size = sizeof(uint32_t),
+ .parse = parse_hex32,
+ .print = print_hex32,
+};
+
+/* --- pointer --- */
+
+static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ void **ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "<%p>", *ptr);
+}
+
+PropertyInfo qdev_prop_ptr = {
+ .name = "ptr",
+ .type = PROP_TYPE_PTR,
+ .size = sizeof(void*),
+ .print = print_ptr,
+};
+
+/* --- mac address --- */
+
+/*
+ * accepted syntax versions:
+ * 01:02:03:04:05:06
+ * 01-02-03-04-05-06
+ */
+static int parse_mac(DeviceState *dev, Property *prop, const char *str)
+{
+ uint8_t *mac = qdev_get_prop_ptr(dev, prop);
+ int i, pos;
+ char *p;
+
+ for (i = 0, pos = 0; i < 6; i++, pos += 3) {
+ if (!isxdigit(str[pos]))
+ return -1;
+ if (!isxdigit(str[pos+1]))
+ return -1;
+ if (i == 5 && str[pos+2] != '\0')
+ return -1;
+ if (str[pos+2] != ':' && str[pos+2] != '-')
+ return -1;
+ mac[i] = strtol(str+pos, &p, 16);
+ }
+ return 0;
+}
+
+static int print_mac(DeviceState *dev, Property *prop, char *dest, size_t len)
+{
+ uint8_t *mac = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+PropertyInfo qdev_prop_macaddr = {
+ .name = "mac-addr",
+ .type = PROP_TYPE_MACADDR,
+ .size = 6,
+ .parse = parse_mac,
+ .print = print_mac,
+};
+
+/* --- public helpers --- */
+
+static Property *qdev_prop_walk(Property *props, const char *name)
+{
+ if (!props)
+ return NULL;
+ while (props->name) {
+ if (strcmp(props->name, name) == 0)
+ return props;
+ props++;
+ }
+ return NULL;
+}
+
+static Property *qdev_prop_find(DeviceState *dev, const char *name)
+{
+ Property *prop;
+
+ /* device properties */
+ prop = qdev_prop_walk(dev->info->props, name);
+ if (prop)
+ return prop;
+
+ /* bus properties */
+ prop = qdev_prop_walk(dev->parent_bus->info->props, name);
+ if (prop)
+ return prop;
+
+ return NULL;
+}
+
+int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
+{
+ Property *prop;
+
+ prop = qdev_prop_find(dev, name);
+ if (!prop) {
+ fprintf(stderr, "property \"%s.%s\" not found\n",
+ dev->info->name, name);
+ return -1;
+ }
+ if (!prop->info->parse) {
+ fprintf(stderr, "property \"%s.%s\" has no parser\n",
+ dev->info->name, name);
+ return -1;
+ }
+ return prop->info->parse(dev, prop, value);
+}
+
+void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)
+{
+ Property *prop;
+ void *dst;
+
+ prop = qdev_prop_find(dev, name);
+ if (!prop) {
+ fprintf(stderr, "%s: property \"%s.%s\" not found\n",
+ __FUNCTION__, dev->info->name, name);
+ abort();
+ }
+ if (prop->info->type != type) {
+ fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",
+ __FUNCTION__, dev->info->name, name);
+ abort();
+ }
+ dst = qdev_get_prop_ptr(dev, prop);
+ memcpy(dst, src, prop->info->size);
+}
+
+void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value)
+{
+ qdev_prop_set(dev, name, &value, PROP_TYPE_UINT16);
+}
+
+void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value)
+{
+ qdev_prop_set(dev, name, &value, PROP_TYPE_UINT32);
+}
+
+void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
+{
+ qdev_prop_set(dev, name, &value, PROP_TYPE_PTR);
+}
+
+void qdev_prop_set_defaults(DeviceState *dev, Property *props)
+{
+ char *dst;
+
+ if (!props)
+ return;
+ while (props->name) {
+ if (props->defval) {
+ dst = qdev_get_prop_ptr(dev, props);
+ memcpy(dst, props->defval, props->info->size);
+ }
+ props++;
+ }
+}
+
+static CompatProperty *compat_props;
+
+void qdev_prop_register_compat(CompatProperty *props)
+{
+ compat_props = props;
+}
+
+void qdev_prop_set_compat(DeviceState *dev)
+{
+ CompatProperty *prop;
+
+ if (!compat_props) {
+ return;
+ }
+ for (prop = compat_props; prop->driver != NULL; prop++) {
+ if (strcmp(dev->info->name, prop->driver) != 0) {
+ continue;
+ }
+ if (qdev_prop_parse(dev, prop->property, prop->value) != 0) {
+ abort();
+ }
+ }
+}
diff --git a/qemu/hw/qdev.c b/qemu/hw/qdev.c
index 83e98bf3..001c74ce 100644
--- a/qemu/hw/qdev.c
+++ b/qemu/hw/qdev.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/* The theory here is that it should be possible to create a machine without
@@ -31,16 +30,6 @@
#include "sysemu.h"
#include "monitor.h"
-struct DeviceProperty {
- const char *name;
- DevicePropType type;
- union {
- uint64_t i;
- void *ptr;
- } value;
- DeviceProperty *next;
-};
-
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
static BusState *main_system_bus;
extern struct BusInfo system_bus_info;
@@ -57,6 +46,32 @@ void qdev_register(DeviceInfo *info)
device_info_list = info;
}
+static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
+{
+ DeviceInfo *info;
+
+ /* first check device names */
+ for (info = device_info_list; info != NULL; info = info->next) {
+ if (bus_info && info->bus_info != bus_info)
+ continue;
+ if (strcmp(info->name, name) != 0)
+ continue;
+ return info;
+ }
+
+ /* failing that check the aliases */
+ for (info = device_info_list; info != NULL; info = info->next) {
+ if (bus_info && info->bus_info != bus_info)
+ continue;
+ if (!info->alias)
+ continue;
+ if (strcmp(info->alias, name) != 0)
+ continue;
+ return info;
+ }
+ return NULL;
+}
+
/* Create a new device. This only initializes the device state structure
and allows properties to be set. qdev_init should be called to
initialize the actual device emulation. */
@@ -72,13 +87,7 @@ DeviceState *qdev_create(BusState *bus, const char *name)
bus = main_system_bus;
}
- for (info = device_info_list; info != NULL; info = info->next) {
- if (info->bus_info != bus->info)
- continue;
- if (strcmp(info->name, name) != 0)
- continue;
- break;
- }
+ info = qdev_find_info(bus->info, name);
if (!info) {
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
}
@@ -86,6 +95,9 @@ DeviceState *qdev_create(BusState *bus, const char *name)
dev = qemu_mallocz(info->size);
dev->info = info;
dev->parent_bus = bus;
+ qdev_prop_set_defaults(dev, dev->info->props);
+ qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
+ qdev_prop_set_compat(dev);
LIST_INSERT_HEAD(&bus->children, dev, sibling);
return dev;
}
@@ -102,55 +114,10 @@ void qdev_init(DeviceState *dev)
void qdev_free(DeviceState *dev)
{
LIST_REMOVE(dev, sibling);
- free(dev);
-}
-
-static DeviceProperty *create_prop(DeviceState *dev, const char *name,
- DevicePropType type)
-{
- DeviceProperty *prop;
-
- /* TODO: Check for duplicate properties. */
- prop = qemu_mallocz(sizeof(*prop));
- prop->name = qemu_strdup(name);
- prop->type = type;
- prop->next = dev->props;
- dev->props = prop;
-
- return prop;
-}
-
-void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value)
-{
- DeviceProperty *prop;
-
- prop = create_prop(dev, name, PROP_TYPE_INT);
- prop->value.i = value;
-}
-
-void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value)
-{
- DeviceProperty *prop;
-
- prop = create_prop(dev, name, PROP_TYPE_DEV);
- prop->value.ptr = value;
-}
-
-void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value)
-{
- DeviceProperty *prop;
-
- prop = create_prop(dev, name, PROP_TYPE_PTR);
- prop->value.ptr = value;
-}
-
-void qdev_set_netdev(DeviceState *dev, NICInfo *nd)
-{
- assert(!dev->nd);
- dev->nd = nd;
+ qemu_free(dev->id);
+ qemu_free(dev);
}
-
/* Get a character (serial) device interface. */
CharDriverState *qdev_init_chardev(DeviceState *dev)
{
@@ -169,52 +136,6 @@ BusState *qdev_get_parent_bus(DeviceState *dev)
return dev->parent_bus;
}
-static DeviceProperty *find_prop(DeviceState *dev, const char *name,
- DevicePropType type)
-{
- DeviceProperty *prop;
-
- for (prop = dev->props; prop; prop = prop->next) {
- if (strcmp(prop->name, name) == 0) {
- assert (prop->type == type);
- return prop;
- }
- }
- return NULL;
-}
-
-uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def)
-{
- DeviceProperty *prop;
-
- prop = find_prop(dev, name, PROP_TYPE_INT);
- if (!prop) {
- return def;
- }
-
- return prop->value.i;
-}
-
-void *qdev_get_prop_ptr(DeviceState *dev, const char *name)
-{
- DeviceProperty *prop;
-
- prop = find_prop(dev, name, PROP_TYPE_PTR);
- assert(prop);
- return prop->value.ptr;
-}
-
-DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name)
-{
- DeviceProperty *prop;
-
- prop = find_prop(dev, name, PROP_TYPE_DEV);
- if (!prop) {
- return NULL;
- }
- return prop->value.ptr;
-}
-
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
{
assert(dev->num_gpio_in == 0);
@@ -327,11 +248,27 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qbus_print(Monitor *mon, BusState *bus, int indent);
+static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
+ const char *prefix, int indent)
+{
+ char buf[64];
+
+ if (!props)
+ return;
+ while (props->name) {
+ if (props->info->print) {
+ props->info->print(dev, props, buf, sizeof(buf));
+ qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
+ }
+ props++;
+ }
+}
+
static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
{
- DeviceProperty *prop;
BusState *child;
- qdev_printf("dev: %s\n", dev->info->name);
+ qdev_printf("dev: %s, id \"%s\"\n", dev->info->name,
+ dev->id ? dev->id : "");
indent += 2;
if (dev->num_gpio_in) {
qdev_printf("gpio-in %d\n", dev->num_gpio_in);
@@ -339,24 +276,8 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
if (dev->num_gpio_out) {
qdev_printf("gpio-out %d\n", dev->num_gpio_out);
}
- for (prop = dev->props; prop; prop = prop->next) {
- switch (prop->type) {
- case PROP_TYPE_INT:
- qdev_printf("prop-int %s 0x%" PRIx64 "\n", prop->name,
- prop->value.i);
- break;
- case PROP_TYPE_PTR:
- qdev_printf("prop-ptr %s\n", prop->name);
- break;
- case PROP_TYPE_DEV:
- qdev_printf("prop-dev %s %s\n", prop->name,
- ((DeviceState *)prop->value.ptr)->info->name);
- break;
- default:
- qdev_printf("prop-unknown%d %s\n", prop->type, prop->name);
- break;
- }
- }
+ qdev_print_props(mon, dev, dev->info->props, "dev", indent);
+ qdev_print_props(mon, dev, dev->parent_bus->info->props, "bus", indent);
if (dev->parent_bus->info->print_dev)
dev->parent_bus->info->print_dev(mon, dev, indent);
LIST_FOREACH(child, &dev->child_bus, sibling) {
diff --git a/qemu/hw/qdev.h b/qemu/hw/qdev.h
index b18dbf91..11744fa5 100644
--- a/qemu/hw/qdev.h
+++ b/qemu/hw/qdev.h
@@ -4,9 +4,13 @@
#include "hw.h"
#include "sys-queue.h"
-typedef struct DeviceInfo DeviceInfo;
+typedef struct Property Property;
+
+typedef struct PropertyInfo PropertyInfo;
-typedef struct DeviceProperty DeviceProperty;
+typedef struct CompatProperty CompatProperty;
+
+typedef struct DeviceInfo DeviceInfo;
typedef struct BusState BusState;
@@ -15,9 +19,9 @@ typedef struct BusInfo BusInfo;
/* This structure should not be accessed directly. We declare it here
so that it can be embedded in individual device state structures. */
struct DeviceState {
+ char *id;
DeviceInfo *info;
BusState *parent_bus;
- DeviceProperty *props;
int num_gpio_out;
qemu_irq *gpio_out;
int num_gpio_in;
@@ -32,6 +36,7 @@ struct BusInfo {
const char *name;
size_t size;
bus_dev_printfn print_dev;
+ Property *props;
};
struct BusState {
@@ -42,18 +47,42 @@ struct BusState {
LIST_ENTRY(BusState) sibling;
};
+struct Property {
+ const char *name;
+ PropertyInfo *info;
+ int offset;
+ void *defval;
+};
+
+enum PropertyType {
+ PROP_TYPE_UNSPEC = 0,
+ PROP_TYPE_UINT16,
+ PROP_TYPE_UINT32,
+ PROP_TYPE_TADDR,
+ PROP_TYPE_MACADDR,
+ PROP_TYPE_PTR,
+};
+
+struct PropertyInfo {
+ const char *name;
+ size_t size;
+ enum PropertyType type;
+ int (*parse)(DeviceState *dev, Property *prop, const char *str);
+ int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
+};
+
+struct CompatProperty {
+ const char *driver;
+ const char *property;
+ const char *value;
+};
+
/*** Board API. This should go away once we have a machine config file. ***/
DeviceState *qdev_create(BusState *bus, const char *name);
void qdev_init(DeviceState *dev);
void qdev_free(DeviceState *dev);
-/* Set properties between creation and init. */
-void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value);
-void qdev_set_prop_dev(DeviceState *dev, const char *name, DeviceState *value);
-void qdev_set_prop_ptr(DeviceState *dev, const char *name, void *value);
-void qdev_set_netdev(DeviceState *dev, NICInfo *nd);
-
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
@@ -61,25 +90,17 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
/*** Device API. ***/
-typedef enum {
- PROP_TYPE_INT,
- PROP_TYPE_PTR,
- PROP_TYPE_DEV
-} DevicePropType;
-
-typedef struct {
- const char *name;
- DevicePropType type;
-} DevicePropList;
-
typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
int unit);
struct DeviceInfo {
const char *name;
+ const char *alias;
+ const char *desc;
size_t size;
- DevicePropList *props;
+ Property *props;
+ int no_user;
/* Private to qdev / bus. */
qdev_initfn init;
@@ -99,10 +120,6 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach);
CharDriverState *qdev_init_chardev(DeviceState *dev);
BusState *qdev_get_parent_bus(DeviceState *dev);
-uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def);
-DeviceState *qdev_get_prop_dev(DeviceState *dev, const char *name);
-/* FIXME: Remove opaque pointer properties. */
-void *qdev_get_prop_ptr(DeviceState *dev, const char *name);
/* Convery from a base type to a parent type, with compile time checking. */
#ifdef __GNUC__
@@ -124,4 +141,25 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name);
void do_info_qtree(Monitor *mon);
+/*** qdev-properties.c ***/
+
+extern PropertyInfo qdev_prop_uint16;
+extern PropertyInfo qdev_prop_uint32;
+extern PropertyInfo qdev_prop_hex32;
+extern PropertyInfo qdev_prop_ptr;
+extern PropertyInfo qdev_prop_macaddr;
+
+/* Set properties between creation and init. */
+void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
+int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
+void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type);
+void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
+void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value);
+/* FIXME: Remove opaque pointer properties. */
+void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
+void qdev_prop_set_defaults(DeviceState *dev, Property *props);
+
+void qdev_prop_register_compat(CompatProperty *props);
+void qdev_prop_set_compat(DeviceState *dev);
+
#endif
diff --git a/qemu/hw/slavio_intctl.c b/qemu/hw/slavio_intctl.c
index a46d926e..39a17854 100644
--- a/qemu/hw/slavio_intctl.c
+++ b/qemu/hw/slavio_intctl.c
@@ -21,9 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
#include "monitor.h"
+#include "sysbus.h"
//#define DEBUG_IRQ_COUNT
//#define DEBUG_IRQ
@@ -49,28 +50,30 @@
#define MAX_CPUS 16
#define MAX_PILS 16
-struct SLAVIO_CPUINTCTLState;
+struct SLAVIO_INTCTLState;
+
+typedef struct SLAVIO_CPUINTCTLState {
+ uint32_t intreg_pending;
+ struct SLAVIO_INTCTLState *master;
+ uint32_t cpu;
+} SLAVIO_CPUINTCTLState;
typedef struct SLAVIO_INTCTLState {
+ SysBusDevice busdev;
uint32_t intregm_pending;
uint32_t intregm_disabled;
uint32_t target_cpu;
#ifdef DEBUG_IRQ_COUNT
uint64_t irq_count[32];
#endif
- qemu_irq *cpu_irqs[MAX_CPUS];
+ qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS];
const uint32_t *intbit_to_level;
uint32_t cputimer_lbit, cputimer_mbit;
+ uint32_t cputimer_bit;
uint32_t pil_out[MAX_CPUS];
- struct SLAVIO_CPUINTCTLState *slaves[MAX_CPUS];
+ SLAVIO_CPUINTCTLState slaves[MAX_CPUS];
} SLAVIO_INTCTLState;
-typedef struct SLAVIO_CPUINTCTLState {
- uint32_t intreg_pending;
- SLAVIO_INTCTLState *master;
- uint32_t cpu;
-} SLAVIO_CPUINTCTLState;
-
#define INTCTL_MAXADDR 0xf
#define INTCTL_SIZE (INTCTL_MAXADDR + 1)
#define INTCTLM_SIZE 0x14
@@ -225,7 +228,7 @@ void slavio_pic_info(Monitor *mon, void *opaque)
for (i = 0; i < MAX_CPUS; i++) {
monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
- s->slaves[i]->intreg_pending);
+ s->slaves[i].intreg_pending);
}
monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
s->intregm_pending, s->intregm_disabled);
@@ -266,7 +269,7 @@ static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs)
pil_pending |= 1 << s->intbit_to_level[j];
}
}
- pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
+ pil_pending |= (s->slaves[i].intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
if (set_irqs) {
for (j = 0; j < MAX_PILS; j++) {
@@ -303,10 +306,10 @@ static void slavio_set_irq(void *opaque, int irq, int level)
s->irq_count[pil]++;
#endif
s->intregm_pending |= mask;
- s->slaves[s->target_cpu]->intreg_pending |= 1 << pil;
+ s->slaves[s->target_cpu].intreg_pending |= 1 << pil;
} else {
s->intregm_pending &= ~mask;
- s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil);
+ s->slaves[s->target_cpu].intreg_pending &= ~(1 << pil);
}
slavio_check_interrupts(s, 1);
}
@@ -320,22 +323,31 @@ static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
if (level) {
s->intregm_pending |= s->cputimer_mbit;
- s->slaves[cpu]->intreg_pending |= s->cputimer_lbit;
+ s->slaves[cpu].intreg_pending |= s->cputimer_lbit;
} else {
s->intregm_pending &= ~s->cputimer_mbit;
- s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit;
+ s->slaves[cpu].intreg_pending &= ~s->cputimer_lbit;
}
slavio_check_interrupts(s, 1);
}
+static void slavio_set_irq_all(void *opaque, int irq, int level)
+{
+ if (irq < 32) {
+ slavio_set_irq(opaque, irq, level);
+ } else {
+ slavio_set_timer_irq_cpu(opaque, irq - 32, level);
+ }
+}
+
static void slavio_intctl_save(QEMUFile *f, void *opaque)
{
SLAVIO_INTCTLState *s = opaque;
int i;
for (i = 0; i < MAX_CPUS; i++) {
- qemu_put_be32s(f, &s->slaves[i]->intreg_pending);
+ qemu_put_be32s(f, &s->slaves[i].intreg_pending);
}
qemu_put_be32s(f, &s->intregm_pending);
qemu_put_be32s(f, &s->intregm_disabled);
@@ -351,7 +363,7 @@ static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id)
return -EINVAL;
for (i = 0; i < MAX_CPUS; i++) {
- qemu_get_be32s(f, &s->slaves[i]->intreg_pending);
+ qemu_get_be32s(f, &s->slaves[i].intreg_pending);
}
qemu_get_be32s(f, &s->intregm_pending);
qemu_get_be32s(f, &s->intregm_disabled);
@@ -366,7 +378,7 @@ static void slavio_intctl_reset(void *opaque)
int i;
for (i = 0; i < MAX_CPUS; i++) {
- s->slaves[i]->intreg_pending = 0;
+ s->slaves[i].intreg_pending = 0;
}
s->intregm_disabled = ~MASTER_IRQ_MASK;
s->intregm_pending = 0;
@@ -374,47 +386,87 @@ static void slavio_intctl_reset(void *opaque)
slavio_check_interrupts(s, 0);
}
-void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
- const uint32_t *intbit_to_level,
- qemu_irq **irq, qemu_irq **cpu_irq,
- qemu_irq **parent_irq, unsigned int cputimer)
+static void slavio_intctl_init1(SysBusDevice *dev)
{
- int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
- SLAVIO_INTCTLState *s;
- SLAVIO_CPUINTCTLState *slave;
+ SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev);
+ int io_memory;
+ unsigned int i, j;
- s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
+ qdev_init_gpio_in(&dev->qdev, slavio_set_irq_all, 32 + MAX_CPUS);
+ io_memory = cpu_register_io_memory(slavio_intctlm_mem_read,
+ slavio_intctlm_mem_write, s);
+ sysbus_init_mmio(dev, INTCTLM_SIZE, io_memory);
+ s->cputimer_mbit = 1 << s->cputimer_bit;
+ s->cputimer_lbit = 1 << s->intbit_to_level[s->cputimer_bit];
- s->intbit_to_level = intbit_to_level;
for (i = 0; i < MAX_CPUS; i++) {
- slave = qemu_mallocz(sizeof(SLAVIO_CPUINTCTLState));
+ for (j = 0; j < MAX_PILS; j++) {
+ sysbus_init_irq(dev, &s->cpu_irqs[i][j]);
+ }
+ io_memory = cpu_register_io_memory(slavio_intctl_mem_read,
+ slavio_intctl_mem_write,
+ &s->slaves[i]);
+ sysbus_init_mmio(dev, INTCTL_SIZE, io_memory);
+ s->slaves[i].cpu = i;
+ s->slaves[i].master = s;
+ }
+ register_savevm("slavio_intctl", -1, 1, slavio_intctl_save,
+ slavio_intctl_load, s);
+ qemu_register_reset(slavio_intctl_reset, s);
+ slavio_intctl_reset(s);
+}
+
+DeviceState *slavio_intctl_init(target_phys_addr_t addr,
+ target_phys_addr_t addrg,
+ const uint32_t *intbit_to_level,
+ qemu_irq **parent_irq, unsigned int cputimer)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ unsigned int i, j;
- slave->cpu = i;
- slave->master = s;
+ dev = qdev_create(NULL, "slavio_intctl");
+ qdev_prop_set_ptr(dev, "intbit_to_level", (void *)intbit_to_level);
+ qdev_prop_set_uint32(dev, "cputimer_bit", cputimer);
+ qdev_init(dev);
- slavio_intctl_io_memory = cpu_register_io_memory(slavio_intctl_mem_read,
- slavio_intctl_mem_write,
- slave);
- cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
- slavio_intctl_io_memory);
+ s = sysbus_from_qdev(dev);
- s->slaves[i] = slave;
- s->cpu_irqs[i] = parent_irq[i];
+ for (i = 0; i < MAX_CPUS; i++) {
+ for (j = 0; j < MAX_PILS; j++) {
+ sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
+ }
+ }
+ sysbus_mmio_map(s, 0, addrg);
+ for (i = 0; i < MAX_CPUS; i++) {
+ sysbus_mmio_map(s, i + 1, addr + i * TARGET_PAGE_SIZE);
}
- slavio_intctlm_io_memory = cpu_register_io_memory(slavio_intctlm_mem_read,
- slavio_intctlm_mem_write,
- s);
- cpu_register_physical_memory(addrg, INTCTLM_SIZE, slavio_intctlm_io_memory);
+ return dev;
+}
- register_savevm("slavio_intctl", addr, 1, slavio_intctl_save,
- slavio_intctl_load, s);
- qemu_register_reset(slavio_intctl_reset, s);
- *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
+static SysBusDeviceInfo slavio_intctl_info = {
+ .init = slavio_intctl_init1,
+ .qdev.name = "slavio_intctl",
+ .qdev.size = sizeof(SLAVIO_INTCTLState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "intbit_to_level",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SLAVIO_INTCTLState, intbit_to_level),
+ },
+ {
+ .name = "cputimer_bit",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SLAVIO_INTCTLState, cputimer_bit),
+ },
+ {/* end of property list */}
+ }
+};
- *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS);
- s->cputimer_mbit = 1 << cputimer;
- s->cputimer_lbit = 1 << intbit_to_level[cputimer];
- slavio_intctl_reset(s);
- return s;
+static void slavio_intctl_register_devices(void)
+{
+ sysbus_register_withprop(&slavio_intctl_info);
}
+
+device_init(slavio_intctl_register_devices);
diff --git a/qemu/hw/slavio_misc.c b/qemu/hw/slavio_misc.c
index 9761290d..9e4ed853 100644
--- a/qemu/hw/slavio_misc.c
+++ b/qemu/hw/slavio_misc.c
@@ -21,9 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
#include "sysemu.h"
+#include "sysbus.h"
/* debug misc */
//#define DEBUG_MISC
@@ -44,16 +45,21 @@
#endif
typedef struct MiscState {
+ SysBusDevice busdev;
qemu_irq irq;
uint8_t config;
uint8_t aux1, aux2;
uint8_t diag, mctrl;
uint32_t sysctrl;
uint16_t leds;
- qemu_irq cpu_halt;
qemu_irq fdc_tc;
} MiscState;
+typedef struct APCState {
+ SysBusDevice busdev;
+ qemu_irq cpu_halt;
+} APCState;
+
#define MISC_SIZE 1
#define SYSCTRL_SIZE 4
@@ -283,7 +289,7 @@ static CPUWriteMemoryFunc *slavio_aux2_mem_write[3] = {
static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
- MiscState *s = opaque;
+ APCState *s = opaque;
MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
qemu_irq_raise(s->cpu_halt);
@@ -434,75 +440,142 @@ static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base,
+void *slavio_misc_init(target_phys_addr_t base,
target_phys_addr_t aux1_base,
target_phys_addr_t aux2_base, qemu_irq irq,
- qemu_irq cpu_halt, qemu_irq **fdc_tc)
+ qemu_irq fdc_tc)
{
- int io;
- MiscState *s;
-
- s = qemu_mallocz(sizeof(MiscState));
+ DeviceState *dev;
+ SysBusDevice *s;
+ MiscState *d;
+ dev = qdev_create(NULL, "slavio_misc");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
if (base) {
/* 8 bit registers */
-
- // Slavio control
- io = cpu_register_io_memory(slavio_cfg_mem_read,
- slavio_cfg_mem_write, s);
- cpu_register_physical_memory(base + MISC_CFG, MISC_SIZE, io);
-
- // Diagnostics
- io = cpu_register_io_memory(slavio_diag_mem_read,
- slavio_diag_mem_write, s);
- cpu_register_physical_memory(base + MISC_DIAG, MISC_SIZE, io);
-
- // Modem control
- io = cpu_register_io_memory(slavio_mdm_mem_read,
- slavio_mdm_mem_write, s);
- cpu_register_physical_memory(base + MISC_MDM, MISC_SIZE, io);
-
+ /* Slavio control */
+ sysbus_mmio_map(s, 0, base + MISC_CFG);
+ /* Diagnostics */
+ sysbus_mmio_map(s, 1, base + MISC_DIAG);
+ /* Modem control */
+ sysbus_mmio_map(s, 2, base + MISC_MDM);
/* 16 bit registers */
- io = cpu_register_io_memory(slavio_led_mem_read,
- slavio_led_mem_write, s);
/* ss600mp diag LEDs */
- cpu_register_physical_memory(base + MISC_LEDS, MISC_SIZE, io);
-
+ sysbus_mmio_map(s, 3, base + MISC_LEDS);
/* 32 bit registers */
- io = cpu_register_io_memory(slavio_sysctrl_mem_read,
- slavio_sysctrl_mem_write, s);
- // System control
- cpu_register_physical_memory(base + MISC_SYS, SYSCTRL_SIZE, io);
+ /* System control */
+ sysbus_mmio_map(s, 4, base + MISC_SYS);
}
-
- // AUX 1 (Misc System Functions)
if (aux1_base) {
- io = cpu_register_io_memory(slavio_aux1_mem_read,
- slavio_aux1_mem_write, s);
- cpu_register_physical_memory(aux1_base, MISC_SIZE, io);
+ /* AUX 1 (Misc System Functions) */
+ sysbus_mmio_map(s, 5, aux1_base);
}
-
- // AUX 2 (Software Powerdown Control)
if (aux2_base) {
- io = cpu_register_io_memory(slavio_aux2_mem_read,
- slavio_aux2_mem_write, s);
- cpu_register_physical_memory(aux2_base, MISC_SIZE, io);
+ /* AUX 2 (Software Powerdown Control) */
+ sysbus_mmio_map(s, 6, aux2_base);
}
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_connect_irq(s, 1, fdc_tc);
- // Power management (APC) XXX: not a Slavio device
- if (power_base) {
- io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s);
- cpu_register_physical_memory(power_base, MISC_SIZE, io);
- }
+ d = FROM_SYSBUS(MiscState, s);
- s->irq = irq;
- s->cpu_halt = cpu_halt;
- *fdc_tc = &s->fdc_tc;
+ return d;
+}
- register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load,
+static void apc_init1(SysBusDevice *dev)
+{
+ APCState *s = FROM_SYSBUS(APCState, dev);
+ int io;
+
+ sysbus_init_irq(dev, &s->cpu_halt);
+
+ /* Power management (APC) XXX: not a Slavio device */
+ io = cpu_register_io_memory(apc_mem_read, apc_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+}
+
+void apc_init(target_phys_addr_t power_base, qemu_irq cpu_halt)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, "apc");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ /* Power management (APC) XXX: not a Slavio device */
+ sysbus_mmio_map(s, 0, power_base);
+ sysbus_connect_irq(s, 0, cpu_halt);
+}
+
+static void slavio_misc_init1(SysBusDevice *dev)
+{
+ MiscState *s = FROM_SYSBUS(MiscState, dev);
+ int io;
+
+ sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(dev, &s->fdc_tc);
+
+ /* 8 bit registers */
+ /* Slavio control */
+ io = cpu_register_io_memory(slavio_cfg_mem_read,
+ slavio_cfg_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ /* Diagnostics */
+ io = cpu_register_io_memory(slavio_diag_mem_read,
+ slavio_diag_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ /* Modem control */
+ io = cpu_register_io_memory(slavio_mdm_mem_read,
+ slavio_mdm_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ /* 16 bit registers */
+ /* ss600mp diag LEDs */
+ io = cpu_register_io_memory(slavio_led_mem_read,
+ slavio_led_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ /* 32 bit registers */
+ /* System control */
+ io = cpu_register_io_memory(slavio_sysctrl_mem_read,
+ slavio_sysctrl_mem_write, s);
+ sysbus_init_mmio(dev, SYSCTRL_SIZE, io);
+
+ /* AUX 1 (Misc System Functions) */
+ io = cpu_register_io_memory(slavio_aux1_mem_read,
+ slavio_aux1_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ /* AUX 2 (Software Powerdown Control) */
+ io = cpu_register_io_memory(slavio_aux2_mem_read,
+ slavio_aux2_mem_write, s);
+ sysbus_init_mmio(dev, MISC_SIZE, io);
+
+ register_savevm("slavio_misc", -1, 1, slavio_misc_save, slavio_misc_load,
s);
qemu_register_reset(slavio_misc_reset, s);
slavio_misc_reset(s);
+}
+
+static SysBusDeviceInfo slavio_misc_info = {
+ .init = slavio_misc_init1,
+ .qdev.name = "slavio_misc",
+ .qdev.size = sizeof(MiscState),
+};
- return s;
+static SysBusDeviceInfo apc_info = {
+ .init = apc_init1,
+ .qdev.name = "apc",
+ .qdev.size = sizeof(MiscState),
+};
+
+static void slavio_misc_register_devices(void)
+{
+ sysbus_register_withprop(&slavio_misc_info);
+ sysbus_register_withprop(&apc_info);
}
+
+device_init(slavio_misc_register_devices);
diff --git a/qemu/hw/slavio_timer.c b/qemu/hw/slavio_timer.c
index a938fb65..982ff6ef 100644
--- a/qemu/hw/slavio_timer.c
+++ b/qemu/hw/slavio_timer.c
@@ -21,9 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
#include "qemu-timer.h"
+#include "sysbus.h"
//#define DEBUG_TIMER
@@ -52,6 +53,7 @@
#define MAX_CPUS 16
typedef struct SLAVIO_TIMERState {
+ SysBusDevice busdev;
qemu_irq irq;
ptimer_state *timer;
uint32_t count, counthigh, reached;
@@ -364,36 +366,53 @@ static void slavio_timer_reset(void *opaque)
static SLAVIO_TIMERState *slavio_timer_init(target_phys_addr_t addr,
qemu_irq irq,
SLAVIO_TIMERState *master,
- uint32_t slave_index)
+ uint32_t slave_index,
+ uint32_t num_slaves)
{
- int slavio_timer_io_memory;
- SLAVIO_TIMERState *s;
+ DeviceState *dev;
+ SysBusDevice *s;
+ SLAVIO_TIMERState *d;
+
+ dev = qdev_create(NULL, "slavio_timer");
+ qdev_prop_set_uint32(dev, "slave_index", slave_index);
+ qdev_prop_set_uint32(dev, "num_slaves", num_slaves);
+ qdev_prop_set_ptr(dev, "master", master);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, irq);
+ sysbus_mmio_map(s, 0, addr);
+
+ d = FROM_SYSBUS(SLAVIO_TIMERState, s);
+
+ return d;
+}
+
+static void slavio_timer_init1(SysBusDevice *dev)
+{
+ int io;
+ SLAVIO_TIMERState *s = FROM_SYSBUS(SLAVIO_TIMERState, dev);
QEMUBH *bh;
- s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
- s->irq = irq;
- s->master = master;
- s->slave_index = slave_index;
- if (!master || slave_index < master->num_slaves) {
+ sysbus_init_irq(dev, &s->irq);
+
+ if (!s->master || s->slave_index < s->master->num_slaves) {
bh = qemu_bh_new(slavio_timer_irq, s);
s->timer = ptimer_init(bh);
ptimer_set_period(s->timer, TIMER_PERIOD);
}
- slavio_timer_io_memory = cpu_register_io_memory(slavio_timer_mem_read,
- slavio_timer_mem_write, s);
- if (master)
- cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
- slavio_timer_io_memory);
- else
- cpu_register_physical_memory(addr, SYS_TIMER_SIZE,
- slavio_timer_io_memory);
- register_savevm("slavio_timer", addr, 3, slavio_timer_save,
+ io = cpu_register_io_memory(slavio_timer_mem_read, slavio_timer_mem_write,
+ s);
+ if (s->master) {
+ sysbus_init_mmio(dev, CPU_TIMER_SIZE, io);
+ } else {
+ sysbus_init_mmio(dev, SYS_TIMER_SIZE, io);
+ }
+
+ register_savevm("slavio_timer", -1, 3, slavio_timer_save,
slavio_timer_load, s);
qemu_register_reset(slavio_timer_reset, s);
slavio_timer_reset(s);
-
- return s;
}
void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
@@ -402,13 +421,43 @@ void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
SLAVIO_TIMERState *master;
unsigned int i;
- master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0);
-
- master->num_slaves = num_cpus;
+ master = slavio_timer_init(base + SYS_TIMER_OFFSET, master_irq, NULL, 0,
+ num_cpus);
for (i = 0; i < MAX_CPUS; i++) {
master->slave[i] = slavio_timer_init(base + (target_phys_addr_t)
CPU_TIMER_OFFSET(i),
- cpu_irqs[i], master, i);
+ cpu_irqs[i], master, i, 0);
}
}
+
+static SysBusDeviceInfo slavio_timer_info = {
+ .init = slavio_timer_init1,
+ .qdev.name = "slavio_timer",
+ .qdev.size = sizeof(SLAVIO_TIMERState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "num_slaves",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SLAVIO_TIMERState, num_slaves),
+ },
+ {
+ .name = "slave_index",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SLAVIO_TIMERState, slave_index),
+ },
+ {
+ .name = "master",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SLAVIO_TIMERState, master),
+ },
+ {/* end of property list */}
+ }
+};
+
+static void slavio_timer_register_devices(void)
+{
+ sysbus_register_withprop(&slavio_timer_info);
+}
+
+device_init(slavio_timer_register_devices);
diff --git a/qemu/hw/smbus_eeprom.c b/qemu/hw/smbus_eeprom.c
index 81e87806..5a5b28d5 100644
--- a/qemu/hw/smbus_eeprom.c
+++ b/qemu/hw/smbus_eeprom.c
@@ -99,14 +99,20 @@ static void smbus_eeprom_init(SMBusDevice *dev)
{
SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
- /* FIXME: Should be a blob rather than a ptr. */
- eeprom->data = qdev_get_prop_ptr(&dev->i2c.qdev, "data");
eeprom->offset = 0;
}
static SMBusDeviceInfo smbus_eeprom_info = {
.i2c.qdev.name = "smbus-eeprom",
.i2c.qdev.size = sizeof(SMBusEEPROMDevice),
+ .i2c.qdev.props = (Property[]) {
+ {
+ .name = "data",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(SMBusEEPROMDevice, data),
+ },
+ {/* end of list */}
+ },
.init = smbus_eeprom_init,
.quick_cmd = eeprom_quick_cmd,
.send_byte = eeprom_send_byte,
diff --git a/qemu/hw/smc91c111.c b/qemu/hw/smc91c111.c
index cf8d864e..5f6956a6 100644
--- a/qemu/hw/smc91c111.c
+++ b/qemu/hw/smc91c111.c
@@ -733,7 +733,7 @@ void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
qemu_check_nic_model(nd, "smc91c111");
dev = qdev_create(NULL, "smc91c111");
- qdev_set_netdev(dev, nd);
+ dev->nd = nd;
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, base);
diff --git a/qemu/hw/sparc32_dma.c b/qemu/hw/sparc32_dma.c
index f272b242..04c307be 100644
--- a/qemu/hw/sparc32_dma.c
+++ b/qemu/hw/sparc32_dma.c
@@ -21,9 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include "hw.h"
#include "sparc32_dma.h"
#include "sun4m.h"
+#include "sysbus.h"
/* debug DMA */
//#define DEBUG_DMA
@@ -60,6 +62,7 @@
typedef struct DMAState DMAState;
struct DMAState {
+ SysBusDevice busdev;
uint32_t dmaregs[DMA_REGS];
qemu_irq irq;
void *iommu;
@@ -242,24 +245,59 @@ static int dma_load(QEMUFile *f, void *opaque, int version_id)
}
void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
- void *iommu, qemu_irq **dev_irq, qemu_irq **reset)
+ void *iommu, qemu_irq *dev_irq, qemu_irq **reset)
{
- DMAState *s;
- int dma_io_memory;
+ DeviceState *dev;
+ SysBusDevice *s;
+ DMAState *d;
+
+ dev = qdev_create(NULL, "sparc32_dma");
+ qdev_prop_set_ptr(dev, "iommu_opaque", iommu);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ sysbus_connect_irq(s, 0, parent_irq);
+ *dev_irq = qdev_get_gpio_in(dev, 0);
+ sysbus_mmio_map(s, 0, daddr);
+
+ d = FROM_SYSBUS(DMAState, s);
+ *reset = &d->dev_reset;
+
+ return d;
+}
- s = qemu_mallocz(sizeof(DMAState));
+static void sparc32_dma_init1(SysBusDevice *dev)
+{
+ DMAState *s = FROM_SYSBUS(DMAState, dev);
+ int dma_io_memory;
- s->irq = parent_irq;
- s->iommu = iommu;
+ sysbus_init_irq(dev, &s->irq);
dma_io_memory = cpu_register_io_memory(dma_mem_read, dma_mem_write, s);
- cpu_register_physical_memory(daddr, DMA_SIZE, dma_io_memory);
+ sysbus_init_mmio(dev, DMA_SIZE, dma_io_memory);
- register_savevm("sparc32_dma", daddr, 2, dma_save, dma_load, s);
+ register_savevm("sparc32_dma", -1, 2, dma_save, dma_load, s);
qemu_register_reset(dma_reset, s);
- *dev_irq = qemu_allocate_irqs(dma_set_irq, s, 1);
- *reset = &s->dev_reset;
+ qdev_init_gpio_in(&dev->qdev, dma_set_irq, 1);
+}
- return s;
+static SysBusDeviceInfo sparc32_dma_info = {
+ .init = sparc32_dma_init1,
+ .qdev.name = "sparc32_dma",
+ .qdev.size = sizeof(DMAState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "iommu_opaque",
+ .info = &qdev_prop_ptr,
+ .offset = offsetof(DMAState, iommu),
+ },
+ {/* end of property list */}
+ }
+};
+
+static void sparc32_dma_register_devices(void)
+{
+ sysbus_register_withprop(&sparc32_dma_info);
}
+
+device_init(sparc32_dma_register_devices);
diff --git a/qemu/hw/sparc32_dma.h b/qemu/hw/sparc32_dma.h
index 00b89216..048b9a51 100644
--- a/qemu/hw/sparc32_dma.h
+++ b/qemu/hw/sparc32_dma.h
@@ -3,7 +3,7 @@
/* sparc32_dma.c */
void *sparc32_dma_init(target_phys_addr_t daddr, qemu_irq parent_irq,
- void *iommu, qemu_irq **dev_irq, qemu_irq **reset);
+ void *iommu, qemu_irq *dev_irq, qemu_irq **reset);
void ledma_memory_read(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap);
void ledma_memory_write(void *opaque, target_phys_addr_t addr,
diff --git a/qemu/hw/stellaris.c b/qemu/hw/stellaris.c
index 5f44bff5..d9434ca2 100644
--- a/qemu/hw/stellaris.c
+++ b/qemu/hw/stellaris.c
@@ -1378,7 +1378,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
qemu_check_nic_model(&nd_table[0], "stellaris");
enet = qdev_create(NULL, "stellaris_enet");
- qdev_set_netdev(enet, &nd_table[0]);
+ enet->nd = &nd_table[0];
qdev_init(enet);
sysbus_mmio_map(sysbus_from_qdev(enet), 0, 0x40048000);
sysbus_connect_irq(sysbus_from_qdev(enet), 0, pic[42]);
diff --git a/qemu/hw/sun4m.c b/qemu/hw/sun4m.c
index c67bf0b1..4954ba37 100644
--- a/qemu/hw/sun4m.c
+++ b/qemu/hw/sun4m.c
@@ -373,8 +373,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
qemu_check_nic_model(&nd_table[0], "lance");
dev = qdev_create(NULL, "lance");
- qdev_set_netdev(dev, nd);
- qdev_set_prop_ptr(dev, "dma", dma_opaque);
+ dev->nd = nd;
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, leaddr);
@@ -382,108 +381,241 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
*reset = qdev_get_gpio_in(dev, 0);
}
+/* NCR89C100/MACIO Internal ID register */
+static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
+
+static void idreg_init(target_phys_addr_t addr)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, "macio_idreg");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+
+ sysbus_mmio_map(s, 0, addr);
+ cpu_physical_memory_write_rom(addr, idreg_data, sizeof(idreg_data));
+}
+
+static void idreg_init1(SysBusDevice *dev)
+{
+ ram_addr_t idreg_offset;
+
+ idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
+ sysbus_init_mmio(dev, sizeof(idreg_data), idreg_offset | IO_MEM_ROM);
+}
+
+static SysBusDeviceInfo idreg_info = {
+ .init = idreg_init1,
+ .qdev.name = "macio_idreg",
+ .qdev.size = sizeof(SysBusDevice),
+};
+
+static void idreg_register_devices(void)
+{
+ sysbus_register_withprop(&idreg_info);
+}
+
+device_init(idreg_register_devices);
+
+/* Boot PROM (OpenBIOS) */
+static void prom_init(target_phys_addr_t addr, const char *bios_name)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ char *filename;
+ int ret;
+
+ dev = qdev_create(NULL, "openprom");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+
+ sysbus_mmio_map(s, 0, addr);
+
+ /* load boot prom */
+ if (bios_name == NULL) {
+ bios_name = PROM_FILENAME;
+ }
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (filename) {
+ ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
+ if (ret < 0 || ret > PROM_SIZE_MAX) {
+ ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
+ }
+ qemu_free(filename);
+ } else {
+ ret = -1;
+ }
+ if (ret < 0 || ret > PROM_SIZE_MAX) {
+ fprintf(stderr, "qemu: could not load prom '%s'\n", bios_name);
+ exit(1);
+ }
+}
+
+static void prom_init1(SysBusDevice *dev)
+{
+ ram_addr_t prom_offset;
+
+ prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
+ sysbus_init_mmio(dev, PROM_SIZE_MAX, prom_offset | IO_MEM_ROM);
+}
+
+static SysBusDeviceInfo prom_info = {
+ .init = prom_init1,
+ .qdev.name = "openprom",
+ .qdev.size = sizeof(SysBusDevice),
+ .qdev.props = (Property[]) {
+ {/* end of property list */}
+ }
+};
+
+static void prom_register_devices(void)
+{
+ sysbus_register_withprop(&prom_info);
+}
+
+device_init(prom_register_devices);
+
+typedef struct RamDevice
+{
+ SysBusDevice busdev;
+ uint32_t size;
+} RamDevice;
+
+/* System RAM */
+static void ram_init1(SysBusDevice *dev)
+{
+ ram_addr_t RAM_size, ram_offset;
+ RamDevice *d = FROM_SYSBUS(RamDevice, dev);
+
+ RAM_size = d->size;
+
+ ram_offset = qemu_ram_alloc(RAM_size);
+ sysbus_init_mmio(dev, RAM_size, ram_offset);
+}
+
+static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size,
+ uint64_t max_mem)
+{
+ DeviceState *dev;
+ SysBusDevice *s;
+ RamDevice *d;
+
+ /* allocate RAM */
+ if ((uint64_t)RAM_size > max_mem) {
+ fprintf(stderr,
+ "qemu: Too much memory for this machine: %d, maximum %d\n",
+ (unsigned int)(RAM_size / (1024 * 1024)),
+ (unsigned int)(max_mem / (1024 * 1024)));
+ exit(1);
+ }
+ dev = qdev_create(NULL, "memory");
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+
+ d = FROM_SYSBUS(RamDevice, s);
+ d->size = RAM_size;
+
+ sysbus_mmio_map(s, 0, addr);
+}
+
+static SysBusDeviceInfo ram_info = {
+ .init = ram_init1,
+ .qdev.name = "memory",
+ .qdev.size = sizeof(RamDevice),
+ .qdev.props = (Property[]) {
+ {
+ .name = "size",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(RamDevice, size),
+ },
+ {/* end of property list */}
+ }
+};
+
+static void ram_register_devices(void)
+{
+ sysbus_register_withprop(&ram_info);
+}
+
+device_init(ram_register_devices);
+
+static CPUState *cpu_devinit(const char *cpu_model, unsigned int id,
+ uint64_t prom_addr, qemu_irq **cpu_irqs)
+{
+ CPUState *env;
+
+ env = cpu_init(cpu_model);
+ if (!env) {
+ fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
+ exit(1);
+ }
+
+ cpu_sparc_set_id(env, id);
+ if (id == 0) {
+ qemu_register_reset(main_cpu_reset, env);
+ } else {
+ qemu_register_reset(secondary_cpu_reset, env);
+ env->halted = 1;
+ }
+ *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
+ env->prom_addr = prom_addr;
+
+ return env;
+}
+
static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, 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)
-
{
- CPUState *env, *envs[MAX_CPUS];
+ CPUState *envs[MAX_CPUS];
unsigned int i;
void *iommu, *espdma, *ledma, *nvram;
- qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
- *espdma_irq, *ledma_irq;
+ qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
+ espdma_irq, ledma_irq;
qemu_irq *esp_reset, *le_reset;
- qemu_irq *fdc_tc;
+ qemu_irq fdc_tc;
qemu_irq *cpu_halt;
- ram_addr_t ram_offset, prom_offset, idreg_offset;
unsigned long kernel_size;
- int ret;
- char *filename;
BlockDriverState *fd[MAX_FD];
int drive_index;
void *fw_cfg;
+ DeviceState *dev;
/* init CPUs */
if (!cpu_model)
cpu_model = hwdef->default_cpu_model;
for(i = 0; i < smp_cpus; i++) {
- env = cpu_init(cpu_model);
- if (!env) {
- fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
- exit(1);
- }
- cpu_sparc_set_id(env, i);
- envs[i] = env;
- if (i == 0) {
- qemu_register_reset(main_cpu_reset, env);
- } else {
- qemu_register_reset(secondary_cpu_reset, env);
- env->halted = 1;
- }
- cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
- env->prom_addr = hwdef->slavio_base;
+ envs[i] = cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
}
for (i = smp_cpus; i < MAX_CPUS; i++)
cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
- /* allocate RAM */
- if ((uint64_t)RAM_size > hwdef->max_mem) {
- fprintf(stderr,
- "qemu: Too much memory for this machine: %d, maximum %d\n",
- (unsigned int)(RAM_size / (1024 * 1024)),
- (unsigned int)(hwdef->max_mem / (1024 * 1024)));
- exit(1);
- }
- ram_offset = qemu_ram_alloc(RAM_size);
- cpu_register_physical_memory(0, RAM_size, ram_offset);
+ /* set up devices */
+ ram_init(0, RAM_size, hwdef->max_mem);
- /* load boot prom */
- prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
- cpu_register_physical_memory(hwdef->slavio_base,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
- TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
+ prom_init(hwdef->slavio_base, bios_name);
- if (bios_name == NULL)
- bios_name = PROM_FILENAME;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (filename) {
- ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR,
- NULL, NULL, NULL);
- if (ret < 0 || ret > PROM_SIZE_MAX)
- ret = load_image_targphys(filename, hwdef->slavio_base,
- PROM_SIZE_MAX);
- qemu_free(filename);
- } else {
- ret = -1;
+ dev = slavio_intctl_init(hwdef->intctl_base,
+ hwdef->intctl_base + 0x10000ULL,
+ &hwdef->intbit_to_level[0],
+ cpu_irqs,
+ hwdef->clock_irq);
+
+ for (i = 0; i < 32; i++) {
+ slavio_irq[i] = qdev_get_gpio_in(dev, i);
}
- if (ret < 0 || ret > PROM_SIZE_MAX) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- bios_name);
- exit(1);
+ for (i = 0; i < MAX_CPUS; i++) {
+ slavio_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
}
- /* set up devices */
- slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
- hwdef->intctl_base + 0x10000ULL,
- &hwdef->intbit_to_level[0],
- &slavio_irq, &slavio_cpu_irq,
- cpu_irqs,
- hwdef->clock_irq);
-
if (hwdef->idreg_base) {
- static const uint8_t idreg_data[] = { 0xfe, 0x81, 0x01, 0x03 };
-
- idreg_offset = qemu_ram_alloc(sizeof(idreg_data));
- cpu_register_physical_memory(hwdef->idreg_base, sizeof(idreg_data),
- idreg_offset | IO_MEM_ROM);
- cpu_physical_memory_write_rom(hwdef->idreg_base, idreg_data,
- sizeof(idreg_data));
+ idreg_init(hwdef->idreg_base);
}
iommu = iommu_init(hwdef->iommu_base, hwdef->iommu_version,
@@ -503,7 +635,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
graphic_depth);
- lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
+ lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
hwdef->nvram_size, 8);
@@ -519,10 +651,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
cpu_halt = qemu_allocate_irqs(cpu_halt_signal, NULL, 1);
- slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->apc_base,
+ slavio_misc = slavio_misc_init(hwdef->slavio_base,
hwdef->aux1_base, hwdef->aux2_base,
- slavio_irq[hwdef->me_irq], cpu_halt[0],
- &fdc_tc);
+ slavio_irq[hwdef->me_irq], fdc_tc);
+ if (hwdef->apc_base) {
+ apc_init(hwdef->apc_base, cpu_halt[0]);
+ }
if (hwdef->fd_base) {
/* there is zero or one floppy drive */
@@ -532,7 +666,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
fd[0] = drives_table[drive_index].bdrv;
sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
- fdc_tc);
+ &fdc_tc);
}
if (drive_get_max_bus(IF_SCSI) > 0) {
@@ -542,10 +676,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, *espdma_irq, esp_reset);
+ espdma, espdma_irq, esp_reset);
- if (hwdef->cs_base)
- cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
+ if (hwdef->cs_base) {
+ sysbus_create_simple("SUNW,CS4231", hwdef->cs_base,
+ slavio_irq[hwdef->cs_irq]);
+ }
kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
RAM_size);
@@ -1183,81 +1319,31 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
const char *kernel_cmdline,
const char *initrd_filename, const char *cpu_model)
{
- CPUState *env, *envs[MAX_CPUS];
+ CPUState *envs[MAX_CPUS];
unsigned int i;
void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram, *sbi;
qemu_irq *cpu_irqs[MAX_CPUS], *sbi_irq, *sbi_cpu_irq,
- *espdma_irq, *ledma_irq;
+ espdma_irq, ledma_irq;
qemu_irq *esp_reset, *le_reset;
- ram_addr_t ram_offset, prom_offset;
unsigned long kernel_size;
- int ret;
- char *filename;
void *fw_cfg;
/* init CPUs */
if (!cpu_model)
cpu_model = hwdef->default_cpu_model;
- for (i = 0; i < smp_cpus; i++) {
- env = cpu_init(cpu_model);
- if (!env) {
- fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
- exit(1);
- }
- cpu_sparc_set_id(env, i);
- envs[i] = env;
- if (i == 0) {
- qemu_register_reset(main_cpu_reset, env);
- } else {
- qemu_register_reset(secondary_cpu_reset, env);
- env->halted = 1;
- }
- cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
- env->prom_addr = hwdef->slavio_base;
+ for(i = 0; i < smp_cpus; i++) {
+ envs[i] = cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
}
for (i = smp_cpus; i < MAX_CPUS; i++)
cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
- /* allocate RAM */
- if ((uint64_t)RAM_size > hwdef->max_mem) {
- fprintf(stderr,
- "qemu: Too much memory for this machine: %d, maximum %d\n",
- (unsigned int)(RAM_size / (1024 * 1024)),
- (unsigned int)(hwdef->max_mem / (1024 * 1024)));
- exit(1);
- }
- ram_offset = qemu_ram_alloc(RAM_size);
- cpu_register_physical_memory(0, RAM_size, ram_offset);
-
- /* load boot prom */
- prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
- cpu_register_physical_memory(hwdef->slavio_base,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
- TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
+ /* set up devices */
+ ram_init(0, RAM_size, hwdef->max_mem);
- if (bios_name == NULL)
- bios_name = PROM_FILENAME;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (filename) {
- ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR,
- NULL, NULL, NULL);
- if (ret < 0 || ret > PROM_SIZE_MAX)
- ret = load_image_targphys(filename, hwdef->slavio_base,
- PROM_SIZE_MAX);
- qemu_free(filename);
- } else {
- ret = -1;
- }
- if (ret < 0 || ret > PROM_SIZE_MAX) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- bios_name);
- exit(1);
- }
+ prom_init(hwdef->slavio_base, bios_name);
- /* set up devices */
sbi = sbi_init(hwdef->sbi_base, &sbi_irq, &sbi_cpu_irq, cpu_irqs);
for (i = 0; i < MAX_IOUNITS; i++)
@@ -1279,7 +1365,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
graphic_depth);
- lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
+ lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
nvram = m48t59_init(sbi_irq[0], hwdef->nvram_base, 0,
hwdef->nvram_size, 8);
@@ -1301,7 +1387,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, *espdma_irq, esp_reset);
+ espdma, espdma_irq, esp_reset);
kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
RAM_size);
@@ -1407,13 +1493,10 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
{
CPUState *env;
void *iommu, *espdma, *ledma, *nvram;
- qemu_irq *cpu_irqs, *slavio_irq, *espdma_irq, *ledma_irq;
+ qemu_irq *cpu_irqs, *slavio_irq, espdma_irq, ledma_irq;
qemu_irq *esp_reset, *le_reset;
- qemu_irq *fdc_tc;
- ram_addr_t ram_offset, prom_offset;
+ qemu_irq fdc_tc;
unsigned long kernel_size;
- int ret;
- char *filename;
BlockDriverState *fd[MAX_FD];
int drive_index;
void *fw_cfg;
@@ -1422,56 +1505,13 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
if (!cpu_model)
cpu_model = hwdef->default_cpu_model;
- env = cpu_init(cpu_model);
- if (!env) {
- fprintf(stderr, "qemu: Unable to find Sparc CPU definition\n");
- exit(1);
- }
-
- cpu_sparc_set_id(env, 0);
-
- qemu_register_reset(main_cpu_reset, env);
- cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
- env->prom_addr = hwdef->slavio_base;
-
- /* allocate RAM */
- if ((uint64_t)RAM_size > hwdef->max_mem) {
- fprintf(stderr,
- "qemu: Too much memory for this machine: %d, maximum %d\n",
- (unsigned int)(RAM_size / (1024 * 1024)),
- (unsigned int)(hwdef->max_mem / (1024 * 1024)));
- exit(1);
- }
- ram_offset = qemu_ram_alloc(RAM_size);
- cpu_register_physical_memory(0, RAM_size, ram_offset);
+ env = cpu_devinit(cpu_model, 0, hwdef->slavio_base, &cpu_irqs);
- /* load boot prom */
- prom_offset = qemu_ram_alloc(PROM_SIZE_MAX);
- cpu_register_physical_memory(hwdef->slavio_base,
- (PROM_SIZE_MAX + TARGET_PAGE_SIZE - 1) &
- TARGET_PAGE_MASK,
- prom_offset | IO_MEM_ROM);
+ /* set up devices */
+ ram_init(0, RAM_size, hwdef->max_mem);
- if (bios_name == NULL)
- bios_name = PROM_FILENAME;
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- if (filename) {
- ret = load_elf(filename, hwdef->slavio_base - PROM_VADDR,
- NULL, NULL, NULL);
- if (ret < 0 || ret > PROM_SIZE_MAX)
- ret = load_image_targphys(filename, hwdef->slavio_base,
- PROM_SIZE_MAX);
- qemu_free(filename);
- } else {
- ret = -1;
- }
- if (ret < 0 || ret > PROM_SIZE_MAX) {
- fprintf(stderr, "qemu: could not load prom '%s'\n",
- filename);
- exit(1);
- }
+ prom_init(hwdef->slavio_base, bios_name);
- /* set up devices */
slavio_intctl = sun4c_intctl_init(hwdef->intctl_base,
&slavio_irq, cpu_irqs);
@@ -1492,7 +1532,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
tcx_init(hwdef->tcx_base, hwdef->vram_size, graphic_width, graphic_height,
graphic_depth);
- lance_init(&nd_table[0], hwdef->le_base, ledma, *ledma_irq, le_reset);
+ lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq, le_reset);
nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
hwdef->nvram_size, 2);
@@ -1505,8 +1545,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
slavio_irq[hwdef->ser_irq], serial_hds[0], serial_hds[1],
ESCC_CLOCK, 1);
- slavio_misc = slavio_misc_init(0, 0, hwdef->aux1_base, 0,
- slavio_irq[hwdef->me_irq], NULL, &fdc_tc);
+ slavio_misc = slavio_misc_init(0, hwdef->aux1_base, 0,
+ slavio_irq[hwdef->me_irq], fdc_tc);
if (hwdef->fd_base != (target_phys_addr_t)-1) {
/* there is zero or one floppy drive */
@@ -1516,7 +1556,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
fd[0] = drives_table[drive_index].bdrv;
sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
- fdc_tc);
+ &fdc_tc);
}
if (drive_get_max_bus(IF_SCSI) > 0) {
@@ -1526,7 +1566,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
esp_init(hwdef->esp_base, 2,
espdma_memory_read, espdma_memory_write,
- espdma, *espdma_irq, esp_reset);
+ espdma, espdma_irq, esp_reset);
kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
RAM_size);
diff --git a/qemu/hw/sun4m.h b/qemu/hw/sun4m.h
index c5605f48..d818fb18 100644
--- a/qemu/hw/sun4m.h
+++ b/qemu/hw/sun4m.h
@@ -28,10 +28,10 @@ void tcx_init(target_phys_addr_t addr, int vram_size, int width, int height,
int depth);
/* slavio_intctl.c */
-void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
- const uint32_t *intbit_to_level,
- qemu_irq **irq, qemu_irq **cpu_irq,
- qemu_irq **parent_irq, unsigned int cputimer);
+DeviceState *slavio_intctl_init(target_phys_addr_t addr,
+ target_phys_addr_t addrg,
+ const uint32_t *intbit_to_level,
+ qemu_irq **parent_irq, unsigned int cputimer);
void slavio_pic_info(Monitor *mon, void *opaque);
void slavio_irq_info(Monitor *mon, void *opaque);
@@ -50,19 +50,17 @@ void slavio_timer_init_all(target_phys_addr_t base, qemu_irq master_irq,
qemu_irq *cpu_irqs, unsigned int num_cpus);
/* slavio_misc.c */
-void *slavio_misc_init(target_phys_addr_t base, target_phys_addr_t power_base,
+void *slavio_misc_init(target_phys_addr_t base,
target_phys_addr_t aux1_base,
target_phys_addr_t aux2_base, qemu_irq irq,
- qemu_irq cpu_halt, qemu_irq **fdc_tc);
+ qemu_irq fdc_tc);
void slavio_set_power_fail(void *opaque, int power_failing);
-
-/* cs4231.c */
-void cs_init(target_phys_addr_t base, int irq, void *intctl);
+void apc_init(target_phys_addr_t power_base, qemu_irq cpu_halt);
/* sparc32_dma.c */
#include "sparc32_dma.h"
/* eccmemctl.c */
-void *ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version);
+void ecc_init(target_phys_addr_t base, qemu_irq irq, uint32_t version);
#endif
diff --git a/qemu/hw/sun4u.c b/qemu/hw/sun4u.c
index 40f0c593..9d2a7f59 100644
--- a/qemu/hw/sun4u.c
+++ b/qemu/hw/sun4u.c
@@ -305,9 +305,12 @@ static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
static void
pci_ebus_init(PCIBus *bus, int devfn)
{
- PCIDevice *s;
+ pci_create_simple(bus, devfn, "ebus");
+}
- s = pci_register_device(bus, "EBUS", sizeof(*s), devfn, NULL, NULL);
+static void
+pci_ebus_init1(PCIDevice *s)
+{
pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN);
pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS);
s->config[0x04] = 0x06; // command = bus master, pci mem
@@ -326,6 +329,19 @@ pci_ebus_init(PCIBus *bus, int devfn)
ebus_mmio_mapfunc);
}
+static PCIDeviceInfo ebus_info = {
+ .qdev.name = "ebus",
+ .qdev.size = sizeof(PCIDevice),
+ .init = pci_ebus_init1,
+};
+
+static void pci_ebus_register(void)
+{
+ pci_qdev_register(&ebus_info);
+}
+
+device_init(pci_ebus_register);
+
static void sun4uv_init(ram_addr_t RAM_size,
const char *boot_devices,
const char *kernel_filename, const char *kernel_cmdline,
@@ -450,7 +466,9 @@ static void sun4uv_init(ram_addr_t RAM_size,
}
}
}
- pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, NULL, &pci_bus2,
+
+ irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
+ pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, &pci_bus2,
&pci_bus3);
isa_mem_base = VGA_BASE;
pci_vga_init(pci_bus, 0, 0);
@@ -481,7 +499,6 @@ static void sun4uv_init(ram_addr_t RAM_size,
for(i = 0; i < nb_nics; i++)
pci_nic_init(&nd_table[i], "ne2k_pci", NULL);
- irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
fprintf(stderr, "qemu: too many IDE bus\n");
exit(1);
diff --git a/qemu/hw/syborg.c b/qemu/hw/syborg.c
index 5ca9977b..d8d38d48 100644
--- a/qemu/hw/syborg.c
+++ b/qemu/hw/syborg.c
@@ -64,7 +64,7 @@ static void syborg_init(ram_addr_t ram_size,
sysbus_create_simple("syborg,rtc", 0xC0001000, NULL);
dev = qdev_create(NULL, "syborg,timer");
- qdev_set_prop_int(dev, "frequency", 1000000);
+ qdev_prop_set_uint32(dev, "frequency", 1000000);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xC0002000);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[1]);
@@ -83,7 +83,7 @@ static void syborg_init(ram_addr_t ram_size,
qemu_check_nic_model(&nd_table[0], "virtio");
dev = qdev_create(NULL, "syborg,virtio-net");
- qdev_set_netdev(dev, &nd_table[0]);
+ dev->nd = &nd_table[0];
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, 0xc000c000);
diff --git a/qemu/hw/syborg_fb.c b/qemu/hw/syborg_fb.c
index 42c62744..2929ffd0 100644
--- a/qemu/hw/syborg_fb.c
+++ b/qemu/hw/syborg_fb.c
@@ -76,8 +76,8 @@ typedef struct {
uint32_t base;
uint32_t pitch;
- int rows;
- int cols;
+ uint32_t rows;
+ uint32_t cols;
int blank;
int bpp;
int rgb; /* 0 = BGR, 1 = RGB */
@@ -507,41 +507,50 @@ static void syborg_fb_init(SysBusDevice *dev)
{
SyborgFBState *s = FROM_SYSBUS(SyborgFBState, dev);
int iomemtype;
- int width;
- int height;
sysbus_init_irq(dev, &s->irq);
iomemtype = cpu_register_io_memory(syborg_fb_readfn,
syborg_fb_writefn, s);
sysbus_init_mmio(dev, 0x1000, iomemtype);
- width = qdev_get_prop_int(&dev->qdev, "width", 0);
- height = qdev_get_prop_int(&dev->qdev, "height", 0);
-
s->ds = graphic_console_init(syborg_fb_update_display,
syborg_fb_invalidate_display,
NULL, NULL, s);
- if (width != 0 && height != 0) {
- qemu_console_resize(s->ds, width, height);
+ if (s->cols != 0 && s->rows != 0) {
+ qemu_console_resize(s->ds, s->cols, s->rows);
}
- if (!width)
- width = ds_get_width(s->ds);
- if (!height)
- height = ds_get_height(s->ds);
-
- s->cols = width;
- s->rows = height;
+ if (!s->cols)
+ s->cols = ds_get_width(s->ds);
+ if (!s->rows)
+ s->rows = ds_get_height(s->ds);
register_savevm("syborg_framebuffer", -1, 1,
syborg_fb_save, syborg_fb_load, s);
}
+static SysBusDeviceInfo syborg_fb_info = {
+ .init = syborg_fb_init,
+ .qdev.name = "syborg,framebuffer",
+ .qdev.size = sizeof(SyborgFBState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "width",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgFBState, cols),
+ },{
+ .name = "height",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgFBState, rows),
+ },
+ {/* end of list */}
+ }
+};
+
static void syborg_fb_register_devices(void)
{
- sysbus_register_dev("syborg,framebuffer", sizeof(SyborgFBState),
- syborg_fb_init);
+ sysbus_register_withprop(&syborg_fb_info);
}
device_init(syborg_fb_register_devices)
diff --git a/qemu/hw/syborg_interrupt.c b/qemu/hw/syborg_interrupt.c
index 569c7f61..a372ec1d 100644
--- a/qemu/hw/syborg_interrupt.c
+++ b/qemu/hw/syborg_interrupt.c
@@ -56,7 +56,7 @@ typedef struct {
typedef struct {
SysBusDevice busdev;
int pending_count;
- int num_irqs;
+ uint32_t num_irqs;
syborg_int_flags *flags;
qemu_irq parent_irq;
} SyborgIntState;
@@ -208,7 +208,6 @@ static void syborg_int_init(SysBusDevice *dev)
int iomemtype;
sysbus_init_irq(dev, &s->parent_irq);
- s->num_irqs = qdev_get_prop_int(&dev->qdev, "num-interrupts", 64);
qdev_init_gpio_in(&dev->qdev, syborg_int_set_irq, s->num_irqs);
iomemtype = cpu_register_io_memory(syborg_int_readfn,
syborg_int_writefn, s);
@@ -218,10 +217,24 @@ static void syborg_int_init(SysBusDevice *dev)
register_savevm("syborg_int", -1, 1, syborg_int_save, syborg_int_load, s);
}
+static SysBusDeviceInfo syborg_int_info = {
+ .init = syborg_int_init,
+ .qdev.name = "syborg,interrupt",
+ .qdev.size = sizeof(SyborgIntState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "num-interrupts",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgIntState, num_irqs),
+ .defval = (uint32_t[]) { 64 },
+ },
+ {/* end of list */}
+ }
+};
+
static void syborg_interrupt_register_devices(void)
{
- sysbus_register_dev("syborg,interrupt", sizeof(SyborgIntState),
- syborg_int_init);
+ sysbus_register_withprop(&syborg_int_info);
}
device_init(syborg_interrupt_register_devices)
diff --git a/qemu/hw/syborg_keyboard.c b/qemu/hw/syborg_keyboard.c
index 84a099ed..ffc85a56 100644
--- a/qemu/hw/syborg_keyboard.c
+++ b/qemu/hw/syborg_keyboard.c
@@ -53,7 +53,7 @@ typedef struct {
SysBusDevice busdev;
int int_enabled;
int extension_bit;
- int fifo_size;
+ uint32_t fifo_size;
uint32_t *key_fifo;
int read_pos, read_count;
qemu_irq irq;
@@ -212,7 +212,6 @@ static void syborg_keyboard_init(SysBusDevice *dev)
iomemtype = cpu_register_io_memory(syborg_keyboard_readfn,
syborg_keyboard_writefn, s);
sysbus_init_mmio(dev, 0x1000, iomemtype);
- s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16);
if (s->fifo_size <= 0) {
fprintf(stderr, "syborg_keyboard: fifo too small\n");
s->fifo_size = 16;
@@ -225,10 +224,24 @@ static void syborg_keyboard_init(SysBusDevice *dev)
syborg_keyboard_save, syborg_keyboard_load, s);
}
+static SysBusDeviceInfo syborg_keyboard_info = {
+ .init = syborg_keyboard_init,
+ .qdev.name = "syborg,keyboard",
+ .qdev.size = sizeof(SyborgKeyboardState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "fifo-size",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgKeyboardState, fifo_size),
+ .defval = (uint32_t[]) { 16 },
+ },
+ {/* end of list */}
+ }
+};
+
static void syborg_keyboard_register_devices(void)
{
- sysbus_register_dev("syborg,keyboard", sizeof(SyborgKeyboardState),
- syborg_keyboard_init);
+ sysbus_register_withprop(&syborg_keyboard_info);
}
device_init(syborg_keyboard_register_devices)
diff --git a/qemu/hw/syborg_pointer.c b/qemu/hw/syborg_pointer.c
index e0a892d0..edd1f222 100644
--- a/qemu/hw/syborg_pointer.c
+++ b/qemu/hw/syborg_pointer.c
@@ -45,11 +45,11 @@ typedef struct {
typedef struct {
SysBusDevice busdev;
int int_enabled;
- int fifo_size;
+ uint32_t fifo_size;
event_data *event_fifo;
int read_pos, read_count;
qemu_irq irq;
- int absolute;
+ uint32_t absolute;
} SyborgPointerState;
static void syborg_pointer_update(SyborgPointerState *s)
@@ -209,8 +209,6 @@ static void syborg_pointer_init(SysBusDevice *dev)
syborg_pointer_writefn, s);
sysbus_init_mmio(dev, 0x1000, iomemtype);
- s->absolute = qdev_get_prop_int(&dev->qdev, "absolute", 1);
- s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16);
if (s->fifo_size <= 0) {
fprintf(stderr, "syborg_pointer: fifo too small\n");
s->fifo_size = 16;
@@ -224,10 +222,29 @@ static void syborg_pointer_init(SysBusDevice *dev)
syborg_pointer_save, syborg_pointer_load, s);
}
+static SysBusDeviceInfo syborg_pointer_info = {
+ .init = syborg_pointer_init,
+ .qdev.name = "syborg,pointer",
+ .qdev.size = sizeof(SyborgPointerState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "fifo-size",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgPointerState, fifo_size),
+ .defval = (uint32_t[]) { 16 },
+ },{
+ .name = "absolute",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgPointerState, absolute),
+ .defval = (uint32_t[]) { 1 },
+ },
+ {/* end of list */}
+ }
+};
+
static void syborg_pointer_register_devices(void)
{
- sysbus_register_dev("syborg,pointer", sizeof(SyborgPointerState),
- syborg_pointer_init);
+ sysbus_register_withprop(&syborg_pointer_info);
}
device_init(syborg_pointer_register_devices)
diff --git a/qemu/hw/syborg_serial.c b/qemu/hw/syborg_serial.c
index f4305080..f6934215 100644
--- a/qemu/hw/syborg_serial.c
+++ b/qemu/hw/syborg_serial.c
@@ -59,7 +59,7 @@ enum {
typedef struct {
SysBusDevice busdev;
uint32_t int_enable;
- int fifo_size;
+ uint32_t fifo_size;
uint32_t *read_fifo;
int read_pos;
int read_count;
@@ -329,7 +329,6 @@ static void syborg_serial_init(SysBusDevice *dev)
qemu_chr_add_handlers(s->chr, syborg_serial_can_receive,
syborg_serial_receive, syborg_serial_event, s);
}
- s->fifo_size = qdev_get_prop_int(&dev->qdev, "fifo-size", 16);
if (s->fifo_size <= 0) {
fprintf(stderr, "syborg_serial: fifo too small\n");
s->fifo_size = 16;
@@ -340,10 +339,24 @@ static void syborg_serial_init(SysBusDevice *dev)
syborg_serial_save, syborg_serial_load, s);
}
+static SysBusDeviceInfo syborg_serial_info = {
+ .init = syborg_serial_init,
+ .qdev.name = "syborg,serial",
+ .qdev.size = sizeof(SyborgSerialState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "fifo-size",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgSerialState, fifo_size),
+ .defval = (uint32_t[]) { 16 },
+ },
+ {/* end of list */}
+ }
+};
+
static void syborg_serial_register_devices(void)
{
- sysbus_register_dev("syborg,serial", sizeof(SyborgSerialState),
- syborg_serial_init);
+ sysbus_register_withprop(&syborg_serial_info);
}
device_init(syborg_serial_register_devices)
diff --git a/qemu/hw/syborg_timer.c b/qemu/hw/syborg_timer.c
index 4f5e3a17..cf96c5ff 100644
--- a/qemu/hw/syborg_timer.c
+++ b/qemu/hw/syborg_timer.c
@@ -209,7 +209,6 @@ static void syborg_timer_init(SysBusDevice *dev)
QEMUBH *bh;
int iomemtype;
- s->freq = qdev_get_prop_int(&dev->qdev, "frequency", 0);
if (s->freq == 0) {
fprintf(stderr, "syborg_timer: Zero/unset frequency\n");
exit(1);
@@ -230,9 +229,13 @@ static SysBusDeviceInfo syborg_timer_info = {
.init = syborg_timer_init,
.qdev.name = "syborg,timer",
.qdev.size = sizeof(SyborgTimerState),
- .qdev.props = (DevicePropList[]) {
- {.name = "frequency", .type = PROP_TYPE_INT},
- {.name = NULL}
+ .qdev.props = (Property[]) {
+ {
+ .name = "frequency",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(SyborgTimerState, freq),
+ },
+ {/* end of list */}
}
};
diff --git a/qemu/hw/sysbus.c b/qemu/hw/sysbus.c
index 08f15e42..814d3470 100644
--- a/qemu/hw/sysbus.c
+++ b/qemu/hw/sysbus.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include "sysbus.h"
diff --git a/qemu/hw/sysbus.h b/qemu/hw/sysbus.h
index 7c20808f..d48ca8ca 100644
--- a/qemu/hw/sysbus.h
+++ b/qemu/hw/sysbus.h
@@ -5,8 +5,8 @@
#include "qdev.h"
-#define QDEV_MAX_MMIO 5
-#define QDEV_MAX_IRQ 32
+#define QDEV_MAX_MMIO 32
+#define QDEV_MAX_IRQ 256
typedef struct SysBusDevice SysBusDevice;
typedef void (*mmio_mapfunc)(SysBusDevice *dev, target_phys_addr_t addr);
diff --git a/qemu/hw/tcx.c b/qemu/hw/tcx.c
index 10bc9813..c5925240 100644
--- a/qemu/hw/tcx.c
+++ b/qemu/hw/tcx.c
@@ -21,10 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "hw.h"
+
#include "sun4m.h"
#include "console.h"
#include "pixel_ops.h"
+#include "sysbus.h"
+#include "qdev-addr.h"
#define MAXX 1024
#define MAXY 768
@@ -34,11 +36,13 @@
#define TCX_TEC_NREGS 0x1000
typedef struct TCXState {
+ SysBusDevice busdev;
target_phys_addr_t addr;
DisplayState *ds;
uint8_t *vram;
uint32_t *vram24, *cplane;
ram_addr_t vram_offset, vram24_offset, cplane_offset;
+ uint32_t vram_size;
uint16_t width, height, depth;
uint8_t r[256], g[256], b[256];
uint32_t palette[256];
@@ -47,8 +51,25 @@ typedef struct TCXState {
static void tcx_screen_dump(void *opaque, const char *filename);
static void tcx24_screen_dump(void *opaque, const char *filename);
-static void tcx_invalidate_display(void *opaque);
-static void tcx24_invalidate_display(void *opaque);
+
+static void tcx_set_dirty(TCXState *s)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAXX * MAXY; i += TARGET_PAGE_SIZE) {
+ cpu_physical_memory_set_dirty(s->vram_offset + i);
+ }
+}
+
+static void tcx24_set_dirty(TCXState *s)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAXX * MAXY * 4; i += TARGET_PAGE_SIZE) {
+ cpu_physical_memory_set_dirty(s->vram24_offset + i);
+ cpu_physical_memory_set_dirty(s->cplane_offset + i);
+ }
+}
static void update_palette_entries(TCXState *s, int start, int end)
{
@@ -73,10 +94,11 @@ static void update_palette_entries(TCXState *s, int start, int end)
break;
}
}
- if (s->depth == 24)
- tcx24_invalidate_display(s);
- else
- tcx_invalidate_display(s);
+ if (s->depth == 24) {
+ tcx24_set_dirty(s);
+ } else {
+ tcx_set_dirty(s);
+ }
}
static void tcx_draw_line32(TCXState *s1, uint8_t *d,
@@ -342,23 +364,18 @@ static void tcx24_update_display(void *opaque)
static void tcx_invalidate_display(void *opaque)
{
TCXState *s = opaque;
- int i;
- for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
- cpu_physical_memory_set_dirty(s->vram_offset + i);
- }
+ tcx_set_dirty(s);
+ qemu_console_resize(s->ds, s->width, s->height);
}
static void tcx24_invalidate_display(void *opaque)
{
TCXState *s = opaque;
- int i;
- tcx_invalidate_display(s);
- for (i = 0; i < MAXX*MAXY * 4; i += TARGET_PAGE_SIZE) {
- cpu_physical_memory_set_dirty(s->vram24_offset + i);
- cpu_physical_memory_set_dirty(s->cplane_offset + i);
- }
+ tcx_set_dirty(s);
+ tcx24_set_dirty(s);
+ qemu_console_resize(s->ds, s->width, s->height);
}
static void tcx_save(QEMUFile *f, void *opaque)
@@ -397,10 +414,11 @@ static int tcx_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_8s(f, &s->dac_index);
qemu_get_8s(f, &s->dac_state);
update_palette_entries(s, 0, 256);
- if (s->depth == 24)
- tcx24_invalidate_display(s);
- else
- tcx_invalidate_display(s);
+ if (s->depth == 24) {
+ tcx24_set_dirty(s);
+ } else {
+ tcx_set_dirty(s);
+ }
return 0;
}
@@ -500,69 +518,97 @@ static CPUWriteMemoryFunc *tcx_dummy_write[3] = {
void tcx_init(target_phys_addr_t addr, int vram_size, int width, int height,
int depth)
{
- TCXState *s;
+ DeviceState *dev;
+ SysBusDevice *s;
+
+ dev = qdev_create(NULL, "SUNW,tcx");
+ qdev_prop_set_taddr(dev, "addr", addr);
+ qdev_prop_set_uint32(dev, "vram_size", vram_size);
+ qdev_prop_set_uint16(dev, "width", width);
+ qdev_prop_set_uint16(dev, "height", height);
+ qdev_prop_set_uint16(dev, "depth", depth);
+ qdev_init(dev);
+ s = sysbus_from_qdev(dev);
+ /* 8-bit plane */
+ sysbus_mmio_map(s, 0, addr + 0x00800000ULL);
+ /* DAC */
+ sysbus_mmio_map(s, 1, addr + 0x00200000ULL);
+ /* TEC (dummy) */
+ sysbus_mmio_map(s, 2, addr + 0x00700000ULL);
+ /* THC 24 bit: NetBSD writes here even with 8-bit display: dummy */
+ sysbus_mmio_map(s, 3, addr + 0x00301000ULL);
+ if (depth == 24) {
+ /* 24-bit plane */
+ sysbus_mmio_map(s, 4, addr + 0x02000000ULL);
+ /* Control plane */
+ sysbus_mmio_map(s, 5, addr + 0x0a000000ULL);
+ } else {
+ /* THC 8 bit (dummy) */
+ sysbus_mmio_map(s, 4, addr + 0x00300000ULL);
+ }
+}
+
+static void tcx_init1(SysBusDevice *dev)
+{
+ TCXState *s = FROM_SYSBUS(TCXState, dev);
int io_memory, dummy_memory;
ram_addr_t vram_offset;
int size;
uint8_t *vram_base;
- vram_offset = qemu_ram_alloc(vram_size * (1 + 4 + 4));
+ vram_offset = qemu_ram_alloc(s->vram_size * (1 + 4 + 4));
vram_base = qemu_get_ram_ptr(vram_offset);
-
- s = qemu_mallocz(sizeof(TCXState));
- s->addr = addr;
s->vram_offset = vram_offset;
- s->width = width;
- s->height = height;
- s->depth = depth;
- // 8-bit plane
+ /* 8-bit plane */
s->vram = vram_base;
- size = vram_size;
- cpu_register_physical_memory(addr + 0x00800000ULL, size, vram_offset);
+ size = s->vram_size;
+ sysbus_init_mmio(dev, size, s->vram_offset);
vram_offset += size;
vram_base += size;
+ /* DAC */
io_memory = cpu_register_io_memory(tcx_dac_read, tcx_dac_write, s);
- cpu_register_physical_memory(addr + 0x00200000ULL, TCX_DAC_NREGS,
- io_memory);
+ sysbus_init_mmio(dev, TCX_DAC_NREGS, io_memory);
+ /* TEC (dummy) */
dummy_memory = cpu_register_io_memory(tcx_dummy_read, tcx_dummy_write,
s);
- cpu_register_physical_memory(addr + 0x00700000ULL, TCX_TEC_NREGS,
- dummy_memory);
- if (depth == 24) {
- // 24-bit plane
- size = vram_size * 4;
+ sysbus_init_mmio(dev, TCX_TEC_NREGS, dummy_memory);
+ /* THC: NetBSD writes here even with 8-bit display: dummy */
+ sysbus_init_mmio(dev, TCX_THC_NREGS_24, dummy_memory);
+
+ if (s->depth == 24) {
+ /* 24-bit plane */
+ size = s->vram_size * 4;
s->vram24 = (uint32_t *)vram_base;
s->vram24_offset = vram_offset;
- cpu_register_physical_memory(addr + 0x02000000ULL, size, vram_offset);
+ sysbus_init_mmio(dev, size, vram_offset);
vram_offset += size;
vram_base += size;
- // Control plane
- size = vram_size * 4;
+ /* Control plane */
+ size = s->vram_size * 4;
s->cplane = (uint32_t *)vram_base;
s->cplane_offset = vram_offset;
- cpu_register_physical_memory(addr + 0x0a000000ULL, size, vram_offset);
+ sysbus_init_mmio(dev, size, vram_offset);
+
s->ds = graphic_console_init(tcx24_update_display,
tcx24_invalidate_display,
tcx24_screen_dump, NULL, s);
} else {
- cpu_register_physical_memory(addr + 0x00300000ULL, TCX_THC_NREGS_8,
- dummy_memory);
+ /* THC 8 bit (dummy) */
+ sysbus_init_mmio(dev, TCX_THC_NREGS_8, dummy_memory);
+
s->ds = graphic_console_init(tcx_update_display,
tcx_invalidate_display,
tcx_screen_dump, NULL, s);
}
- // NetBSD writes here even with 8-bit display
- cpu_register_physical_memory(addr + 0x00301000ULL, TCX_THC_NREGS_24,
- dummy_memory);
- register_savevm("tcx", addr, 4, tcx_save, tcx_load, s);
+ register_savevm("tcx", -1, 4, tcx_save, tcx_load, s);
qemu_register_reset(tcx_reset, s);
tcx_reset(s);
- qemu_console_resize(s->ds, width, height);
+ qemu_console_resize(s->ds, s->width, s->height);
}
static void tcx_screen_dump(void *opaque, const char *filename)
@@ -627,3 +673,45 @@ static void tcx24_screen_dump(void *opaque, const char *filename)
fclose(f);
return;
}
+
+static SysBusDeviceInfo tcx_info = {
+ .init = tcx_init1,
+ .qdev.name = "SUNW,tcx",
+ .qdev.size = sizeof(TCXState),
+ .qdev.props = (Property[]) {
+ {
+ .name = "addr",
+ .info = &qdev_prop_taddr,
+ .offset = offsetof(TCXState, addr),
+ .defval = (target_phys_addr_t[]) { -1 },
+ },{
+ .name = "vram_size",
+ .info = &qdev_prop_hex32,
+ .offset = offsetof(TCXState, vram_size),
+ .defval = (uint32_t[]) { -1 },
+ },{
+ .name = "width",
+ .info = &qdev_prop_uint16,
+ .offset = offsetof(TCXState, width),
+ .defval = (uint16_t[]) { -1 },
+ },{
+ .name = "height",
+ .info = &qdev_prop_uint16,
+ .offset = offsetof(TCXState, height),
+ .defval = (uint16_t[]) { -1 },
+ },{
+ .name = "depth",
+ .info = &qdev_prop_uint16,
+ .offset = offsetof(TCXState, depth),
+ .defval = (uint16_t[]) { -1 },
+ },
+ {/* end of list */}
+ }
+};
+
+static void tcx_register_devices(void)
+{
+ sysbus_register_withprop(&tcx_info);
+}
+
+device_init(tcx_register_devices)
diff --git a/qemu/hw/usb-ohci.c b/qemu/hw/usb-ohci.c
index 23b5e214..28ab3a91 100644
--- a/qemu/hw/usb-ohci.c
+++ b/qemu/hw/usb-ohci.c
@@ -15,8 +15,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*
* TODO:
* o Isochronous transfers
@@ -1150,9 +1149,9 @@ static void ohci_frame_boundary(void *opaque)
/* Frame boundary, so do EOF stuf here */
ohci->frt = ohci->fit;
- /* XXX: endianness */
+ /* Increment frame number and take care of endianness. */
ohci->frame_number = (ohci->frame_number + 1) & 0xffff;
- hcca.frame = cpu_to_le32(ohci->frame_number);
+ hcca.frame = cpu_to_le16(ohci->frame_number);
if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) {
if (!ohci->done)
diff --git a/qemu/hw/virtio-pci.c b/qemu/hw/virtio-pci.c
index e2cc036f..579e5bc7 100644
--- a/qemu/hw/virtio-pci.c
+++ b/qemu/hw/virtio-pci.c
@@ -86,12 +86,7 @@ typedef struct {
PCIDevice pci_dev;
VirtIODevice *vdev;
uint32_t addr;
-
- uint16_t vendor;
- uint16_t device;
- uint16_t subvendor;
- uint16_t class_code;
- uint8_t pif;
+ uint32_t class_code;
} VirtIOPCIProxy;
/* virtio device */
@@ -126,11 +121,18 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
VirtIOPCIProxy *proxy = opaque;
int ret;
ret = pci_device_load(&proxy->pci_dev, f);
- if (ret)
+ if (ret) {
return ret;
+ }
msix_load(&proxy->pci_dev, f);
- if (msix_present(&proxy->pci_dev))
+ if (msix_present(&proxy->pci_dev)) {
qemu_get_be16s(f, &proxy->vdev->config_vector);
+ } else {
+ proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
+ }
+ if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
+ return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
+ }
return 0;
}
@@ -138,10 +140,15 @@ static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
{
VirtIOPCIProxy *proxy = opaque;
uint16_t vector;
- if (!msix_present(&proxy->pci_dev))
- return 0;
- qemu_get_be16s(f, &vector);
+ if (msix_present(&proxy->pci_dev)) {
+ qemu_get_be16s(f, &vector);
+ } else {
+ vector = VIRTIO_NO_VECTOR;
+ }
virtio_queue_set_vector(proxy->vdev, n, vector);
+ if (vector != VIRTIO_NO_VECTOR) {
+ return msix_vector_use(&proxy->pci_dev, vector);
+ }
return 0;
}
@@ -414,7 +421,8 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
}
-static void virtio_blk_init_pci(PCIDevice *pci_dev)
+static void virtio_blk_init_pci_with_class(PCIDevice *pci_dev,
+ uint16_t class_code)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
VirtIODevice *vdev;
@@ -423,11 +431,27 @@ static void virtio_blk_init_pci(PCIDevice *pci_dev)
virtio_init_pci(proxy, vdev,
PCI_VENDOR_ID_REDHAT_QUMRANET,
PCI_DEVICE_ID_VIRTIO_BLOCK,
- PCI_CLASS_STORAGE_OTHER,
- 0x00);
+ class_code, 0x00);
}
-static void virtio_console_init_pci(PCIDevice *pci_dev)
+static void virtio_blk_init_pci(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
+ proxy->class_code != PCI_CLASS_STORAGE_OTHER)
+ proxy->class_code = PCI_CLASS_STORAGE_SCSI;
+
+ virtio_blk_init_pci_with_class(pci_dev, proxy->class_code);
+}
+
+static void virtio_blk_init_pci_0_10(PCIDevice *pci_dev)
+{
+ virtio_blk_init_pci_with_class(pci_dev, PCI_CLASS_STORAGE_OTHER);
+}
+
+static void virtio_console_init_pci_with_class(PCIDevice *pci_dev,
+ uint16_t class_code)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
VirtIODevice *vdev;
@@ -436,8 +460,24 @@ static void virtio_console_init_pci(PCIDevice *pci_dev)
virtio_init_pci(proxy, vdev,
PCI_VENDOR_ID_REDHAT_QUMRANET,
PCI_DEVICE_ID_VIRTIO_CONSOLE,
- PCI_CLASS_DISPLAY_OTHER,
- 0x00);
+ class_code, 0x00);
+}
+
+static void virtio_console_init_pci(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+ if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
+ proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
+ proxy->class_code != PCI_CLASS_OTHERS) /* qemu-kvm */
+ proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
+
+ virtio_console_init_pci_with_class(pci_dev, proxy->class_code);
+}
+
+static void virtio_console_init_pci_0_10(PCIDevice *pci_dev)
+{
+ virtio_console_init_pci_with_class(pci_dev, PCI_CLASS_DISPLAY_OTHER);
}
static void virtio_net_init_pci(PCIDevice *pci_dev)
@@ -471,6 +511,14 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.name = "virtio-blk-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_blk_init_pci,
+ .qdev.props = (Property[]) {
+ {
+ .name = "class",
+ .info = &qdev_prop_hex32,
+ .offset = offsetof(VirtIOPCIProxy, class_code),
+ },
+ {/* end of list */}
+ },
},{
.qdev.name = "virtio-net-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
@@ -479,10 +527,27 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.name = "virtio-console-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_console_init_pci,
+ .qdev.props = (Property[]) {
+ {
+ .name = "class",
+ .info = &qdev_prop_hex32,
+ .offset = offsetof(VirtIOPCIProxy, class_code),
+ },
+ {/* end of list */}
+ },
},{
.qdev.name = "virtio-balloon-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_balloon_init_pci,
+ },{
+ /* For compatibility with 0.10 */
+ .qdev.name = "virtio-blk-pci-0-10",
+ .qdev.size = sizeof(VirtIOPCIProxy),
+ .init = virtio_blk_init_pci_0_10,
+ },{
+ .qdev.name = "virtio-console-pci-0-10",
+ .qdev.size = sizeof(VirtIOPCIProxy),
+ .init = virtio_console_init_pci_0_10,
},{
/* end of list */
}
diff --git a/qemu/hw/xilinx.h b/qemu/hw/xilinx.h
index 9707a0e0..070679c2 100644
--- a/qemu/hw/xilinx.h
+++ b/qemu/hw/xilinx.h
@@ -8,7 +8,7 @@ xilinx_intc_create(target_phys_addr_t base, qemu_irq irq, int kind_of_intr)
DeviceState *dev;
dev = qdev_create(NULL, "xilinx,intc");
- qdev_set_prop_int(dev, "kind-of-intr", kind_of_intr);
+ qdev_prop_set_uint32(dev, "kind-of-intr", kind_of_intr);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
@@ -22,8 +22,8 @@ xilinx_timer_create(target_phys_addr_t base, qemu_irq irq, int nr, int freq)
DeviceState *dev;
dev = qdev_create(NULL, "xilinx,timer");
- qdev_set_prop_int(dev, "nr-timers", nr);
- qdev_set_prop_int(dev, "frequency", freq);
+ qdev_prop_set_uint32(dev, "nr-timers", nr);
+ qdev_prop_set_uint32(dev, "frequency", freq);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
@@ -40,9 +40,9 @@ xilinx_ethlite_create(NICInfo *nd, target_phys_addr_t base, qemu_irq irq,
qemu_check_nic_model(nd, "xilinx-ethlite");
dev = qdev_create(NULL, "xilinx,ethlite");
- qdev_set_netdev(dev, nd);
- qdev_set_prop_int(dev, "txpingpong", txpingpong);
- qdev_set_prop_int(dev, "rxpingpong", rxpingpong);
+ dev->nd = nd;
+ qdev_prop_set_uint32(dev, "txpingpong", txpingpong);
+ qdev_prop_set_uint32(dev, "rxpingpong", rxpingpong);
qdev_init(dev);
sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
diff --git a/qemu/hw/xilinx_ethlite.c b/qemu/hw/xilinx_ethlite.c
index f4b40c7b..b3fd25bb 100644
--- a/qemu/hw/xilinx_ethlite.c
+++ b/qemu/hw/xilinx_ethlite.c
@@ -53,8 +53,8 @@ struct xlx_ethlite
qemu_irq irq;
VLANClientState *vc;
- unsigned int c_tx_pingpong;
- unsigned int c_rx_pingpong;
+ uint32_t c_tx_pingpong;
+ uint32_t c_rx_pingpong;
unsigned int txbuf;
unsigned int rxbuf;
@@ -213,8 +213,6 @@ static void xilinx_ethlite_init(SysBusDevice *dev)
int regs;
sysbus_init_irq(dev, &s->irq);
- s->c_tx_pingpong = qdev_get_prop_int(&dev->qdev, "txpingpong", 1);
- s->c_rx_pingpong = qdev_get_prop_int(&dev->qdev, "rxpingpong", 1);
s->rxbuf = 0;
regs = cpu_register_io_memory(eth_read, eth_write, s);
@@ -225,10 +223,29 @@ static void xilinx_ethlite_init(SysBusDevice *dev)
eth_can_rx, eth_rx, NULL, eth_cleanup, s);
}
+static SysBusDeviceInfo xilinx_ethlite_info = {
+ .init = xilinx_ethlite_init,
+ .qdev.name = "xilinx,ethlite",
+ .qdev.size = sizeof(struct xlx_ethlite),
+ .qdev.props = (Property[]) {
+ {
+ .name = "txpingpong",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct xlx_ethlite, c_tx_pingpong),
+ .defval = (uint32_t[]) { 1 },
+ },{
+ .name = "rxpingpong",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct xlx_ethlite, c_rx_pingpong),
+ .defval = (uint32_t[]) { 1 },
+ },
+ {/* end of list */}
+ }
+};
+
static void xilinx_ethlite_register(void)
{
- sysbus_register_dev("xilinx,ethlite", sizeof (struct xlx_ethlite),
- xilinx_ethlite_init);
+ sysbus_register_withprop(&xilinx_ethlite_info);
}
device_init(xilinx_ethlite_register)
diff --git a/qemu/hw/xilinx_intc.c b/qemu/hw/xilinx_intc.c
index 0540f52d..3f08bf81 100644
--- a/qemu/hw/xilinx_intc.c
+++ b/qemu/hw/xilinx_intc.c
@@ -150,7 +150,6 @@ static void xilinx_intc_init(SysBusDevice *dev)
struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev);
int pic_regs;
- p->c_kind_of_intr = qdev_get_prop_int(&dev->qdev, "kind-of-intr", 0);
qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
sysbus_init_irq(dev, &p->parent_irq);
@@ -158,10 +157,23 @@ static void xilinx_intc_init(SysBusDevice *dev)
sysbus_init_mmio(dev, R_MAX * 4, pic_regs);
}
+static SysBusDeviceInfo xilinx_intc_info = {
+ .init = xilinx_intc_init,
+ .qdev.name = "xilinx,intc",
+ .qdev.size = sizeof(struct xlx_pic),
+ .qdev.props = (Property[]) {
+ {
+ .name = "kind-of-intr",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct xlx_pic, c_kind_of_intr),
+ },
+ {/* end of list */}
+ }
+};
+
static void xilinx_intc_register(void)
{
- sysbus_register_dev("xilinx,intc", sizeof (struct xlx_pic),
- xilinx_intc_init);
+ sysbus_register_withprop(&xilinx_intc_info);
}
device_init(xilinx_intc_register)
diff --git a/qemu/hw/xilinx_timer.c b/qemu/hw/xilinx_timer.c
index a64ad2d8..efb6a04f 100644
--- a/qemu/hw/xilinx_timer.c
+++ b/qemu/hw/xilinx_timer.c
@@ -61,7 +61,8 @@ struct timerblock
{
SysBusDevice busdev;
qemu_irq irq;
- unsigned int nr_timers;
+ uint32_t nr_timers;
+ uint32_t freq_hz;
struct xlx_timer *timers;
};
@@ -192,14 +193,12 @@ static void xilinx_timer_init(SysBusDevice *dev)
{
struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
unsigned int i;
- int timer_regs, freq_hz;
+ int timer_regs;
/* All timers share a single irq line. */
sysbus_init_irq(dev, &t->irq);
/* Init all the ptimers. */
- freq_hz = qdev_get_prop_int(&dev->qdev, "frequency", 2);
- t->nr_timers = qdev_get_prop_int(&dev->qdev, "nr-timers", 2);
t->timers = qemu_mallocz(sizeof t->timers[0] * t->nr_timers);
for (i = 0; i < t->nr_timers; i++) {
struct xlx_timer *xt = &t->timers[i];
@@ -208,17 +207,36 @@ static void xilinx_timer_init(SysBusDevice *dev)
xt->nr = i;
xt->bh = qemu_bh_new(timer_hit, xt);
xt->ptimer = ptimer_init(xt->bh);
- ptimer_set_freq(xt->ptimer, freq_hz);
+ ptimer_set_freq(xt->ptimer, t->freq_hz);
}
timer_regs = cpu_register_io_memory(timer_read, timer_write, t);
sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
}
+static SysBusDeviceInfo xilinx_timer_info = {
+ .init = xilinx_timer_init,
+ .qdev.name = "xilinx,timer",
+ .qdev.size = sizeof(struct timerblock),
+ .qdev.props = (Property[]) {
+ {
+ .name = "frequency",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct timerblock, freq_hz),
+ .defval = (uint32_t[]) { 2 },
+ },{
+ .name = "nr-timers",
+ .info = &qdev_prop_uint32,
+ .offset = offsetof(struct timerblock, nr_timers),
+ .defval = (uint32_t[]) { 2 },
+ },
+ {/* end of list */}
+ }
+};
+
static void xilinx_timer_register(void)
{
- sysbus_register_dev("xilinx,timer", sizeof (struct timerblock),
- xilinx_timer_init);
+ sysbus_register_withprop(&xilinx_timer_info);
}
device_init(xilinx_timer_register)
diff --git a/qemu/ioport-user.c b/qemu/ioport-user.c
index fe8567f4..11c76c76 100644
--- a/qemu/ioport-user.c
+++ b/qemu/ioport-user.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
@@ -25,35 +23,38 @@
#include "qemu-common.h"
#include "ioport.h"
-void cpu_outb(CPUState *env, int addr, int val)
+void cpu_outb(CPUState *env, pio_addr_t addr, uint8_t val)
{
- fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
+ fprintf(stderr, "outb: port=0x%04"FMT_pioaddr", data=%02"PRIx8"\n",
+ addr, val);
}
-void cpu_outw(CPUState *env, int addr, int val)
+void cpu_outw(CPUState *env, pio_addr_t addr, uint16_t val)
{
- fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
+ fprintf(stderr, "outw: port=0x%04"FMT_pioaddr", data=%04"PRIx16"\n",
+ addr, val);
}
-void cpu_outl(CPUState *env, int addr, int val)
+void cpu_outl(CPUState *env, pio_addr_t addr, uint32_t val)
{
- fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
+ fprintf(stderr, "outl: port=0x%04"FMT_pioaddr", data=%08"PRIx32"\n",
+ addr, val);
}
-int cpu_inb(CPUState *env, int addr)
+uint8_t cpu_inb(CPUState *env, pio_addr_t addr)
{
- fprintf(stderr, "inb: port=0x%04x\n", addr);
+ fprintf(stderr, "inb: port=0x%04"FMT_pioaddr"\n", addr);
return 0;
}
-int cpu_inw(CPUState *env, int addr)
+uint16_t cpu_inw(CPUState *env, pio_addr_t addr)
{
- fprintf(stderr, "inw: port=0x%04x\n", addr);
+ fprintf(stderr, "inw: port=0x%04"FMT_pioaddr"\n", addr);
return 0;
}
-int cpu_inl(CPUState *env, int addr)
+uint32_t cpu_inl(CPUState *env, pio_addr_t addr)
{
- fprintf(stderr, "inl: port=0x%04x\n", addr);
+ fprintf(stderr, "inl: port=0x%04"FMT_pioaddr"\n", addr);
return 0;
}
diff --git a/qemu/ioport.c b/qemu/ioport.c
index 01cfaf70..13183a2f 100644
--- a/qemu/ioport.c
+++ b/qemu/ioport.c
@@ -33,6 +33,12 @@
//#define DEBUG_UNUSED_IOPORT
//#define DEBUG_IOPORT
+#ifdef DEBUG_UNUSED_IOPORT
+# define LOG_UNUSED_IOPORT(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
+#else
+# define LOG_UNUSED_IOPORT(fmt, ...) do{ } while (0)
+#endif
+
#ifdef DEBUG_IOPORT
# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
#else
@@ -76,17 +82,14 @@ static void ioport_write(int index, uint32_t address, uint32_t data)
static uint32_t default_ioport_readb(void *opaque, uint32_t address)
{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused inb: port=0x%04x\n", address);
-#endif
+ LOG_UNUSED_IOPORT("unused inb: port=0x%04"PRIx32"\n", address);
return 0xff;
}
static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);
-#endif
+ LOG_UNUSED_IOPORT("unused outb: port=0x%04"PRIx32" data=0x%02"PRIx32"\n",
+ address, data);
}
/* default is to make two byte accesses */
@@ -108,17 +111,14 @@ static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
static uint32_t default_ioport_readl(void *opaque, uint32_t address)
{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused inl: port=0x%04x\n", address);
-#endif
+ LOG_UNUSED_IOPORT("unused inl: port=0x%04"PRIx32"\n", address);
return 0xffffffff;
}
static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
{
-#ifdef DEBUG_UNUSED_IOPORT
- fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);
-#endif
+ LOG_UNUSED_IOPORT("unused outl: port=0x%04"PRIx32" data=0x%02"PRIx32"\n",
+ address, data);
}
static int ioport_bsize(int size, int *bsize)
@@ -136,7 +136,7 @@ static int ioport_bsize(int size, int *bsize)
}
/* size is the word size in byte */
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(pio_addr_t start, int length, int size,
IOPortReadFunc *func, void *opaque)
{
int i, bsize;
@@ -155,7 +155,7 @@ int register_ioport_read(int start, int length, int size,
}
/* size is the word size in byte */
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(pio_addr_t start, int length, int size,
IOPortWriteFunc *func, void *opaque)
{
int i, bsize;
@@ -173,7 +173,7 @@ int register_ioport_write(int start, int length, int size,
return 0;
}
-void isa_unassign_ioport(int start, int length)
+void isa_unassign_ioport(pio_addr_t start, int length)
{
int i;
@@ -192,9 +192,9 @@ void isa_unassign_ioport(int start, int length)
/***********************************************************/
-void cpu_outb(CPUState *env, int addr, int val)
+void cpu_outb(CPUState *env, pio_addr_t addr, uint8_t val)
{
- LOG_IOPORT("outb: %04x %02x\n", addr, val);
+ LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
ioport_write(0, addr, val);
#ifdef CONFIG_KQEMU
if (env)
@@ -202,9 +202,9 @@ void cpu_outb(CPUState *env, int addr, int val)
#endif
}
-void cpu_outw(CPUState *env, int addr, int val)
+void cpu_outw(CPUState *env, pio_addr_t addr, uint16_t val)
{
- LOG_IOPORT("outw: %04x %04x\n", addr, val);
+ LOG_IOPORT("outw: %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
ioport_write(1, addr, val);
#ifdef CONFIG_KQEMU
if (env)
@@ -212,9 +212,9 @@ void cpu_outw(CPUState *env, int addr, int val)
#endif
}
-void cpu_outl(CPUState *env, int addr, int val)
+void cpu_outl(CPUState *env, pio_addr_t addr, uint32_t val)
{
- LOG_IOPORT("outl: %04x %08x\n", addr, val);
+ LOG_IOPORT("outl: %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
ioport_write(2, addr, val);
#ifdef CONFIG_KQEMU
if (env)
@@ -222,11 +222,11 @@ void cpu_outl(CPUState *env, int addr, int val)
#endif
}
-int cpu_inb(CPUState *env, int addr)
+uint8_t cpu_inb(CPUState *env, pio_addr_t addr)
{
- int val;
+ uint8_t val;
val = ioport_read(0, addr);
- LOG_IOPORT("inb : %04x %02x\n", addr, val);
+ LOG_IOPORT("inb : %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
@@ -234,11 +234,11 @@ int cpu_inb(CPUState *env, int addr)
return val;
}
-int cpu_inw(CPUState *env, int addr)
+uint16_t cpu_inw(CPUState *env, pio_addr_t addr)
{
- int val;
+ uint16_t val;
val = ioport_read(1, addr);
- LOG_IOPORT("inw : %04x %04x\n", addr, val);
+ LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);
#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
@@ -246,15 +246,14 @@ int cpu_inw(CPUState *env, int addr)
return val;
}
-int cpu_inl(CPUState *env, int addr)
+uint32_t cpu_inl(CPUState *env, pio_addr_t addr)
{
- int val;
+ uint32_t val;
val = ioport_read(2, addr);
- LOG_IOPORT("inl : %04x %08x\n", addr, val);
+ LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
return val;
}
-
diff --git a/qemu/ioport.h b/qemu/ioport.h
index 4cb59e95..f981e8c4 100644
--- a/qemu/ioport.h
+++ b/qemu/ioport.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/**************************************************************************
@@ -27,6 +26,9 @@
#include "qemu-common.h"
+typedef uint32_t pio_addr_t;
+#define FMT_pioaddr PRIx32
+
#define MAX_IOPORTS (64 * 1024)
#define IOPORTS_MASK (MAX_IOPORTS - 1)
@@ -34,22 +36,22 @@
typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
-int register_ioport_read(int start, int length, int size,
+int register_ioport_read(pio_addr_t start, int length, int size,
IOPortReadFunc *func, void *opaque);
-int register_ioport_write(int start, int length, int size,
+int register_ioport_write(pio_addr_t start, int length, int size,
IOPortWriteFunc *func, void *opaque);
-void isa_unassign_ioport(int start, int length);
+void isa_unassign_ioport(pio_addr_t start, int length);
/* NOTE: as these functions may be even used when there is an isa
brige on non x86 targets, we always defined them */
#if !defined(NO_CPU_IO_DEFS) && defined(NEED_CPU_H)
-void cpu_outb(CPUState *env, int addr, int val);
-void cpu_outw(CPUState *env, int addr, int val);
-void cpu_outl(CPUState *env, int addr, int val);
-int cpu_inb(CPUState *env, int addr);
-int cpu_inw(CPUState *env, int addr);
-int cpu_inl(CPUState *env, int addr);
+void cpu_outb(CPUState *env, pio_addr_t addr, uint8_t val);
+void cpu_outw(CPUState *env, pio_addr_t addr, uint16_t val);
+void cpu_outl(CPUState *env, pio_addr_t addr, uint32_t val);
+uint8_t cpu_inb(CPUState *env, pio_addr_t addr);
+uint16_t cpu_inw(CPUState *env, pio_addr_t addr);
+uint32_t cpu_inl(CPUState *env, pio_addr_t addr);
#endif
#endif /* IOPORT_H */
diff --git a/qemu/linux-user/flatload.c b/qemu/linux-user/flatload.c
index 8eba5a81..6a2c3f95 100644
--- a/qemu/linux-user/flatload.c
+++ b/qemu/linux-user/flatload.c
@@ -13,9 +13,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*
* Copyright (C) 2006 CodeSourcery.
* Copyright (C) 2000-2003 David McCullough
diff --git a/qemu/linux-user/m68k-sim.c b/qemu/linux-user/m68k-sim.c
index 8a2b1d87..64d3b23d 100644
--- a/qemu/linux-user/m68k-sim.c
+++ b/qemu/linux-user/m68k-sim.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
diff --git a/qemu/linux-user/main.c b/qemu/linux-user/main.c
index e331d658..9038b58e 100644
--- a/qemu/linux-user/main.c
+++ b/qemu/linux-user/main.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
#include
@@ -1053,7 +1051,8 @@ do { \
fprintf(stderr, fmt , ## __VA_ARGS__); \
cpu_dump_state(env, stderr, fprintf, 0); \
qemu_log(fmt, ## __VA_ARGS__); \
- log_cpu_state(env, 0); \
+ if (logfile) \
+ log_cpu_state(env, 0); \
} while (0)
void cpu_loop(CPUPPCState *env)
diff --git a/qemu/linux-user/mmap.c b/qemu/linux-user/mmap.c
index aa22006f..79cb4e60 100644
--- a/qemu/linux-user/mmap.c
+++ b/qemu/linux-user/mmap.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
#include
diff --git a/qemu/linux-user/ppc/syscall.h b/qemu/linux-user/ppc/syscall.h
index d789911e..481047b2 100644
--- a/qemu/linux-user/ppc/syscall.h
+++ b/qemu/linux-user/ppc/syscall.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/* XXX: ABSOLUTELY BUGGY:
diff --git a/qemu/linux-user/signal.c b/qemu/linux-user/signal.c
index 6ee61a91..93c2ebe1 100644
--- a/qemu/linux-user/signal.c
+++ b/qemu/linux-user/signal.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
#include
diff --git a/qemu/linux-user/syscall.c b/qemu/linux-user/syscall.c
index 00096232..8b0a5fa3 100644
--- a/qemu/linux-user/syscall.c
+++ b/qemu/linux-user/syscall.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#define _ATFILE_SOURCE
#include
diff --git a/qemu/linux-user/vm86.c b/qemu/linux-user/vm86.c
index cc6c8c99..0b2439df 100644
--- a/qemu/linux-user/vm86.c
+++ b/qemu/linux-user/vm86.c
@@ -14,9 +14,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- * MA 02110-1301, USA.
+ * along with this program; if not, see .
*/
#include
#include
diff --git a/qemu/migration-exec.c b/qemu/migration-exec.c
index 6ed322a9..e472979d 100644
--- a/qemu/migration-exec.c
+++ b/qemu/migration-exec.c
@@ -18,7 +18,6 @@
#include "migration.h"
#include "qemu-char.h"
#include "sysemu.h"
-#include "console.h"
#include "buffered_file.h"
#include "block.h"
@@ -55,7 +54,7 @@ static int exec_close(FdMigrationState *s)
MigrationState *exec_start_outgoing_migration(const char *command,
int64_t bandwidth_limit,
- int async)
+ int detach)
{
FdMigrationState *s;
FILE *f;
@@ -89,14 +88,11 @@ MigrationState *exec_start_outgoing_migration(const char *command,
s->mig_state.release = migrate_fd_release;
s->state = MIG_STATE_ACTIVE;
- s->detach = !async;
+ s->mon_resume = NULL;
s->bandwidth_limit = bandwidth_limit;
- if (s->detach == 1) {
- dprintf("detaching from monitor\n");
- monitor_suspend();
- s->detach = 2;
- }
+ if (!detach)
+ migrate_fd_monitor_suspend(s);
migrate_fd_connect(s);
return &s->mig_state;
@@ -108,18 +104,11 @@ MigrationState *exec_start_outgoing_migration(const char *command,
return NULL;
}
-int exec_start_incoming_migration(const char *command)
+static void exec_accept_incoming_migration(void *opaque)
{
+ QEMUFile *f = opaque;
int ret;
- QEMUFile *f;
- dprintf("Attempting to start an incoming migration\n");
- f = qemu_popen_cmd(command, "r");
- if(f == NULL) {
- dprintf("Unable to apply qemu wrapper to popen file\n");
- return -errno;
- }
- vm_stop(0); /* just in case */
ret = qemu_loadvm_state(f);
if (ret < 0) {
fprintf(stderr, "load of migration failed\n");
@@ -127,11 +116,27 @@ int exec_start_incoming_migration(const char *command)
}
qemu_announce_self();
dprintf("successfully loaded vm state\n");
- vm_start();
- qemu_fclose(f);
- return 0;
+ /* we've successfully migrated, close the fd */
+ qemu_set_fd_handler2(qemu_popen_fd(f), NULL, NULL, NULL, NULL);
err:
qemu_fclose(f);
- return -errno;
+}
+
+int exec_start_incoming_migration(const char *command)
+{
+ QEMUFile *f;
+
+ dprintf("Attempting to start an incoming migration\n");
+ f = qemu_popen_cmd(command, "r");
+ if(f == NULL) {
+ dprintf("Unable to apply qemu wrapper to popen file\n");
+ return -errno;
+ }
+
+ qemu_set_fd_handler2(qemu_popen_fd(f), NULL,
+ exec_accept_incoming_migration, NULL,
+ (void *)(unsigned long)f);
+
+ return 0;
}
diff --git a/qemu/migration-tcp.c b/qemu/migration-tcp.c
index 1f4358ee..7a87a1ed 100644
--- a/qemu/migration-tcp.c
+++ b/qemu/migration-tcp.c
@@ -155,7 +155,6 @@ static void tcp_accept_incoming_migration(void *opaque)
goto out;
}
- vm_stop(0); /* just in case */
ret = qemu_loadvm_state(f);
if (ret < 0) {
fprintf(stderr, "load of migration failed\n");
@@ -168,8 +167,6 @@ static void tcp_accept_incoming_migration(void *opaque)
qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
close(s);
- vm_start();
-
out_fopen:
qemu_fclose(f);
out:
diff --git a/qemu/migration.c b/qemu/migration.c
index e6c8b16a..ee64d410 100644
--- a/qemu/migration.c
+++ b/qemu/migration.c
@@ -266,6 +266,7 @@ void migrate_fd_put_ready(void *opaque)
dprintf("done iterating\n");
vm_stop(0);
+ qemu_aio_flush();
bdrv_flush_all();
if ((qemu_savevm_state_complete(s->file)) < 0) {
if (old_vm_running) {
diff --git a/qemu/monitor.c b/qemu/monitor.c
index b1bdbdb2..e3028352 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -1185,28 +1185,34 @@ static void do_ioport_read(Monitor *mon, int count, int format, int size,
suffix, addr, size * 2, val);
}
-/* boot_set handler */
-static QEMUBootSetHandler *qemu_boot_set_handler = NULL;
-static void *boot_opaque;
-
-void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
+static void do_ioport_write(Monitor *mon, int count, int format, int size,
+ int addr, int val)
{
- qemu_boot_set_handler = func;
- boot_opaque = opaque;
+ addr &= IOPORTS_MASK;
+
+ switch (size) {
+ default:
+ case 1:
+ cpu_outb(NULL, addr, val);
+ break;
+ case 2:
+ cpu_outw(NULL, addr, val);
+ break;
+ case 4:
+ cpu_outl(NULL, addr, val);
+ break;
+ }
}
static void do_boot_set(Monitor *mon, const char *bootdevice)
{
int res;
- if (qemu_boot_set_handler) {
- res = qemu_boot_set_handler(boot_opaque, bootdevice);
- if (res == 0)
- monitor_printf(mon, "boot device list now set to %s\n",
- bootdevice);
- else
- monitor_printf(mon, "setting boot device list failed with "
- "error %i\n", res);
+ res = qemu_boot_set(bootdevice);
+ if (res == 0) {
+ monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
+ } else if (res > 0) {
+ monitor_printf(mon, "setting boot device list failed\n");
} else {
monitor_printf(mon, "no function defined to set boot device list for "
"this architecture\n");
diff --git a/qemu/net.c b/qemu/net.c
index b407c453..0054b1ef 100644
--- a/qemu/net.c
+++ b/qemu/net.c
@@ -783,8 +783,8 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
const char *vsmbserver)
{
/* default settings according to historic slirp */
- struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
- struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */
+ struct in_addr net = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
+ struct in_addr mask = { .s_addr = htonl(0xffffff00) }; /* 255.255.255.0 */
struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
@@ -2429,7 +2429,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
}
if (!strcmp(device, "nic")) {
static const char * const nic_params[] = {
- "vlan", "name", "macaddr", "model", "addr", "vectors", NULL
+ "vlan", "name", "macaddr", "model", "addr", "id", "vectors", NULL
};
NICInfo *nd;
uint8_t *macaddr;
@@ -2467,6 +2467,9 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
if (get_param_value(buf, sizeof(buf), "addr", p)) {
nd->devaddr = strdup(buf);
}
+ if (get_param_value(buf, sizeof(buf), "id", p)) {
+ nd->id = strdup(buf);
+ }
nd->nvectors = NIC_NVECTORS_UNSPECIFIED;
if (get_param_value(buf, sizeof(buf), "vectors", p)) {
char *endptr;
diff --git a/qemu/net.h b/qemu/net.h
index 6026e103..188fa395 100644
--- a/qemu/net.h
+++ b/qemu/net.h
@@ -95,6 +95,7 @@ struct NICInfo {
const char *model;
const char *name;
const char *devaddr;
+ const char *id;
VLANState *vlan;
VLANClientState *vc;
void *private;
diff --git a/qemu/pc-bios/bios-pq/0013_fix-non-acpi-timer-interrupt-routing.patch b/qemu/pc-bios/bios-pq/0013_fix-non-acpi-timer-interrupt-routing.patch
index c9d74e83..80e7716c 100644
--- a/qemu/pc-bios/bios-pq/0013_fix-non-acpi-timer-interrupt-routing.patch
+++ b/qemu/pc-bios/bios-pq/0013_fix-non-acpi-timer-interrupt-routing.patch
@@ -1,30 +1,49 @@
-Fix non-ACPI Timer Interrupt Routing (Beth Kon)
+From c09142004a409bf27070939f470c5e0b37595a5a Mon Sep 17 00:00:00 2001
+From: Beth Kon
+Date: Fri, 19 Jun 2009 14:22:00 -0400
+Subject: [PATCH] Fix non-ACPI Timer Interrupt Routing - v3
Replicate ACPI irq0->inti2 override in mp table for non-acpi case.
v1 -> v2 adds comment suggested by Ryan.
+v2 -> v3 clarifies comment and corrects entry count
Signed-off-by: Beth Kon
Signed-off-by: Anthony Liguori
+---
+ bios/rombios32.c | 14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/bios/rombios32.c b/bios/rombios32.c
-index 7be4216..dc7b5f3 100644
+index 1a1ed64..d789e20 100644
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
-@@ -1168,6 +1168,12 @@ static void mptable_init(void)
+@@ -1124,7 +1124,11 @@ static void mptable_init(void)
+ putstr(&q, "0.1 "); /* vendor id */
+ putle32(&q, 0); /* OEM table ptr */
+ putle16(&q, 0); /* OEM table size */
++#ifdef BX_QEMU
++ putle16(&q, smp_cpus + 17); /* entry count */
++#else
+ putle16(&q, smp_cpus + 18); /* entry count */
++#endif
+ putle32(&q, 0xfee00000); /* local APIC addr */
+ putle16(&q, 0); /* ext table length */
+ putb(&q, 0); /* ext table checksum */
+@@ -1166,6 +1170,12 @@ static void mptable_init(void)
/* irqs */
for(i = 0; i < 16; i++) {
+#ifdef BX_QEMU
-+ /* One entry per ioapic input. Input 2 is covered by
-+ irq0->inti2 override (i == 0). irq 2 is unused */
++ /* One entry per ioapic interrupt destination. Destination 2 is covered
++ by irq0->inti2 override (i == 0). Source IRQ 2 is unused */
+ if (i == 2)
+ continue;
-+#endif
++#endif
putb(&q, 3); /* entry type = I/O interrupt */
putb(&q, 0); /* interrupt type = vectored interrupt */
putb(&q, 0); /* flags: po=0, el=0 */
-@@ -1175,7 +1181,11 @@ static void mptable_init(void)
+@@ -1173,7 +1183,11 @@ static void mptable_init(void)
putb(&q, 0); /* source bus ID = ISA */
putb(&q, i); /* source bus IRQ */
putb(&q, ioapic_id); /* dest I/O APIC ID */
@@ -32,7 +51,10 @@ index 7be4216..dc7b5f3 100644
+ putb(&q, i == 0 ? 2 : i); /* dest I/O APIC interrupt in */
+#else
putb(&q, i); /* dest I/O APIC interrupt in */
-+#endif
++#endif
}
/* patch length */
len = q - mp_config_table;
+--
+1.6.2.5
+
diff --git a/qemu/pc-bios/bios-pq/0017-bochs-bios-Move-QEMU_CFG-constants-to-rombios.h.patch b/qemu/pc-bios/bios-pq/0017-bochs-bios-Move-QEMU_CFG-constants-to-rombios.h.patch
new file mode 100644
index 00000000..f6a1788a
--- /dev/null
+++ b/qemu/pc-bios/bios-pq/0017-bochs-bios-Move-QEMU_CFG-constants-to-rombios.h.patch
@@ -0,0 +1,59 @@
+From f371c480cb93f3516f34af5e3a4524ee6ba43c24 Mon Sep 17 00:00:00 2001
+From: Jan Kiszka
+Date: Thu, 2 Jul 2009 00:11:38 +0200
+Subject: [PATCH 1/2] bochs-bios: Move QEMU_CFG constants to rombios.h
+
+We will need them outside of rombios32.c.
+
+Signed-off-by: Jan Kiszka
+Signed-off-by: Anthony Liguori
+---
+ bios/rombios.h | 10 ++++++++++
+ bios/rombios32.c | 10 ----------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/bios/rombios.h b/bios/rombios.h
+index 6f9cbb1..59ce19d 100644
+--- a/bios/rombios.h
++++ b/bios/rombios.h
+@@ -58,6 +58,16 @@
+ #define SMB_IO_BASE 0xb100
+ #define SMP_MSR_ADDR 0x0510
+
++#define QEMU_CFG_CTL_PORT 0x510
++#define QEMU_CFG_DATA_PORT 0x511
++#define QEMU_CFG_SIGNATURE 0x00
++#define QEMU_CFG_ID 0x01
++#define QEMU_CFG_UUID 0x02
++#define QEMU_CFG_NUMA 0x0d
++#define QEMU_CFG_ARCH_LOCAL 0x8000
++#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
++#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
++
+ // Define the application NAME
+ #if defined(BX_QEMU)
+ # define BX_APPNAME "QEMU"
+diff --git a/bios/rombios32.c b/bios/rombios32.c
+index f861f81..3fe4e48 100644
+--- a/bios/rombios32.c
++++ b/bios/rombios32.c
+@@ -468,16 +468,6 @@ void wrmsr_smp(uint32_t index, uint64_t val)
+ }
+
+ #ifdef BX_QEMU
+-#define QEMU_CFG_CTL_PORT 0x510
+-#define QEMU_CFG_DATA_PORT 0x511
+-#define QEMU_CFG_SIGNATURE 0x00
+-#define QEMU_CFG_ID 0x01
+-#define QEMU_CFG_UUID 0x02
+-#define QEMU_CFG_NUMA 0x0D
+-#define QEMU_CFG_ARCH_LOCAL 0x8000
+-#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
+-#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
+-
+ int qemu_cfg_port;
+
+ void qemu_cfg_select(int f)
+--
+1.6.2.5
+
diff --git a/qemu/pc-bios/bios-pq/0018-bochs-bios-Make-boot-prompt-optional.patch b/qemu/pc-bios/bios-pq/0018-bochs-bios-Make-boot-prompt-optional.patch
new file mode 100644
index 00000000..cda97572
--- /dev/null
+++ b/qemu/pc-bios/bios-pq/0018-bochs-bios-Make-boot-prompt-optional.patch
@@ -0,0 +1,68 @@
+From fff8ffe1c92474ee58ebd6da82fede0ab7929214 Mon Sep 17 00:00:00 2001
+From: Jan Kiszka
+Date: Thu, 2 Jul 2009 00:11:44 +0200
+Subject: [PATCH 2/2] bochs-bios: Make boot prompt optional
+
+Check via QEMU's firmware configuration interface if the boot prompt
+should be given. This allows to disable the prompt with its several
+seconds long delay, speeding up the common boot case.
+
+Signed-off-by: Jan Kiszka
+Signed-off-by: Anthony Liguori
+---
+ bios/rombios.c | 19 +++++++++++++++++++
+ bios/rombios.h | 1 +
+ 2 files changed, 20 insertions(+), 0 deletions(-)
+
+diff --git a/bios/rombios.c b/bios/rombios.c
+index 0f13b53..560e6d5 100644
+--- a/bios/rombios.c
++++ b/bios/rombios.c
+@@ -2015,6 +2015,21 @@ Bit16u i; ipl_entry_t *e;
+ }
+
+ #if BX_ELTORITO_BOOT
++#ifdef BX_QEMU
++int
++qemu_cfg_probe_bootkey()
++{
++ outw(QEMU_CFG_CTL_PORT, QEMU_CFG_SIGNATURE);
++ if (inb(QEMU_CFG_DATA_PORT) != 'Q' ||
++ inb(QEMU_CFG_DATA_PORT) != 'E' ||
++ inb(QEMU_CFG_DATA_PORT) != 'M' ||
++ inb(QEMU_CFG_DATA_PORT) != 'U') return 1;
++
++ outw(QEMU_CFG_CTL_PORT, QEMU_CFG_BOOT_MENU);
++ return inb(QEMU_CFG_DATA_PORT);
++}
++#endif // BX_QEMU
++
+ void
+ interactive_bootkey()
+ {
+@@ -2026,6 +2041,10 @@ interactive_bootkey()
+ Bit16u ss = get_SS();
+ Bit16u valid_choice = 0;
+
++#ifdef BX_QEMU
++ if (!qemu_cfg_probe_bootkey()) return;
++#endif
++
+ while (check_for_keystroke())
+ get_keystroke();
+
+diff --git a/bios/rombios.h b/bios/rombios.h
+index 59ce19d..8ece2ee 100644
+--- a/bios/rombios.h
++++ b/bios/rombios.h
+@@ -64,6 +64,7 @@
+ #define QEMU_CFG_ID 0x01
+ #define QEMU_CFG_UUID 0x02
+ #define QEMU_CFG_NUMA 0x0d
++#define QEMU_CFG_BOOT_MENU 0x0e
+ #define QEMU_CFG_ARCH_LOCAL 0x8000
+ #define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
+ #define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
+--
+1.6.2.5
+
diff --git a/qemu/pc-bios/bios-pq/0019-bios-fix-multiple-calls.patch b/qemu/pc-bios/bios-pq/0019-bios-fix-multiple-calls.patch
new file mode 100644
index 00000000..cfa4c130
--- /dev/null
+++ b/qemu/pc-bios/bios-pq/0019-bios-fix-multiple-calls.patch
@@ -0,0 +1,35 @@
+bios: Fix multiple calls into smbios_load_ex
+
+We're marking the used entry bitmap in smbios_load_external() for each
+type we check, regardless of whether we loaded anything. This makes
+subsequent calls behave as if we've already loaded the tables from qemu
+and can result in missing tables (ex. multiple type4 entries on an SMP
+guest). Only mark the bitmap if we actually load something.
+
+Signed-off-by: Alex Williamson
+Signed-off-by: Anthony Liguori
+
+diff --git a/bios/rombios32.c b/bios/rombios32.c
+index f861f81..c869798 100644
+--- a/bios/rombios32.c
++++ b/bios/rombios32.c
+@@ -2554,13 +2554,14 @@ smbios_load_external(int type, char **p, unsigned *nr_structs,
+ *max_struct_size = *p - (char *)header;
+ }
+
+- /* Mark that we've reported on this type */
+- used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
++ if (start != *p) {
++ /* Mark that we've reported on this type */
++ used_bitmap[(type >> 6) & 0x3] |= (1ULL << (type & 0x3f));
++ return 1;
++ }
+
+- return (start != *p);
+-#else /* !BX_QEMU */
++#endif /* !BX_QEMU */
+ return 0;
+-#endif
+ }
+
+ void smbios_init(void)
diff --git a/qemu/pc-bios/bios-pq/series b/qemu/pc-bios/bios-pq/series
index c7c7f67e..695b148a 100644
--- a/qemu/pc-bios/bios-pq/series
+++ b/qemu/pc-bios/bios-pq/series
@@ -14,3 +14,6 @@
0014_add-srat-acpi-table-support.patch
0015_enable-power-button-even-generation.patch
0016-use-correct-mask-to-size-pci-option-rom-bar.patch
+0017-bochs-bios-Move-QEMU_CFG-constants-to-rombios.h.patch
+0018-bochs-bios-Make-boot-prompt-optional.patch
+0019-bios-fix-multiple-calls.patch
diff --git a/qemu/pc-bios/bios.bin b/qemu/pc-bios/bios.bin
index 6c8bc9f6..e4323c05 100644
Binary files a/qemu/pc-bios/bios.bin and b/qemu/pc-bios/bios.bin differ
diff --git a/qemu/pc-bios/optionrom/Makefile b/qemu/pc-bios/optionrom/Makefile
index 7f987d89..88fbc4c9 100644
--- a/qemu/pc-bios/optionrom/Makefile
+++ b/qemu/pc-bios/optionrom/Makefile
@@ -3,7 +3,6 @@ all: build-all
include ../../config-host.mak
VPATH=$(SRC_PATH)/pc-bios/optionrom
-OBJCOPY=objcopy
# from kernel sources - scripts/Kbuild.include
# try-run
@@ -35,11 +34,13 @@ build-all: multiboot.bin
$(CC) $(CFLAGS) -o $@ -c $<
%.img: %.o
- $(LD) --oformat binary -Ttext 0 -o $@ $<
+ $(LD) -Ttext 0 -e _start -s -o $@ $<
-%.bin: %.img
+%.raw: %.img
+ $(OBJCOPY) -O binary -j .text $< $@
+
+%.bin: %.raw
$(SRC_PATH)/pc-bios/optionrom/signrom.sh $< $@
- cp $@ $(SRC_PATH)/pc-bios/
clean:
$(RM) *.o *.img *.bin *~
diff --git a/qemu/pc-bios/optionrom/multiboot.S b/qemu/pc-bios/optionrom/multiboot.S
index e04cd033..93beb51b 100644
--- a/qemu/pc-bios/optionrom/multiboot.S
+++ b/qemu/pc-bios/optionrom/multiboot.S
@@ -12,8 +12,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program; if not, see .
*
* Copyright Novell Inc, 2009
* Authors: Alexander Graf
diff --git a/qemu/pc-bios/optionrom/signrom.sh b/qemu/pc-bios/optionrom/signrom.sh
index 4273d1f0..263ba5ff 100644
--- a/qemu/pc-bios/optionrom/signrom.sh
+++ b/qemu/pc-bios/optionrom/signrom.sh
@@ -13,8 +13,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+# along with this program; if not, see .
#
# Copyright Novell Inc, 2009
# Authors: Alexander Graf
diff --git a/qemu/qemu-io.c b/qemu/qemu-io.c
index 566ca79f..6c35a071 100644
--- a/qemu/qemu-io.c
+++ b/qemu/qemu-io.c
@@ -98,6 +98,57 @@ print_report(const char *op, struct timeval *t, int64_t offset,
}
}
+/*
+ * Parse multiple length statements for vectored I/O, and construct an I/O
+ * vector matching it.
+ */
+static void *
+create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
+{
+ size_t *sizes = calloc(nr_iov, sizeof(size_t));
+ size_t count = 0;
+ void *buf, *p;
+ int i;
+
+ for (i = 0; i < nr_iov; i++) {
+ char *arg = argv[i];
+ long long len;
+
+ len = cvtnum(arg);
+ if (len < 0) {
+ printf("non-numeric length argument -- %s\n", arg);
+ return NULL;
+ }
+
+ /* should be SIZE_T_MAX, but that doesn't exist */
+ if (len > UINT_MAX) {
+ printf("too large length argument -- %s\n", arg);
+ return NULL;
+ }
+
+ if (len & 0x1ff) {
+ printf("length argument %lld is not sector aligned\n",
+ len);
+ return NULL;
+ }
+
+ sizes[i] = len;
+ count += len;
+ }
+
+ qemu_iovec_init(qiov, nr_iov);
+
+ buf = p = qemu_io_alloc(count, pattern);
+
+ for (i = 0; i < nr_iov; i++) {
+ qemu_iovec_add(qiov, p, sizes[i]);
+ p += sizes[i];
+ }
+
+ free(sizes);
+ return buf;
+}
+
static int do_read(char *buf, int64_t offset, int count, int *total)
{
int ret;
@@ -136,6 +187,22 @@ static int do_pwrite(char *buf, int64_t offset, int count, int *total)
return 1;
}
+static int do_load_vmstate(char *buf, int64_t offset, int count, int *total)
+{
+ *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count);
+ if (*total < 0)
+ return *total;
+ return 1;
+}
+
+static int do_save_vmstate(char *buf, int64_t offset, int count, int *total)
+{
+ *total = bdrv_save_vmstate(bs, (uint8_t *)buf, offset, count);
+ if (*total < 0)
+ return *total;
+ return 1;
+}
+
#define NOT_DONE 0x7fffffff
static void aio_rw_done(void *opaque, int ret)
{
@@ -191,6 +258,7 @@ read_help(void)
"\n"
" Reads a segment of the currently open file, optionally dumping it to the\n"
" standard output stream (with -v option) for subsequent inspection.\n"
+" -b, -- read from the VM state rather than the virtual disk\n"
" -C, -- report statistics in a machine parsable format\n"
" -l, -- length for pattern verification (only with -P)\n"
" -p, -- use bdrv_pread to read the file\n"
@@ -206,7 +274,7 @@ read_f(int argc, char **argv)
{
struct timeval t1, t2;
int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
- int Pflag = 0, sflag = 0, lflag = 0;
+ int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
int c, cnt;
char *buf;
int64_t offset;
@@ -215,8 +283,11 @@ read_f(int argc, char **argv)
int total = 0;
int pattern = 0, pattern_offset = 0, pattern_count = 0;
- while ((c = getopt(argc, argv, "Cl:pP:qs:v")) != EOF) {
+ while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != EOF) {
switch (c) {
+ case 'b':
+ bflag = 1;
+ break;
case 'C':
Cflag = 1;
break;
@@ -257,6 +328,11 @@ read_f(int argc, char **argv)
if (optind != argc - 2)
return command_usage(&read_cmd);
+ if (bflag && pflag) {
+ printf("-b and -p cannot be specified at the same time\n");
+ return 0;
+ }
+
offset = cvtnum(argv[optind]);
if (offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
@@ -301,13 +377,15 @@ read_f(int argc, char **argv)
gettimeofday(&t1, NULL);
if (pflag)
cnt = do_pread(buf, offset, count, &total);
+ else if (bflag)
+ cnt = do_load_vmstate(buf, offset, count, &total);
else
cnt = do_read(buf, offset, count, &total);
gettimeofday(&t2, NULL);
if (cnt < 0) {
printf("read failed: %s\n", strerror(-cnt));
- return 0;
+ goto out;
}
if (Pflag) {
@@ -322,7 +400,7 @@ read_f(int argc, char **argv)
}
if (qflag)
- return 0;
+ goto out;
if (vflag)
dump_buffer(buf, offset, count);
@@ -331,6 +409,7 @@ read_f(int argc, char **argv)
t2 = tsub(t2, t1);
print_report("read", &t2, offset, count, total, cnt, Cflag);
+out:
qemu_io_free(buf);
return 0;
@@ -342,7 +421,7 @@ static const cmdinfo_t read_cmd = {
.cfunc = read_f,
.argmin = 2,
.argmax = -1,
- .args = "[-aCpqv] [-P pattern [-s off] [-l len]] off len",
+ .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
.oneline = "reads a number of bytes at a specified offset",
.help = read_help,
};
@@ -375,10 +454,10 @@ readv_f(int argc, char **argv)
struct timeval t1, t2;
int Cflag = 0, qflag = 0, vflag = 0;
int c, cnt;
- char *buf, *p;
+ char *buf;
int64_t offset;
- int count = 0, total;
- int nr_iov, i;
+ int total;
+ int nr_iov;
QEMUIOVector qiov;
int pattern = 0;
int Pflag = 0;
@@ -420,40 +499,8 @@ readv_f(int argc, char **argv)
return 0;
}
- if (count & 0x1ff) {
- printf("count %d is not sector aligned\n",
- count);
- return 0;
- }
-
- for (i = optind; i < argc; i++) {
- size_t len;
-
- len = cvtnum(argv[i]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n", argv[i]);
- return 0;
- }
- count += len;
- }
-
nr_iov = argc - optind;
- qemu_iovec_init(&qiov, nr_iov);
- buf = p = qemu_io_alloc(count, 0xab);
- for (i = 0; i < nr_iov; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n",
- argv[optind]);
- return 0;
- }
-
- qemu_iovec_add(&qiov, p, len);
- p += len;
- optind++;
- }
+ buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
gettimeofday(&t1, NULL);
cnt = do_aio_readv(&qiov, offset, &total);
@@ -461,22 +508,22 @@ readv_f(int argc, char **argv)
if (cnt < 0) {
printf("readv failed: %s\n", strerror(-cnt));
- return 0;
+ goto out;
}
if (Pflag) {
- void* cmp_buf = malloc(count);
- memset(cmp_buf, pattern, count);
- if (memcmp(buf, cmp_buf, count)) {
+ void* cmp_buf = malloc(qiov.size);
+ memset(cmp_buf, pattern, qiov.size);
+ if (memcmp(buf, cmp_buf, qiov.size)) {
printf("Pattern verification failed at offset %lld, "
- "%d bytes\n",
- (long long) offset, count);
+ "%zd bytes\n",
+ (long long) offset, qiov.size);
}
free(cmp_buf);
}
if (qflag)
- return 0;
+ goto out;
if (vflag)
dump_buffer(buf, offset, qiov.size);
@@ -485,8 +532,8 @@ readv_f(int argc, char **argv)
t2 = tsub(t2, t1);
print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
+out:
qemu_io_free(buf);
-
return 0;
}
@@ -514,6 +561,7 @@ write_help(void)
"\n"
" Writes into a segment of the currently open file, using a buffer\n"
" filled with a set pattern (0xcdcdcdcd).\n"
+" -b, -- write to the VM state rather than the virtual disk\n"
" -p, -- use bdrv_pwrite to write the file\n"
" -P, -- use different pattern to fill file\n"
" -C, -- report statistics in a machine parsable format\n"
@@ -525,7 +573,7 @@ static int
write_f(int argc, char **argv)
{
struct timeval t1, t2;
- int Cflag = 0, pflag = 0, qflag = 0;
+ int Cflag = 0, pflag = 0, qflag = 0, bflag = 0;
int c, cnt;
char *buf;
int64_t offset;
@@ -534,8 +582,11 @@ write_f(int argc, char **argv)
int total = 0;
int pattern = 0xcd;
- while ((c = getopt(argc, argv, "CpP:q")) != EOF) {
+ while ((c = getopt(argc, argv, "bCpP:q")) != EOF) {
switch (c) {
+ case 'b':
+ bflag = 1;
+ break;
case 'C':
Cflag = 1;
break;
@@ -556,6 +607,11 @@ write_f(int argc, char **argv)
if (optind != argc - 2)
return command_usage(&write_cmd);
+ if (bflag && pflag) {
+ printf("-b and -p cannot be specified at the same time\n");
+ return 0;
+ }
+
offset = cvtnum(argv[optind]);
if (offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
@@ -588,22 +644,25 @@ write_f(int argc, char **argv)
gettimeofday(&t1, NULL);
if (pflag)
cnt = do_pwrite(buf, offset, count, &total);
+ else if (bflag)
+ cnt = do_save_vmstate(buf, offset, count, &total);
else
cnt = do_write(buf, offset, count, &total);
gettimeofday(&t2, NULL);
if (cnt < 0) {
printf("write failed: %s\n", strerror(-cnt));
- return 0;
+ goto out;
}
if (qflag)
- return 0;
+ goto out;
/* Finally, report back -- -C gives a parsable format */
t2 = tsub(t2, t1);
print_report("wrote", &t2, offset, count, total, cnt, Cflag);
+out:
qemu_io_free(buf);
return 0;
@@ -615,7 +674,7 @@ static const cmdinfo_t write_cmd = {
.cfunc = write_f,
.argmin = 2,
.argmax = -1,
- .args = "[-aCpq] [-P pattern ] off len",
+ .args = "[-abCpq] [-P pattern ] off len",
.oneline = "writes a number of bytes at a specified offset",
.help = write_help,
};
@@ -646,10 +705,10 @@ writev_f(int argc, char **argv)
struct timeval t1, t2;
int Cflag = 0, qflag = 0;
int c, cnt;
- char *buf, *p;
+ char *buf;
int64_t offset;
- int count = 0, total;
- int nr_iov, i;
+ int total;
+ int nr_iov;
int pattern = 0xcd;
QEMUIOVector qiov;
@@ -685,41 +744,8 @@ writev_f(int argc, char **argv)
return 0;
}
- if (count & 0x1ff) {
- printf("count %d is not sector aligned\n",
- count);
- return 0;
- }
-
-
- for (i = optind; i < argc; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n", argv[i]);
- return 0;
- }
- count += len;
- }
-
nr_iov = argc - optind;
- qemu_iovec_init(&qiov, nr_iov);
- buf = p = qemu_io_alloc(count, pattern);
- for (i = 0; i < nr_iov; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n",
- argv[optind]);
- return 0;
- }
-
- qemu_iovec_add(&qiov, p, len);
- p += len;
- optind++;
- }
+ buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
gettimeofday(&t1, NULL);
cnt = do_aio_writev(&qiov, offset, &total);
@@ -727,18 +753,17 @@ writev_f(int argc, char **argv)
if (cnt < 0) {
printf("writev failed: %s\n", strerror(-cnt));
- return 0;
+ goto out;
}
if (qflag)
- return 0;
+ goto out;
/* Finally, report back -- -C gives a parsable format */
t2 = tsub(t2, t1);
print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
-
+out:
qemu_io_free(buf);
-
return 0;
}
@@ -769,26 +794,24 @@ aio_write_done(void *opaque, int ret)
{
struct aio_ctx *ctx = opaque;
struct timeval t2;
- int total;
- int cnt = 1;
gettimeofday(&t2, NULL);
- total = ctx->qiov.size;
if (ret < 0) {
printf("aio_write failed: %s\n", strerror(-ret));
- return;
+ goto out;
}
- if (ctx->qflag)
- return;
+ if (ctx->qflag) {
+ goto out;
+ }
/* Finally, report back -- -C gives a parsable format */
t2 = tsub(t2, ctx->t1);
- print_report("wrote", &t2, ctx->offset, ctx->qiov.size, total, cnt,
- ctx->Cflag);
-
+ print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
+ ctx->qiov.size, 1, ctx->Cflag);
+out:
qemu_io_free(ctx->buf);
free(ctx);
}
@@ -800,44 +823,41 @@ aio_read_done(void *opaque, int ret)
{
struct aio_ctx *ctx = opaque;
struct timeval t2;
- int total;
- int cnt = 1;
gettimeofday(&t2, NULL);
- total = ctx->qiov.size;
-
if (ret < 0) {
printf("readv failed: %s\n", strerror(-ret));
- return;
+ goto out;
}
if (ctx->Pflag) {
- void *cmp_buf = malloc(total);
+ void *cmp_buf = malloc(ctx->qiov.size);
- memset(cmp_buf, ctx->pattern, total);
- if (memcmp(ctx->buf, cmp_buf, total)) {
+ memset(cmp_buf, ctx->pattern, ctx->qiov.size);
+ if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
printf("Pattern verification failed at offset %lld, "
- "%d bytes\n",
- (long long) ctx->offset, total);
+ "%zd bytes\n",
+ (long long) ctx->offset, ctx->qiov.size);
}
free(cmp_buf);
}
- if (ctx->qflag)
- return;
+ if (ctx->qflag) {
+ goto out;
+ }
- if (ctx->vflag)
- dump_buffer(ctx->buf, ctx->offset, total);
+ if (ctx->vflag) {
+ dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
+ }
/* Finally, report back -- -C gives a parsable format */
t2 = tsub(t2, ctx->t1);
- print_report("read", &t2, ctx->offset, ctx->qiov.size, total, cnt,
- ctx->Cflag);
-
+ print_report("read", &t2, ctx->offset, ctx->qiov.size,
+ ctx->qiov.size, 1, ctx->Cflag);
+out:
qemu_io_free(ctx->buf);
free(ctx);
-
}
static void
@@ -864,14 +884,10 @@ aio_read_help(void)
static int
aio_read_f(int argc, char **argv)
{
- char *p;
- int count = 0;
- int nr_iov, i, c;
+ int nr_iov, c;
struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
BlockDriverAIOCB *acb;
- ctx->pattern = 0xcd;
-
while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
switch (c) {
case 'C':
@@ -888,17 +904,20 @@ aio_read_f(int argc, char **argv)
ctx->vflag = 1;
break;
default:
+ free(ctx);
return command_usage(&aio_read_cmd);
}
}
- if (optind > argc - 2)
+ if (optind > argc - 2) {
+ free(ctx);
return command_usage(&aio_read_cmd);
-
+ }
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
+ free(ctx);
return 0;
}
optind++;
@@ -906,49 +925,21 @@ aio_read_f(int argc, char **argv)
if (ctx->offset & 0x1ff) {
printf("offset %lld is not sector aligned\n",
(long long)ctx->offset);
+ free(ctx);
return 0;
}
- if (count & 0x1ff) {
- printf("count %d is not sector aligned\n",
- count);
- return 0;
- }
-
- for (i = optind; i < argc; i++) {
- size_t len;
-
- len = cvtnum(argv[i]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n", argv[i]);
- return 0;
- }
- count += len;
- }
-
nr_iov = argc - optind;
- qemu_iovec_init(&ctx->qiov, nr_iov);
- ctx->buf = p = qemu_io_alloc(count, 0xab);
- for (i = 0; i < nr_iov; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n",
- argv[optind]);
- return 0;
- }
-
- qemu_iovec_add(&ctx->qiov, p, len);
- p += len;
- optind++;
- }
+ ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
gettimeofday(&ctx->t1, NULL);
acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
ctx->qiov.size >> 9, aio_read_done, ctx);
- if (!acb)
+ if (!acb) {
+ free(ctx->buf);
+ free(ctx);
return -EIO;
+ }
return 0;
}
@@ -990,9 +981,7 @@ aio_write_help(void)
static int
aio_write_f(int argc, char **argv)
{
- char *p;
- int count = 0;
- int nr_iov, i, c;
+ int nr_iov, c;
int pattern = 0xcd;
struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
BlockDriverAIOCB *acb;
@@ -1009,16 +998,20 @@ aio_write_f(int argc, char **argv)
pattern = atoi(optarg);
break;
default:
+ free(ctx);
return command_usage(&aio_write_cmd);
}
}
- if (optind > argc - 2)
+ if (optind > argc - 2) {
+ free(ctx);
return command_usage(&aio_write_cmd);
+ }
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
+ free(ctx);
return 0;
}
optind++;
@@ -1026,50 +1019,21 @@ aio_write_f(int argc, char **argv)
if (ctx->offset & 0x1ff) {
printf("offset %lld is not sector aligned\n",
(long long)ctx->offset);
+ free(ctx);
return 0;
}
- if (count & 0x1ff) {
- printf("count %d is not sector aligned\n",
- count);
- return 0;
- }
-
-
- for (i = optind; i < argc; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n", argv[i]);
- return 0;
- }
- count += len;
- }
-
nr_iov = argc - optind;
- qemu_iovec_init(&ctx->qiov, nr_iov);
- ctx->buf = p = qemu_io_alloc(count, pattern);
- for (i = 0; i < nr_iov; i++) {
- size_t len;
-
- len = cvtnum(argv[optind]);
- if (len < 0) {
- printf("non-numeric length argument -- %s\n",
- argv[optind]);
- return 0;
- }
-
- qemu_iovec_add(&ctx->qiov, p, len);
- p += len;
- optind++;
- }
+ ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
gettimeofday(&ctx->t1, NULL);
acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
ctx->qiov.size >> 9, aio_write_done, ctx);
- if (!acb)
+ if (!acb) {
+ free(ctx->buf);
+ free(ctx);
return -EIO;
+ }
return 0;
}
@@ -1262,7 +1226,7 @@ static const cmdinfo_t close_cmd = {
.oneline = "close the current open file",
};
-static int openfile(char *name, int flags)
+static int openfile(char *name, int flags, int growable)
{
if (bs) {
fprintf(stderr, "file open already, try 'help close'\n");
@@ -1273,12 +1237,19 @@ static int openfile(char *name, int flags)
if (!bs)
return 1;
+ if (growable) {
+ flags |= BDRV_O_FILE;
+ }
+
if (bdrv_open(bs, name, flags) == -1) {
fprintf(stderr, "%s: can't open device %s\n", progname, name);
bs = NULL;
return 1;
}
+ if (growable) {
+ bs->growable = 1;
+ }
return 0;
}
@@ -1297,6 +1268,7 @@ open_help(void)
" -r, -- open file read-only\n"
" -s, -- use snapshot file\n"
" -n, -- disable host cache\n"
+" -g, -- allow file to grow (only applies to protocols)"
"\n");
}
@@ -1307,9 +1279,10 @@ open_f(int argc, char **argv)
{
int flags = 0;
int readonly = 0;
+ int growable = 0;
int c;
- while ((c = getopt(argc, argv, "snCr")) != EOF) {
+ while ((c = getopt(argc, argv, "snCrg")) != EOF) {
switch (c) {
case 's':
flags |= BDRV_O_SNAPSHOT;
@@ -1323,6 +1296,9 @@ open_f(int argc, char **argv)
case 'r':
readonly = 1;
break;
+ case 'g':
+ growable = 1;
+ break;
default:
return command_usage(&open_cmd);
}
@@ -1336,7 +1312,7 @@ open_f(int argc, char **argv)
if (optind != argc - 1)
return command_usage(&open_cmd);
- return openfile(argv[optind], flags);
+ return openfile(argv[optind], flags, growable);
}
static const cmdinfo_t open_cmd = {
@@ -1385,6 +1361,7 @@ static void usage(const char *name)
" -r, --read-only export read-only\n"
" -s, --snapshot use snapshot file\n"
" -n, --nocache disable host cache\n"
+" -g, --growable allow file to grow (only applies to protocols)\n"
" -m, --misalign misalign allocations for O_DIRECT\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n"
@@ -1396,7 +1373,8 @@ static void usage(const char *name)
int main(int argc, char **argv)
{
int readonly = 0;
- const char *sopt = "hVc:Crsnm";
+ int growable = 0;
+ const char *sopt = "hVc:Crsnmg";
struct option lopt[] = {
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
@@ -1407,6 +1385,7 @@ int main(int argc, char **argv)
{ "snapshot", 0, 0, 's' },
{ "nocache", 0, 0, 'n' },
{ "misalign", 0, 0, 'm' },
+ { "growable", 0, 0, 'g' },
{ NULL, 0, 0, 0 }
};
int c;
@@ -1435,6 +1414,9 @@ int main(int argc, char **argv)
case 'm':
misalign = 1;
break;
+ case 'g':
+ growable = 1;
+ break;
case 'V':
printf("%s version %s\n", progname, VERSION);
exit(0);
@@ -1482,7 +1464,7 @@ int main(int argc, char **argv)
flags |= BDRV_O_RDWR;
if ((argc - optind) == 1)
- openfile(argv[optind], flags);
+ openfile(argv[optind], flags, growable);
command_loop();
/*
diff --git a/qemu/qemu-monitor.hx b/qemu/qemu-monitor.hx
index 62edbcde..70e24758 100644
--- a/qemu/qemu-monitor.hx
+++ b/qemu/qemu-monitor.hx
@@ -306,6 +306,11 @@ STEXI
Read I/O port.
ETEXI
+ { "o", "/ii", do_ioport_write,
+ "/fmt addr value", "I/O port write" },
+STEXI
+Write to I/O port.
+ETEXI
{ "sendkey", "si?", do_sendkey,
"keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
diff --git a/qemu/qemu-options.hx b/qemu/qemu-options.hx
index 3f699659..a58287cb 100644
--- a/qemu/qemu-options.hx
+++ b/qemu/qemu-options.hx
@@ -219,11 +219,30 @@ Use 'file' as a parallel flash image.
ETEXI
DEF("boot", HAS_ARG, QEMU_OPTION_boot,
- "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n")
+ "-boot [order=drives][,once=drives][,menu=on|off]\n"
+ " 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n)\n")
STEXI
-@item -boot [a|c|d|n]
-Boot on floppy (a), hard disk (c), CD-ROM (d), or Etherboot (n). Hard disk boot
-is the default.
+@item -boot [order=@var{drives}][,once=@var{drives}][,menu=on|off]
+
+Specify boot order @var{drives} as a string of drive letters. Valid
+drive letters depend on the target achitecture. The x86 PC uses: a, b
+(floppy 1 and 2), c (first hard disk), d (first CD-ROM), n-p (Etherboot
+from network adapter 1-4), hard disk boot is the default. To apply a
+particular boot order only on the first startup, specify it via
+@option{once}.
+
+Interactive boot menus/prompts can be enabled via @option{menu=on} as far
+as firmware/BIOS supports them. The default is non-interactive boot.
+
+@example
+# try to boot from network first, then from hard disk
+qemu -boot order=nc
+# boot from CD-ROM first, switch back to default order after reboot
+qemu -boot once=d
+@end example
+
+Note: The legacy format '-boot @var{drives}' is still supported but its
+use is discouraged as it may be removed from future versions.
ETEXI
DEF("snapshot", 0, QEMU_OPTION_snapshot,
diff --git a/qemu/savevm.c b/qemu/savevm.c
index 4cdb55b8..dc32f945 100644
--- a/qemu/savevm.c
+++ b/qemu/savevm.c
@@ -338,46 +338,28 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
return NULL;
}
-typedef struct QEMUFileBdrv
-{
- BlockDriverState *bs;
- int64_t base_offset;
-} QEMUFileBdrv;
-
static int block_put_buffer(void *opaque, const uint8_t *buf,
int64_t pos, int size)
{
- QEMUFileBdrv *s = opaque;
- bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
+ bdrv_save_vmstate(opaque, buf, pos, size);
return size;
}
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
{
- QEMUFileBdrv *s = opaque;
- return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
+ return bdrv_load_vmstate(opaque, buf, pos, size);
}
static int bdrv_fclose(void *opaque)
{
- QEMUFileBdrv *s = opaque;
- qemu_free(s);
return 0;
}
-static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
+static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int is_writable)
{
- QEMUFileBdrv *s;
-
- s = qemu_mallocz(sizeof(QEMUFileBdrv));
-
- s->bs = bs;
- s->base_offset = offset;
-
if (is_writable)
- return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
-
- return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
+ return qemu_fopen_ops(bs, block_put_buffer, NULL, bdrv_fclose, NULL, NULL);
+ return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclose, NULL, NULL);
}
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
@@ -575,7 +557,9 @@ int qemu_file_rate_limit(QEMUFile *f)
size_t qemu_file_set_rate_limit(QEMUFile *f, size_t new_rate)
{
- if (f->set_rate_limit)
+ /* any failed or completed migration keeps its state to allow probing of
+ * migration data, but has no associated file anymore */
+ if (f && f->set_rate_limit)
return f->set_rate_limit(f->opaque, new_rate);
return 0;
@@ -1070,7 +1054,6 @@ void do_savevm(Monitor *mon, const char *name)
BlockDriverState *bs, *bs1;
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
int must_delete, ret, i;
- BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUFile *f;
int saved_vm_running;
uint32_t vm_state_size;
@@ -1120,14 +1103,8 @@ void do_savevm(Monitor *mon, const char *name)
#endif
sn->vm_clock_nsec = qemu_get_clock(vm_clock);
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- monitor_printf(mon, "Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- goto the_end;
- }
-
/* save the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 1);
+ f = qemu_fopen_bdrv(bs, 1);
if (!f) {
monitor_printf(mon, "Could not open VM state file\n");
goto the_end;
@@ -1171,7 +1148,6 @@ void do_savevm(Monitor *mon, const char *name)
void do_loadvm(Monitor *mon, const char *name)
{
BlockDriverState *bs, *bs1;
- BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUSnapshotInfo sn;
QEMUFile *f;
int i, ret;
@@ -1219,19 +1195,13 @@ void do_loadvm(Monitor *mon, const char *name)
}
}
- if (bdrv_get_info(bs, bdi) < 0 || bdi->vm_state_offset <= 0) {
- monitor_printf(mon, "Device %s does not support VM state snapshots\n",
- bdrv_get_device_name(bs));
- return;
- }
-
/* Don't even try to load empty VM states */
ret = bdrv_snapshot_find(bs, &sn, name);
if ((ret >= 0) && (sn.vm_state_size == 0))
goto the_end;
/* restore the VM state */
- f = qemu_fopen_bdrv(bs, bdi->vm_state_offset, 0);
+ f = qemu_fopen_bdrv(bs, 0);
if (!f) {
monitor_printf(mon, "Could not open VM state file\n");
goto the_end;
diff --git a/qemu/softmmu_header.h b/qemu/softmmu_header.h
index 6e9297d5..4202baac 100644
--- a/qemu/softmmu_header.h
+++ b/qemu/softmmu_header.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/*
@@ -81,150 +80,6 @@
#define ADDR_READ addr_read
#endif
-#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
- (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
-
-static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
- "movl %%eax, %0\n"
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movzbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movzwl (%%eax), %0\n"
-#elif DATA_SIZE == 4
- "movl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-
-#if DATA_SIZE <= 2
-static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
-{
- int res;
-
- asm volatile ("movl %1, %%edx\n"
- "movl %1, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %1, %%eax\n"
- "je 1f\n"
- "movl %6, %%edx\n"
- "call %7\n"
-#if DATA_SIZE == 1
- "movsbl %%al, %0\n"
-#elif DATA_SIZE == 2
- "movswl %%ax, %0\n"
-#else
-#error unsupported size
-#endif
- "jmp 2f\n"
- "1:\n"
- "addl 12(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movsbl (%%eax), %0\n"
-#elif DATA_SIZE == 2
- "movswl (%%eax), %0\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- : "=r" (res)
- : "r" (ptr),
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
- return res;
-}
-#endif
-
-static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
-{
- asm volatile ("movl %0, %%edx\n"
- "movl %0, %%eax\n"
- "shrl %3, %%edx\n"
- "andl %4, %%eax\n"
- "andl %2, %%edx\n"
- "leal %5(%%edx, %%ebp), %%edx\n"
- "cmpl (%%edx), %%eax\n"
- "movl %0, %%eax\n"
- "je 1f\n"
-#if DATA_SIZE == 1
- "movzbl %b1, %%edx\n"
-#elif DATA_SIZE == 2
- "movzwl %w1, %%edx\n"
-#elif DATA_SIZE == 4
- "movl %1, %%edx\n"
-#else
-#error unsupported size
-#endif
- "movl %6, %%ecx\n"
- "call %7\n"
- "jmp 2f\n"
- "1:\n"
- "addl 8(%%edx), %%eax\n"
-#if DATA_SIZE == 1
- "movb %b1, (%%eax)\n"
-#elif DATA_SIZE == 2
- "movw %w1, (%%eax)\n"
-#elif DATA_SIZE == 4
- "movl %1, (%%eax)\n"
-#else
-#error unsupported size
-#endif
- "2:\n"
- :
- : "r" (ptr),
-#if DATA_SIZE == 1
- "q" (v),
-#else
- "r" (v),
-#endif
- "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
- "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
- "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
- "i" (CPU_MMU_INDEX),
- "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
- : "%eax", "%ecx", "%edx", "memory", "cc");
-}
-
-#else
-
/* generic load/store macros */
#ifdef _MSC_VER
DATA_TYPE glue(glue(my__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
@@ -316,8 +171,6 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
-#endif /* !asm */
-
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
#if DATA_SIZE == 8
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index 06dc4c68..df19f028 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -124,6 +124,7 @@ extern int graphic_rotate;
extern int no_quit;
extern int semihosting_enabled;
extern int old_param;
+extern int boot_menu;
#ifdef CONFIG_KQEMU
extern int kqemu_allowed;
diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h
index 0f802668..96294010 100644
--- a/qemu/target-i386/cpu.h
+++ b/qemu/target-i386/cpu.h
@@ -267,11 +267,11 @@
#define MCE_CAP_DEF MCG_CTL_P
#define MCE_BANKS_DEF 10
-#define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */
+#define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
-#define MCI_STATUS_VAL (1UL<<63) /* valid error */
-#define MCI_STATUS_OVER (1UL<<62) /* previous errors lost */
-#define MCI_STATUS_UC (1UL<<61) /* uncorrected error */
+#define MCI_STATUS_VAL (1ULL<<63) /* valid error */
+#define MCI_STATUS_OVER (1ULL<<62) /* previous errors lost */
+#define MCI_STATUS_UC (1ULL<<61) /* uncorrected error */
#define MSR_IA32_TSC 0x10
#define MSR_IA32_APICBASE 0x1b
@@ -785,6 +785,10 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
}
}
+int cpu_x86_get_descr_debug(CPUX86State* env, unsigned int selector,
+ target_ulong* base, unsigned int* limit,
+ unsigned int* flags);
+
/* wrapper, just in case memory mappings must be changed */
static inline void cpu_x86_set_cpl(CPUX86State *s, int cpl)
{
diff --git a/qemu/target-i386/helper.c b/qemu/target-i386/helper.c
index 48641f3a..ea781963 100644
--- a/qemu/target-i386/helper.c
+++ b/qemu/target-i386/helper.c
@@ -145,8 +145,7 @@ static x86_def_t x86_defs[] = {
CPUID_PSE36,
.ext_features = CPUID_EXT_SSE3,
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
- CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
- CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
.ext3_features = CPUID_EXT3_SVM,
.xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_VERSION,
@@ -1809,6 +1808,35 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
}
}
+int cpu_x86_get_descr_debug(CPUX86State* env, unsigned int selector,
+ target_ulong* base, unsigned int* limit,
+ unsigned int* flags)
+{
+ SegmentCache* dt;
+ target_ulong ptr;
+ uint32_t e1, e2;
+ int index;
+
+ if (selector & 0x4)
+ dt = &env->ldt;
+ else
+ dt = &env->gdt;
+ index = selector & ~7;
+ ptr = dt->base + index;
+ if ((index + 7) > dt->limit
+ || cpu_memory_rw_debug(env, ptr, (uint8_t*)&e1, sizeof(e1), 0) != 0
+ || cpu_memory_rw_debug(env, ptr + 4, (uint8_t*)&e2, sizeof(e2), 0) != 0)
+ return 0;
+
+ *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
+ *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
+ if (e2 & DESC_G_MASK)
+ *limit = (*limit << 12) | 0xfff;
+ *flags = e2;
+
+ return 1;
+}
+
CPUX86State *cpu_x86_init(const char *cpu_model)
{
CPUX86State *env;
diff --git a/qemu/target-i386/kvm.c b/qemu/target-i386/kvm.c
index 4a3f598e..cab9fcca 100644
--- a/qemu/target-i386/kvm.c
+++ b/qemu/target-i386/kvm.c
@@ -239,8 +239,11 @@ static int kvm_has_msr_star(CPUState *env)
if (ret < 0)
return 0;
- kvm_msr_list = qemu_mallocz(sizeof(msr_list) +
- msr_list.nmsrs * sizeof(msr_list.indices[0]));
+ /* Old kernel modules had a bug and could write beyond the provided
+ memory. Allocate at least a safe amount of 1K. */
+ kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) +
+ msr_list.nmsrs *
+ sizeof(msr_list.indices[0])));
kvm_msr_list->nmsrs = msr_list.nmsrs;
ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);
diff --git a/qemu/target-mips/helper.c b/qemu/target-mips/helper.c
index fecbcb2f..73690257 100644
--- a/qemu/target-mips/helper.c
+++ b/qemu/target-mips/helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include
diff --git a/qemu/target-mips/op_helper.c b/qemu/target-mips/op_helper.c
index b4c98fc0..194414c7 100644
--- a/qemu/target-mips/op_helper.c
+++ b/qemu/target-mips/op_helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include "exec.h"
diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c
index cf467f89..6a1273f0 100644
--- a/qemu/target-mips/translate.c
+++ b/qemu/target-mips/translate.c
@@ -16,8 +16,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
@@ -1174,19 +1173,18 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
#if defined(TARGET_MIPS64)
case OPC_SCD:
save_cpu_state(ctx, 0);
- op_ldst_scd(t0, t1, t0, ctx);
+ op_ldst_scd(t1, t0, rt, ctx);
opn = "scd";
break;
#endif
case OPC_SC:
save_cpu_state(ctx, 0);
- op_ldst_sc(t0, t1, t0, ctx);
+ op_ldst_sc(t1, t0, rt, ctx);
opn = "sc";
break;
}
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
tcg_temp_free(t1);
- gen_store_gpr(t0, rt);
tcg_temp_free(t0);
}
diff --git a/qemu/target-mips/translate_init.c b/qemu/target-mips/translate_init.c
index d7617f60..eb35dbad 100644
--- a/qemu/target-mips/translate_init.c
+++ b/qemu/target-mips/translate_init.c
@@ -15,8 +15,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/* CPU / CPU family specific config register values. */
diff --git a/qemu/target-ppc/cpu.h b/qemu/target-ppc/cpu.h
index 59d47d2d..69c1d580 100644
--- a/qemu/target-ppc/cpu.h
+++ b/qemu/target-ppc/cpu.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#if !defined (__CPU_PPC_H__)
#define __CPU_PPC_H__
diff --git a/qemu/target-ppc/exec.h b/qemu/target-ppc/exec.h
index f6b9ee6c..0481eb23 100644
--- a/qemu/target-ppc/exec.h
+++ b/qemu/target-ppc/exec.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#if !defined (__PPC_H__)
#define __PPC_H__
diff --git a/qemu/target-ppc/helper.c b/qemu/target-ppc/helper.c
index 5a7a935b..bd9bc8a8 100644
--- a/qemu/target-ppc/helper.c
+++ b/qemu/target-ppc/helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include
diff --git a/qemu/target-ppc/helper_regs.h b/qemu/target-ppc/helper_regs.h
index 15392393..2a1f541d 100644
--- a/qemu/target-ppc/helper_regs.h
+++ b/qemu/target-ppc/helper_regs.h
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#if !defined(__HELPER_REGS_H__)
diff --git a/qemu/target-ppc/op_helper.c b/qemu/target-ppc/op_helper.c
index 94e53032..c352aa71 100644
--- a/qemu/target-ppc/op_helper.c
+++ b/qemu/target-ppc/op_helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include "exec.h"
diff --git a/qemu/target-ppc/translate.c b/qemu/target-ppc/translate.c
index a14d197e..da3d7de8 100644
--- a/qemu/target-ppc/translate.c
+++ b/qemu/target-ppc/translate.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include
@@ -5935,7 +5934,7 @@ static void gen_wrteei(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
- if (ctx->opcode & 0x00010000) {
+ if (ctx->opcode & 0x00008000) {
tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
/* Stop translation to have a chance to raise an exception */
gen_stop_exception(ctx);
@@ -6908,8 +6907,8 @@ static always_inline void gen_evmergelo (DisasContext *ctx)
tcg_temp_free(t0);
tcg_temp_free(t1);
#else
- tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
#endif
}
static always_inline void gen_evmergehilo (DisasContext *ctx)
@@ -6946,8 +6945,16 @@ static always_inline void gen_evmergelohi (DisasContext *ctx)
tcg_temp_free(t0);
tcg_temp_free(t1);
#else
- tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
- tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+ if (rD(ctx->opcode) == rA(ctx->opcode)) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+ tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
+ tcg_temp_free_i32(tmp);
+ } else {
+ tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+ tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+ }
#endif
}
static always_inline void gen_evsplati (DisasContext *ctx)
@@ -8150,7 +8157,7 @@ GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
-GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE),
+GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE),
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
diff --git a/qemu/target-ppc/translate_init.c b/qemu/target-ppc/translate_init.c
index 04225e55..3b6e2d50 100644
--- a/qemu/target-ppc/translate_init.c
+++ b/qemu/target-ppc/translate_init.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
/* A lot of PowerPC definition have been included here.
@@ -3381,7 +3380,7 @@ static void init_proc_405 (CPUPPCState *env)
PPC_DCR | PPC_WRTEE | PPC_RFMCI | \
PPC_CACHE | PPC_CACHE_ICBI | \
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | \
+ PPC_MEM_TLBSYNC | PPC_MFTB | \
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
PPC_440_SPEC)
#define POWERPC_MSRM_440EP (0x000000000006D630ULL)
@@ -3461,7 +3460,7 @@ static void init_proc_440EP (CPUPPCState *env)
PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI | \
PPC_CACHE | PPC_CACHE_ICBI | \
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVA | \
+ PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | \
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
PPC_440_SPEC)
#define POWERPC_MSRM_440GP (0x000000000006FF30ULL)
@@ -3523,7 +3522,7 @@ static void init_proc_440GP (CPUPPCState *env)
PPC_DCR | PPC_WRTEE | \
PPC_CACHE | PPC_CACHE_ICBI | \
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | \
+ PPC_MEM_TLBSYNC | PPC_MFTB | \
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
PPC_440_SPEC)
#define POWERPC_MSRM_440x4 (0x000000000006FF30ULL)
@@ -3585,7 +3584,7 @@ static void init_proc_440x4 (CPUPPCState *env)
PPC_DCR | PPC_WRTEE | PPC_RFMCI | \
PPC_CACHE | PPC_CACHE_ICBI | \
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | \
+ PPC_MEM_TLBSYNC | PPC_MFTB | \
PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
PPC_440_SPEC)
#define POWERPC_MSRM_440x5 (0x000000000006FF30ULL)
@@ -3663,7 +3662,7 @@ static void init_proc_440x5 (CPUPPCState *env)
/* PowerPC 460 (guessed) */
#define POWERPC_INSNS_460 (PPC_INSNS_BASE | PPC_STRING | \
PPC_DCR | PPC_DCRX | PPC_DCRUX | \
- PPC_WRTEE | PPC_MFAPIDI | \
+ PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB | \
PPC_CACHE | PPC_CACHE_ICBI | \
PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
PPC_MEM_TLBSYNC | PPC_TLBIVA | \
@@ -3750,7 +3749,7 @@ static void init_proc_460 (CPUPPCState *env)
#define POWERPC_INSNS_460F (PPC_INSNS_BASE | PPC_STRING | \
PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | \
PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
+ PPC_FLOAT_STFIWX | PPC_MFTB | \
PPC_DCR | PPC_DCRX | PPC_DCRUX | \
PPC_WRTEE | PPC_MFAPIDI | \
PPC_CACHE | PPC_CACHE_ICBI | \
diff --git a/qemu/target-sparc/cpu.h b/qemu/target-sparc/cpu.h
index d592bea3..76e1e796 100644
--- a/qemu/target-sparc/cpu.h
+++ b/qemu/target-sparc/cpu.h
@@ -115,15 +115,18 @@ enum {
#define TBR_BASE_MASK 0xfffff000
#if defined(TARGET_SPARC64)
-#define PS_IG (1<<11)
-#define PS_MG (1<<10)
+#define PS_TCT (1<<12) /* UA2007, impl.dep. trap on control transfer */
+#define PS_IG (1<<11) /* v9, zero on UA2007 */
+#define PS_MG (1<<10) /* v9, zero on UA2007 */
+#define PS_CLE (1<<9) /* UA2007 */
+#define PS_TLE (1<<8) /* UA2007 */
#define PS_RMO (1<<7)
-#define PS_RED (1<<5)
-#define PS_PEF (1<<4)
-#define PS_AM (1<<3)
+#define PS_RED (1<<5) /* v9, zero on UA2007 */
+#define PS_PEF (1<<4) /* enable fpu */
+#define PS_AM (1<<3) /* address mask */
#define PS_PRIV (1<<2)
#define PS_IE (1<<1)
-#define PS_AG (1<<0)
+#define PS_AG (1<<0) /* v9, zero on UA2007 */
#define FPRS_FEF (1<<2)
@@ -291,11 +294,15 @@ typedef struct CPUSPARCState {
float32 fpr[TARGET_FPREGS]; /* floating point registers */
uint32_t cwp; /* index of current register window (extracted
from PSR) */
+#if !defined(TARGET_SPARC64) || defined(TARGET_ABI32)
uint32_t wim; /* window invalid mask */
+#endif
target_ulong tbr; /* trap base register */
int psrs; /* supervisor mode (extracted from PSR) */
int psrps; /* previous supervisor mode */
+#if !defined(TARGET_SPARC64)
int psret; /* enable traps */
+#endif
uint32_t psrpil; /* interrupt blocking level */
uint32_t pil_in; /* incoming interrupt level bitmap */
int psref; /* enable fpu */
@@ -378,12 +385,21 @@ void gen_intermediate_code_init(CPUSPARCState *env);
/* cpu-exec.c */
int cpu_sparc_exec(CPUSPARCState *s);
+#if !defined (TARGET_SPARC64)
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
(env->psref? PSR_EF : 0) | \
(env->psrpil << 8) | \
(env->psrs? PSR_S : 0) | \
(env->psrps? PSR_PS : 0) | \
(env->psret? PSR_ET : 0) | env->cwp)
+#else
+#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
+ (env->psref? PSR_EF : 0) | \
+ (env->psrpil << 8) | \
+ (env->psrs? PSR_S : 0) | \
+ (env->psrps? PSR_PS : 0) | \
+ env->cwp)
+#endif
#ifndef NO_CPU_IO_DEFS
static inline void memcpy32(target_ulong *dst, const target_ulong *src)
@@ -425,6 +441,7 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
}
#endif
+#if !defined (TARGET_SPARC64)
#define PUT_PSR(env, val) do { int _tmp = val; \
env->psr = _tmp & PSR_ICC; \
env->psref = (_tmp & PSR_EF)? 1 : 0; \
@@ -435,6 +452,17 @@ static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
cpu_set_cwp(env, _tmp & PSR_CWP); \
CC_OP = CC_OP_FLAGS; \
} while (0)
+#else
+#define PUT_PSR(env, val) do { int _tmp = val; \
+ env->psr = _tmp & PSR_ICC; \
+ env->psref = (_tmp & PSR_EF)? 1 : 0; \
+ env->psrpil = (_tmp & PSR_PIL) >> 8; \
+ env->psrs = (_tmp & PSR_S)? 1 : 0; \
+ env->psrps = (_tmp & PSR_PS)? 1 : 0; \
+ cpu_set_cwp(env, _tmp & PSR_CWP); \
+ CC_OP = CC_OP_FLAGS; \
+ } while (0)
+#endif
#ifdef TARGET_SPARC64
#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20))
diff --git a/qemu/target-sparc/exec.h b/qemu/target-sparc/exec.h
index f37c8ad9..e120d6fe 100644
--- a/qemu/target-sparc/exec.h
+++ b/qemu/target-sparc/exec.h
@@ -24,10 +24,23 @@ static inline void regs_to_env(void)
/* op_helper.c */
void do_interrupt(CPUState *env);
+static inline int cpu_interrupts_enabled(CPUState *env1)
+{
+#if !defined (TARGET_SPARC64)
+ if (env1->psret != 0)
+ return 1;
+#else
+ if (env1->pstate & PS_IE)
+ return 1;
+#endif
+
+ return 0;
+}
+
static inline int cpu_has_work(CPUState *env1)
{
return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env1->psret != 0);
+ cpu_interrupts_enabled(env1);
}
diff --git a/qemu/target-sparc/helper.c b/qemu/target-sparc/helper.c
index 2f41418c..04513f82 100644
--- a/qemu/target-sparc/helper.c
+++ b/qemu/target-sparc/helper.c
@@ -14,8 +14,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ * License along with this library; if not, see .
*/
#include
#include
@@ -369,42 +368,79 @@ void dump_mmu(CPUState *env)
#endif /* DEBUG_MMU */
#else /* !TARGET_SPARC64 */
+
+// 41 bit physical address space
+static inline target_phys_addr_t ultrasparc_truncate_physical(uint64_t x)
+{
+ return x & 0x1ffffffffffULL;
+}
+
/*
* UltraSparc IIi I/DMMUs
*/
+
+static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask)
+{
+ return (x & mask) == (y & mask);
+}
+
+// Returns true if TTE tag is valid and matches virtual address value in context
+// requires virtual address mask value calculated from TTE entry size
+static inline int ultrasparc_tag_match(uint64_t tlb_tag, uint64_t tlb_tte,
+ uint64_t address, uint64_t context,
+ target_phys_addr_t *physical)
+{
+ uint64_t mask;
+
+ switch ((tlb_tte >> 61) & 3) {
+ default:
+ case 0x0: // 8k
+ mask = 0xffffffffffffe000ULL;
+ break;
+ case 0x1: // 64k
+ mask = 0xffffffffffff0000ULL;
+ break;
+ case 0x2: // 512k
+ mask = 0xfffffffffff80000ULL;
+ break;
+ case 0x3: // 4M
+ mask = 0xffffffffffc00000ULL;
+ break;
+ }
+
+ // valid, context match, virtual address match?
+ if ((tlb_tte & 0x8000000000000000ULL) &&
+ compare_masked(context, tlb_tag, 0x1fff) &&
+ compare_masked(address, tlb_tag, mask))
+ {
+ // decode physical address
+ *physical = ((tlb_tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL;
+ return 1;
+ }
+
+ return 0;
+}
+
static int get_physical_address_data(CPUState *env,
target_phys_addr_t *physical, int *prot,
target_ulong address, int rw, int is_user)
{
- target_ulong mask;
unsigned int i;
+ uint64_t context;
if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
- *physical = address;
+ *physical = ultrasparc_truncate_physical(address);
*prot = PAGE_READ | PAGE_WRITE;
return 0;
}
+ context = env->dmmuregs[1] & 0x1fff;
+
for (i = 0; i < 64; i++) {
- switch ((env->dtlb_tte[i] >> 61) & 3) {
- default:
- case 0x0: // 8k
- mask = 0xffffffffffffe000ULL;
- break;
- case 0x1: // 64k
- mask = 0xffffffffffff0000ULL;
- break;
- case 0x2: // 512k
- mask = 0xfffffffffff80000ULL;
- break;
- case 0x3: // 4M
- mask = 0xffffffffffc00000ULL;
- break;
- }
// ctx match, vaddr match, valid?
- if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->dtlb_tag[i] & mask) &&
- (env->dtlb_tte[i] & 0x8000000000000000ULL)) {
+ if (ultrasparc_tag_match(env->dtlb_tag[i], env->dtlb_tte[i],
+ address, context, physical)
+ ) {
// access ok?
if (((env->dtlb_tte[i] & 0x4) && is_user) ||
(!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
@@ -419,8 +455,6 @@ static int get_physical_address_data(CPUState *env,
#endif
return 1;
}
- *physical = ((env->dtlb_tte[i] & mask) | (address & ~mask)) &
- 0x1ffffffe000ULL;
*prot = PAGE_READ;
if (env->dtlb_tte[i] & 0x2)
*prot |= PAGE_WRITE;
@@ -430,7 +464,7 @@ static int get_physical_address_data(CPUState *env,
#ifdef DEBUG_MMU
printf("DMISS at 0x%" PRIx64 "\n", address);
#endif
- env->dmmuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
+ env->dmmuregs[6] = (address & ~0x1fffULL) | context;
env->exception_index = TT_DMISS;
return 1;
}
@@ -439,35 +473,23 @@ static int get_physical_address_code(CPUState *env,
target_phys_addr_t *physical, int *prot,
target_ulong address, int is_user)
{
- target_ulong mask;
unsigned int i;
+ uint64_t context;
- if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
- *physical = address;
+ if ((env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0) {
+ /* IMMU disabled */
+ *physical = ultrasparc_truncate_physical(address);
*prot = PAGE_EXEC;
return 0;
}
+ context = env->dmmuregs[1] & 0x1fff;
+
for (i = 0; i < 64; i++) {
- switch ((env->itlb_tte[i] >> 61) & 3) {
- default:
- case 0x0: // 8k
- mask = 0xffffffffffffe000ULL;
- break;
- case 0x1: // 64k
- mask = 0xffffffffffff0000ULL;
- break;
- case 0x2: // 512k
- mask = 0xfffffffffff80000ULL;
- break;
- case 0x3: // 4M
- mask = 0xffffffffffc00000ULL;
- break;
- }
// ctx match, vaddr match, valid?
- if (env->dmmuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
- (address & mask) == (env->itlb_tag[i] & mask) &&
- (env->itlb_tte[i] & 0x8000000000000000ULL)) {
+ if (ultrasparc_tag_match(env->itlb_tag[i], env->itlb_tte[i],
+ address, context, physical)
+ ) {
// access ok?
if ((env->itlb_tte[i] & 0x4) && is_user) {
if (env->immuregs[3]) /* Fault status register */
@@ -480,8 +502,6 @@ static int get_physical_address_code(CPUState *env,
#endif
return 1;
}
- *physical = ((env->itlb_tte[i] & mask) | (address & ~mask)) &
- 0x1ffffffe000ULL;
*prot = PAGE_EXEC;
return 0;
}
@@ -490,7 +510,7 @@ static int get_physical_address_code(CPUState *env,
printf("TMISS at 0x%" PRIx64 "\n", address);
#endif
/* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
- env->immuregs[6] = (address & ~0x1fffULL) | (env->dmmuregs[1] & 0x1fff);
+ env->immuregs[6] = (address & ~0x1fffULL) | context;
env->exception_index = TT_TMISS;
return 1;
}
@@ -646,7 +666,9 @@ void cpu_reset(CPUSPARCState *env)
tlb_flush(env, 1);
env->cwp = 0;
+#ifndef TARGET_SPARC64
env->wim = 1;
+#endif
env->regwptr = env->regbase + (env->cwp * 16);
#if defined(CONFIG_USER_ONLY)
#ifdef TARGET_SPARC64
@@ -656,7 +678,9 @@ void cpu_reset(CPUSPARCState *env)
env->asi = 0x82; // Primary no-fault
#endif
#else
+#if !defined(TARGET_SPARC64)
env->psret = 0;
+#endif
env->psrs = 1;
env->psrps = 1;
CC_OP = CC_OP_FLAGS;
diff --git a/qemu/target-sparc/op_helper.c b/qemu/target-sparc/op_helper.c
index a1f50549..d25b642c 100644
--- a/qemu/target-sparc/op_helper.c
+++ b/qemu/target-sparc/op_helper.c
@@ -1949,13 +1949,13 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
case 0x89: // Secondary LE
switch(size) {
case 2:
- addr = bswap16(addr);
+ val = bswap16(val);
break;
case 4:
- addr = bswap32(addr);
+ val = bswap32(val);
break;
case 8:
- addr = bswap64(addr);
+ val = bswap64(val);
break;
default:
break;
@@ -2321,13 +2321,13 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
case 0x89: // Secondary LE
switch(size) {
case 2:
- addr = bswap16(addr);
+ val = bswap16(val);
break;
case 4:
- addr = bswap32(addr);
+ val = bswap32(val);
break;
case 8:
- addr = bswap64(addr);
+ val = bswap64(val);
break;
default:
break;
@@ -3225,8 +3225,14 @@ static inline void change_pstate(uint64_t new_pstate)
uint64_t pstate_regs, new_pstate_regs;
uint64_t *src, *dst;
+ if (env->def->features & CPU_FEATURE_GL) {
+ // PS_AG is not implemented in this case
+ new_pstate &= ~PS_AG;
+ }
+
pstate_regs = env->pstate & 0xc01;
new_pstate_regs = new_pstate & 0xc01;
+
if (new_pstate_regs != pstate_regs) {
// Switch global register bank
src = get_gregset(new_pstate_regs);
@@ -3239,8 +3245,7 @@ static inline void change_pstate(uint64_t new_pstate)
void helper_wrpstate(target_ulong new_state)
{
- if (!(env->def->features & CPU_FEATURE_GL))
- change_pstate(new_state & 0xf3f);
+ change_pstate(new_state & 0xf3f);
}
void helper_done(void)
@@ -3392,23 +3397,23 @@ void do_interrupt(CPUState *env)
env->tsptr->tpc = env->pc;
env->tsptr->tnpc = env->npc;
env->tsptr->tt = intno;
- if (!(env->def->features & CPU_FEATURE_GL)) {
- switch (intno) {
- case TT_IVEC:
- change_pstate(PS_PEF | PS_PRIV | PS_IG);
- break;
- case TT_TFAULT:
- case TT_TMISS:
- case TT_DFAULT:
- case TT_DMISS:
- case TT_DPROT:
- change_pstate(PS_PEF | PS_PRIV | PS_MG);
- break;
- default:
- change_pstate(PS_PEF | PS_PRIV | PS_AG);
- break;
- }
+
+ switch (intno) {
+ case TT_IVEC:
+ change_pstate(PS_PEF | PS_PRIV | PS_IG);
+ break;
+ case TT_TFAULT:
+ case TT_TMISS:
+ case TT_DFAULT:
+ case TT_DMISS:
+ case TT_DPROT:
+ change_pstate(PS_PEF | PS_PRIV | PS_MG);
+ break;
+ default:
+ change_pstate(PS_PEF | PS_PRIV | PS_AG);
+ break;
}
+
if (intno == TT_CLRWIN)
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
else if ((intno & 0x1c0) == TT_SPILL)
diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c
index 6de40791..a372ecab 100644
--- a/qemu/target-sparc/translate.c
+++ b/qemu/target-sparc/translate.c
@@ -15,8 +15,7 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
+ License along with this library; if not, see .
*/
#include
diff --git a/qemu/usb-linux.c b/qemu/usb-linux.c
index 67e4acd5..3c724baf 100644
--- a/qemu/usb-linux.c
+++ b/qemu/usb-linux.c
@@ -1265,6 +1265,15 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
/* only check the host once */
if (!usb_fs_type) {
+ dir = opendir(USBSYSBUS_PATH "/devices");
+ if (dir) {
+ /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
+ strcpy(devpath, USBDEVBUS_PATH);
+ usb_fs_type = USB_FS_SYS;
+ closedir(dir);
+ dprintf(USBDBG_DEVOPENED, USBSYSBUS_PATH);
+ goto found_devices;
+ }
f = fopen(USBPROCBUS_PATH "/devices", "r");
if (f) {
/* devices found in /proc/bus/usb/ */
@@ -1284,15 +1293,6 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
dprintf(USBDBG_DEVOPENED, USBDEVBUS_PATH);
goto found_devices;
}
- dir = opendir(USBSYSBUS_PATH "/devices");
- if (dir) {
- /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
- strcpy(devpath, USBDEVBUS_PATH);
- usb_fs_type = USB_FS_SYS;
- closedir(dir);
- dprintf(USBDBG_DEVOPENED, USBSYSBUS_PATH);
- goto found_devices;
- }
found_devices:
if (!usb_fs_type) {
monitor_printf(mon, "husb: unable to access USB devices\n");
diff --git a/qemu/vl.c b/qemu/vl.c
index b3b2c5e1..dce1f19f 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -265,6 +265,7 @@ const char *prom_envs[MAX_PROM_ENVS];
#endif
int nb_drives_opt;
struct drive_opt drives_opt[MAX_DRIVES];
+int boot_menu;
int nb_numa_nodes;
uint64_t node_mem[MAX_NODES];
@@ -285,6 +286,9 @@ static QEMUTimer *nographic_timer;
uint8_t qemu_uuid[16];
+static QEMUBootSetHandler *boot_set_handler;
+static void *boot_set_opaque;
+
/***********************************************************/
/* x86 ISA bus support */
@@ -2367,6 +2371,59 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
return drives_table_idx;
}
+void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
+{
+ boot_set_handler = func;
+ boot_set_opaque = opaque;
+}
+
+int qemu_boot_set(const char *boot_devices)
+{
+ if (!boot_set_handler) {
+ return -EINVAL;
+ }
+ return boot_set_handler(boot_set_opaque, boot_devices);
+}
+
+static int parse_bootdevices(char *devices)
+{
+ /* We just do some generic consistency checks */
+ const char *p;
+ int bitmap = 0;
+
+ for (p = devices; *p != '\0'; p++) {
+ /* Allowed boot devices are:
+ * a-b: floppy disk drives
+ * c-f: IDE disk drives
+ * g-m: machine implementation dependant drives
+ * n-p: network devices
+ * It's up to each machine implementation to check if the given boot
+ * devices match the actual hardware implementation and firmware
+ * features.
+ */
+ if (*p < 'a' || *p > 'p') {
+ fprintf(stderr, "Invalid boot device '%c'\n", *p);
+ exit(1);
+ }
+ if (bitmap & (1 << (*p - 'a'))) {
+ fprintf(stderr, "Boot device '%c' was given twice\n", *p);
+ exit(1);
+ }
+ bitmap |= 1 << (*p - 'a');
+ }
+ return bitmap;
+}
+
+static void restore_boot_devices(void *opaque)
+{
+ char *standard_boot_devices = opaque;
+
+ qemu_boot_set(standard_boot_devices);
+
+ qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
+ qemu_free(standard_boot_devices);
+}
+
static void numa_add(const char *optarg)
{
char option[128];
@@ -3407,12 +3464,13 @@ void vm_start(void)
/* reset/shutdown handler */
typedef struct QEMUResetEntry {
+ TAILQ_ENTRY(QEMUResetEntry) entry;
QEMUResetHandler *func;
void *opaque;
- struct QEMUResetEntry *next;
} QEMUResetEntry;
-static QEMUResetEntry *first_reset_entry;
+static TAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
+ TAILQ_HEAD_INITIALIZER(reset_handlers);
static int reset_requested;
static int shutdown_requested;
static int powerdown_requested;
@@ -3466,24 +3524,32 @@ static void do_vm_stop(int reason)
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
{
- QEMUResetEntry **pre, *re;
+ QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
- pre = &first_reset_entry;
- while (*pre != NULL)
- pre = &(*pre)->next;
- re = qemu_mallocz(sizeof(QEMUResetEntry));
re->func = func;
re->opaque = opaque;
- re->next = NULL;
- *pre = re;
+ TAILQ_INSERT_TAIL(&reset_handlers, re, entry);
}
-void qemu_system_reset(void)
+void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
{
QEMUResetEntry *re;
+ TAILQ_FOREACH(re, &reset_handlers, entry) {
+ if (re->func == func && re->opaque == opaque) {
+ TAILQ_REMOVE(&reset_handlers, re, entry);
+ qemu_free(re);
+ return;
+ }
+ }
+}
+
+void qemu_system_reset(void)
+{
+ QEMUResetEntry *re, *nre;
+
/* reset all devices */
- for(re = first_reset_entry; re != NULL; re = re->next) {
+ TAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
re->func(re->opaque);
}
}
@@ -4783,7 +4849,7 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp)
int snapshot, linux_boot, net_boot;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
- const char *boot_devices = "";
+ char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
DisplayState *ds;
DisplayChangeListener *dcl;
int cyls, heads, secs, translation;
@@ -5072,33 +5138,51 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp)
drive_add(optarg, CDROM_ALIAS);
break;
case QEMU_OPTION_boot:
- boot_devices = optarg;
- /* We just do some generic consistency checks */
{
- /* Could easily be extended to 64 devices if needed */
- const char *p;
-
- boot_devices_bitmap = 0;
- for (p = boot_devices; *p != '\0'; p++) {
- /* Allowed boot devices are:
- * a b : floppy disk drives
- * c ... f : IDE disk drives
- * g ... m : machine implementation dependant drives
- * n ... p : network devices
- * It's up to each machine implementation to check
- * if the given boot devices match the actual hardware
- * implementation and firmware features.
- */
- if (*p < 'a' || *p > 'q') {
- fprintf(stderr, "Invalid boot device '%c'\n", *p);
- exit(1);
+ static const char * const params[] = {
+ "order", "once", "menu", NULL
+ };
+ char buf[sizeof(boot_devices)];
+ char *standard_boot_devices;
+ int legacy = 0;
+
+ if (!strchr(optarg, '=')) {
+ legacy = 1;
+ pstrcpy(buf, sizeof(buf), optarg);
+ } else if (check_params(buf, sizeof(buf), params, optarg) < 0) {
+ fprintf(stderr,
+ "qemu: unknown boot parameter '%s' in '%s'\n",
+ buf, optarg);
+ exit(1);
+ }
+
+ if (legacy ||
+ get_param_value(buf, sizeof(buf), "order", optarg)) {
+ boot_devices_bitmap = parse_bootdevices(buf);
+ pstrcpy(boot_devices, sizeof(boot_devices), buf);
+ }
+ if (!legacy) {
+ if (get_param_value(buf, sizeof(buf),
+ "once", optarg)) {
+ boot_devices_bitmap |= parse_bootdevices(buf);
+ standard_boot_devices = qemu_strdup(boot_devices);
+ pstrcpy(boot_devices, sizeof(boot_devices), buf);
+ qemu_register_reset(restore_boot_devices,
+ standard_boot_devices);
}
- if (boot_devices_bitmap & (1 << (*p - 'a'))) {
- fprintf(stderr,
- "Boot device '%c' was given twice\n",*p);
- exit(1);
+ if (get_param_value(buf, sizeof(buf),
+ "menu", optarg)) {
+ if (!strcmp(buf, "on")) {
+ boot_menu = 1;
+ } else if (!strcmp(buf, "off")) {
+ boot_menu = 0;
+ } else {
+ fprintf(stderr,
+ "qemu: invalid option value '%s'\n",
+ buf);
+ exit(1);
+ }
}
- boot_devices_bitmap |= 1 << (*p - 'a');
}
}
break;
@@ -5667,10 +5751,6 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp)
exit(1);
}
- /* boot to floppy or the default cd if no hard disk defined yet */
- if (!boot_devices[0]) {
- boot_devices = "cad";
- }
#ifndef _MSC_VER
setvbuf(stdout, NULL, _IOLBF, 0);
#else
@@ -5888,6 +5968,9 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp)
module_call_init(MODULE_INIT_DEVICE);
+ if (machine->compat_props) {
+ qdev_prop_register_compat(machine->compat_props);
+ }
machine->init(ram_size, boot_devices,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
@@ -6012,10 +6095,8 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp)
if (loadvm)
do_loadvm(cur_mon, loadvm);
- if (incoming) {
- autostart = 0; /* fixme how to deal with -daemonize */
+ if (incoming)
qemu_start_incoming_migration(incoming);
- }
if (autostart)
vm_start();