[Qemu-devel] Broken -usbdevice option in 0.12.1
In version 0.12.1, using -usbdevice with an inexistent device exits without any error message, thus confusing the user: $ qemu-system-x86_64 -usbdevice null ; echo $? 1 $ In 0.11.X, the error is ignored, but at least a message is displayed: $ qemu-system-x86_64 -usbdevice null Warning: could not add USB device null -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
[Qemu-devel] [PATCH master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivity a...@redhat.com --- hw/loader.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 2ceb8eb..c6bf0f1 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -654,6 +654,9 @@ int rom_load_all(void) Rom *rom; QTAILQ_FOREACH(rom, roms, next) { +if (!rom-addr) { +continue; +} if (addr rom-addr) { fprintf(stderr, rom: requested regions overlap (rom %s. free=0x TARGET_FMT_plx -- 1.6.5.3
Re: [Qemu-devel] [PATCH master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
On Tue, Dec 22, 2009 at 11:25:13AM +0200, Avi Kivity wrote: The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivity a...@redhat.com --- hw/loader.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 2ceb8eb..c6bf0f1 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -654,6 +654,9 @@ int rom_load_all(void) Rom *rom; QTAILQ_FOREACH(rom, roms, next) { +if (!rom-addr) { +continue; +} Some roms needs to be loaded at address 0, it's the case for example of the arm versatile bootloader. Adding this code will break the board emulation. if (addr rom-addr) { fprintf(stderr, rom: requested regions overlap (rom %s. free=0x TARGET_FMT_plx -- 1.6.5.3 -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] [PATCH master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
On 12/22/2009 11:35 AM, Aurelien Jarno wrote: On Tue, Dec 22, 2009 at 11:25:13AM +0200, Avi Kivity wrote: The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivitya...@redhat.com --- hw/loader.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 2ceb8eb..c6bf0f1 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -654,6 +654,9 @@ int rom_load_all(void) Rom *rom; QTAILQ_FOREACH(rom,roms, next) { +if (!rom-addr) { +continue; +} Some roms needs to be loaded at address 0, it's the case for example of the arm versatile bootloader. Adding this code will break the board emulation. The idea of keying bios-loading or host-loading on address is broken (another instance of mixing control and data). We need a separate control for this. I'll leave this to the authors of the code as I can't make heads or tails of it. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH v2 master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivity a...@redhat.com --- Changes from v1: - use -fw_file instead of -addr to distinguish between host-loaded and firmware-loaded roms - add the same check in a couple more places hw/loader.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/hw/loader.c b/hw/loader.c index 2ceb8eb..eef385e 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -636,6 +636,9 @@ static void rom_reset(void *unused) Rom *rom; QTAILQ_FOREACH(rom, roms, next) { +if (rom-fw_file) { +continue; +} if (rom-data == NULL) continue; cpu_physical_memory_write_rom(rom-addr, rom-data, rom-romsize); @@ -654,6 +657,9 @@ int rom_load_all(void) Rom *rom; QTAILQ_FOREACH(rom, roms, next) { +if (rom-fw_file) { +continue; +} if (addr rom-addr) { fprintf(stderr, rom: requested regions overlap (rom %s. free=0x TARGET_FMT_plx @@ -752,7 +758,7 @@ void do_info_roms(Monitor *mon) Rom *rom; QTAILQ_FOREACH(rom, roms, next) { -if (rom-addr) { +if (!rom-fw_file) { monitor_printf(mon, addr= TARGET_FMT_plx size=0x%06zx mem=%s name=\%s\ \n, rom-addr, rom-romsize, -- 1.6.5.3
[Qemu-devel] [PATCH] Always swap endianness in DBDMA
When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. Signed-off-by: Alexander Graf ag...@suse.de CC: Laurent Vivier laur...@vivier.eu --- hw/mac_dbdma.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 98dccfd..4dbfc16 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -40,6 +40,14 @@ #include isa.h #include mac_dbdma.h +/* + * XXX This is just plain wrong. Apparently we don't want to have big endian + * values, but reversed endian ones. The code as is doesn't work on big + * endian hosts. With these defines it does. + */ +#define cpu_to_be32 bswap32 +#define be32_to_cpu bswap32 + /* debug DBDMA */ //#define DEBUG_DBDMA -- 1.6.0.2
Re: [Qemu-devel] [PATCH 1/5] tcg: Generic support for conditional set
On Sat, Dec 19, 2009 at 7:01 PM, Richard Henderson r...@twiddle.net wrote: Defines setcond_{i32,i64} and setcond2_i32 for 64-on-32-bit. Signed-off-by: Richard Henderson r...@twiddle.net --- tcg/README | 20 +++- tcg/tcg-op.h | 47 +++ tcg/tcg-opc.h | 3 +++ tcg/tcg.c | 21 +++-- 4 files changed, 84 insertions(+), 7 deletions(-) [...] diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index faf2e8b..70a75a0 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -280,6 +280,32 @@ static inline void tcg_gen_op6_i64(int opc, TCGv_i64 arg1, TCGv_i64 arg2, *gen_opparam_ptr++ = GET_TCGV_I64(arg6); } +static inline void tcg_gen_op6i_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2, + TCGv_i32 arg3, TCGv_i32 arg4, + TCGv_i32 arg5, TCGArg arg6) +{ + *gen_opc_ptr++ = opc; + *gen_opparam_ptr++ = GET_TCGV_I32(arg1); + *gen_opparam_ptr++ = GET_TCGV_I32(arg2); + *gen_opparam_ptr++ = GET_TCGV_I32(arg3); + *gen_opparam_ptr++ = GET_TCGV_I32(arg4); + *gen_opparam_ptr++ = GET_TCGV_I32(arg5); + *gen_opparam_ptr++ = arg6; +} + +static inline void tcg_gen_op6i_i64(int opc, TCGv_i64 arg1, TCGv_i64 arg2, + TCGv_i64 arg3, TCGv_i64 arg4, + TCGv_i64 arg5, TCGArg arg6) +{ + *gen_opc_ptr++ = opc; + *gen_opparam_ptr++ = GET_TCGV_I64(arg1); + *gen_opparam_ptr++ = GET_TCGV_I64(arg2); + *gen_opparam_ptr++ = GET_TCGV_I64(arg3); + *gen_opparam_ptr++ = GET_TCGV_I64(arg4); + *gen_opparam_ptr++ = GET_TCGV_I64(arg5); + *gen_opparam_ptr++ = arg6; +} + static inline void tcg_gen_op6ii_i32(int opc, TCGv_i32 arg1, TCGv_i32 arg2, TCGv_i32 arg3, TCGv_i32 arg4, TCGArg arg5, TCGArg arg6) @@ -1795,6 +1821,25 @@ static inline void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) } } +static inline void tcg_gen_setcond_i32(int cond, TCGv_i32 ret, + TCGv_i32 arg1, TCGv_i32 arg2) +{ + tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond); +} + +static inline void tcg_gen_setcond_i64(int cond, TCGv_i64 ret, + TCGv_i64 arg1, TCGv_i64 arg2) +{ +#if TCG_TARGET_REG_BITS == 64 + tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); +#else + tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), + TCGV_LOW(arg1), TCGV_HIGH(arg1), + TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); + tcg_gen_movi_i32(TCGV_HIGH(ret), 0); +#endif +} I wonder if it wouldn't be better to let the back-ends emit the clearing of TCGV_HIGH(ret). This would reduce the number of emitted TCG ops. Any thoughts? Laurent
[Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
On Tue, Dec 08, 2009 at 06:18:18PM +0200, Michael S. Tsirkin wrote: The following fixes a class of long-standing bugs in qemu: when kvm is enabled, guest might access device structures in memory while they are updated by qemu on another CPU. In this scenario, memory barriers are necessary to prevent host CPU from reordering memory accesses, which might confuse the guest. This patch only fixes virtio, but other emulated devices might have a similar bug. They'll need to be discovered and addressed case by case. This is still under test ... meanwhile: any early feedback/flames? Any comments on this one? The patch works fine in my testing, and even though it did not fix a crash that I hoped it will fix, it seems required for correctness... Right? Michael S. Tsirkin (3): qemu: add barriers.h header virtio: use a real wmb virtio: add missing barriers hw/barriers.h | 131 + hw/virtio.c | 18 2 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 hw/barriers.h
[Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA
On Tue, Dec 22, 2009 at 11:24:18AM +0100, Alexander Graf wrote: When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. Come on, #define cpu_to_dbdma32 bswap32 #define dbdma_to_cpu32 bswap32 and then s/cpu_to_be32/cpu_to_dbdma32/g s/be32_to_cpu/dbdma32_to_cpu/g is not too hard, is it? Signed-off-by: Alexander Graf ag...@suse.de CC: Laurent Vivier laur...@vivier.eu --- hw/mac_dbdma.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 98dccfd..4dbfc16 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -40,6 +40,14 @@ #include isa.h #include mac_dbdma.h +/* + * XXX This is just plain wrong. Apparently we don't want to have big endian + * values, but reversed endian ones. The code as is doesn't work on big + * endian hosts. With these defines it does. + */ +#define cpu_to_be32 bswap32 +#define be32_to_cpu bswap32 + /* debug DBDMA */ //#define DEBUG_DBDMA -- 1.6.0.2
[Qemu-devel] [PATCH][RESEND] block/vdi: allow disk sizes not multiple of block size (fwd)
Anyone just tried it yet ? François. -- Forwarded Message: -- To: qemu-devel@nongnu.org From: François Revol re...@free.fr Subject: [PATCH] block/vdi: allow disk sizes not multiple of block size Date: Tue, 08 Dec 2009 15:34:18 +0100 CET The disk image I created from my old laptop disk with VBoxManage internalcommand converthd obviously was not a multiple of 1MB as when created from scratch. This fixes QEMU refusing it. We still require the size to be a multiple of sector size though. It then boots correctly. Allow opening VDI images with size not multiple of 1MB (as when converted from a raw disk). Signed-off-by: François Revol re...@free.fr diff --git a/block/vdi.c b/block/vdi.c index 45aa81c..c91961a 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -411,14 +411,17 @@ static int vdi_open(BlockDriverState *bs, const char *filename, int flags) /* We only support data blocks which start on a sector boundary. */ logout(unsupported data offset 0x%x B\n, header.offset_data); goto fail; +} else if (header.disk_size % SECTOR_SIZE != 0) { +logout(unsupported disk size % PRIu64 B\n, header.disk_size); +goto fail; } else if (header.sector_size != SECTOR_SIZE) { logout(unsupported sector size %u B\n, header.sector_size); goto fail; } else if (header.block_size != 1 * MiB) { logout(unsupported block size %u B\n, header.block_size); goto fail; -} else if (header.disk_size != - (uint64_t)header.blocks_in_image * header.block_size) { +} else if ((header.disk_size + header.block_size - 1) / header.block_size != + (uint64_t)header.blocks_in_image) { logout(unexpected block number %u B\n, header.blocks_in_image); goto fail; } else if (!uuid_is_null(header.uuid_link)) {
[Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA
Michael S. Tsirkin wrote: On Tue, Dec 22, 2009 at 11:24:18AM +0100, Alexander Graf wrote: When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. Come on, #define cpu_to_dbdma32 bswap32 #define dbdma_to_cpu32 bswap32 and then s/cpu_to_be32/cpu_to_dbdma32/g s/be32_to_cpu/dbdma32_to_cpu/g is not too hard, is it? Well, if I'd want to do a sed'ish approach I'd just s/cpu_to_be32/bswap32/g s/be32_to_cpu/bswap32/g The problem is that the whole define is just plain wrong which tells me that the code is using the bswap functions incorrectly. This really needs to be fixed by someone who knows the dbdma device. I don't see how calling incorrect calls even more incorrect makes any difference. Alex
Re: [Qemu-devel] [PATCH 5/5] tcg-i386: Implement setcond.
On Sun, Dec 20, 2009 at 12:11 AM, Aurelien Jarno aurel...@aurel32.net wrote: On Sat, Dec 19, 2009 at 10:46:38AM -0800, Richard Henderson wrote: Signed-off-by: Richard Henderson r...@twiddle.net This looks ok, though I would appreciate someone else to review it in details. It looks good to me too (though I didn't test it explicitly). Laurent --- tcg/i386/tcg-target.c | 73 +++-- 1 files changed, 70 insertions(+), 3 deletions(-) diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index 4c42caf..43e0155 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -360,9 +360,8 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small) } } -static void tcg_out_brcond(TCGContext *s, int cond, - TCGArg arg1, TCGArg arg2, int const_arg2, - int label_index, int small) +static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2, + int const_arg2) { if (const_arg2) { if (arg2 == 0) { @@ -374,6 +373,13 @@ static void tcg_out_brcond(TCGContext *s, int cond, } else { tcg_out_modrm(s, 0x01 | (ARITH_CMP 3), arg2, arg1); } +} + +static void tcg_out_brcond(TCGContext *s, int cond, + TCGArg arg1, TCGArg arg2, int const_arg2, + int label_index, int small) +{ + tcg_out_cmp(s, arg1, arg2, const_arg2); tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small); } @@ -459,6 +465,57 @@ static void tcg_out_brcond2(TCGContext *s, const TCGArg *args, tcg_out_label(s, label_next, (tcg_target_long)s-code_ptr); } +static void tcg_out_setcond(TCGContext *s, int cond, TCGArg dest, + TCGArg arg1, TCGArg arg2, int const_arg2) +{ + tcg_out_cmp(s, arg1, arg2, const_arg2); + /* setcc */ + tcg_out_modrm(s, 0x90 | tcg_cond_to_jcc[cond] | P_EXT, 0, dest); + tgen_arithi(s, ARITH_AND, dest, 0xff, 0); +} + +static void tcg_out_setcond2(TCGContext *s, const TCGArg *args, + const int *const_args) +{ + TCGArg new_args[6]; + int label_true, label_over; + + memcpy(new_args, args+1, 5*sizeof(TCGArg)); + + if (args[0] == args[1] || args[0] == args[2] + || (!const_args[3] args[0] == args[3]) + || (!const_args[4] args[0] == args[4])) { + /* When the destination overlaps with one of the argument + registers, don't do anything tricky. */ + label_true = gen_new_label(); + label_over = gen_new_label(); + + new_args[5] = label_true; + tcg_out_brcond2(s, new_args, const_args+1, 1); + + tcg_out_movi(s, TCG_TYPE_I32, args[0], 0); + tcg_out_jxx(s, JCC_JMP, label_over, 1); + tcg_out_label(s, label_true, (tcg_target_long)s-code_ptr); + + tcg_out_movi(s, TCG_TYPE_I32, args[0], 1); + tcg_out_label(s, label_over, (tcg_target_long)s-code_ptr); + } else { + /* When the destination does not overlap one of the arguments, + clear the destination first, jump if cond false, and emit an + increment in the true case. This results in smaller code. */ + + tcg_out_movi(s, TCG_TYPE_I32, args[0], 0); + + label_over = gen_new_label(); + new_args[4] = tcg_invert_cond(new_args[4]); + new_args[5] = label_over; + tcg_out_brcond2(s, new_args, const_args+1, 1); + + tgen_arithi(s, ARITH_ADD, args[0], 1, 0); + tcg_out_label(s, label_over, (tcg_target_long)s-code_ptr); + } +} + #if defined(CONFIG_SOFTMMU) #include ../../softmmu_defs.h @@ -1120,6 +1177,13 @@ static inline void tcg_out_op(TCGContext *s, int opc, tcg_out_modrm(s, 0xb7 | P_EXT, args[0], args[1]); break; + case INDEX_op_setcond_i32: + tcg_out_setcond(s, args[3], args[0], args[1], args[2], const_args[2]); + break; + case INDEX_op_setcond2_i32: + tcg_out_setcond2(s, args, const_args); + break; + case INDEX_op_qemu_ld8u: tcg_out_qemu_ld(s, args, 0); break; @@ -1208,6 +1272,9 @@ static const TCGTargetOpDef x86_op_defs[] = { { INDEX_op_ext8u_i32, { r, q} }, { INDEX_op_ext16u_i32, { r, r} }, + { INDEX_op_setcond_i32, { q, r, ri } }, + { INDEX_op_setcond2_i32, { r, r, r, ri, ri } }, + #if TARGET_LONG_BITS == 32 { INDEX_op_qemu_ld8u, { r, L } }, { INDEX_op_qemu_ld8s, { r, L } }, -- 1.6.5.2 -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net
Re: [Qemu-devel] CELF Project Proposal - Device tree support for QEMU system emulation.
http://thread.gmane.org/gmane.comp.emulators.qemu/44869 I'm not sure why Paul never pushed it but I think he was able to create the syborg board purely from a device tree. The patches referenced above include purely device-tree based Syborg and Stellaris boards. It works fairly nicely for some embedded boards, but gets fairly hairy when you start considering more complex topologies/machines. I particular the PCI OF/FDT bindings don't really fit what we need for qemu. Obviously full qdev conversion is a prerequisite for device tree based configuration, and at that time qdev was still in its infancy. Part of the reason for posting that patch was to demonstrate the abstraction layers required for the internal device model. Previous patches tended to be based on the pre-existing PC commandline options, which IMO is a mistake. Likewise if (like my implementation) you focus on embedded machines you risk serious problems trying to extend to server class machines. Paul
[Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA
On Tue, Dec 22, 2009 at 01:07:20PM +0100, Alexander Graf wrote: Michael S. Tsirkin wrote: On Tue, Dec 22, 2009 at 11:24:18AM +0100, Alexander Graf wrote: When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. Come on, #define cpu_to_dbdma32 bswap32 #define dbdma_to_cpu32 bswap32 and then s/cpu_to_be32/cpu_to_dbdma32/g s/be32_to_cpu/dbdma32_to_cpu/g is not too hard, is it? Well, if I'd want to do a sed'ish approach I'd just s/cpu_to_be32/bswap32/g s/be32_to_cpu/bswap32/g This would throw away some information: it is better to know whether you are converting from or to cpu mode. Hopefully at some point we will add sparce annotations which will make this even more important. The problem is that the whole define is just plain wrong which tells me that the code is using the bswap functions incorrectly. This really needs to be fixed by someone who knows the dbdma device. I don't see how calling incorrect calls even more incorrect makes any difference. Alex At least build will not break in strange ways e.g. when someone changes cpu_to_be32 to a macro. I don't really know about this hardware either, but why make it more fragile than it already is? -- MST
Re: [Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loading overhaul.
We should just qemu_ram_alloc() that memory regardless of whether we every map it into the guest. Since roms can be large, we want to send their contents over during the live part of migration. If we use qemu_ram_alloc(), we get that for free. Currently live migration uses ram_addrs, so this would work. But ram_addrs have no meaning in the guest and thus depend on qemu implementation details. IMO we should switch live migration to use guest physical addresses, which would require a different migration implementation for roms. Most of it can be shared with ram, though. Ram allocations should be associated with a device. The VMState stuff this should make this fairly straightforward. Guest address space mappings are a completely separate issue. The device should be migrating the mappings (directly or via a PCI BAR) as part of its state migration. The ram regions might not be mapped into guest address space at all. Paul
Re: [Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loading overhaul.
On 12/22/2009 03:04 PM, Paul Brook wrote: We should just qemu_ram_alloc() that memory regardless of whether we every map it into the guest. Since roms can be large, we want to send their contents over during the live part of migration. If we use qemu_ram_alloc(), we get that for free. Currently live migration uses ram_addrs, so this would work. But ram_addrs have no meaning in the guest and thus depend on qemu implementation details. IMO we should switch live migration to use guest physical addresses, which would require a different migration implementation for roms. Most of it can be shared with ram, though. Ram allocations should be associated with a device. The VMState stuff this should make this fairly straightforward. Guest address space mappings are a completely separate issue. The device should be migrating the mappings (directly or via a PCI BAR) as part of its state migration. The ram regions might not be mapped into guest address space at all. Yes, this is essentially Anthony's reply (which I agree with). -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] M68K Or PPC Status Update to Run Mac OS in Qemu
Alexander Graf wrote: OpenBIOS is missing an implementation for local variables. See this thread: http://www.openfirmware.info/pipermail/openbios/2009-July/003796.html Alex How do local variables work? Are they just substitutions for stack places? If you can point me towards a specification for this, I can have a look and see how feasible it would be to add this to OpenBIOS. ATB, Mark. -- Mark Cave-Ayland - Senior Technical Architect PostgreSQL - PostGIS Sirius Corporation plc - control through freedom http://www.siriusit.co.uk t: +44 870 608 0063 Sirius Labs: http://www.siriusit.co.uk/labs
[Qemu-devel] [PATCH] Always swap endianness in DBDMA
When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. Signed-off-by: Alexander Graf ag...@suse.de CC: Laurent Vivier laur...@vivier.eu --- V1 - V2: - s/cpu_to_be32/dbdma_cpu_to_be32/g - s/be32_to_cpu/dbdma_be32_to_cpu/g --- hw/mac_dbdma.c | 86 ++- 1 files changed, 47 insertions(+), 39 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 98dccfd..555983a 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -40,6 +40,14 @@ #include isa.h #include mac_dbdma.h +/* + * XXX This is just plain wrong. Apparently we don't want to have big endian + * values, but reversed endian ones. The code as is doesn't work on big + * endian hosts. With these defines it does. + */ +#define dbdma_cpu_to_be32 bswap32 +#define dbdma_be32_to_cpu bswap32 + /* debug DBDMA */ //#define DEBUG_DBDMA @@ -184,19 +192,19 @@ static void dump_dbdma_cmd(dbdma_cmd *cmd) static void dbdma_cmdptr_load(DBDMA_channel *ch) { DBDMA_DPRINTF(dbdma_cmdptr_load 0x%08x\n, - be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); -cpu_physical_memory_read(be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), + dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); +cpu_physical_memory_read(dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), (uint8_t*)ch-current, sizeof(dbdma_cmd)); } static void dbdma_cmdptr_save(DBDMA_channel *ch) { DBDMA_DPRINTF(dbdma_cmdptr_save 0x%08x\n, - be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); + dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); DBDMA_DPRINTF(xfer_status 0x%08x res_count 0x%04x\n, le16_to_cpu(ch-current.xfer_status), le16_to_cpu(ch-current.res_count)); -cpu_physical_memory_write(be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), +cpu_physical_memory_write(dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), (uint8_t*)ch-current, sizeof(dbdma_cmd)); } @@ -204,8 +212,8 @@ static void kill_channel(DBDMA_channel *ch) { DBDMA_DPRINTF(kill_channel\n); -ch-regs[DBDMA_STATUS] |= cpu_to_be32(DEAD); -ch-regs[DBDMA_STATUS] = cpu_to_be32(~ACTIVE); +ch-regs[DBDMA_STATUS] |= dbdma_cpu_to_be32(DEAD); +ch-regs[DBDMA_STATUS] = dbdma_cpu_to_be32(~ACTIVE); qemu_irq_raise(ch-irq); } @@ -230,10 +238,10 @@ static void conditional_interrupt(DBDMA_channel *ch) return; } -status = be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; +status = dbdma_be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; -sel_mask = (be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 16) 0x0f; -sel_value = be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 0x0f; +sel_mask = (dbdma_be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 16) 0x0f; +sel_value = dbdma_be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 0x0f; cond = (status sel_mask) == (sel_value sel_mask); @@ -268,10 +276,10 @@ static int conditional_wait(DBDMA_channel *ch) return 1; } -status = be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; +status = dbdma_be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; -sel_mask = (be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 16) 0x0f; -sel_value = be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 0x0f; +sel_mask = (dbdma_be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 16) 0x0f; +sel_value = dbdma_be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 0x0f; cond = (status sel_mask) == (sel_value sel_mask); @@ -292,10 +300,10 @@ static void next(DBDMA_channel *ch) { uint32_t cp; -ch-regs[DBDMA_STATUS] = cpu_to_be32(~BT); +ch-regs[DBDMA_STATUS] = dbdma_cpu_to_be32(~BT); -cp = be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]); -ch-regs[DBDMA_CMDPTR_LO] = cpu_to_be32(cp + sizeof(dbdma_cmd)); +cp = dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]); +ch-regs[DBDMA_CMDPTR_LO] = dbdma_cpu_to_be32(cp + sizeof(dbdma_cmd)); dbdma_cmdptr_load(ch); } @@ -304,7 +312,7 @@ static void branch(DBDMA_channel *ch) dbdma_cmd *current = ch-current; ch-regs[DBDMA_CMDPTR_LO] = current-cmd_dep; -ch-regs[DBDMA_STATUS] |= cpu_to_be32(BT); +ch-regs[DBDMA_STATUS] |= dbdma_cpu_to_be32(BT); dbdma_cmdptr_load(ch); } @@ -331,10 +339,10 @@ static void conditional_branch(DBDMA_channel *ch) return; } -
Re: [Qemu-devel] cpuid problem in upstream qemu with kvm
On 12/22/2009 12:51 AM, john cooper wrote: Dor Laor wrote: Qemu will check the required cpuid of the cpu model on the host and refuse to load otherwise. When moving to this model, migration can be simplified too since there are fewer combination, and one can choose performance over migration flexibility and wise versa. Due to the above check, the destination qemu won't load if the host does not support its cpu model. If you're referring to the check in my patch, that's currently advisory only. The existing cpu model encoding of CPUID tosses flags in to the soup on speculation they may be available on the host. If not it assumes they will be quietly disabled on their way to the guest along with whatever why not shout loudly and abort? Do you want windows to reactivate itself? flags were enabled via +flag on the command line. This mixed treatment for model implied vs. user specified flags could be partly an artifact of trying to adapt the legacy qemu64 model to whatever host silicon it finds itself upon. -john
Re: [Qemu-devel] M68K Or PPC Status Update to Run Mac OS in Qemu
Mark Cave-Ayland wrote: Alexander Graf wrote: OpenBIOS is missing an implementation for local variables. See this thread: http://www.openfirmware.info/pipermail/openbios/2009-July/003796.html Alex How do local variables work? Are they just substitutions for stack places? I seriously am the last person to know anything about Forth :-). But I'm sure Stefan can help out here. He's been looking into that before. If you can point me towards a specification for this, I can have a look and see how feasible it would be to add this to OpenBIOS. 1) http://www.complang.tuwien.ac.at/viewcvs/cgi-bin/viewcvs.cgi/gforth/locals.fs?rev=1.8view=markup 2) http://www.openfirmware.info/FCODE_suite - see local value support - has an incompatible license - contains links to documentation IIRC 3) http://www.forthos.org/ - claims to have local value support, haven't found the sources yet The code BootX executes: http://www.openfirmware.info/pipermail/openbios/2009-July/003812.html Alex
Re: [Qemu-devel] [PATCH 0/5] tcg conditional set, round 4
On Tue, Dec 22, 2009 at 1:02 AM, Richard Henderson r...@twiddle.net wrote: On 12/21/2009 03:08 PM, Laurent Desnogues wrote: If you wanted to use movcond, you'd have to make cond + move a special case... You'd certainly want the ARM front-end to use movcond more often than that. For instance: addeq r1,r2,r3 -- add_i32 tmp,r2,r3 movcond_i32 r1,ZF,0,tmp,r1,eq You'd want to continue to use a branch around if the instruction has side effects like cpu fault (e.g. load, store) or updating flags. It ought not be very hard to arrange for something like if (cond != 0xe) { if (may_use_movcond(insn)) { s-condlabel = -1; /* Save the true destination register. */ s-conddest = cpu_R[dest]; /* Implement the instruction into a temporary. */ cpu_R[dest] = tcg_temp_new(); } else { s-condlabel = gen_new_label(); ArmConditional cmp = gen_test_cc(cond ^ 1); tcg_gen_brcondi_i32(cmp.cond, cmp.reg, 0, s-condlabel); } s-condjmp = 1; } // ... implement the instruction as we currently do. if (s-condjmp) { if (s-condlabel == -1) { /* Conditionally move the temporary result into the true destination register. */ ArmConditional cmp = gen_test_cc(cond); tcg_gen_movcond_i32(cmp.cond, s-conddest, cmp.reg, 0, cpu_R[dest], s-conddest); tcg_temp_free(cpu_R[dest]); /* Restore the true destination register. */ cpu_R[dest] = s-conddest; } else { tcg_set_label(d-condlabel); } } I agree, that looks nice. But I'll let you dig into ARM instruction encoding and see how to implement may_use_movcond and getting the correct dest to save is not that cheap (and before you get back to me, yes, you could only consider a small subset of the instructions for which you want to do that :-). There's a point I have kept on insisting on that you keep on not answering :-) How does all of that perform in practice? We can discuss forever, as long as it isn't measured, we are just guessing. Laurent
[Qemu-devel] Re: [PATCH v2 master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
On 12/22/2009 03:57 AM, Avi Kivity wrote: The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivitya...@redhat.com This fixes extboot in qemu-kvm? Regards, Anthony Liguori
[Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
On 12/22/2009 05:26 AM, Michael S. Tsirkin wrote: On Tue, Dec 08, 2009 at 06:18:18PM +0200, Michael S. Tsirkin wrote: The following fixes a class of long-standing bugs in qemu: when kvm is enabled, guest might access device structures in memory while they are updated by qemu on another CPU. In this scenario, memory barriers are necessary to prevent host CPU from reordering memory accesses, which might confuse the guest. This patch only fixes virtio, but other emulated devices might have a similar bug. They'll need to be discovered and addressed case by case. This is still under test ... meanwhile: any early feedback/flames? Any comments on this one? The patch works fine in my testing, and even though it did not fix a crash that I hoped it will fix, it seems required for correctness... Right? It's definitely better than what we have. Rusty mentioned something to me a bit ago about the barriers for virtio in the kernel needing some work. I've been meaning to ask him about it in the context of this patch. Rusty, am I remembering correctly or have I been sipping too much eggnog? :-) Regards, Anthony Liguori
[Qemu-devel] Re: [PATCH v2 master, stable-0.12] Don't load options roms intended to be loaded by the bios in qemu
On 12/22/2009 04:50 PM, Anthony Liguori wrote: On 12/22/2009 03:57 AM, Avi Kivity wrote: The first such option rom will load at address 0, which isn't very nice, and the second will report a conflict and abort, which is horrible. Signed-off-by: Avi Kivitya...@redhat.com This fixes extboot in qemu-kvm? Yes. -- error compiling committee.c: too many arguments to function
[Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loadingoverhaul.
On 12/22/2009 01:58 AM, Gleb Natapov wrote: Your cable TV provider does likely also control what beside the FW (if anything) runs on your set-top-box. So he can verify the FW upgrade doesn't break anything in the field. That pre-deployment verification is not possible in non closed environments. Yet it doesn't stop HW manufacturers to require FW update as the first step of their support procedure. They don't do it automatically only because they can't. Let's put correctness aside for a moment. Right now, if you replace the contents of pc-bios while you have a guest running, heck, even if you rm -rf, the guest will continue functioning until you do a hard power off. Changing this behavior feels like a regression to me. It really seems to me like it makes things a lot more brittle. The only benefit I can see is that you'll use a new rom after migration after the first reset. Maybe that's desirable behavior although I'm not sure. I'd feel a lot better about something that read the real rom contents at start-up, and then replaced migrated roms after reset or something like that. That gives us the use-case without making qemu depend on rereading things while it's running. Regards, Anthony Liguori
Re: [Qemu-devel] Broken -usbdevice option in 0.12.1
On 12/22/2009 02:52 AM, Aurelien Jarno wrote: In version 0.12.1, using -usbdevice with an inexistent device exits without any error message, thus confusing the user: $ qemu-system-x86_64 -usbdevice null ; echo $? 1 $ Would be good to file in launchpad since I think a lot of folks are out for the next couple weeks. I regularly go through launchpad bugs and ping people so it won't get lost that way unless you care enough to fix it immediately. Regards, Anthony Liguori
Re: [Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loading overhaul.
On 12/22/2009 07:04 AM, Paul Brook wrote: We should just qemu_ram_alloc() that memory regardless of whether we every map it into the guest. Since roms can be large, we want to send their contents over during the live part of migration. If we use qemu_ram_alloc(), we get that for free. Currently live migration uses ram_addrs, so this would work. But ram_addrs have no meaning in the guest and thus depend on qemu implementation details. IMO we should switch live migration to use guest physical addresses, which would require a different migration implementation for roms. Most of it can be shared with ram, though. Ram allocations should be associated with a device. The VMState stuff this should make this fairly straightforward. Right, but for the sake of simplicity, you don't want to treat that ram any differently than main ram wrt live migration. That's why I proposed adding a context id for each ram region. That would allow us to use something like the qdev name + id as the context id for a ram chunk to get that association while still doing live ram migration of the memory. Guest address space mappings are a completely separate issue. The device should be migrating the mappings (directly or via a PCI BAR) as part of its state migration. The ram regions might not be mapped into guest address space at all. We don't migrate guest address space memory today. We migrate anything that's qemu_ram_alloc()'d. The big problem we have though is that we don't have any real association between the qemu_ram_alloc() results and what the context of the allocation was. We assume the order of these allocations are fixed and that's entirely wrong. For non-device qemu_ram_alloc()'s, we could either create essentially dummy ram devices or we could just special case it. Regards, Anthony Liguori Paul
Re: [Qemu-devel] cpuid problem in upstream qemu with kvm
Dor Laor wrote: On 12/22/2009 12:51 AM, john cooper wrote: Dor Laor wrote: Qemu will check the required cpuid of the cpu model on the host and refuse to load otherwise. When moving to this model, migration can be simplified too since there are fewer combination, and one can choose performance over migration flexibility and wise versa. Due to the above check, the destination qemu won't load if the host does not support its cpu model. If you're referring to the check in my patch, that's currently advisory only. The existing cpu model encoding of CPUID tosses flags in to the soup on speculation they may be available on the host. If not it assumes they will be quietly disabled on their way to the guest along with whatever why not shout loudly and abort? Do you want windows to reactivate itself? This was the existing behavior of that code which expected certain requested flags to be casually dropped. But bailing after the warning is probably fine as well given the warning itself is optional and bailing wouldn't happen by default. That code could probably use a cleanup going forward to iron out such issues. Andre mentioned he had pending patches which in part addressed this so I thought to let those resolve beforehand. Thanks, -john -- john.coo...@redhat.com
Re: [Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loading overhaul.
Ram allocations should be associated with a device. The VMState stuff this should make this fairly straightforward. Right, but for the sake of simplicity, you don't want to treat that ram any differently than main ram wrt live migration. That's why I proposed adding a context id for each ram region. That would allow us to use something like the qdev name + id as the context id for a ram chunk to get that association while still doing live ram migration of the memory. IMO the best way to do this is to do it via existing VMState machinery. We've already matched up DeviceStates so this gets us a handy unique identifier for every ram block. For system memory we can add a dummy device. Medium term we're probably going to want this anyway. Guest address space mappings are a completely separate issue. The device should be migrating the mappings (directly or via a PCI BAR) as part of its state migration. The ram regions might not be mapped into guest address space at all. We don't migrate guest address space memory today. We migrate anything that's qemu_ram_alloc()'d. The big problem we have though is that we don't have any real association between the qemu_ram_alloc() results and what the context of the allocation was. We assume the order of these allocations are fixed and that's entirely wrong. The nice thing about the VMState approach is that the device doesn't know or care how the migration occurs. For bonus points it leads fairly directly to an object based mapping API, so we can change the implementation or migrate the ram to a different location without disturbing the device. Paul
Re: [Qemu-devel] [PATCH 1/5] tcg: Generic support for conditional set
On 12/22/2009 03:27 AM, Laurent Desnogues wrote: +#if TCG_TARGET_REG_BITS == 64 +tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond); +#else +tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret), + TCGV_LOW(arg1), TCGV_HIGH(arg1), + TCGV_LOW(arg2), TCGV_HIGH(arg2), cond); +tcg_gen_movi_i32(TCGV_HIGH(ret), 0); +#endif +} I wonder if it wouldn't be better to let the back-ends emit the clearing of TCGV_HIGH(ret). This would reduce the number of emitted TCG ops. Any thoughts? (1) That would require 6 registers on i386 simultaneously. (2) You lose the constant propagation that TCG would perform. r~
Re: [Qemu-devel] cpuid problem in upstream qemu with kvm
On 12/21/2009 02:28 AM, Dor Laor wrote: John's new cpu definitions are the exact solution for this issue - all users, whether using mgmt app or direct qemu (this is no user, this is a developer/hacker/other, let's do not optimize this case) should use the various 'real' cpu definitions like -cpu Merom | Nehalem | Penry | Opteron G1, Of course, the tricky part is at what level do you define these names. For instance, do you do just Nehalem, or do you also do Nehalem, Nehalem-EP, Nehalem-EX? Nehalem is really just a code name. Would it be better to use core-i7? I think the only two Fully Correct approachs are to support a very specific CPU (e.g. Xeon-X5270) or provide the ability to individually tweak cpu flags. The notion of compatibility classes should probably be left to management tools. We can make it a lot easier for them though by supporting turning point CPU models. For instance, Xeon-X5570 should be a least common denominator for Nehalem processors. It's probably better for users too. It's easier for them to answer do I have anything older than a Xeon-X5570 than to ask do I have any Woodcrest class processors. I encounter this confusion a lot. I usually ask people whether they have a Nehalem processor when debugging something and their response is always, I have a Xeon-XYZ, is that Nehalem? Regards, Anthony Liguori
Re: [Qemu-devel] Re: [SeaBIOS] [PATCH 0/8] option rom loading overhaul.
On 12/22/2009 09:54 AM, Paul Brook wrote: Ram allocations should be associated with a device. The VMState stuff this should make this fairly straightforward. Right, but for the sake of simplicity, you don't want to treat that ram any differently than main ram wrt live migration. That's why I proposed adding a context id for each ram region. That would allow us to use something like the qdev name + id as the context id for a ram chunk to get that association while still doing live ram migration of the memory. IMO the best way to do this is to do it via existing VMState machinery. We've already matched up DeviceStates so this gets us a handy unique identifier for every ram block. For system memory we can add a dummy device. Medium term we're probably going to want this anyway. Okay, I understand and agree. I think the way this would work is that we would have a ram_addr type for VMState that would be an actual ram allocation and size. qemu_ram_alloc() would not need to take a context. ram live migration would walk the list of registered VMState entries searching for anything that had a ram_addr type and would add that to the ram migration. For system ram, we need dummy devices. I think we probably ought to integrate VMState into qdev first though. I think that makes everything a bit more managable. Guest address space mappings are a completely separate issue. The device should be migrating the mappings (directly or via a PCI BAR) as part of its state migration. The ram regions might not be mapped into guest address space at all. We don't migrate guest address space memory today. We migrate anything that's qemu_ram_alloc()'d. The big problem we have though is that we don't have any real association between the qemu_ram_alloc() results and what the context of the allocation was. We assume the order of these allocations are fixed and that's entirely wrong. The nice thing about the VMState approach is that the device doesn't know or care how the migration occurs. For bonus points it leads fairly directly to an object based mapping API, so we can change the implementation or migrate the ram to a different location without disturbing the device. Yeah, I like it. Regards, Anthony Liguori Paul
[Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
On Tuesday 22 December 2009, Anthony Liguori wrote: On 12/22/2009 05:26 AM, Michael S. Tsirkin wrote: On Tue, Dec 08, 2009 at 06:18:18PM +0200, Michael S. Tsirkin wrote: The following fixes a class of long-standing bugs in qemu: when kvm is enabled, guest might access device structures in memory while they are updated by qemu on another CPU. In this scenario, memory barriers are necessary to prevent host CPU from reordering memory accesses, which might confuse the guest. This patch only fixes virtio, but other emulated devices might have a similar bug. They'll need to be discovered and addressed case by case. Real devices generally aren't cache coherent, so I'd expect problems to be rare. I guess theoretically you may need barriers around the MMIO/IO port handlers, though in practice the KVM context switch probably provides this anyway. This is still under test ... meanwhile: any early feedback/flames? Any comments on this one? The patch works fine in my testing, and even though it did not fix a crash that I hoped it will fix, it seems required for correctness... Right? It's definitely better than what we have. Rusty mentioned something to me a bit ago about the barriers for virtio in the kernel needing some work. I've been meaning to ask him about it in the context of this patch. Given this is supposed to be portable code, I wonder if we should have atomic ordered memory accessors instead. Paul
Re: [Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
On 12/22/2009 06:25 PM, Paul Brook wrote: On Tuesday 22 December 2009, Anthony Liguori wrote: On 12/22/2009 05:26 AM, Michael S. Tsirkin wrote: On Tue, Dec 08, 2009 at 06:18:18PM +0200, Michael S. Tsirkin wrote: The following fixes a class of long-standing bugs in qemu: when kvm is enabled, guest might access device structures in memory while they are updated by qemu on another CPU. In this scenario, memory barriers are necessary to prevent host CPU from reordering memory accesses, which might confuse the guest. This patch only fixes virtio, but other emulated devices might have a similar bug. They'll need to be discovered and addressed case by case. Real devices generally aren't cache coherent, so I'd expect problems to be rare. I guess theoretically you may need barriers around the MMIO/IO port handlers, though in practice the KVM context switch probably provides this anyway. We're not guaranteed to have a context switch. One thread can update the ring while another consumes it. -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH V4 03/18] target-i386: support a20 mask for NEC PC-9812
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- target-i386/cpu.h|3 +++ target-i386/helper.c | 46 -- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index f3834b3..271cc20 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -405,6 +405,8 @@ #define CPUID_EXT3_IBS (1 10) #define CPUID_EXT3_SKINIT (1 12) +#define PRIVATE_FEATURE_PC98_A20MASK (1 0) + #define CPUID_VENDOR_INTEL_1 0x756e6547 /* Genu */ #define CPUID_VENDOR_INTEL_2 0x49656e69 /* ineI */ #define CPUID_VENDOR_INTEL_3 0x6c65746e /* ntel */ @@ -684,6 +686,7 @@ typedef struct CPUX86State { uint32_t cpuid_model[12]; uint32_t cpuid_ext2_features; uint32_t cpuid_ext3_features; +uint32_t private_features; /* private features not defined in CPUID */ uint32_t cpuid_apic_id; int cpuid_vendor_override; diff --git a/target-i386/helper.c b/target-i386/helper.c index 730e396..53d9422 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -57,11 +57,18 @@ static const char *ext3_feature_name[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; +static const char *private_feature_name[] = { +pc98_a20mask, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, uint32_t *ext_features, uint32_t *ext2_features, -uint32_t *ext3_features) +uint32_t *ext3_features, +uint32_t *private_features) { int i; int found = 0; @@ -86,6 +93,11 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features, *ext3_features |= 1 i; found = 1; } +for ( i = 0 ; i 32 ; i++ ) +if (private_feature_name[i] !strcmp (flagname, private_feature_name[i])) { +*private_features |= 1 i; +found = 1; +} if (!found) { fprintf(stderr, CPU feature %s not found\n, flagname); } @@ -99,6 +111,7 @@ typedef struct x86_def_t { int model; int stepping; uint32_t features, ext_features, ext2_features, ext3_features; +uint32_t private_features; uint32_t xlevel; char model_id[48]; int vendor_override; @@ -377,6 +390,7 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) char *featurestr, *name = strtok(s, ,); uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0; uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0; +uint32_t plus_private_features = 0, minus_private_features = 0; uint32_t numvalue; def = NULL; @@ -395,16 +409,21 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) } add_flagname_to_bitmaps(hypervisor, plus_features, -plus_ext_features, plus_ext2_features, plus_ext3_features); +plus_ext_features, plus_ext2_features, plus_ext3_features, +plus_private_features); featurestr = strtok(NULL, ,); while (featurestr) { char *val; if (featurestr[0] == '+') { -add_flagname_to_bitmaps(featurestr + 1, plus_features, plus_ext_features, plus_ext2_features, plus_ext3_features); +add_flagname_to_bitmaps(featurestr + 1, plus_features, +plus_ext_features, plus_ext2_features, plus_ext3_features, +plus_private_features); } else if (featurestr[0] == '-') { -add_flagname_to_bitmaps(featurestr + 1, minus_features, minus_ext_features, minus_ext2_features, minus_ext3_features); +add_flagname_to_bitmaps(featurestr + 1, minus_features, +minus_ext_features, minus_ext2_features, minus_ext3_features, +minus_private_features); } else if ((val = strchr(featurestr, '='))) { *val = 0; val++; if (!strcmp(featurestr, family)) { @@ -481,10 +500,12 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) x86_cpu_def-ext_features |= plus_ext_features; x86_cpu_def-ext2_features |= plus_ext2_features; x86_cpu_def-ext3_features |= plus_ext3_features; +x86_cpu_def-private_features |= plus_private_features; x86_cpu_def-features = ~minus_features; x86_cpu_def-ext_features = ~minus_ext_features; x86_cpu_def-ext2_features = ~minus_ext2_features; x86_cpu_def-ext3_features = ~minus_ext3_features; +x86_cpu_def-private_features = ~minus_private_features;
[Qemu-devel] [PATCH V4 06/18] support NEC PC-9821 memory
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc98mem.c | 861 ++ 1 files changed, 861 insertions(+), 0 deletions(-) create mode 100644 hw/pc98mem.c diff --git a/hw/pc98mem.c b/hw/pc98mem.c new file mode 100644 index 000..36a60cc --- /dev/null +++ b/hw/pc98mem.c @@ -0,0 +1,861 @@ +/* + * QEMU NEC PC-9821 memory + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw.h +#include pc.h +#include isa.h +#include loader.h + +#define PCI_FILE_NAME pc98pci.bin +#define PCI_FILE_SIZE 0x8000 +#define IDE_FILE_NAME pc98ide.bin +#define IDE_FILE_SIZE 0x2000 +#define ITF_FILE_NAME pc98itf.bin +#define ITF_FILE_SIZE 0x8000 +#define BIOS_FILE_NAME pc98bios.bin +#define BIOS_FILE_SIZE 0x18000 +#define BANK_FILE_NAME pc98bank%d.bin +#define BANK_FILE_SIZE 0x8000 + +#define PCI_ROM_BANK 0 +#define IDE_ROM_BANK 3 +#define ITF_ROM_BANK 4 +#define BIOS_ROM_BANK 5 +#define ROM_BANK_NUM 8 + +#define REQUIRED_ROM_BANK ((1 ITF_ROM_BANK) | (7 BIOS_ROM_BANK)) + +#define BANK_BITS 12 +/* (1 BANK_BITS) */ +#define BANK_SIZE 0x1000 + +#define PCI_BIOS_OFS (BANK_FILE_SIZE * PCI_ROM_BANK) +#define IDE_BIOS_OFS (BANK_FILE_SIZE * IDE_ROM_BANK) +#define ITF_OFS(BANK_FILE_SIZE * ITF_ROM_BANK) +#define BIOS_OFS (BANK_FILE_SIZE * BIOS_ROM_BANK) +#define NONE_OFS (BANK_FILE_SIZE * ROM_BANK_NUM) +#define TOTAL_ROM_SIZE (NONE_OFS + BANK_SIZE) + +enum { +D8000_BANK_IDE = 1, +D8000_BANK_PCI = 2, +D8000_BANK_PnP = 3, +}; + +struct MemoryState { +ram_addr_t ram_addr[0x100 BANK_BITS]; /* 16MB */ +ram_addr_t rom_addr[TOTAL_ROM_SIZE BANK_BITS]; +ram_addr_t mem_bank[0x10 BANK_BITS]; /* 1MB */ + +int tvram_io_memory; +int vram_a8000_io_memory; +int vram_b_io_memory; +int vram_e_io_memory; +int vram_f0_io_memory; + +uint8_t ram_window_map1; +uint8_t ram_window_map2; +uint8_t d8000_bank; +uint8_t ide_bios_enabled; +uint8_t ide_ram_selected; +uint8_t bios_ram_selected; +uint8_t itf_selected; +uint8_t use_system_16mb; + +uint8_t ide_bios_loaded; +uint8_t hd_connect; +uint8_t init_done; +}; + +typedef struct MemoryState MemoryState; + +static uint8_t *get_ram_ptr(void *opaque, ram_addr_t addr) +{ +MemoryState *s = opaque; +uint32_t ofs = addr (BANK_SIZE - 1); + +return qemu_get_ram_ptr(s-ram_addr[addr BANK_BITS]) + ofs; +} + +static void register_ram(void *opaque, target_phys_addr_t top, ram_addr_t size, + ram_addr_t addr) +{ +MemoryState *s = opaque; +target_phys_addr_t a; +int smram_update = 0; + +for (a = top; a top + size; a += BANK_SIZE) { +ram_addr_t phys_offset = s-ram_addr[addr BANK_BITS]; +if (s-mem_bank[a BANK_BITS] != phys_offset) { +cpu_register_physical_memory(a, BANK_SIZE, phys_offset); +if (a = 0xa) { +smram_update = 1; +if (s-use_system_16mb) { +cpu_register_physical_memory(0xf0 + a, BANK_SIZE, + phys_offset); +} +cpu_register_physical_memory(0xfff0 + a, BANK_SIZE, + phys_offset); +} +s-mem_bank[a BANK_BITS] = phys_offset; +} +addr += BANK_SIZE; +} +if (i440fx_state smram_update s-init_done) { +i440fx_init_memory_mappings(i440fx_state); +} +} + +static void register_rom(void *opaque, target_phys_addr_t top, ram_addr_t size, + ram_addr_t addr) +{ +MemoryState *s = opaque; +target_phys_addr_t a; +int smram_update = 0; + +for (a = top; a top + size; a += BANK_SIZE) { +ram_addr_t phys_offset = s-rom_addr[addr BANK_BITS]; +if (s-mem_bank[a
[Qemu-devel] [PATCH V4 02/18] sysemu: support qemu_cpu_reset()
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- sysemu.h |3 +++ vl.c | 32 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/sysemu.h b/sysemu.h index 9d80bb2..51c7ac8 100644 --- a/sysemu.h +++ b/sysemu.h @@ -45,13 +45,16 @@ void cpu_enable_ticks(void); void cpu_disable_ticks(void); void qemu_system_reset_request(void); +void qemu_cpu_reset_request(void); void qemu_system_shutdown_request(void); void qemu_system_powerdown_request(void); int qemu_shutdown_requested(void); int qemu_reset_requested(void); +int qemu_cpu_reset_requested(void); int qemu_powerdown_requested(void); extern qemu_irq qemu_system_powerdown; void qemu_system_reset(void); +void qemu_cpu_reset(void); void do_savevm(Monitor *mon, const QDict *qdict); int load_vmstate(Monitor *mon, const char *name); diff --git a/vl.c b/vl.c index e606903..565dae4 100644 --- a/vl.c +++ b/vl.c @@ -3261,6 +3261,7 @@ typedef struct QEMUResetEntry { static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers = QTAILQ_HEAD_INITIALIZER(reset_handlers); static int reset_requested; +static int cpu_reset_requested; static int shutdown_requested; static int powerdown_requested; static int debug_requested; @@ -3280,6 +3281,13 @@ int qemu_reset_requested(void) return r; } +int qemu_cpu_reset_requested(void) +{ +int r = cpu_reset_requested; +cpu_reset_requested = 0; +return r; +} + int qemu_powerdown_requested(void) { int r = powerdown_requested; @@ -3343,6 +3351,16 @@ void qemu_system_reset(void) } } +void qemu_cpu_reset(void) +{ +CPUState *env; + +/* reset all cpus */ +for(env = first_cpu; env != NULL; env = env-next_cpu) { +cpu_reset(env); +} +} + void qemu_system_reset_request(void) { if (no_reboot) { @@ -3353,6 +3371,12 @@ void qemu_system_reset_request(void) qemu_notify_event(); } +void qemu_cpu_reset_request(void) +{ +cpu_reset_requested = 1; +qemu_notify_event(); +} + void qemu_system_shutdown_request(void) { shutdown_requested = 1; @@ -4129,6 +4153,8 @@ static int vm_can_run(void) return 0; if (reset_requested) return 0; +if (cpu_reset_requested) +return 0; if (shutdown_requested) return 0; if (debug_requested) @@ -4182,6 +4208,12 @@ static void main_loop(void) qemu_system_reset(); resume_all_vcpus(); } +if (qemu_cpu_reset_requested()) { +monitor_protocol_event(QEVENT_RESET, NULL); +pause_all_vcpus(); +qemu_cpu_reset(); +resume_all_vcpus(); +} if (qemu_powerdown_requested()) { monitor_protocol_event(QEVENT_POWERDOWN, NULL); qemu_irq_raise(qemu_system_powerdown); -- 1.6.4
[Qemu-devel] [PATCH V4 01/18] Makefile.target: add NEC PC-9821 modules
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- Makefile.target |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Makefile.target b/Makefile.target index 7c1f30c..18c8428 100644 --- a/Makefile.target +++ b/Makefile.target @@ -195,6 +195,7 @@ obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o obj-i386-y += ne2000-isa.o +obj-i386-y += ide/pc98.o pc98kbd.o pc98mouse.o pc98sys.o pc98vga.o pc98mem.o pc98.o # shared objects obj-ppc-y = ppc.o ide/core.o ide/qdev.o ide/isa.o ide/pci.o ide/macio.o -- 1.6.4
[Qemu-devel] [PATCH V4 07/18] support NEC PC-9821 mouse
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc98mouse.c | 266 1 files changed, 266 insertions(+), 0 deletions(-) create mode 100644 hw/pc98mouse.c diff --git a/hw/pc98mouse.c b/hw/pc98mouse.c new file mode 100644 index 000..0868180 --- /dev/null +++ b/hw/pc98mouse.c @@ -0,0 +1,266 @@ +/* + * QEMU NEC PC-9821 mouse + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw.h +#include pc.h +#include console.h +#include qemu-timer.h +#include isa.h +#include qdev-addr.h + +static const int64_t mouse_expire[4] = {120, 60, 30, 15}; + +struct MouseState { +int button; +int dx, dy; +int lx, ly; +uint8_t freq; +uint8_t portc; + +QEMUTimer *mouse_timer; +qemu_irq irq; +}; + +typedef struct ISAMouseState { +ISADevice dev; +uint32_t isairq; +struct MouseState state; +} ISAMouseState; + +typedef struct MouseState MouseState; + +/* mouse */ + +static void mouse_timer_handler(void *opaque) +{ +MouseState *s = opaque; + +if (!(s-portc 0x10)) { +qemu_set_irq(s-irq, 1); +qemu_set_irq(s-irq, 0); +} + +/* set next timer */ +qemu_mod_timer(s-mouse_timer, qemu_get_clock(rt_clock) + + 1000 / mouse_expire[s-freq 3]); +} + +static void mouse_event_handler(void *opaque, +int dx, int dy, int dz, int buttons_state) +{ +MouseState *s = opaque; + +s-button = buttons_state; +s-dx += dx; +s-dy += dy; +} + +static void mouse_freq_write(void *opaque, uint32_t addr, uint32_t value) +{ +MouseState *s = opaque; + +if(!(value 0xfc)) { +s-freq = value; +} +} + +static uint32_t mouse_freq_read(void *opaque, uint32_t addr) +{ +MouseState *s = opaque; + +return s-freq 3; +} + +/* pio */ + +static uint32_t pio_porta_read(void *opaque, uint32_t addr) +{ +MouseState *s = opaque; +uint32_t val = 0; + +if (!(s-button 1)) { +val |= 0x80; +} +if (!(s-button 2)) { +val |= 0x40; +} +if (!(s-button 4)) { +val |= 0x20; +} +switch (s-portc 0xe0) { +case 0x00: +val |= (s-dx 0) 0x0f; +break; +case 0x20: +val |= (s-dx 4) 0x0f; +break; +case 0x40: +val |= (s-dy 0) 0x0f; +break; +case 0x60: +val |= (s-dy 4) 0x0f; +break; +case 0x80: +val |= (s-lx 0) 0x0f; +break; +case 0xa0: +val |= (s-lx 4) 0x0f; +break; +case 0xc0: +val |= (s-ly 0) 0x0f; +break; +case 0xe0: +val |= (s-ly 4) 0x0f; +break; +} +return val; +} + +static uint32_t pio_portb_read(void *opaque, uint32_t addr) +{ +return 0xff; +} + +static void pio_portc_write(void *opaque, uint32_t addr, uint32_t value) +{ +MouseState *s = opaque; + +if (!(s-portc 0x80) (value 0x80)) { +/* latch mouse count */ +s-lx = s-dx; +s-ly = s-dy; +s-dx = s-dy = 0; +} +s-portc = (uint8_t)value; +} + +static uint32_t pio_portc_read(void *opaque, uint32_t addr) +{ +MouseState *s = opaque; + +return (s-portc 0xf0) | 0x08; +} + +static void pio_ctrl_write(void *opaque, uint32_t addr, uint32_t value) +{ +MouseState *s = opaque; + +if (!(value 0x80)) { +/* set/reset portc bit */ +uint8_t portc = s-portc; +uint8_t bit = 1 ((value 1) 7); +if (value 1) { +portc |= bit; +} else { +portc = ~bit; +} +pio_portc_write(s, 0, portc); +} +} + +/* interface */ + +static void pc98_mouse_reset(void *opaque) +{ +MouseState *s = opaque; + +s-button = 0; +s-dx = s-dy = 0; +s-lx = s-ly = -1; +s-freq = 0; +s-portc = 0xf0; + +qemu_mod_timer(s-mouse_timer, qemu_get_clock(rt_clock) + +
[Qemu-devel] [PATCH V4 10/18] dma: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/dma.c | 186 -- hw/isa.h |1 + 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/hw/dma.c b/hw/dma.c index 44c642e..28219e7 100644 --- a/hw/dma.c +++ b/hw/dma.c @@ -45,6 +45,8 @@ struct dma_regs { uint8_t eop; DMA_transfer_handler transfer_handler; void *opaque; +/* NEC PC-9821 */ +uint8_t bound; }; #define ADDR 0 @@ -57,6 +59,9 @@ static struct dma_cont { uint8_t flip_flop; int dshift; struct dma_regs regs[4]; +/* NEC PC-9821 */ +uint8_t pc98; +uint8_t access_ctrl; } dma_controllers[2]; enum { @@ -74,6 +79,14 @@ enum { }; +enum { +MODE_DIR = 0x20, +}; + +enum { +PC98_DISABLE_DMA_OVER_1MB = 0x04, +}; + static void DMA_run (void); static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0}; @@ -329,7 +342,8 @@ void DMA_release_DREQ (int nchan) static void channel_run (int ncont, int ichan) { int n; -struct dma_regs *r = dma_controllers[ncont].regs[ichan]; +struct dma_cont *d = dma_controllers[ncont]; +struct dma_regs *r = d-regs[ichan]; #ifdef DEBUG_DMA int dir, opmode; @@ -344,11 +358,26 @@ static void channel_run (int ncont, int ichan) } #endif -r = dma_controllers[ncont].regs + ichan; n = r-transfer_handler (r-opaque, ichan + (ncont 2), r-now[COUNT], (r-base[COUNT] + 1) ncont); r-now[COUNT] = n; ldebug (dma_pos %d size %d\n, n, (r-base[COUNT] + 1) ncont); + +/* increment page register */ +if (d-pc98 r-bound) { +uint32_t last_addr = r-base[ADDR]; +if (r-mode MODE_DIR) { +last_addr -= n ncont; +if (last_addr 0x) { +r-page = ((r-page - 1) r-bound) | (r-page (~r-bound)); +} +} else { +last_addr += n ncont; +if (last_addr 0x) { +r-page = ((r-page + 1) r-bound) | (r-page (~r-bound)); +} +} +} } static QEMUBH *dma_bh; @@ -400,10 +429,14 @@ void DMA_register_channel (int nchan, int DMA_read_memory (int nchan, void *buf, int pos, int len) { -struct dma_regs *r = dma_controllers[nchan 3].regs[nchan 3]; +struct dma_cont *d = dma_controllers[nchan 3]; +struct dma_regs *r = d-regs[nchan 3]; target_phys_addr_t addr = ((r-pageh 0x7f) 24) | (r-page 16) | r-now[ADDR]; -if (r-mode 0x20) { +if (d-pc98 (d-access_ctrl PC98_DISABLE_DMA_OVER_1MB)) { +addr = 0xf; +} +if (r-mode MODE_DIR) { int i; uint8_t *p = buf; @@ -422,10 +455,14 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len) int DMA_write_memory (int nchan, void *buf, int pos, int len) { -struct dma_regs *r = dma_controllers[nchan 3].regs[nchan 3]; +struct dma_cont *d = dma_controllers[nchan 3]; +struct dma_regs *r = d-regs[nchan 3]; target_phys_addr_t addr = ((r-pageh 0x7f) 24) | (r-page 16) | r-now[ADDR]; -if (r-mode 0x20) { +if (d-pc98 (d-access_ctrl PC98_DISABLE_DMA_OVER_1MB)) { +addr = 0xf; +} +if (r-mode MODE_DIR) { int i; uint8_t *p = buf; @@ -542,6 +579,8 @@ static const VMStateDescription vmstate_dma = { void DMA_init (int high_page_enable) { +dma_controllers[0].pc98 = 0; +dma_controllers[1].pc98 = 0; dma_init2(dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1); dma_init2(dma_controllers[1], 0xc0, 1, 0x88, @@ -551,3 +590,138 @@ void DMA_init (int high_page_enable) dma_bh = qemu_bh_new(DMA_run_bh, NULL); } + +/* NEC PC-9821 */ + +static void pc98_write_port (void *opaque, uint32_t nport, uint32_t data) +{ +static const uint8_t bounds[4] = {0, 0x0f, 0, 0xff}; +struct dma_cont *d = opaque; +int ichan; + +switch (nport) { +case 0x01: case 0x03: case 0x05: case 0x07: +case 0x09: case 0x0b: case 0x0d: case 0x0f: +write_chan (d, nport 1, data); +break; +case 0x11: case 0x13: case 0x15: case 0x17: +case 0x19: case 0x1b: case 0x1d: case 0x1f: +write_cont (d, nport 1, data); +break; +case 0x21: case 0x23: case 0x25: case 0x27: +ichan = ((nport 1) + 1) 3; +d-regs[ichan].page = data; +break; +case 0x29: +ichan = data 3; +d-regs[ichan].bound = bounds[(data 2) 3]; +break; +case 0x439: +d-access_ctrl = data; +break; +case 0xe05: case 0xe07: case 0xe09: case 0xe0b: +ichan = ((nport 1) - 2) 3; +d-regs[ichan].pageh = data; +break; +} +} + +static uint32_t pc98_read_port (void *opaque, uint32_t nport) +{ +struct dma_cont *d = opaque; + +switch (nport) { +case 0x01: case 0x03: case 0x05: case 0x07: +case 0x09: case 0x0b: case 0x0d: case 0x0f: +return read_chan (d, nport 1);
[Qemu-devel] [PATCH V4 00/18] support NEC PC-9821
Dear members, Sorry too late reply for comments of previous patch. (I was busy in these months for my business...) This is new patch. Change from v3 to v4: - use vmstate for save/load state - remove sound device with MAME opna sound core Thanks, TAKEDA, toshiya
[Qemu-devel] [PATCH V4 04/18] support NEC PC-9821 architecture
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc98.c | 317 + hw/pc98.h | 65 + 2 files changed, 382 insertions(+), 0 deletions(-) create mode 100644 hw/pc98.c create mode 100644 hw/pc98.h diff --git a/hw/pc98.c b/hw/pc98.c new file mode 100644 index 000..4bc4805 --- /dev/null +++ b/hw/pc98.c @@ -0,0 +1,317 @@ +/* + * QEMU NEC PC-9821 System Emulator + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw.h +#include pc.h +#include fdc.h +#include pci.h +#include block.h +#include sysemu.h +#include audio/audio.h +#include audiodev.h +#include net.h +#include boards.h +#include monitor.h +#include ide.h + +static void *sys; + +#define MAX_IDE_BUS 2 + +typedef struct isa_irq_state { +qemu_irq *i8259; +qemu_irq *ioapic; +} IsaIrqState; + +/* IRQ handling */ +static void isa_irq_handler(void *opaque, int n, int level) +{ +IsaIrqState *isa = (IsaIrqState *)opaque; + +if (n 16) { +qemu_set_irq(isa-i8259[n], level); +} +if (isa-ioapic) { +qemu_set_irq(isa-ioapic[n], level); +} +}; + +static void pic_irq_request(void *opaque, int irq, int level) +{ +CPUState *env = first_cpu; + +if (env-apic_state) { +while (env) { +if (apic_accept_pic_intr(env)) { +apic_deliver_pic_intr(env, level); +} +env = env-next_cpu; +} +} else { +if (level) { +cpu_interrupt(env, CPU_INTERRUPT_HARD); +} else { +cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); +} +} +} + +#define NE2000_NB_MAX 4 + +static const int ne2000_io[NE2000_NB_MAX] = { 0x00d0, 0x10d0, 0x20d0, 0x30d0 }; +static const int ne2000_irq[NE2000_NB_MAX] = { 3, 5, 6, 12 }; + +static void pc98_init_ne2k_isa(NICInfo *nd) +{ +static int nb_ne2k = 0; + +if (nb_ne2k == NE2000_NB_MAX) { +return; +} +pc98_ne2000_init(ne2000_io[nb_ne2k], ne2000_irq[nb_ne2k], nd); +nb_ne2k++; +} + +static CPUState *pc_new_cpu(const char *cpu_model) +{ +CPUState *env; + +env = cpu_init(cpu_model); +if (!env) { +fprintf(stderr, Unable to find x86 CPU definition\n); +exit(1); +} +if ((env-cpuid_features CPUID_APIC) || smp_cpus 1) { +env-cpuid_apic_id = env-cpu_index; +/* APIC reset callback resets cpu */ +apic_init(env); +} else { +qemu_register_reset((QEMUResetHandler*)cpu_reset, env); +} +return env; +} + +/* I/O */ +static void ioport_f2_write(void *opaque, uint32_t addr, uint32_t data) +{ +ioport_set_a20(1); +} + +static uint32_t ioport_f2_read(void *opaque, uint32_t addr) +{ +return (ioport_get_a20() ^ 1) | 0x2e; +} + +static void ioport_f6_write(void *opaque, uint32_t addr, uint32_t data) +{ +switch (data) { +case 0x02: +ioport_set_a20(1); +break; +case 0x03: +ioport_set_a20(0); +break; +} +} + +static uint32_t ioport_f6_read(void *opaque, uint32_t addr) +{ +return (ioport_get_a20() ^ 1) | 0x5e; +} + +static uint32_t ioport_534_read(void *opaque, uint32_t addr) +{ +return 0xec; /* cpu mode */ +} + +static uint32_t ioport_9894_read(void *opaque, uint32_t addr) +{ +return 0x90; /* cpu wait */ +} + +void pc98_cpu_shutdown(void) +{ +if (pc98_sys_read_shut(sys)) { +qemu_system_reset_request(); +} else { +qemu_cpu_reset_request(); +} +} + +/* PC-9821 hardware initialisation */ +static void pc98_init1(ram_addr_t ram_size, + const char *cpu_model, + int pci_enabled) +{ +char cpu_model_opt[64]; +PCIBus *pci_bus; +int piix3_devfn = -1; +CPUState *env = NULL; +qemu_irq *cpu_irq; +qemu_irq *isa_irq; +qemu_irq *i8259; +IsaIrqState *isa_irq_state; +PITState *pit; +DriveInfo
[Qemu-devel] [PATCH V4 05/18] support NEC PC-9821 keyboard
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc98kbd.c | 395 ++ 1 files changed, 395 insertions(+), 0 deletions(-) create mode 100644 hw/pc98kbd.c diff --git a/hw/pc98kbd.c b/hw/pc98kbd.c new file mode 100644 index 000..04e1fa5 --- /dev/null +++ b/hw/pc98kbd.c @@ -0,0 +1,395 @@ +/* + * QEMU NEC PC-9821 keyboard + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw.h +#include pc.h +#include isa.h +#include qdev.h +#include console.h +#include qemu-timer.h + +#define SIO_BUFFER_SIZE 256 +#define SIO_RECV_DELAY 8 + +enum { +SIO_STAT_TXRDY = 0x01, +SIO_STAT_RXRDY = 0x02, +SIO_STAT_TXE= 0x04, +SIO_STAT_PE = 0x08, +SIO_STAT_OE = 0x10, +SIO_STAT_FE = 0x20, +SIO_STAT_SYNDET = 0x40, +SIO_STAT_DSR= 0x80, +}; + +enum { +SIO_MODE_CLEAR, +SIO_MODE_SYNC, +SIO_MODE_ASYNC, +SIO_MODE_SYNC1, +SIO_MODE_SYNC2, +}; + +enum { +KBD_LOCK_NUMLK = 1, +KBD_LOCK_CAPS = 4, +KBD_LOCK_KANA = 8, +KBD_LOCK_MASK = (1 | 4 | 8), +}; + +/* +END - HELP +F11 - STOP +F12 - COPY +*/ + +static const uint8_t kbd_table[128] = { +0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, +0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, +0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, +0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x74, 0x1d, 0x1e, +0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, +0x27, 0xff, 0x70, 0x28, 0x29, 0x2a, 0x2b, 0x2c, +0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x70, 0xff, +0x70, 0x34, 0xff, 0x62, 0x63, 0x64, 0x65, 0x66, +0x67, 0x68, 0x69, 0x6a, 0x6b, 0xff, 0xff, 0x3e, +0x3a, 0x36, 0xff, 0x3b, 0xff, 0x3c, 0xff, 0x3f, +0x3d, 0x37, 0x38, 0x39, 0xff, 0xff, 0xff, 0x60, +0x61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0x33, 0xff, 0xff, 0xff, 0xff, +0xff, 0x35, 0xff, 0x51, 0xff, 0x0d, 0xff, 0xff, +}; + +struct KeyBoardState { +/* keyboard */ +uint8_t lock; +uint8_t pressed[128]; + +/* sio */ +uint8_t mode; +uint8_t status; +uint8_t rxen; +uint8_t txen; +uint8_t recv_data; +uint8_t recv_buf[SIO_BUFFER_SIZE]; +int recv_count; +int recv_read; +int recv_write; +uint8_t send_buf[2]; +int send_count; + +QEMUTimer *sio_timer; +qemu_irq irq; +}; + +typedef struct ISAKeyBoardState { +ISADevice dev; +uint32_t isairq; +struct KeyBoardState state; +} ISAKeyBoardState; + +typedef struct KeyBoardState KeyBoardState; + +/* keyboard */ + +static void kbd_recv(void *opaque, uint8_t value) +{ +KeyBoardState *s = opaque; + +if (s-recv_count SIO_BUFFER_SIZE) { +s-recv_buf[(s-recv_write++) (SIO_BUFFER_SIZE - 1)] = value; +s-recv_count++; +if (s-recv_count == 1) { +qemu_mod_timer(s-sio_timer, qemu_get_clock(rt_clock) + + SIO_RECV_DELAY); +} +} +} + +static void kbd_send(void *opaque, uint8_t value) +{ +KeyBoardState *s = opaque; + +s-send_buf[(s-send_count++) 1] = value; + +switch (s-send_buf[0]) { +case 0x95: +case 0x9c: +kbd_recv(s, 0xfa); +if (s-send_count == 2) { +s-send_count = 0; +} +break; +case 0x96: +kbd_recv(s, 0xfa); +kbd_recv(s, 0xa0); +kbd_recv(s, 0x85);/*0x86*/ +s-send_count = 0; +break; +case 0x99: +kbd_recv(s, 0xfa); +kbd_recv(s, 0xfb); +s-send_count = 0; +break; +case 0x9d: +kbd_recv(s, 0xfa); +if (s-send_count == 2) { +if (s-send_buf[1] == 0x60) { +kbd_recv(s, 0x70 | (s-lock KBD_LOCK_MASK)); +} else { +s-lock = value; +} +
[Qemu-devel] [PATCH V4 08/18] support NEC PC-9821 system port
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc98sys.c | 482 ++ 1 files changed, 482 insertions(+), 0 deletions(-) create mode 100644 hw/pc98sys.c diff --git a/hw/pc98sys.c b/hw/pc98sys.c new file mode 100644 index 000..43a910a --- /dev/null +++ b/hw/pc98sys.c @@ -0,0 +1,482 @@ +/* + * QEMU NEC PC-9821 systemp port + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw.h +#include pc.h +#include qemu-timer.h +#include isa.h +#include qdev-addr.h +#include loader.h + +enum { +RTC_STROBE = 0x08, +RTC_CLOCK = 0x10, +RTC_DIN= 0x20, +}; + +enum { +RTC_CMD_SHIFT = 0x01, +RTC_CMD_READ = 0x03, +RTC_CMD_EXMODE = 0x07, +}; + +enum { +RTC_MODE_UPD4993A = 0x20, +}; + +#define TSTMP_FREQ 307200 + +struct SysPortState { +uint8_t rtc_mode; +uint8_t rtc_reg; +uint8_t rtc_cmd; +uint64_t rtc_shift_out; +uint8_t rtc_shift_cmd; +uint8_t rtc_irq_mode; +uint8_t rtc_irq_count; + +uint8_t sys_portc; +int sys_portc_patch; +uint8_t prn_porta; +uint8_t prn_portc; + +uint8_t sdip[24]; +uint8_t sdip_bank; + +QEMUTimer *rtc_timer; +qemu_irq irq; +int64_t tstmp_initial_clock; +}; + +typedef struct ISASysPortState { +ISADevice dev; +uint32_t isairq; +struct SysPortState state; +} ISASysPortState; + +typedef struct SysPortState SysPortState; + +/* NEC uPD4993A RTC */ + +// 1000/64 = 15.625 +static const int rtc_period[8] = { 15, 16, 16, 15, 16, 16, 15, 16 }; +static int rtc_period_ptr = 0; + +static void rtc_timer_handler(void *opaque) +{ +SysPortState *s = opaque; + +/* rtc_irq_mode = 0 : 1/64 sec += 1 : 1/32 sec += 2 : no irq += 3 : 1/16 sec +*/ +if ((s-rtc_irq_mode 0x03) != 2) { +if (++s-rtc_irq_count (s-rtc_irq_mode 0x03)) { +qemu_set_irq(s-irq, 1); +s-rtc_irq_count = 0; +} +} + +/* set next timer */ +qemu_mod_timer(s-rtc_timer, qemu_get_clock(rt_clock) + + rtc_period[(rtc_period_ptr++) 7]); +} + +static void rtc_read_time(void *opaque) +{ +SysPortState *s = opaque; +struct tm tm; + +qemu_get_timedate(tm, 0); +s-rtc_shift_out = (uint64_t)to_bcd(tm.tm_sec); +s-rtc_shift_out |= (uint64_t)to_bcd(tm.tm_min) 8; +s-rtc_shift_out |= (uint64_t)to_bcd(tm.tm_hour) 16; +s-rtc_shift_out |= (uint64_t)to_bcd(tm.tm_mday) 24; +s-rtc_shift_out |= (uint64_t)tm.tm_wday 32; +s-rtc_shift_out |= (uint64_t)(tm.tm_mon + 1) 36; +s-rtc_shift_out |= (uint64_t)to_bcd(tm.tm_year % 100) 40; +if (s-rtc_mode RTC_MODE_UPD4993A) { +s-rtc_shift_out = 4; +} +} + +static void rtc_reg_write(void *opaque, uint32_t addr, uint32_t value) +{ +SysPortState *s = opaque; + +if ((s-rtc_reg RTC_STROBE) !(value RTC_STROBE)) { +s-rtc_cmd = s-rtc_reg 0x07; +if (s-rtc_cmd == RTC_CMD_READ) { +rtc_read_time(s); +} else if (s-rtc_cmd == RTC_CMD_EXMODE) { +s-rtc_cmd = s-rtc_shift_cmd 0x0f; +if (s-rtc_cmd == RTC_CMD_READ) { +rtc_read_time(s); +} +} +} +if ((s-rtc_reg RTC_CLOCK) !(value RTC_CLOCK)) { +uint8_t din = ((s-rtc_reg RTC_DIN) != 0); +//if ((s-rtc_reg 0x07) == RTC_CMD_EXMODE) { +s-rtc_shift_cmd |= din 4; +s-rtc_shift_cmd = 1; +//} else if (s-rtc_cmd == RTC_CMD_SHIFT) { +s-rtc_shift_out = 1; +//} +} +s-rtc_reg = value; +} + +static void rtc_mode_write(void *opaque, uint32_t addr, uint32_t value) +{ +SysPortState *s = opaque; + +s-rtc_mode = value; +} + +static uint32_t rtc_mode_read(void *opaque, uint32_t addr) +{ +SysPortState *s = opaque; + +return s-rtc_mode; +} + +static void
[Qemu-devel] [PATCH V4 16/18] ide: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/ide.h |3 + hw/ide/pc98.c | 288 + 2 files changed, 291 insertions(+), 0 deletions(-) create mode 100644 hw/ide/pc98.c diff --git a/hw/ide.h b/hw/ide.h index 0e7d540..0a94bac 100644 --- a/hw/ide.h +++ b/hw/ide.h @@ -22,4 +22,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, qemu_irq irq, int shift, DriveInfo *hd0, DriveInfo *hd1); +/* ide-pc98.c */ +int pc98_ide_init(DriveInfo **hd_table); + #endif /* HW_IDE_H */ diff --git a/hw/ide/pc98.c b/hw/ide/pc98.c new file mode 100644 index 000..8f6c7a1 --- /dev/null +++ b/hw/ide/pc98.c @@ -0,0 +1,288 @@ +/* + * QEMU NEC PC-9821 IDE Bus + * + * Copyright (c) 2009 TAKEDA, toshiya + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include hw/hw.h +#include hw/pc.h +#include hw/isa.h +#include block.h +#include block_int.h +#include sysemu.h +#include dma.h + +#include hw/ide/internal.h + +/***/ +/* NEC PC-9821 IDE definitions */ + +typedef struct PC98IDEState { +ISADevice dev; +IDEBus bus[2]; +IDEBus *cur_bus; +uint8_t bus1_selected_vmstate; +uint32_t isairq; +qemu_irq irq; +} PC98IDEState; + +static void pc98_ide_cpu_shutdown(void *opaque, uint32_t addr, uint32_t val) +{ +pc98_cpu_shutdown(); +} + +static uint32_t pc98_ide_connection_read(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; +uint32_t ret; + +ret = 0x01; +if (s-cur_bus-ifs[0].bs !s-cur_bus-ifs[0].is_cdrom) { +ret |= 0x20; +} +if (s-cur_bus-ifs[1].bs !s-cur_bus-ifs[1].is_cdrom) { +ret |= 0x40; +} +return ret; +} + +static void pc98_ide_bank_write(void *opaque, uint32_t addr, uint32_t val) +{ +PC98IDEState *s = opaque; + +if (!(val 0x80)) { +s-cur_bus = s-bus[val 1]; +} +} + +static uint32_t pc98_ide_bank_read(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; + +if (s-cur_bus == s-bus[1]) { +return 0x01; +} +return 0x00; +} + +static void pc98_ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ +PC98IDEState *s = opaque; + +ide_ioport_write(s-cur_bus, addr 1, val); +} + +static uint32_t pc98_ide_ioport_read(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; + +return ide_ioport_read(s-cur_bus, addr 1); +} + +static void pc98_ide_data_writew(void *opaque, uint32_t addr, uint32_t val) +{ +PC98IDEState *s = opaque; + +ide_data_writew(s-cur_bus, addr 1, val); +} + +static uint32_t pc98_ide_data_readw(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; + +return ide_data_readw(s-cur_bus, addr 1); +} + +static void pc98_ide_data_writel(void *opaque, uint32_t addr, uint32_t val) +{ +PC98IDEState *s = opaque; + +ide_data_writel(s-cur_bus, addr 1, val); +} + +static uint32_t pc98_ide_data_readl(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; + +return ide_data_readl(s-cur_bus, addr 1); +} + +static void pc98_ide_digital_write(void *opaque, uint32_t addr, uint32_t val) +{ +PC98IDEState *s = opaque; +uint8_t prev = s-cur_bus-cmd; + +ide_cmd_write(s-cur_bus, addr, val); +if ((prev IDE_CMD_RESET) != (val IDE_CMD_RESET)) { +s-cur_bus-ifs[0].status = READY_STAT | SEEK_STAT; +s-cur_bus-ifs[1].status = READY_STAT | SEEK_STAT; +} +} + +static uint32_t pc98_ide_status_read(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; + +return ide_status_read(s-cur_bus, addr); +} + +static uint32_t pc98_ide_digital_read(void *opaque, uint32_t addr) +{ +PC98IDEState *s = opaque; +uint32_t ret; + +ret = 0xc0; +ret |= (~s-cur_bus-ifs[0].select 0x0f) 2; +if (s-cur_bus-unit == 1) { +ret |= 1; +} else { +ret |= 2; +} +
[Qemu-devel] [PATCH V4 11/18] fdc: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/fdc.c | 591 -- hw/fdc.h |1 + hw/hw.h | 12 ++ 3 files changed, 472 insertions(+), 132 deletions(-) diff --git a/hw/fdc.c b/hw/fdc.c index 0579b03..3041a22 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -57,6 +57,7 @@ /* Will always be a fixed parameter for us */ #define FD_SECTOR_LEN 512 +#define FD_SECTOR_LEN_21024 #define FD_SECTOR_SC 2 /* Sector size code */ #define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */ @@ -95,7 +96,10 @@ typedef struct fdrive_t { uint8_t last_sect;/* Nb sector per track*/ uint8_t max_track;/* Nb of tracks */ uint16_t bps; /* Bytes per sector */ +int sect_mul; /* Bytes per sector / 512 */ uint8_t ro; /* Is read-only */ +/* NEC PC-9821 */ +uint8_t status0; } fdrive_t; static void fd_init (fdrive_t *drv) @@ -107,6 +111,8 @@ static void fd_init (fdrive_t *drv) /* Disk */ drv-last_sect = 0; drv-max_track = 0; +drv-bps = FD_SECTOR_LEN; +drv-sect_mul = 1; } static int _fd_sector (uint8_t head, uint8_t track, @@ -176,12 +182,14 @@ static void fd_recalibrate (fdrive_t *drv) drv-head = 0; drv-track = 0; drv-sect = 1; +drv-status0 = 0; } /* Recognize floppy formats */ typedef struct fd_format_t { fdrive_type_t drive; fdisk_type_t disk; +uint16_t bps; uint8_t last_sect; uint8_t max_track; uint8_t max_head; @@ -191,48 +199,52 @@ typedef struct fd_format_t { static const fd_format_t fd_formats[] = { /* First entry is default format */ /* 1.44 MB 31/2 floppy disks */ -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, 1.44 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, 1.6 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, 1.68 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, 1.72 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, 1.74 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, 1.76 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, 1.84 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, 1.92 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 18, 80, 1, 1.44 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 20, 80, 1, 1.6 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 21, 80, 1, 1.68 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 21, 82, 1, 1.72 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 21, 83, 1, 1.74 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 22, 80, 1, 1.76 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 23, 80, 1, 1.84 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_144, 512, 24, 80, 1, 1.92 MB 3\1/2, }, /* 2.88 MB 31/2 floppy disks */ -{ FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, 2.88 MB 3\1/2, }, -{ FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, 3.12 MB 3\1/2, }, -{ FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, 3.2 MB 3\1/2, }, -{ FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, 3.52 MB 3\1/2, }, -{ FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, 3.84 MB 3\1/2, }, +{ FDRIVE_DRV_288, FDRIVE_DISK_288, 512, 36, 80, 1, 2.88 MB 3\1/2, }, +{ FDRIVE_DRV_288, FDRIVE_DISK_288, 512, 39, 80, 1, 3.12 MB 3\1/2, }, +{ FDRIVE_DRV_288, FDRIVE_DISK_288, 512, 40, 80, 1, 3.2 MB 3\1/2, }, +{ FDRIVE_DRV_288, FDRIVE_DISK_288, 512, 44, 80, 1, 3.52 MB 3\1/2, }, +{ FDRIVE_DRV_288, FDRIVE_DISK_288, 512, 48, 80, 1, 3.84 MB 3\1/2, }, /* 720 kB 31/2 floppy disks */ -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, 720 kB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, 800 kB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, 820 kB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, 830 kB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, 1.04 MB 3\1/2, }, -{ FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, 1.12 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 9, 80, 1, 720 kB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 10, 80, 1, 800 kB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 10, 82, 1, 820 kB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 10, 83, 1, 830 kB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 13, 80, 1, 1.04 MB 3\1/2, }, +{ FDRIVE_DRV_144, FDRIVE_DISK_720, 512, 14, 80, 1, 1.12 MB 3\1/2, }, +/* 1.23 MB 51/4 floppy disks */ +{ FDRIVE_DRV_120, FDRIVE_DISK_288, 1024, 8, 77, 1, 1.23 MB 5\1/4, }, /* 1.2 MB 51/4 floppy disks */ -{ FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, 1.2 kB 5\1/4, }, -{ FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, 1.44 MB 5\1/4, }, -{ FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, 1.48 MB 5\1/4, }, -{ FDRIVE_DRV_120,
[Qemu-devel] [PATCH V4 18/18] pc: extern i440fx_state and ferr_irq
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pc.c |4 ++-- hw/pc.h |7 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index db7d58e..ddefb7f 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -67,7 +67,7 @@ static fdctrl_t *floppy_controller; static RTCState *rtc_state; static PITState *pit; -static PCII440FXState *i440fx_state; +PCII440FXState *i440fx_state; typedef struct isa_irq_state { qemu_irq *i8259; @@ -90,7 +90,7 @@ static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) } /* MSDOS compatibility mode FPU exception support */ -static qemu_irq ferr_irq; +qemu_irq ferr_irq; /* XXX: add IGNNE support */ void cpu_set_ferr(CPUX86State *s) { diff --git a/hw/pc.h b/hw/pc.h index 03ffc91..b39d7a1 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -93,6 +93,7 @@ extern int fd_bootchk; void ioport_set_a20(int enable); int ioport_get_a20(void); +int cpu_is_bsp(CPUState *env); /* acpi.c */ extern int acpi_enabled; @@ -146,8 +147,10 @@ void pci_cirrus_vga_init(PCIBus *bus); void isa_cirrus_vga_init(void); /* ne2000.c */ - void isa_ne2000_init(int base, int irq, NICInfo *nd); -int cpu_is_bsp(CPUState *env); +/* NEC PC-9821 */ +extern PCII440FXState *i440fx_state; +extern qemu_irq ferr_irq; +#include pc98.h #endif -- 1.6.4
[Qemu-devel] [PATCH V4 15/18] pcspk: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/pcspk.c | 32 +++- 1 files changed, 27 insertions(+), 5 deletions(-) diff --git a/hw/pcspk.c b/hw/pcspk.c index 26a0ecb..4a21aae 100644 --- a/hw/pcspk.c +++ b/hw/pcspk.c @@ -38,6 +38,7 @@ typedef struct { QEMUSoundCard card; SWVoiceOut *voice; PITState *pit; +int pit_ch; unsigned int pit_count; unsigned int samples; unsigned int play_pos; @@ -72,10 +73,10 @@ static void pcspk_callback(void *opaque, int free) PCSpkState *s = opaque; unsigned int n; -if (pit_get_mode(s-pit, 2) != 3) +if (pit_get_mode(s-pit, s-pit_ch) != 3) return; -n = pit_get_initial_count(s-pit, 2); +n = pit_get_initial_count(s-pit, s-pit_ch); /* avoid frequencies that are not reproducible with sample rate */ if (n PCSPK_MIN_COUNT) n = 0; @@ -118,9 +119,9 @@ static uint32_t pcspk_ioport_read(void *opaque, uint32_t addr) int out; s-dummy_refresh_clock ^= (1 4); -out = pit_get_out(s-pit, 2, qemu_get_clock(vm_clock)) 5; +out = pit_get_out(s-pit, s-pit_ch, qemu_get_clock(vm_clock)) 5; -return pit_get_gate(s-pit, 2) | (s-data_on 1) | s-dummy_refresh_clock | out; +return pit_get_gate(s-pit, s-pit_ch) | (s-data_on 1) | s-dummy_refresh_clock | out; } static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -129,7 +130,7 @@ static void pcspk_ioport_write(void *opaque, uint32_t addr, uint32_t val) const int gate = val 1; s-data_on = (val 1) 1; -pit_set_gate(s-pit, 2, gate); +pit_set_gate(s-pit, s-pit_ch, gate); if (s-voice) { if (gate) /* restart */ s-play_pos = 0; @@ -142,6 +143,27 @@ void pcspk_init(PITState *pit) PCSpkState *s = pcspk_state; s-pit = pit; +s-pit_ch = 2; register_ioport_read(0x61, 1, 1, pcspk_ioport_read, s); register_ioport_write(0x61, 1, 1, pcspk_ioport_write, s); } + +/* NEC PC-9821 */ + +void pc98_pcspk_write(uint32_t val) +{ +PCSpkState *s = pcspk_state; + +s-data_on = ((val 0x08) == 0); +if (s-voice) { +AUD_set_active_out(s-voice, s-data_on); +} +} + +void pc98_pcspk_init(PITState *pit) +{ +PCSpkState *s = pcspk_state; + +s-pit = pit; +s-pit_ch = 1; +} -- 1.6.4
[Qemu-devel] [PATCH V4 12/18] i8254: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/i8254.c | 57 +++-- 1 files changed, 51 insertions(+), 6 deletions(-) diff --git a/hw/i8254.c b/hw/i8254.c index faaa884..155f879 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -47,6 +47,7 @@ typedef struct PITChannelState { uint8_t bcd; /* not supported */ uint8_t gate; /* timer start */ int64_t count_load_time; +uint64_t frequency; /* irq handling */ int64_t next_transition_time; QEMUTimer *irq_timer; @@ -66,7 +67,7 @@ static int pit_get_count(PITChannelState *s) uint64_t d; int counter; -d = muldiv64(qemu_get_clock(vm_clock) - s-count_load_time, PIT_FREQ, +d = muldiv64(qemu_get_clock(vm_clock) - s-count_load_time, s-frequency, get_ticks_per_sec()); switch(s-mode) { case 0: @@ -92,7 +93,7 @@ static int pit_get_out1(PITChannelState *s, int64_t current_time) uint64_t d; int out; -d = muldiv64(current_time - s-count_load_time, PIT_FREQ, +d = muldiv64(current_time - s-count_load_time, s-frequency, get_ticks_per_sec()); switch(s-mode) { default: @@ -132,7 +133,7 @@ static int64_t pit_get_next_transition_time(PITChannelState *s, uint64_t d, next_time, base; int period2; -d = muldiv64(current_time - s-count_load_time, PIT_FREQ, +d = muldiv64(current_time - s-count_load_time, s-frequency, get_ticks_per_sec()); switch(s-mode) { default: @@ -170,7 +171,7 @@ static int64_t pit_get_next_transition_time(PITChannelState *s, } /* convert to timer units */ next_time = s-count_load_time + muldiv64(next_time, get_ticks_per_sec(), - PIT_FREQ); + s-frequency); /* fix potential rounding problems */ /* XXX: better solution: use a clock at PIT_FREQ Hz */ if (next_time = current_time) @@ -498,20 +499,64 @@ void hpet_pit_enable(void) pit_load_count(s, 0); } -PITState *pit_init(int base, qemu_irq irq) +static void pit_init_common(PITState *pit, int base, qemu_irq irq, +uint64_t frequency) { -PITState *pit = pit_state; PITChannelState *s; +int i; s = pit-channels[0]; /* the timer 0 is connected to an IRQ */ s-irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s); s-irq = irq; +for (i = 0; i 3; i++) { +pit-channels[i].frequency = frequency; +} + vmstate_register(base, vmstate_pit, pit); qemu_register_reset(pit_reset, pit); +} + +PITState *pit_init(int base, qemu_irq irq) +{ +PITState *pit = pit_state; + +pit_init_common(pit, base, irq, PIT_FREQ); + register_ioport_write(base, 4, 1, pit_ioport_write, pit); register_ioport_read(base, 3, 1, pit_ioport_read, pit); return pit; } + +/* NEC PC-9821 */ + +static void pc98_pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ +pit_ioport_write(opaque, addr 1, val); +} + +static uint32_t pc98_pit_ioport_read(void *opaque, uint32_t addr) +{ +return pit_ioport_read(opaque, addr 1); +} + +PITState *pc98_pit_init(qemu_irq irq) +{ +PITState *pit = pit_state; +int i; + +pit_init_common(pit, 0, irq, PC98_PIT_FREQ); + +for (i = 0; i 4; i++) { +register_ioport_write(0x71 + (i 1), 1, 1, pc98_pit_ioport_write, pit); +register_ioport_write(0x3fd9 + (i 1), 1, 1, pc98_pit_ioport_write, pit); +} +for (i = 0; i 3; i++) { +register_ioport_read(0x71 + (i 1), 1, 1, pc98_pit_ioport_read, pit); +register_ioport_read(0x3fd9 + (i 1), 1, 1, pc98_pit_ioport_read, pit); +} + +return pit; +} -- 1.6.4
[Qemu-devel] [PATCH V4 13/18] i8259: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/i8259.c | 63 --- 1 files changed, 55 insertions(+), 8 deletions(-) diff --git a/hw/i8259.c b/hw/i8259.c index 3de22e3..eaf75dd 100644 --- a/hw/i8259.c +++ b/hw/i8259.c @@ -59,6 +59,7 @@ struct PicState2 { /* XXX: better separation between the two pics */ PicState pics[2]; qemu_irq parent_irq; +uint8_t irq_cascade; void *irq_request_opaque; }; @@ -124,7 +125,7 @@ static int pic_get_irq(PicState *s) if (s-special_mask) mask = ~s-imr; if (s-special_fully_nested_mode s == s-pics_state-pics[0]) -mask = ~(1 2); +mask = ~(1 s-pics_state-irq_cascade); cur_priority = get_priority(s, mask); if (priority cur_priority) { /* higher priority found: an irq should be generated */ @@ -145,8 +146,8 @@ void pic_update_irq(PicState2 *s) irq2 = pic_get_irq(s-pics[1]); if (irq2 = 0) { /* if irq request by slave pic, signal master PIC */ -pic_set_irq1(s-pics[0], 2, 1); -pic_set_irq1(s-pics[0], 2, 0); +pic_set_irq1(s-pics[0], s-irq_cascade, 1); +pic_set_irq1(s-pics[0], s-irq_cascade, 0); } /* look at requested irq */ irq = pic_get_irq(s-pics[0]); @@ -171,6 +172,11 @@ void pic_update_irq(PicState2 *s) else { qemu_irq_lower(s-parent_irq); } +#elif defined(TARGET_I386) +else if (s-irq_cascade == 7) { +/* NEC PC-9821 */ +qemu_irq_lower(s-parent_irq); +} #endif } @@ -224,7 +230,7 @@ int pic_read_irq(PicState2 *s) irq = pic_get_irq(s-pics[0]); if (irq = 0) { pic_intack(s-pics[0], irq); -if (irq == 2) { +if (irq == s-irq_cascade) { irq2 = pic_get_irq(s-pics[1]); if (irq2 = 0) { pic_intack(s-pics[1], irq2); @@ -377,12 +383,12 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) ret = pic_get_irq(s); if (ret = 0) { if (addr1 7) { -s-pics_state-pics[0].isr = ~(1 2); -s-pics_state-pics[0].irr = ~(1 2); +s-pics_state-pics[0].isr = ~(1 s-pics_state-irq_cascade); +s-pics_state-pics[0].irr = ~(1 s-pics_state-irq_cascade); } s-irr = ~(1 ret); s-isr = ~(1 ret); -if (addr1 7 || ret != 2) +if (addr1 7 || ret != s-pics_state-irq_cascade) pic_update_irq(s-pics_state); } else { ret = 0x07; @@ -426,7 +432,7 @@ uint32_t pic_intack_read(PicState2 *s) int ret; ret = pic_poll_read(s-pics[0], 0x00); -if (ret == 2) +if (ret == s-irq_cascade) ret = pic_poll_read(s-pics[1], 0x80) + 8; /* Prepare for ISR read */ s-pics[0].read_reg_select = 1; @@ -530,6 +536,47 @@ qemu_irq *i8259_init(qemu_irq parent_irq) s-pics[0].elcr_mask = 0xf8; s-pics[1].elcr_mask = 0xde; s-parent_irq = parent_irq; +s-irq_cascade = 2; +s-pics[0].pics_state = s; +s-pics[1].pics_state = s; +isa_pic = s; +return qemu_allocate_irqs(i8259_set_irq, s, 16); +} + +/* NEC PC-9821 */ + +static void pc98_pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ +pic_ioport_write(opaque, addr 1, val); +} + +static uint32_t pc98_pic_ioport_read(void *opaque, uint32_t addr) +{ +return pic_ioport_read(opaque, addr 1); +} + +static void pc98_pic_init1(int io_addr, PicState *s) +{ +int i; +for (i = 0; i 2; i++) { +register_ioport_write(io_addr + (i 1), 1, 1, pc98_pic_ioport_write, s); +register_ioport_read(io_addr + (i 1), 1, 1, pc98_pic_ioport_read, s); +} +vmstate_register(io_addr, vmstate_pic, s); +qemu_register_reset(pic_reset, s); +} + +qemu_irq *pc98_i8259_init(qemu_irq parent_irq) +{ +PicState2 *s; + +s = qemu_mallocz(sizeof(PicState2)); +pc98_pic_init1(0x00, s-pics[0]); +pc98_pic_init1(0x08, s-pics[1]); +s-pics[0].elcr_mask = 0; +s-pics[1].elcr_mask = 0; +s-parent_irq = parent_irq; +s-irq_cascade = 7; s-pics[0].pics_state = s; s-pics[1].pics_state = s; isa_pic = s; -- 1.6.4
[Qemu-devel] [PATCH V4 17/18] ide: support CHS mode
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/ide/core.c | 13 +++-- hw/ide/internal.h |1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/ide/core.c b/hw/ide/core.c index 76c3820..4c77415 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1801,8 +1801,10 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case 6: /* FIXME: HOB readback uses bit 7 */ -bus-ifs[0].select = (val ~0x10) | 0xa0; -bus-ifs[1].select = (val | 0x10) | 0xa0; +bus-ifs[0].select = (val ~0x10) | + (bus-ifs[0].support_chs ? 0x80 : 0xa0); +bus-ifs[1].select = (val | 0x10) | + (bus-ifs[1].support_chs ? 0x80 : 0xa0); /* select drive */ bus-unit = (val 4) 1; break; @@ -1839,6 +1841,13 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) ide_set_irq(s-bus); break; case WIN_SPECIFY: +if (s-support_chs !(s-select 0x40)) { +uint64_t sectors; +bdrv_get_geometry(s-bs, sectors); +s-heads = (s-select 0xf) + 1; +s-sectors = s-nsector; +s-cylinders = sectors / (s-heads * s-sectors); +} case WIN_RECAL: s-error = 0; s-status = READY_STAT | SEEK_STAT; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index eb5b404..bf26c52 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -396,6 +396,7 @@ struct IDEState { /* set for lba48 access */ uint8_t lba48; +uint8_t support_chs; BlockDriverState *bs; /* ATAPI specific */ uint8_t sense_key; -- 1.6.4
[Qemu-devel] [PATCH V4 14/18] ne2000-isa: support NEC PC-9821 interface
Signed-off-by: TAKEDA, toshiya t-tak...@m1.interq.or.jp --- hw/ne2000-isa.c | 71 -- 1 files changed, 63 insertions(+), 8 deletions(-) diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c index 03a5a1f..4a1733b 100644 --- a/hw/ne2000-isa.c +++ b/hw/ne2000-isa.c @@ -61,6 +61,19 @@ static const VMStateDescription vmstate_isa_ne2000 = { } }; +static void isa_ne2000_initfn_common(ISADevice *dev, + ISANE2000State *isa, NE2000State *s) +{ +isa_init_irq(dev, s-irq, isa-isairq); + +qemu_macaddr_default_if_unset(s-c.macaddr); +ne2000_reset(s); + +s-nic = qemu_new_nic(net_ne2000_isa_info, s-c, + dev-qdev.info-name, dev-qdev.id, s); +qemu_format_nic_info_str(s-nic-nc, s-c.macaddr.a); +} + static int isa_ne2000_initfn(ISADevice *dev) { ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev); @@ -77,14 +90,7 @@ static int isa_ne2000_initfn(ISADevice *dev) register_ioport_write(isa-iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s); register_ioport_read(isa-iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s); -isa_init_irq(dev, s-irq, isa-isairq); - -qemu_macaddr_default_if_unset(s-c.macaddr); -ne2000_reset(s); - -s-nic = qemu_new_nic(net_ne2000_isa_info, s-c, - dev-qdev.info-name, dev-qdev.id, s); -qemu_format_nic_info_str(s-nic-nc, s-c.macaddr.a); +isa_ne2000_initfn_common(dev, isa, s); return 0; } @@ -114,9 +120,58 @@ static ISADeviceInfo ne2000_isa_info = { }, }; +/* NEC PC-9821 (MELCO LGY-98) */ + +static int pc98_ne2000_initfn(ISADevice *dev) +{ +ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev); +NE2000State *s = isa-ne2000; + +register_ioport_write(isa-iobase, 16, 1, ne2000_ioport_write, s); +register_ioport_read(isa-iobase, 16, 1, ne2000_ioport_read, s); + +register_ioport_write(isa-iobase + 0x200, 1, 1, ne2000_asic_ioport_write, s); +register_ioport_read(isa-iobase + 0x200, 1, 1, ne2000_asic_ioport_read, s); +register_ioport_write(isa-iobase + 0x200, 2, 2, ne2000_asic_ioport_write, s); +register_ioport_read(isa-iobase + 0x200, 2, 2, ne2000_asic_ioport_read, s); + +register_ioport_write(isa-iobase + 0x18, 1, 1, ne2000_reset_ioport_write, s); +register_ioport_read(isa-iobase + 0x18, 1, 1, ne2000_reset_ioport_read, s); + +isa_ne2000_initfn_common(dev, isa, s); + +return 0; +} + +void pc98_ne2000_init(int base, int irq, NICInfo *nd) +{ +ISADevice *dev; + +qemu_check_nic_model(nd, ne2k_isa); + +dev = isa_create(ne2k_pc98); +qdev_prop_set_uint32(dev-qdev, iobase, base); +qdev_prop_set_uint32(dev-qdev, irq,irq); +qdev_set_nic_properties(dev-qdev, nd); +qdev_init_nofail(dev-qdev); +} + +static ISADeviceInfo ne2000_pc98_info = { +.qdev.name = ne2k_pc98, +.qdev.size = sizeof(ISANE2000State), +.init = pc98_ne2000_initfn, +.qdev.props = (Property[]) { +DEFINE_PROP_HEX32(iobase, ISANE2000State, iobase, 0xd0), +DEFINE_PROP_UINT32(irq, ISANE2000State, isairq, 3), +DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c), +DEFINE_PROP_END_OF_LIST(), +}, +}; + static void ne2000_isa_register_devices(void) { isa_qdev_register(ne2000_isa_info); +isa_qdev_register(ne2000_pc98_info); } device_init(ne2000_isa_register_devices) -- 1.6.4
[Qemu-devel] [RFC PATCH 0/3] virtio-console: Move to qdev, multiple devices, generic ports
Hello, Here's the latest patch series for enabling support for generic serial ports over the virtio-console device. This series converts virtio-console to the qdev infrastructure, creates a new virtio-serial bus on which console and generic ports are put and adds support for multiple devices, each of which can have multiple ports. I've tried converting the s390 bits but acks from the maintainers would be good. The vl.c bits have to be changed to accomodate s390 -- what I'm currently doing is when an old-style -virtioconsole argument is found, a virtio-serial-pci bus is created and a virtioconsole device is put on top of that. That needs to change to check for either virtio-serial-pci or virtio-serial-s390 and use the appropriate one. Other than that, this series passes my tests which ensures that the console and the other functionality works fine on old as well as new guests. The major change from the last time this patch series was sent is that each port now has its own IO vqs instead of a common pair for all the ports. Please review, Amit. Amit Shah (3): virtio: Remove duplicate macro definition for max. virtqueues, bump up the max virtio-console: Add a virtio-serial bus, support for multiple devices and ports virtio-serial: Add a new virtserialport device for generic serial port support Makefile.target|2 +- hw/pc.c|9 - hw/ppc440_bamboo.c |7 - hw/qdev.c |8 +- hw/s390-virtio-bus.c | 16 +- hw/s390-virtio-bus.h |1 + hw/virtio-console.c| 213 ++- hw/virtio-console.h| 19 - hw/virtio-pci.c| 11 +- hw/virtio-serial-bus.c | 964 hw/virtio-serial.h | 230 hw/virtio.c|2 - hw/virtio.h|4 +- qemu-options.hx|4 + sysemu.h |6 - vl.c | 18 +- 16 files changed, 1350 insertions(+), 164 deletions(-) delete mode 100644 hw/virtio-console.h create mode 100644 hw/virtio-serial-bus.c create mode 100644 hw/virtio-serial.h
[Qemu-devel] [PATCH 3/3] virtio-serial: Add a new virtserialport device for generic serial port support
This patch adds generic serial ports over the virtio serial bus. These ports have a few more options that are not relevant for virtio console ports: the ability to cache buffers that are received for a port while it's disconnected, setting of limits to the bytes that are cached so as to prevent OOM conditions, etc. Sample uses for such a device can be obtaining info from the guest like the file systems used, apps installed, etc. for offline usage and logged-in users, clipboard copy-paste, etc. for online usage. For requirements, use-cases, test cases and some history see http://www.linux-kvm.org/page/VMchannel_Requirements Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio-console.c | 37 + 1 files changed, 37 insertions(+), 0 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index b2e4eb1..fc0c239 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -119,3 +119,40 @@ static void virtcon_register(void) virtio_serial_port_qdev_register(virtcon_info); } device_init(virtcon_register) + + +/* Generic Virtio Serial Ports */ +static int virtserial_port_initfn(VirtIOSerialDevice *dev) +{ +VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev); +VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + +port-info = dev-info; + +if (vcon-chr) { +qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read, chr_event, + vcon); +} +return 0; +} + +static VirtIOSerialPortInfo virtserial_port_info = { +.qdev.name = virtserialport, +.qdev.size = sizeof(VirtConsole), +.init = virtserial_port_initfn, +.exit = vcon_exitfn, +.have_data = flush_buf, +.qdev.props = (Property[]) { +DEFINE_PROP_CHR(chardev, VirtConsole, chr), +DEFINE_PROP_STRING(name, VirtConsole, port.name), +DEFINE_PROP_INT32(cache_buffers, VirtConsole, port.cache_buffers, 1), +DEFINE_PROP_UINT64(byte_limit, VirtConsole, port.byte_limit, 0), +DEFINE_PROP_END_OF_LIST(), +}, +}; + +static void virtserial_port_register(void) +{ +virtio_serial_port_qdev_register(virtserial_port_info); +} +device_init(virtserial_port_register) -- 1.6.2.5
[Qemu-devel] [PATCH 1/3] virtio: Remove duplicate macro definition for max. virtqueues, bump up the max
VIRTIO_PCI_QUEUE_MAX is redefined in hw/virtio.c. Let's just keep it in hw/virtio.h. Also, bump up the value of the maximum allowed virtqueues to 32. This is in preparation to allow multiple ports per virtio-console device. Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio.c |2 -- hw/virtio.h |2 +- 2 files changed, 1 insertions(+), 3 deletions(-) diff --git a/hw/virtio.c b/hw/virtio.c index cecd0dc..88f4e78 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -75,8 +75,6 @@ struct VirtQueue void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); }; -#define VIRTIO_PCI_QUEUE_MAX16 - /* virt queue functions */ static void virtqueue_init(VirtQueue *vq) { diff --git a/hw/virtio.h b/hw/virtio.h index 35532a6..769f540 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -90,7 +90,7 @@ typedef struct { unsigned (*get_features)(void * opaque); } VirtIOBindings; -#define VIRTIO_PCI_QUEUE_MAX 16 +#define VIRTIO_PCI_QUEUE_MAX 32 #define VIRTIO_NO_VECTOR 0x -- 1.6.2.5
[Qemu-devel] [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
This patch migrates virtio-console to the qdev infrastructure and creates a new virtio-serial bus on which multiple ports are exposed as devices. The bulk of the code now resides in a new file with virtio-console.c being just a simple qdev device. This interface enables spawning of multiple virtio consoles as well as generic serial ports. The older -virtconsole argument still works, but when using the new functionality, it is recommended to use -device virtio-serial-pci -device virtconsole,... The virtconsole device type accepts a chardev as an argument and a 'name' argument to identify the corresponding consoles on the host as well as the guest. The name, if given, is exposed via the 'name' sysfs attribute in the guest. Care has been taken to ensure compatibility with kernels that do not support multiple ports as well as accepting incoming migrations from older qemu versions. Signed-off-by: Amit Shah amit.s...@redhat.com --- Makefile.target|2 +- hw/pc.c|9 - hw/ppc440_bamboo.c |7 - hw/qdev.c |8 +- hw/s390-virtio-bus.c | 16 +- hw/s390-virtio-bus.h |1 + hw/virtio-console.c| 186 -- hw/virtio-console.h| 19 - hw/virtio-pci.c| 11 +- hw/virtio-serial-bus.c | 964 hw/virtio-serial.h | 230 hw/virtio.h|2 +- qemu-options.hx|4 + sysemu.h |6 - vl.c | 18 +- 15 files changed, 1317 insertions(+), 166 deletions(-) delete mode 100644 hw/virtio-console.h create mode 100644 hw/virtio-serial-bus.c create mode 100644 hw/virtio-serial.h diff --git a/Makefile.target b/Makefile.target index 7c1f30c..74bb548 100644 --- a/Makefile.target +++ b/Makefile.target @@ -156,7 +156,7 @@ ifdef CONFIG_SOFTMMU obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly -obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o +obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o virtio-console.o virtio-pci.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_ISA_MMIO) += isa_mmio.o LIBS+=-lz diff --git a/hw/pc.c b/hw/pc.c index db7d58e..5e742bf 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1242,15 +1242,6 @@ static void pc_init1(ram_addr_t ram_size, } } -/* Add virtio console devices */ -if (pci_enabled) { -for(i = 0; i MAX_VIRTIO_CONSOLES; i++) { -if (virtcon_hds[i]) { -pci_create_simple(pci_bus, -1, virtio-console-pci); -} -} -} - rom_load_fw(fw_cfg); } diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index a488240..1ab9872 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -108,13 +108,6 @@ static void bamboo_init(ram_addr_t ram_size, env = ppc440ep_init(ram_size, pcibus, pci_irq_nrs, 1, cpu_model); if (pcibus) { -/* Add virtio console devices */ -for(i = 0; i MAX_VIRTIO_CONSOLES; i++) { -if (virtcon_hds[i]) { -pci_create_simple(pcibus, -1, virtio-console-pci); -} -} - /* Register network interfaces. */ for (i = 0; i nb_nics; i++) { /* There are no PCI NICs on the Bamboo board, but there are diff --git a/hw/qdev.c b/hw/qdev.c index b6bd4ae..38c6e15 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -321,13 +321,9 @@ void qdev_machine_creation_done(void) CharDriverState *qdev_init_chardev(DeviceState *dev) { static int next_serial; -static int next_virtconsole; + /* FIXME: This is a nasty hack that needs to go away. */ -if (strncmp(dev-info-name, virtio, 6) == 0) { -return virtcon_hds[next_virtconsole++]; -} else { -return serial_hds[next_serial++]; -} +return serial_hds[next_serial++]; } BusState *qdev_get_parent_bus(DeviceState *dev) diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index dc154ed..79ba9fc 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -26,7 +26,7 @@ #include loader.h #include elf.h #include hw/virtio.h -#include hw/virtio-console.h +#include hw/virtio-serial.h #include hw/sysbus.h #include kvm.h @@ -130,7 +130,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev) return s390_virtio_device_init(dev, vdev); } -static int s390_virtio_console_init(VirtIOS390Device *dev) +static int s390_virtio_serial_init(VirtIOS390Device *dev) { VirtIOS390Bus *bus; VirtIODevice *vdev; @@ -138,7 +138,7 @@ static int s390_virtio_console_init(VirtIOS390Device *dev) bus = DO_UPCAST(VirtIOS390Bus, bus, dev-qdev.parent_bus); -vdev = virtio_console_init((DeviceState *)dev); +vdev = virtio_serial_init((DeviceState *)dev, dev-max_virtserial_ports); if (!vdev) { return -1; } @@ -336,11
[Qemu-devel] Re: [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
Amit Shah wrote: This patch migrates virtio-console to the qdev infrastructure and creates a new virtio-serial bus on which multiple ports are exposed as devices. The bulk of the code now resides in a new file with virtio-console.c being just a simple qdev device. This interface enables spawning of multiple virtio consoles as well as generic serial ports. The older -virtconsole argument still works, but when using the new functionality, it is recommended to use -device virtio-serial-pci -device virtconsole,... The virtconsole device type accepts a chardev as an argument and a 'name' argument to identify the corresponding consoles on the host as well as the guest. The name, if given, is exposed via the 'name' sysfs attribute in the guest. Care has been taken to ensure compatibility with kernels that do not support multiple ports as well as accepting incoming migrations from older qemu versions. Signed-off-by: Amit Shah amit.s...@redhat.com Please split this patch. I got dizzy after only reading 1/4th of it :-). Alex
[Qemu-devel] Re: [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
On (Tue) Dec 22 2009 [18:55:16], Alexander Graf wrote: Amit Shah wrote: This patch migrates virtio-console to the qdev infrastructure and creates a new virtio-serial bus on which multiple ports are exposed as devices. The bulk of the code now resides in a new file with virtio-console.c being just a simple qdev device. This interface enables spawning of multiple virtio consoles as well as generic serial ports. The older -virtconsole argument still works, but when using the new functionality, it is recommended to use -device virtio-serial-pci -device virtconsole,... The virtconsole device type accepts a chardev as an argument and a 'name' argument to identify the corresponding consoles on the host as well as the guest. The name, if given, is exposed via the 'name' sysfs attribute in the guest. Care has been taken to ensure compatibility with kernels that do not support multiple ports as well as accepting incoming migrations from older qemu versions. Signed-off-by: Amit Shah amit.s...@redhat.com Please split this patch. I got dizzy after only reading 1/4th of it :-). Ah, sooner the better I guess. I'll do that soon. The interesting bits for you are in hw/s390-* and vl.c though. Amit
[Qemu-devel] Re: [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
Amit Shah wrote: This patch migrates virtio-console to the qdev infrastructure and creates a new virtio-serial bus on which multiple ports are exposed as devices. The bulk of the code now resides in a new file with virtio-console.c being just a simple qdev device. This interface enables spawning of multiple virtio consoles as well as generic serial ports. The older -virtconsole argument still works, but when using the new functionality, it is recommended to use -device virtio-serial-pci -device virtconsole,... The virtconsole device type accepts a chardev as an argument and a 'name' argument to identify the corresponding consoles on the host as well as the guest. The name, if given, is exposed via the 'name' sysfs attribute in the guest. Care has been taken to ensure compatibility with kernels that do not support multiple ports as well as accepting incoming migrations from older qemu versions. Signed-off-by: Amit Shah amit.s...@redhat.com --- Makefile.target|2 +- hw/pc.c|9 - hw/ppc440_bamboo.c |7 - hw/qdev.c |8 +- hw/s390-virtio-bus.c | 16 +- hw/s390-virtio-bus.h |1 + hw/virtio-console.c| 186 -- hw/virtio-console.h| 19 - hw/virtio-pci.c| 11 +- hw/virtio-serial-bus.c | 964 hw/virtio-serial.h | 230 hw/virtio.h|2 +- qemu-options.hx|4 + sysemu.h |6 - vl.c | 18 +- 15 files changed, 1317 insertions(+), 166 deletions(-) delete mode 100644 hw/virtio-console.h create mode 100644 hw/virtio-serial-bus.c create mode 100644 hw/virtio-serial.h diff --git a/Makefile.target b/Makefile.target index 7c1f30c..74bb548 100644 --- a/Makefile.target +++ b/Makefile.target @@ -156,7 +156,7 @@ ifdef CONFIG_SOFTMMU obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly -obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o +obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o virtio-console.o virtio-pci.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_ISA_MMIO) += isa_mmio.o LIBS+=-lz diff --git a/hw/pc.c b/hw/pc.c index db7d58e..5e742bf 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1242,15 +1242,6 @@ static void pc_init1(ram_addr_t ram_size, } } -/* Add virtio console devices */ -if (pci_enabled) { -for(i = 0; i MAX_VIRTIO_CONSOLES; i++) { -if (virtcon_hds[i]) { -pci_create_simple(pci_bus, -1, virtio-console-pci); -} -} -} - We have something pretty similar in s390-virtio.c. I suppose that needs to be changed too? rom_load_fw(fw_cfg); } diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index a488240..1ab9872 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -108,13 +108,6 @@ static void bamboo_init(ram_addr_t ram_size, env = ppc440ep_init(ram_size, pcibus, pci_irq_nrs, 1, cpu_model); if (pcibus) { -/* Add virtio console devices */ -for(i = 0; i MAX_VIRTIO_CONSOLES; i++) { -if (virtcon_hds[i]) { -pci_create_simple(pcibus, -1, virtio-console-pci); -} -} - /* Register network interfaces. */ for (i = 0; i nb_nics; i++) { /* There are no PCI NICs on the Bamboo board, but there are diff --git a/hw/qdev.c b/hw/qdev.c index b6bd4ae..38c6e15 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -321,13 +321,9 @@ void qdev_machine_creation_done(void) CharDriverState *qdev_init_chardev(DeviceState *dev) { static int next_serial; -static int next_virtconsole; + /* FIXME: This is a nasty hack that needs to go away. */ -if (strncmp(dev-info-name, virtio, 6) == 0) { -return virtcon_hds[next_virtconsole++]; -} else { -return serial_hds[next_serial++]; -} +return serial_hds[next_serial++]; } BusState *qdev_get_parent_bus(DeviceState *dev) diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index dc154ed..79ba9fc 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -26,7 +26,7 @@ #include loader.h #include elf.h #include hw/virtio.h -#include hw/virtio-console.h +#include hw/virtio-serial.h #include hw/sysbus.h #include kvm.h @@ -130,7 +130,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *dev) return s390_virtio_device_init(dev, vdev); } -static int s390_virtio_console_init(VirtIOS390Device *dev) +static int s390_virtio_serial_init(VirtIOS390Device *dev) { VirtIOS390Bus *bus; VirtIODevice *vdev; @@ -138,7 +138,7 @@ static int s390_virtio_console_init(VirtIOS390Device *dev)
[Qemu-devel] Re: [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
On (Tue) Dec 22 2009 [19:08:40], Alexander Graf wrote: -/* Add virtio console devices */ -if (pci_enabled) { -for(i = 0; i MAX_VIRTIO_CONSOLES; i++) { -if (virtcon_hds[i]) { -pci_create_simple(pci_bus, -1, virtio-console-pci); -} -} -} - We have something pretty similar in s390-virtio.c. I suppose that needs to be changed too? Yes, it'll have to be changed as well then; done in my tree. -static VirtIOS390DeviceInfo s390_virtio_console = { -.init = s390_virtio_console_init, -.qdev.name = virtio-console-s390, +static VirtIOS390DeviceInfo s390_virtio_serial = { +.init = s390_virtio_serial_init, +.qdev.name = virtio-serial-s390, Are you sure you changed all users of the old name too? There's only virtio-serial-pci and virtio-serial-s390. Is there something I missed? The new changes in vl.c, on the other hand, I've not yet fully studied so there might be something missing there. --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -1,143 +1,121 @@ /* - * Virtio Console Device + * Virtio Console and Generic Port Devices * - * Copyright IBM, Corp. 2008 + * Copyright Red Hat, Inc. 2009 * * Authors: - * Christian Ehrhardt ehrha...@linux.vnet.ibm.com + * Amit Shah amit.s...@redhat.com Please don't remove copyrights. It seems that way due to file name changes. This is actually a new file that has nothing in common with the old one. Whatever is left of the old content is now in virtio-serial-bus.c. @@ -4823,6 +4826,13 @@ static int virtcon_parse(const char *devname) fprintf(stderr, qemu: too many virtio consoles\n); exit(1); } + +opts = qemu_opts_create(qemu_device_opts, NULL, 0); +qemu_opt_set(opts, driver, virtio-serial-pci); As you stated in your comment, this breaks. Maybe something as simple as #ifdef TARGET_S390X qemu_opt_set(opts, driver, virtio-serial-pci); #else qemu_opt_set(opts, driver, virtio-serial-s390); #endif is enough here? But it's ugly; Markus said we could do something better but I didn't fully understand it. On the lines of creating default devices or setting virtio-console's preferred bus type. Thanks for looking at this, Amit
Re: [Qemu-devel] [PATCH 02/18] block.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC block.o cc1: warnings being treated as errors block.c: In function 'bdrv_open2': block.c:400: error: ignoring return value of 'realpath', declared with attribute warn_unused_result Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- block.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index 3f3496e..30ae2b1 100644 --- a/block.c +++ b/block.c @@ -396,8 +396,8 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, if (is_protocol) snprintf(backing_filename, sizeof(backing_filename), %s, filename); - else - realpath(filename, backing_filename); + else if (!realpath(filename, backing_filename)) + return -errno; bdrv_qcow2 = bdrv_find_format(qcow2); options = parse_option_parameters(, bdrv_qcow2-create_options, NULL); This patch appears to be correct considering: - return value of realpath - errno codes in the error case (as advertised by Linux man page and the functions referenced by OpenBSD man page: lstat(), readlink(2) and getcwd()) - return value of bdrv_open2().
Re: [Qemu-devel] [PATCH 10/18] net/slirp.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC net/slirp.o cc1: warnings being treated as errors net/slirp.c: In function 'slirp_smb_cleanup': net/slirp.c:470: error: ignoring return value of 'system', declared with attribute warn_unused_result make: *** [net/slirp.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- net/slirp.c | 7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/net/slirp.c b/net/slirp.c index 3f91c4b..1f16814 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -464,10 +464,15 @@ int net_slirp_redir(const char *redir_str) static void slirp_smb_cleanup(SlirpState *s) { char cmd[128]; + int ret; if (s-smb_dir[0] != '\0') { snprintf(cmd, sizeof(cmd), rm -rf %s, s-smb_dir); - system(cmd); + ret = system(cmd); + if (ret) { + qemu_error('%s' failed. Error code: %d\n, cmd, ret); + /* abort() ? */ This is not correct. - system() returns -1 on error and the command exit status otherwise, which may also be nonzero. - the exit status should be retrieved with WEXITSTATUS() macro, or in case of error via errno. - in no case abort() is warranted for smb cleanup.
Re: [Qemu-devel] [PATCH 11/18] usb-linux.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC usb-linux.o cc1: warnings being treated as errors usb-linux.c: In function 'usb_host_read_file': usb-linux.c:1204: error: ignoring return value of 'fgets', declared with attribute warn_unused_result make: *** [usb-linux.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- usb-linux.c | 7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/usb-linux.c b/usb-linux.c index 88728e9..67bfa7a 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -1201,9 +1201,12 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f device_file); f = fopen(filename, r); if (f) { - fgets(line, line_size, f); + if (fgets(line, line_size, f)) + ret = 1; + else + ret = 0; + fclose(f); - ret = 1; Considering the return values of fgets() and usb_host_read_file(), this patch looks OK except for the CODING_STYLE violation.
Re: [Qemu-devel] [PATCH 12/18] savevm.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC savevm.o cc1: warnings being treated as errors savevm.c: In function 'file_put_buffer': savevm.c:342: error: ignoring return value of 'fwrite', declared with attribute warn_unused_result make: *** [savevm.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- savevm.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/savevm.c b/savevm.c index aefe052..829f735 100644 --- a/savevm.c +++ b/savevm.c @@ -339,8 +339,7 @@ static int file_put_buffer(void *opaque, const uint8_t *buf, { QEMUFileStdio *s = opaque; fseek(s-stdio_file, pos, SEEK_SET); - fwrite(buf, 1, size, s-stdio_file); - return size; + return fwrite(buf, 1, size, s-stdio_file); Looks OK. The callers do not handle partial writes, but that's because the return value is not used correctly. They should be fixed some time. We are truncating size_t to int, but that is OK given that the input size is also int. The interfaces should be cleaned up to use size_t/ssize_t later.
[Qemu-devel] [FOR 0.12][PATCH] Improve usbdevice error messages
When an non-existent USB device is specified on the command line, print qemu: could not add USB device 'X'. Likewise for the usb_{add,del} monitor commands. Signed-off-by: Scott Tsai scottt...@gmail.com --- vl.c | 17 ++--- 1 files changed, 14 insertions(+), 3 deletions(-) diff --git a/vl.c b/vl.c index 8be3648..ee9c3f9 100644 --- a/vl.c +++ b/vl.c @@ -2689,17 +2689,28 @@ static int usb_device_del(const char *devname) static int usb_parse(const char *cmdline) { -return usb_device_add(cmdline, 0); +int r; +r = usb_device_add(cmdline, 0); +if (r 0) { +fprintf(stderr, qemu: could not add USB device '%s'\n, cmdline); +} +return r; } void do_usb_add(Monitor *mon, const QDict *qdict) { -usb_device_add(qdict_get_str(qdict, devname), 1); +const char *devname = qdict_get_str(qdict, devname); +if (usb_device_add(devname, 1) 0) { +qemu_error(could not add USB device '%s'\n, devname); +} } void do_usb_del(Monitor *mon, const QDict *qdict) { -usb_device_del(qdict_get_str(qdict, devname)); +const char *devname = qdict_get_str(qdict, devname); +if (usb_device_del(devname) 0) { +qemu_error(could not delete USB device '%s'\n, devname); +} } /***/ -- 1.6.5.2
Re: [Qemu-devel] Broken -usbdevice option in 0.12.1
On Tue, Dec 22, 2009 at 11:05 PM, Anthony Liguori anth...@codemonkey.ws wrote: On 12/22/2009 02:52 AM, Aurelien Jarno wrote: In version 0.12.1, using -usbdevice with an inexistent device exits without any error message, thus confusing the user: Would be good to file in launchpad since I think a lot of folks are out for the next couple weeks. I regularly go through launchpad bugs and ping people so it won't get lost that way unless you care enough to fix it immediately. I just posted a trivial patch for this.
Re: [Qemu-devel] [PATCH 16/18] hw/pc.c: fix warnings with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC i386-softmmu/pc.o cc1: warnings being treated as errors /usr/src/RPM/BUILD/qemu-0.11.92/hw/pc.c: In function 'load_multiboot': /usr/src/RPM/BUILD/qemu-0.11.92/hw/pc.c:614: error: ignoring return value of 'fread', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/hw/pc.c: In function 'load_linux': /usr/src/RPM/BUILD/qemu-0.11.92/hw/pc.c:888: error: ignoring return value of 'fread', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/hw/pc.c:889: error: ignoring return value of 'fread', declared with attribute warn_unused_result make[1]: *** [pc.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- hw/pc.c | 15 --- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index db7d58e..83f8dd0 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -613,7 +613,10 @@ static int load_multiboot(void *fw_cfg, mb_kernel_data = qemu_malloc(mb_kernel_size); fseek(f, mb_kernel_text_offset, SEEK_SET); - fread(mb_kernel_data, 1, mb_kernel_size, f); + if (fread(mb_kernel_data, 1, mb_kernel_size, f) != mb_kernel_size) { + fprintf(stderr, fread() failed\n); + exit(1); + } fclose(f); } @@ -887,8 +890,14 @@ static void load_linux(void *fw_cfg, setup = qemu_malloc(setup_size); kernel = qemu_malloc(kernel_size); fseek(f, 0, SEEK_SET); - fread(setup, 1, setup_size, f); - fread(kernel, 1, kernel_size, f); + if (fread(setup, 1, setup_size, f) != setup_size) { + fprintf(stderr, fread() failed\n); + exit(1); + } + if (fread(kernel, 1, kernel_size, f) != kernel_size) { + fprintf(stderr, fread() failed\n); + exit(1); + } fclose(f); memcpy(setup, header, MIN(sizeof(header), setup_size)); Looks fine to me. If we can't read the kernel, PEBCAK.
Re: [Qemu-devel] [PATCH 17/18] path.c fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC libuser/path.o cc1: warnings being treated as errors /usr/src/RPM/BUILD/qemu-0.11.92/path.c: In function 'new_entry': /usr/src/RPM/BUILD/qemu-0.11.92/path.c:49: error: ignoring return value of 'asprintf', declared with attribute warn_unused_result make[1]: *** [path.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- path.c | 5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/path.c b/path.c index cc9e007..0d2bf14 100644 --- a/path.c +++ b/path.c @@ -46,7 +46,10 @@ static struct pathelem *new_entry(const char *root, { struct pathelem *new = malloc(sizeof(*new)); new-name = strdup(name); - asprintf(new-pathname, %s/%s, root, name); + if (asprintf(new-pathname, %s/%s, root, name) == -1) { + printf(Cannot allocate memory\n); + exit(1); + } new-num_entries = 0; return new; } Looks OK.
[Qemu-devel] Re: Re: [SeaBIOS] [PATCH 0/8] option rom loadingoverhaul.
Anthony Liguori wrote: On 12/21/2009 01:43 PM, Gleb Natapov wrote: Please stop thinking so :) Especially about user driven upgrades. Why combine disadvantages of vitalization with pain of physical HW management? Or may be next step will be to require uploading of CPU microcode to take advantage of KVM/tcg bug fixes? I think your real argument boils down to that we can be better than real hardware therefore we should. I actually agree with you for 90% of users. Let me summarize where I'm at. - We are currently horribly broken with respect to how we handle roms particularly with respect to backwards compatibility - We must support running older roms on newer qemu at least within a stable series (because of live migration) - We need a mechanism to include roms specific to a machine type - Probably by default, we want new roms to be used by guests at some well defined time (either first reset or first power-down/start-up) Start-up sounds good. - We ought to make all roms live in qemu_ram_alloc()'d memory and we ought to change that api to contain contexts, this will make sure rom live migration works properly. The best approach I can think of is to introduce an nvram mechanism. A tar file probably work really well. If a user doesn't supply an explicit -nvram, we could create a temporary file and delete it. If the nvram is empty, we populate it with whatever the appropriate roms are for the machine type. I would also suggest that we support the guest updating roms on its own (through fw_cfg). I can think of a number of reasons for this. For instance, why shouldn't a guest be able to update the gPXE associated with the network card? The code runs entirely in the guest so there's no harm to the host. You mean the nvram file on the host or in memory? Will there be a size limit? Allow a guest to do this sort of thing takes pressure off of the management system so particularly in an environment like a cloud, I think this could prove very useful. It might not be desired and make support efforts harder. Could have security implications too. It could be possible to add an option to -nvram to make it re-read roms from disk every reboot. I really think this is a bad idea though, I'd like to hear more people comment on it but it's certainly technically feasible. - Sebastian
Re: [Qemu-devel] [PATCH 07/18] block/bochs.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC block/bochs.o cc1: warnings being treated as errors block/bochs.c: In function 'seek_to_sector': block/bochs.c:202: error: ignoring return value of 'read', declared with attribute warn_unused_result make: *** [block/bochs.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- block/bochs.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/block/bochs.c b/block/bochs.c index bac81c4..f6a18f2 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -199,7 +199,8 @@ static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num) // read in bitmap for current extent lseek(s-fd, bitmap_offset + (extent_offset / 8), SEEK_SET); - read(s-fd, bitmap_entry, 1); + if (read(s-fd, bitmap_entry, 1) != 1) + return -1; I think a short read can't happen with 1 bytes, so this looks fine. Though error checking is incomplete unless it is extended to lseek() calls too.
Re: [Qemu-devel] [PATCH 14/18] vl.c: fix warning with _FORTIFY_SOURCE
On Sun, Dec 20, 2009 at 1:39 AM, Kirill A. Shutemov kir...@shutemov.name wrote: CC i386-softmmu/vl.o cc1: warnings being treated as errors /usr/src/RPM/BUILD/qemu-0.11.92/vl.c: In function 'qemu_event_increment': /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:3404: error: ignoring return value of 'write', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c: In function 'main': /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:5774: error: ignoring return value of 'write', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:6064: error: ignoring return value of 'chdir', declared with attribute warn_unused_result /usr/src/RPM/BUILD/qemu-0.11.92/vl.c:6083: error: ignoring return value of 'chdir', declared with attribute warn_unused_result make[1]: *** [vl.o] Error 1 Signed-off-by: Kirill A. Shutemov kir...@shutemov.name --- vl.c | 15 +++ 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/vl.c b/vl.c index e606903..60a2c5e 100644 --- a/vl.c +++ b/vl.c @@ -3383,7 +3383,11 @@ static void qemu_event_increment(void) if (io_thread_fd == -1) return; - write(io_thread_fd, byte, sizeof(byte)); + if (write(io_thread_fd, byte, sizeof(byte)) != sizeof(byte)){ + fprintf(stderr, qemu_event_increment: write() filed: %s\n, + strerror(errno)); + exit (1); + } } static void qemu_event_read(void *opaque) @@ -5767,7 +5771,8 @@ int main(int argc, char **argv, char **envp) #ifndef _WIN32 if (daemonize) { uint8_t status = 1; - write(fds[1], status, 1); + if (write(fds[1], status, 1) != 1) + perror(write()); } else #endif fprintf(stderr, Could not acquire pid file: %s\n, strerror(errno)); @@ -6064,7 +6069,8 @@ int main(int argc, char **argv, char **envp) if (len != 1) exit(1); - chdir(/); + if (chdir(/)) + exit(1); TFR(fd = qemu_open(/dev/null, O_RDWR)); if (fd == -1) exit(1); @@ -6083,7 +6089,8 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, chroot failed\n); exit(1); } - chdir(/); + if (chdir(/)) + exit(1); Can't comment much on write() parts. chdir() checks are OK, except an error message would be in order.
Re: [Qemu-devel] [PATCH 2/3] virtio-console: Add a virtio-serial bus, support for multiple devices and ports
On 12/22/2009 11:49 AM, Amit Shah wrote: This patch migrates virtio-console to the qdev infrastructure and creates a new virtio-serial bus on which multiple ports are exposed as devices. The bulk of the code now resides in a new file with virtio-console.c being just a simple qdev device. This interface enables spawning of multiple virtio consoles as well as generic serial ports. The older -virtconsole argument still works, but when using the new functionality, it is recommended to use -device virtio-serial-pci -device virtconsole,... The virtconsole device type accepts a chardev as an argument and a 'name' argument to identify the corresponding consoles on the host as well as the guest. The name, if given, is exposed via the 'name' sysfs attribute in the guest. Care has been taken to ensure compatibility with kernels that do not support multiple ports as well as accepting incoming migrations from older qemu versions. Signed-off-by: Amit Shahamit.s...@redhat.com This is really difficult to review. If you're introducing a completely new file, why don't you just call it virtio-serial.c and delete virtio-console.c It will save quite a bit of reviewing head ache. Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH V4 03/18] target-i386: support a20 mask for NEC PC-9812
TAKEDA, toshiya wrote: @@ -940,7 +966,15 @@ void cpu_x86_set_a20(CPUX86State *env, int a20_state) /* when a20 is changed, all the MMU mappings are invalid, so we must flush everything */ tlb_flush(env, 1); -env-a20_mask = ~(1 20) | (a20_state 20); +if (env-private_features PRIVATE_FEATURE_PC98_A20MASK) { +if (a20_state) { +env-a20_mask = ~0x0; +} else { +env-a20_mask = 0xf; +} +} else { +env-a20_mask = ~(1 20) | (a20_state 20); +} } } It seems strange to mix different styles in that way. How about this, which I think makes the PC98 vs. PC difference clearer too: if (a20_state) { env-a20_mask = ~0x0; } else if (env-private_features PRIVATE_FEATURE_PC98_A20MASK) { env-a20_mask = (1 20) - 1; /* A20 masks all bits = 20. */ } else { env-a20_mask = ~(1 20); /* A20 masks only bit 20. */ } (When I say clearer, it's not _that_ obvious that these or the original expressions store the right thing into uint64 env-a20_mask, given these expressions are all of type int, but, in fact, they do owing to C type promotion rules. Same for the save/load state). -- Jamie
Re: [Qemu-devel] cpuid problem in upstream qemu with kvm
Michael S. Tsirkin wrote: Bootup on different machines has some of the same issues as migration. Consider a 64 bit guest as an example, I think it can not boot on a 32 bit host OS with kvm. I think you can use tcg, but it will be slower. Same thing applies to other CPU features. Alas, perhaps tcg will not work. The impression I got from irqchip threads was if you have a 64 bit KVM guest and only access to a 32 bit host, you are screwed because KVM/QEMU irqchip models are not interchangable. Could be wrong though, it was a bit too in depth for my knowledge. Many guests reconfigure themselves when you swap harware under them. This makes it easier to move such guests between machines, or change qemu configuration and still reuse guest image. Others might record hardware state on setup (64 bit above is one such example) making such changes more painful. Windows is notorious for breaking when the hardware changes. Ignoring the activation issue, which doesn't apply to corporate licenses or time-limited free issues, for example replacing IDE on PIIX4 with IDE on PIIX3 was enough to prevent both Windows 2000 and Windows Server 2003 from booting at all. Same when switching between SCSI and IDE, or vice versa. That's because they load the drivers needed for booting from a preassembled list of drivers that it needed list time, basically just the specific IDE or SCSI driver and a few other things, and they look for exact PCI ID matches to load them. I think the behaviour goes back to NT days, and is much worse for their server class OSes; their consumer ones like XP try harder to detect and cope with changes. In a nutshell, I have had to take a disk image from a real Windows machine to a working KVM image several times, and I've never been able to do it without either a technical blue screen on boot problem or an activation problem. -- Jamie
Re: [Qemu-devel] Re: cpuid problem in upstream qemu with kvm
Paolo Bonzini wrote: No, Windows tries to detect changes in your hardware and assumes that if too many things change, you might be a pirate and requires you to phone their offices to re-authenticate. 'Just' the CPU is not big deal. Might hit you with two 'bad' points. Network interface + CPU will require re-activation. I think the problem is only for networked images. For normal images, it would be the same if you were running Windows natively---upgrade CPU, and you risk having to do reactivation. For networked images, does changing CPU twice count as changing one thing? If so that's not too bad, not many things are likely to change in a VM beyond the CPU. Besides, if you have networked images, it's relatively likely that you're doing it for a company, hence that you have some kind of MSDN subscription which grants you unlimited activations for a given product key. Are you joking? Even as a casual users, when would you ever run Windows without networking these days???! I don't think you can even buy a computer without networking any more :-) Even just to transfer files from host to guest, you'll typically use a network. Or do you mean something else by networked images in a company context? Fwiw, when I have done Windows migrations for companies, they never have MSDN subscriptions (and neither do I :-) They have purchased Windows with the machines, and later they want to migrate those machines into VMs. No hint of MSDN anywhere, why would they? -- Jamie
[Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
Given this is supposed to be portable code, I wonder if we should have atomic ordered memory accessors instead. Paul Could you clarify please? The infiniband bits I used as base are very portable, I know they build on a ton of platforms. I just stripped a couple of infiniband specific assumptions from there. Do you suggest we use __sync_synchronize? Unfortunately this is broken or slow on many platforms. I do use it when it seems safe or when we see a platform we don't know about. I mean have a single function that does both the atomic load/store and the memory barrier. Instead of: stw_phys(addr, val) barrier(); We do: stw_phys_barrier(addr, val). This avoids issues in the future (multithreaded TCG) where atomic memory accesses may be nontrivial. Paul
Re: [Qemu-devel] cpuid problem in upstream qemu with kvm
Anthony Liguori wrote: It would be insane to emulate sse3 too. It doesn't sound too ridiculous if TCG is involved, provided the switching between TCG and KVM isn't too rapid. TCG is slower, but it's not ridiculously slow. Though, I don't expect anyone to volunteer to implement it :-) how likely is it that any given guest is using an obscure feature? Could KVM detect when a guest starts using each feature? For example, by disabling access to those features, enabling each one when the KVM trap occurs and recording that fact? Is it possible to enable them in the guest-visible cpuid, but force a trap on access to them? That might be quite useful information when you want to migrate something that wasn't planned for X years ago. -- Jamie
Re: [Fwd: Re: [Qemu-devel] X86_64 problem]
Andreas, Thanks for the tip about qemu-system-x86_64 - I didn't see that anywhere in the documentation: http://www.qemu.org/qemu-doc.html Now that I'm running the right qemu, it loads the kernel and the initrd, but hangs following these lines: Setting APIC routing to flat .TIMER: vector=0x30 apic1=0 pin1=0 apic2=-1 pin2=-1 .MP-BIOS bug: 8254 timer not connected to IO-APIC ..trying to set up timer (IRQ0) through the 8259A ... (found apic 0 pin 0) ... .. failed. ..trying to set up timer as Virtual Wire IRQ which I had to transcribe manually because there appears to be no way to capture text in the qemu window. I click in it and it says hit ctrl-alt to exit grab but it isn't actually grabbing anything -- neither the mouse or keyboard does anything in the qemu window. Any help greatly appreciated. -dave
[Qemu-devel] Re: [PATCH] Always swap endianness in DBDMA
On Tue, Dec 22, 2009 at 02:45:17PM +0100, Alexander Graf wrote: When we get an MMIO request, we always get variables in host endianness. The only time we need to actually reverse byte order is when we read bytes from guest memory. Apparently the DBDMA implementation is different there. A lot of the logic in there depends on values being big endian. Now, qemu does all the conversion in the MMIO handlers for us already though, so it turns out that we're in the same byte order from a C point of view, but cpu_to_be32 and be32_to_cpu end up being nops. This makes the code work differently on x86 (little endian) than on ppc (big endian). On x86 it works, on ppc it doesn't. This patch (while being seriously hacky and ugly) makes dbdma emulation work on ppc hosts. I'll leave the real fixing to someone else. I have to say I found it too hacky to be included in QEMU. I would prefer if someone can provide a real fix. Signed-off-by: Alexander Graf ag...@suse.de CC: Laurent Vivier laur...@vivier.eu --- V1 - V2: - s/cpu_to_be32/dbdma_cpu_to_be32/g - s/be32_to_cpu/dbdma_be32_to_cpu/g --- hw/mac_dbdma.c | 86 ++- 1 files changed, 47 insertions(+), 39 deletions(-) diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c index 98dccfd..555983a 100644 --- a/hw/mac_dbdma.c +++ b/hw/mac_dbdma.c @@ -40,6 +40,14 @@ #include isa.h #include mac_dbdma.h +/* + * XXX This is just plain wrong. Apparently we don't want to have big endian + * values, but reversed endian ones. The code as is doesn't work on big + * endian hosts. With these defines it does. + */ +#define dbdma_cpu_to_be32 bswap32 +#define dbdma_be32_to_cpu bswap32 + /* debug DBDMA */ //#define DEBUG_DBDMA @@ -184,19 +192,19 @@ static void dump_dbdma_cmd(dbdma_cmd *cmd) static void dbdma_cmdptr_load(DBDMA_channel *ch) { DBDMA_DPRINTF(dbdma_cmdptr_load 0x%08x\n, - be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); -cpu_physical_memory_read(be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), + dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); +cpu_physical_memory_read(dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), (uint8_t*)ch-current, sizeof(dbdma_cmd)); } static void dbdma_cmdptr_save(DBDMA_channel *ch) { DBDMA_DPRINTF(dbdma_cmdptr_save 0x%08x\n, - be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); + dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO])); DBDMA_DPRINTF(xfer_status 0x%08x res_count 0x%04x\n, le16_to_cpu(ch-current.xfer_status), le16_to_cpu(ch-current.res_count)); -cpu_physical_memory_write(be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), +cpu_physical_memory_write(dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]), (uint8_t*)ch-current, sizeof(dbdma_cmd)); } @@ -204,8 +212,8 @@ static void kill_channel(DBDMA_channel *ch) { DBDMA_DPRINTF(kill_channel\n); -ch-regs[DBDMA_STATUS] |= cpu_to_be32(DEAD); -ch-regs[DBDMA_STATUS] = cpu_to_be32(~ACTIVE); +ch-regs[DBDMA_STATUS] |= dbdma_cpu_to_be32(DEAD); +ch-regs[DBDMA_STATUS] = dbdma_cpu_to_be32(~ACTIVE); qemu_irq_raise(ch-irq); } @@ -230,10 +238,10 @@ static void conditional_interrupt(DBDMA_channel *ch) return; } -status = be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; +status = dbdma_be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; -sel_mask = (be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 16) 0x0f; -sel_value = be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 0x0f; +sel_mask = (dbdma_be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 16) 0x0f; +sel_value = dbdma_be32_to_cpu(ch-regs[DBDMA_INTR_SEL]) 0x0f; cond = (status sel_mask) == (sel_value sel_mask); @@ -268,10 +276,10 @@ static int conditional_wait(DBDMA_channel *ch) return 1; } -status = be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; +status = dbdma_be32_to_cpu(ch-regs[DBDMA_STATUS]) DEVSTAT; -sel_mask = (be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 16) 0x0f; -sel_value = be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 0x0f; +sel_mask = (dbdma_be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 16) 0x0f; +sel_value = dbdma_be32_to_cpu(ch-regs[DBDMA_WAIT_SEL]) 0x0f; cond = (status sel_mask) == (sel_value sel_mask); @@ -292,10 +300,10 @@ static void next(DBDMA_channel *ch) { uint32_t cp; -ch-regs[DBDMA_STATUS] = cpu_to_be32(~BT); +ch-regs[DBDMA_STATUS] = dbdma_cpu_to_be32(~BT); -cp = be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]); -ch-regs[DBDMA_CMDPTR_LO] = cpu_to_be32(cp + sizeof(dbdma_cmd)); +cp = dbdma_be32_to_cpu(ch-regs[DBDMA_CMDPTR_LO]); +ch-regs[DBDMA_CMDPTR_LO] = dbdma_cpu_to_be32(cp + sizeof(dbdma_cmd)); dbdma_cmdptr_load(ch); } @@ -304,7 +312,7 @@ static void branch(DBDMA_channel *ch) dbdma_cmd *current =
[Qemu-devel] Re: [PATCH-RFC 0/3] qemu: memory barriers in virtio
On Wed, 23 Dec 2009 01:21:43 am Anthony Liguori wrote: On 12/22/2009 05:26 AM, Michael S. Tsirkin wrote: On Tue, Dec 08, 2009 at 06:18:18PM +0200, Michael S. Tsirkin wrote: The following fixes a class of long-standing bugs in qemu: when kvm is enabled, guest might access device structures in memory while they are updated by qemu on another CPU. In this scenario, memory barriers are necessary to prevent host CPU from reordering memory accesses, which might confuse the guest. This patch only fixes virtio, but other emulated devices might have a similar bug. They'll need to be discovered and addressed case by case. This is still under test ... meanwhile: any early feedback/flames? Any comments on this one? The patch works fine in my testing, and even though it did not fix a crash that I hoped it will fix, it seems required for correctness... Right? It's definitely better than what we have. Rusty mentioned something to me a bit ago about the barriers for virtio in the kernel needing some work. I've been meaning to ask him about it in the context of this patch. Rusty, am I remembering correctly or have I been sipping too much eggnog? :-) It's possible, but I don't know of any missing cases. Certainly *lguest* i is missing barriers, since it's UP, but the core virtio should have them. Cheers, Rusty.
Re: [Qemu-devel] Broken -usbdevice option in 0.12.1
On Wed, Dec 23, 2009 at 04:33:32AM +0800, Scott Tsai wrote: On Tue, Dec 22, 2009 at 11:05 PM, Anthony Liguori anth...@codemonkey.ws wrote: On 12/22/2009 02:52 AM, Aurelien Jarno wrote: In version 0.12.1, using -usbdevice with an inexistent device exits without any error message, thus confusing the user: Would be good to file in launchpad since I think a lot of folks are out for the next couple weeks. I regularly go through launchpad bugs and ping people so it won't get lost that way unless you care enough to fix it immediately. I just posted a trivial patch for this. Thanks a lot, I have just committed it to both HEAD and stable-0.12. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurel...@aurel32.net http://www.aurel32.net