Re: [Qemu-devel] Howto debug boot device not showing up in bios

2011-05-09 Thread Mulyadi Santosa
Hi

On Tue, May 10, 2011 at 05:24, Adnan Khaleel  wrote:
> Can somebody give me some pointers on what the best way to debug the boot
> process in Qemu and seabios?

At first, I guess "-s" a.k.a qemu gdb stub of Qemu could help
you...but uhm, on a second thought, I think it is the qemu itself that
you need to run under Qemu...

regarding seabios code, i have no idea how to debug that... is it a
binary blob only?

-- 
regards,

Mulyadi Santosa
Freelance Linux trainer and consultant

blog: the-hydra.blogspot.com
training: mulyaditraining.blogspot.com



[Qemu-devel] [PATCH] Fix off-by-one error in sizing pSeries hcall table

2011-05-09 Thread David Gibson
The pSeries machine uses two tables to look up guest hcalls for emulation.
One of these is exactly one entry too small to hold all the hcalls it needs
to, leading to memory corruption.

This patch fixes the bug, and while we're at it, make both tables 'static'
since they're never used from other modules.

Signed-off-by: David Gibson 
---
 hw/spapr_hcall.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index f88e1d2..5281ba2 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -455,8 +455,8 @@ static target_ulong h_rtas(CPUState *env, sPAPREnvironment 
*spapr,
nret, rtas_r3 + 12 + 4*nargs);
 }
 
-spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
-spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE];
+static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
+static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - 
KVMPPC_HCALL_BASE + 1];
 
 void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
 {
-- 
1.7.4.4




Re: [Qemu-devel] [PATCH] Fix off-by-one error in sizing pSeries hcall table

2011-05-09 Thread Alexander Graf

On 10.05.2011, at 08:06, David Gibson wrote:

> The pSeries machine uses two tables to look up guest hcalls for emulation.
> One of these is exactly one entry too small to hold all the hcalls it needs
> to, leading to memory corruption.
> 
> This patch fixes the bug, and while we're at it, make both tables 'static'
> since they're never used from other modules.
> 
> Signed-off-by: David Gibson 

Thanks, applied to the ppc-next queue.


Alex




Re: [Qemu-devel] Allow ARMv7M to be started without a kernel

2011-05-09 Thread Rob Landley
On 05/09/2011 10:50 AM, Peter Maydell wrote:
> On 9 May 2011 16:11, Alexander Graf  wrote:
> [about -kernel, unless I've got confused]
>> The issue is that this is not how it works on real hardware. Grub won't just
>> load a vmlinux file and boot it. I'm not even sure how much exactly the
>> early entry code handles in Linux before it jumps to the ELF entry point.
>>
>> Either way, if you get something rolling that also ensures that it fails
>> when it's an ELF file that's not Linux, I'd be very open to it :).
> 
> If we do that we need to document what the new way of doing "just load
> and jump to the entry point of my not-a-linux-kernel ELF image" is; at
> the moment for ARM that use case is supported by -kernel (the code
> specifically handles ELF images as not-kernels), so changing that would
> be a back-compatibility break...

Arm doesn't need nearly as much setup as x86, some boards just map flash
at the physical start address with a jump straight to the kernel entry
point.

On arm there's no legacy start mode, meaning no 16->32 bit transfer
requiring mmu initialization as part of the setup.  (I believe arm
starts with a 1-1 virtual/physical mapping in the absence of initialized
page tables, or something like that.)  The big black magic thing
coreboot/bios and uboot do is DRAM refresh, which QEMU simply doesn't
care about: we map dram from the host and it gets refreshed at that level.

So this behavior may actually be correct for Linux in the absence of a
device tree (which just means initializinng a register to point to it on
ppc, dunno what ARM does).

And if you feed in an "-append" option to set a kernel command line,
then you know it's a linux kernel.  If we explicitly ask for more setup,
then you know to do more setup.  (I think that bit still needs to be
written, I have to go read the code...)

Rob



Re: [Qemu-devel] Allow ARMv7M to be started without a kernel

2011-05-09 Thread Alexander Graf

On 10.05.2011, at 06:58, Rob Landley wrote:

> On 05/09/2011 09:11 AM, Alexander Graf wrote:
>>> C) requires more research, because I have to make sure the entry point
>>> is either doing the 16->32 (or 64) bit startup dance or that it's being
>>> launched in the right mode (which the bios isn't doing), but vmlinux
>>> doesn't need to be decompressed and copied so it's just making sure
>>> we're expecting the right layer of stuff.  Which means reading through
>>> arch/x86/boot to see what the vmlinux->bzImage packaging is adding, I
>>> suppose.
>> 
>> The issue is that this is not how it works on real hardware.
> 
> Real hardware doesn't have the -kernel option.  On x86 that option is
> currently patching the rdev area after loading the blob into DRAM.
> 
>> Grub won't just load a vmlinux file and boot it.
> 
> The -kernel option doesn't load grub, it loads a _kernel_.  -kernel is a
> linux-specific bootloader.  It doesn't chainload other bootloaders.

My point is that -kernel is on the same level as grub. It's a bootloader - just 
(mostly) implemented in host mode, not guest mode. I'm not objecting to your 
idea. Just saying that what you're doing isn't streamlined in Linux atm, so you 
might hit barriers that people didn't expect :).


> 
>> I'm not even sure how much exactly
>> the early entry code handles in Linux before it jumps to the ELF entry
>> point.
>> 
>> Either way, if you get something rolling that also ensures that it fails
>> when it's an ELF file that's not Linux, I'd be very open to it :).
> 
> If it's an ELF file that's not Linux, I can ensure the result won't boot
> Linux.  It's guaranteed to fail without me doing anything.
> 
> I don't understand your objection.  (The option is called -kernel.  It
> does what it says on the tin.  If you feed it something that isn't a
> kernel, which you can do now, this is pilot error.)
> 
> By the way, I just did "qemu -kernel qemu-img" an the emulated vga
> screen was very colorful.  Feeding it qemu-io gave a different pattern
> of vga text mode garbage.  It's happily loading an elf file _now_, and
> spinning its little CPU on the resulting garbage...

IIRC -kernel loads ELF images as raw blobs atm. Just try to implement it and 
you'll see what I mean, seriously :).

Basically, -kernel with an OpenBSD ELF kernel would be different. You somehow 
need to be able to find out the boot protocol. Either it's defined by 
architecture or by random OS conventions. If you can somehow make sure that a 
kernel really is Linux and nothing else, speaking some random Linux boot 
protocol with it is just fine!

> 
>>> But "-kernel vmlinux" is not currently at the top of my todo list, lemme
>>> finish studying the v9fs code first...
>>> 
 Point being, the handling of -bios is board-specific (not even
 architecture-specific) and thus inconsistent.
>>> So, currently, is -kernel.  Having it accept vmlinux on more platforms
>>> would make it more consistent.  (Having -bios accept that too sounds
>>> great, but is orthogonal to what I'm trying to do.)
>>> 
 Your points above - page
 tables, TLB entries etc. - only apply to -kernel but not to -bios, that
 should give us a bare-metal machine.
>>> In 16 bit mode.
>> 
>> Depends on the machine. On PPC e500 for example, even with -bios we have
>> to set up TLB entries, but those are at least defined by the spec :).
> 
> Yes, -kernel has to do setup work before starting the kernel.  This is
> true now, it remains true if the kernel is in a different file format.
> -kernel is a linux bootloader, which is not the same thing as the -bios
> option.

I disagree. -kernel is a _kernel_ bootloader. There's more out there than just 
Linux :).


Alex




> 
> Rob




Re: [Qemu-devel] Allow ARMv7M to be started without a kernel

2011-05-09 Thread Rob Landley
On 05/09/2011 09:11 AM, Alexander Graf wrote:
>> C) requires more research, because I have to make sure the entry point
>> is either doing the 16->32 (or 64) bit startup dance or that it's being
>> launched in the right mode (which the bios isn't doing), but vmlinux
>> doesn't need to be decompressed and copied so it's just making sure
>> we're expecting the right layer of stuff.  Which means reading through
>> arch/x86/boot to see what the vmlinux->bzImage packaging is adding, I
>> suppose.
> 
> The issue is that this is not how it works on real hardware.

Real hardware doesn't have the -kernel option.  On x86 that option is
currently patching the rdev area after loading the blob into DRAM.

> Grub won't just load a vmlinux file and boot it.

The -kernel option doesn't load grub, it loads a _kernel_.  -kernel is a
linux-specific bootloader.  It doesn't chainload other bootloaders.

> I'm not even sure how much exactly
> the early entry code handles in Linux before it jumps to the ELF entry
> point.
> 
> Either way, if you get something rolling that also ensures that it fails
> when it's an ELF file that's not Linux, I'd be very open to it :).

If it's an ELF file that's not Linux, I can ensure the result won't boot
Linux.  It's guaranteed to fail without me doing anything.

I don't understand your objection.  (The option is called -kernel.  It
does what it says on the tin.  If you feed it something that isn't a
kernel, which you can do now, this is pilot error.)

By the way, I just did "qemu -kernel qemu-img" an the emulated vga
screen was very colorful.  Feeding it qemu-io gave a different pattern
of vga text mode garbage.  It's happily loading an elf file _now_, and
spinning its little CPU on the resulting garbage...

>> But "-kernel vmlinux" is not currently at the top of my todo list, lemme
>> finish studying the v9fs code first...
>>
>>> Point being, the handling of -bios is board-specific (not even
>>> architecture-specific) and thus inconsistent.
>> So, currently, is -kernel.  Having it accept vmlinux on more platforms
>> would make it more consistent.  (Having -bios accept that too sounds
>> great, but is orthogonal to what I'm trying to do.)
>>
>>> Your points above - page
>>> tables, TLB entries etc. - only apply to -kernel but not to -bios, that
>>> should give us a bare-metal machine.
>> In 16 bit mode.
> 
> Depends on the machine. On PPC e500 for example, even with -bios we have
> to set up TLB entries, but those are at least defined by the spec :).

Yes, -kernel has to do setup work before starting the kernel.  This is
true now, it remains true if the kernel is in a different file format.
-kernel is a linux bootloader, which is not the same thing as the -bios
option.

Rob



Re: [Qemu-devel] [PATCH V4 00/10] Qemu Trusted Platform Module (TPM) integration

2011-05-09 Thread Serge E. Hallyn
To get this to compile on top of qemu-kvm, I needed the following
patch to force CONFIG_THREAD on so as to define things like
qemu_mutex_lock:

Index: qemu-kvm-tpm/configure
===
--- qemu-kvm-tpm.orig/configure 2011-05-09 21:19:10.920002303 -0500
+++ qemu-kvm-tpm/configure  2011-05-09 21:19:22.150002305 -0500
@@ -3420,6 +3420,7 @@
   exit 1
   fi
   echo "CONFIG_TPM=y" >> $config_host_mak
+  echo "CONFIG_THREAD=y" >> $config_host_mak
   fi
 fi
 



Re: [Qemu-devel] Supporting emulation of IOMMUs

2011-05-09 Thread David Gibson
On Thu, Apr 21, 2011 at 09:47:31PM +0300, Eduard - Gabriel Munteanu wrote:
> On Thu, Apr 21, 2011 at 05:03:47PM +1000, David Gibson wrote:
> > A few months ago, Eduard - Gabriel Munteanu posted a series of patches
> > implementing support for emulating the AMD PCI IOMMU
> > (http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg03196.html).
> > 
> > In fact, this series implemented a general DMA/IOMMU layer which can
> > be used by any device model, and one translation backend for this
> > implementing the AMD specific PCI IOMMU.
> > 
> > These patches don't seem to have gone anywhere for the last few
> > months, however, and so far I've been unable to contact the author
> > (trying again with this mail).
> > 
> > I have an interest in this code, because the pSeries machine will also
> > need IOMMU emulation support.  At present we only support virtual
> > devices, through the PAPR interface, and we have support for the
> > hypervisor-controller IOMMU translation in the PAPR VIO code.
> > However, we want to add PCI device support and this will also need
> > IOMMU translation.
> > 
> > The series seems to have the right basic approach, so if the author is
> > indeed MIA, I was planning to pick up the patches and resubmit them
> > (with support for the pSeries IOMMU added).
> 
> Hi,
> 
> Not really MIA, but I've been a bit busy lately, so I'm sorry if I
> couldn't answer your mail in a timely fashion.
> 
> I'll try making another merge attempt tonight/tomorrow.

Ok.  Did this happen?  Sorry, I've been away the last couple of weeks
- I had a google at the qemu-devel archives but couldn't spot a new
merge, but did I just not look hard enough?

> > Before I do that, I was hoping to get some consensus that this is the
> > right way to go.  For reference, I have an updated version of the
> > first patch (which adds the core IOMMU layer) below.

I think the base DMA layer is the correct approach.  There are some
problems with the handling in PCI - as someone else pointed out the
fact that it assumes the IOMMU is itself a PCI device is problematic
for non-x86 platforms.

> Some developers expressed a few concerns during my last merge attempt,
> I'm going to go through them and see if they have been solved.

Ok.

[snip]
> >  * the dma_memory_map() tracking was storing the guest physical
> >address of each mapping, but not the qemu user virtual address.
> >However in unmap() it was then attempting to lookup by virtual
> >using a completely bogus cast.
> 
> Thanks. Map invalidation didn't get much testing, maybe figuring out a
> way to trigger it from a guest would be nice, say a testcase.

Well, I didn't catch a logic problem - for me this bug caused compile
failure.

> >  * The dma_memory_rw() function is moved from dma_rw.h to dma_rw.c, it
> >was a bit too much code for an inline.
> > 
> >  * IOMMU support is now available on all target platforms, not just
> >i386, but is configurable (--enable-iommu/--disable-iommu).  Stubs
> >are used so that individual drivers can use the new dma interface
> >and it will turn into old-style cpu physical accesses at no cost on
> >IOMMU-less builds.
> 
> My impression was people were in favor of having the IOMMU code always
> built in (and go through the direct cpu_physical_* when not configured
> by the guest). And perhaps poison the old interfaces once everything
> goes through the new DMA layer. I'm okay any way, though.

Oh, I had the opposite impression.  I don't care either way,
personally.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson



[Qemu-devel] Howto debug boot device not showing up in bios

2011-05-09 Thread Adnan Khaleel
Can somebody give me some pointers on what the best way to debug the boot 
process in Qemu and seabios?
Seabios reports that no boot device is present even though I'm passing it the 
hda commandline argument. 


What I'm looking for in particular is what Qemu does to map the path to a 
device and how it passes this on to seabios.
Any information on debug switches, general description of the process would be 
extremely helpful. 


AK

[Qemu-devel] [PATCH 5/7] PPC: Implement e500 (FSL) MMU

2011-05-09 Thread Alexander Graf
Most of the code to support e500 style MMUs is already in place, but
we're missing on some of the special TLB0-TLB1 handling code and slightly
different TLB modification.

This patch adds support for the FSL style MMU.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - fix linux-user build
  - optimize tlb invalidate & search

v3 -> v4:

  - remove tlb_nbs
  - rename BOOKE_FSL to BOOKE206
  - generalize implementation to be extensible for future MMUs
  - check if tsize should be set
  - check if iprot should be set
  - set RPN on tlb miss
  - implement tlb_invalidate_all
  - use specific helper to set PIDs
  - create generic booke206 tlb flushing function
  - make e500 check more explicit
  - rename functions to booke206
  - rework page size finder

  Special thanks go to Scott here for pointing out all the issues :)

v4 -> v5:

  - dont check iprot during tlb flush on reset (scott)

v5 -> v6:

  - implement rA for tlbsx
---
 target-ppc/cpu.h|  304 ++-
 target-ppc/helper.c |  269 ++
 target-ppc/helper.h |6 +
 target-ppc/op_helper.c  |  296 +
 target-ppc/translate.c  |   95 +-
 target-ppc/translate_init.c |  163 ---
 6 files changed, 1020 insertions(+), 113 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 2a7431c..dd2f93f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -108,8 +108,8 @@ enum powerpc_mmu_t {
 POWERPC_MMU_MPC8xx = 0x0007,
 /* BookE MMU model */
 POWERPC_MMU_BOOKE  = 0x0008,
-/* BookE FSL MMU model */
-POWERPC_MMU_BOOKE_FSL  = 0x0009,
+/* BookE 2.06 MMU model*/
+POWERPC_MMU_BOOKE206   = 0x0009,
 /* PowerPC 601 MMU model (specific BATs format)*/
 POWERPC_MMU_601= 0x000A,
 #if defined(TARGET_PPC64)
@@ -608,6 +608,224 @@ enum {
 #define vscr_sat   (((env->vscr) >> VSCR_SAT)  & 0x1)
 
 /*/
+/* BookE e500 MMU registers */
+
+#define MAS0_NV_SHIFT  0
+#define MAS0_NV_MASK   (0xfff << MAS0_NV_SHIFT)
+
+#define MAS0_WQ_SHIFT  12
+#define MAS0_WQ_MASK   (3 << MAS0_WQ_SHIFT)
+/* Write TLB entry regardless of reservation */
+#define MAS0_WQ_ALWAYS (0 << MAS0_WQ_SHIFT)
+/* Write TLB entry only already in use */
+#define MAS0_WQ_COND   (1 << MAS0_WQ_SHIFT)
+/* Clear TLB entry */
+#define MAS0_WQ_CLR_RSRV   (2 << MAS0_WQ_SHIFT)
+
+#define MAS0_HES_SHIFT 14
+#define MAS0_HES   (1 << MAS0_HES_SHIFT)
+
+#define MAS0_ESEL_SHIFT16
+#define MAS0_ESEL_MASK (0xfff << MAS0_ESEL_SHIFT)
+
+#define MAS0_TLBSEL_SHIFT  28
+#define MAS0_TLBSEL_MASK   (3 << MAS0_TLBSEL_SHIFT)
+#define MAS0_TLBSEL_TLB0   (0 << MAS0_TLBSEL_SHIFT)
+#define MAS0_TLBSEL_TLB1   (1 << MAS0_TLBSEL_SHIFT)
+#define MAS0_TLBSEL_TLB2   (2 << MAS0_TLBSEL_SHIFT)
+#define MAS0_TLBSEL_TLB3   (3 << MAS0_TLBSEL_SHIFT)
+
+#define MAS0_ATSEL_SHIFT   31
+#define MAS0_ATSEL (1 << MAS0_ATSEL_SHIFT)
+#define MAS0_ATSEL_TLB 0
+#define MAS0_ATSEL_LRATMAS0_ATSEL
+
+#define MAS1_TSIZE_SHIFT   8
+#define MAS1_TSIZE_MASK(0xf << MAS1_TSIZE_SHIFT)
+
+#define MAS1_TS_SHIFT  12
+#define MAS1_TS(1 << MAS1_TS_SHIFT)
+
+#define MAS1_IND_SHIFT 13
+#define MAS1_IND   (1 << MAS1_IND_SHIFT)
+
+#define MAS1_TID_SHIFT 16
+#define MAS1_TID_MASK  (0x3fff << MAS1_TID_SHIFT)
+
+#define MAS1_IPROT_SHIFT   30
+#define MAS1_IPROT (1 << MAS1_IPROT_SHIFT)
+
+#define MAS1_VALID_SHIFT   31
+#define MAS1_VALID 0x8000
+
+#define MAS2_EPN_SHIFT 12
+#define MAS2_EPN_MASK  (0xf << MAS2_EPN_SHIFT)
+
+#define MAS2_ACM_SHIFT 6
+#define MAS2_ACM   (1 << MAS2_ACM_SHIFT)
+
+#define MAS2_VLE_SHIFT 5
+#define MAS2_VLE   (1 << MAS2_VLE_SHIFT)
+
+#define MAS2_W_SHIFT   4
+#define MAS2_W (1 << MAS2_W_SHIFT)
+
+#define MAS2_I_SHIFT   3
+#define MAS2_I (1 << MAS2_I_SHIFT)
+
+#define MAS2_M_SHIFT   2
+#define MAS2_M (1 << MAS2_M_SHIFT)
+
+#define MAS2_G_SHIFT   1
+#define MAS2_G (1 << MAS2_G_SHIFT)
+
+#define MAS2_E_SHIFT   0
+#define MAS2_E (1 << MAS2_E_SHIFT)
+
+#define MAS3_RPN_SHIFT 12
+#define MAS3_RPN_MASK  (0xf << MAS3_RPN_SHIFT)
+
+#define MAS3_U0 0x0200
+#define MAS3_U1 0x0100
+#define MAS3_U2 0x0080
+#define MAS3_U3 0x0040
+#define MAS3_UX 0x0020
+#define MAS3_SX 0x0010
+#define MAS3_UW 0x0008
+#define MAS3_SW 0x0004
+#define MAS3_UR 0x0002
+#define MAS3_SR 0x0001
+#define M

[Qemu-devel] [PATCH 2/7] PPC: Make MPC8544DS emulation work w/o KVM

2011-05-09 Thread Alexander Graf
The MPC8544DS board emulation was only used with KVM so far, so some
parts of the code didn't provide proper values for non-KVM execution.

This patch makes the machine work without KVM enabled. To actually use
this, you also need proper e500v2 MMU emulation.

Signed-off-by: Alexander Graf 

---

v2 -> v3:

  - fix mpc initial tlb size comment
  - enable cpu reset

v5 -> v6:

  - use dynamically allocated boot_info struct
---
 hw/ppce500_mpc8544ds.c |   91 +++-
 1 files changed, 74 insertions(+), 17 deletions(-)

diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 1b8a1c4..25c14c1 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -28,6 +28,7 @@
 #include "kvm_ppc.h"
 #include "device_tree.h"
 #include "openpic.h"
+#include "ppc.h"
 #include "ppce500.h"
 #include "loader.h"
 #include "elf.h"
@@ -50,6 +51,12 @@
 #define MPC8544_PCI_IO 0xE100
 #define MPC8544_PCI_IOLEN  0x1
 
+struct boot_info
+{
+uint32_t dt_base;
+uint32_t entry;
+};
+
 #ifdef CONFIG_FDT
 static int mpc8544_copy_soc_cell(void *fdt, const char *node, const char *prop)
 {
@@ -82,7 +89,7 @@ static int mpc8544_load_device_tree(target_phys_addr_t addr,
 {
 int ret = -1;
 #ifdef CONFIG_FDT
-uint32_t mem_reg_property[] = {0, ramsize};
+uint32_t mem_reg_property[] = {0, cpu_to_be32(ramsize)};
 char *filename;
 int fdt_size;
 void *fdt;
@@ -103,15 +110,19 @@ static int mpc8544_load_device_tree(target_phys_addr_t 
addr,
 if (ret < 0)
 fprintf(stderr, "couldn't set /memory/reg\n");
 
-ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
-initrd_base);
-if (ret < 0)
-fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
+if (initrd_size) {
+ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+initrd_base);
+if (ret < 0) {
+fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
+}
 
-ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
-(initrd_base + initrd_size));
-if (ret < 0)
-fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
+ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+(initrd_base + initrd_size));
+if (ret < 0) {
+fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
+}
+}
 
 ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
   kernel_cmdline);
@@ -145,6 +156,13 @@ static int mpc8544_load_device_tree(target_phys_addr_t 
addr,
 
 mpc8544_copy_soc_cell(fdt, buf, "clock-frequency");
 mpc8544_copy_soc_cell(fdt, buf, "timebase-frequency");
+} else {
+const uint32_t freq = 4;
+
+qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
+  "clock-frequency", freq);
+qemu_devtree_setprop_cell(fdt, "/cpus/PowerPC,8544@0",
+  "timebase-frequency", freq);
 }
 
 ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
@@ -156,6 +174,35 @@ out:
 return ret;
 }
 
+/* Create -kernel TLB entries for BookE, linearly spanning 256MB.  */
+static void mmubooke_create_initial_mapping(CPUState *env,
+ target_ulong va,
+ target_phys_addr_t pa)
+{
+ppcemb_tlb_t *tlb = &env->tlb[512].tlbe;
+
+tlb->attr = 0;
+tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
+tlb->size = 256 * 1024 * 1024;
+tlb->EPN = va & TARGET_PAGE_MASK;
+tlb->RPN = pa & TARGET_PAGE_MASK;
+tlb->PID = 0;
+}
+
+static void mpc8544ds_cpu_reset(void *opaque)
+{
+CPUState *env = opaque;
+struct boot_info *bi = env->load_info;
+
+cpu_reset(env);
+
+/* Set initial guest state. */
+env->gpr[1] = (16<<20) - 8;
+env->gpr[3] = bi->dt_base;
+env->nip = bi->entry;
+mmubooke_create_initial_mapping(env, 0, 0);
+}
+
 static void mpc8544ds_init(ram_addr_t ram_size,
  const char *boot_device,
  const char *kernel_filename,
@@ -176,6 +223,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
 int i=0;
 unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
 qemu_irq *irqs, *mpic, *pci_irqs;
+struct boot_info *boot_info;
 
 /* Setup CPU */
 if (cpu_model == NULL) {
@@ -188,6 +236,13 @@ static void mpc8544ds_init(ram_addr_t ram_size,
 exit(1);
 }
 
+/* XXX register timer? */
+ppc_emb_timers_init(env, 4, PPC_INTERRUPT_DECR);
+ppc_dcr_init(env, NULL, NULL);
+
+/* Register reset handler */
+qemu_register_reset(mpc8544ds_cpu_reset, env);
+
 /* Fixup Memory size on a alignment bou

[Qemu-devel] [PATCH 3/7] PPC: Add GS MSR definition

2011-05-09 Thread Alexander Graf
The BookE specification defines MSR bit 28 as Guest State. Add it
to the list of MSR macros.

Signed-off-by: Alexander Graf 
---
 target-ppc/cpu.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 303f8ce..c6b2255 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -420,6 +420,7 @@ struct ppc_slb_t {
 #define MSR_CM   31 /* Computation mode for BookE hflags */
 #define MSR_ICM  30 /* Interrupt computation mode for BookE  */
 #define MSR_THV  29 /* hypervisor state for 32 bits PowerPC   hflags */
+#define MSR_GS   28 /* guest state for BookE */
 #define MSR_UCLE 26 /* User-mode cache lock enable for BookE */
 #define MSR_VR   25 /* altivec availablex hflags */
 #define MSR_SPE  25 /* SPE enable for BookE x hflags */
@@ -457,6 +458,7 @@ struct ppc_slb_t {
 #define msr_cm   ((env->msr >> MSR_CM)   & 1)
 #define msr_icm  ((env->msr >> MSR_ICM)  & 1)
 #define msr_thv  ((env->msr >> MSR_THV)  & 1)
+#define msr_gs   ((env->msr >> MSR_GS)   & 1)
 #define msr_ucle ((env->msr >> MSR_UCLE) & 1)
 #define msr_vr   ((env->msr >> MSR_VR)   & 1)
 #define msr_spe  ((env->msr >> MSR_SPE)  & 1)
-- 
1.6.0.2




[Qemu-devel] [PATCH 6/7] PPC MPC7544DS: Use new TLB helper function

2011-05-09 Thread Alexander Graf
Now that we have some nice helpers that can find us a TLB entry, let's
use that on the machine initialization code, so we don't need to know
about the internals of the TLB array.

Signed-off-by: Alexander Graf 
---
 hw/ppce500_mpc8544ds.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 25c14c1..96c37df 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -179,7 +179,7 @@ static void mmubooke_create_initial_mapping(CPUState *env,
  target_ulong va,
  target_phys_addr_t pa)
 {
-ppcemb_tlb_t *tlb = &env->tlb[512].tlbe;
+ppcemb_tlb_t *tlb = booke206_get_tlbe(env, 1, 0, 0);
 
 tlb->attr = 0;
 tlb->prot = PAGE_VALID | ((PAGE_READ | PAGE_WRITE | PAGE_EXEC) << 4);
-- 
1.6.0.2




[Qemu-devel] [PATCH 4/7] PPC: Add another 64 bits to instruction feature mask

2011-05-09 Thread Alexander Graf
To enable quick runtime detection of instruction groups to the currently
selected CPU emulation, we have a feature mask of what exactly the respective
instruction supports.

This feature mask is 64 bits long and we just successfully exceeded those 64
bits. To add more features, we need to think of something.

The easiest solution that came to my mind was to simply add another 64 bits
that we can also match on. Since the comparison is only done on start of the
qemu process to generate an internal opcode calling table, we should be fine
on any performance penalties here.

Signed-off-by: Alexander Graf 
---
 target-ppc/cpu.h|1 +
 target-ppc/translate.c  |   25 +++--
 target-ppc/translate_init.c |  123 +++
 3 files changed, 110 insertions(+), 39 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index c6b2255..2a7431c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -722,6 +722,7 @@ struct CPUPPCState {
 int bfd_mach;
 uint32_t flags;
 uint64_t insns_flags;
+uint64_t insns_flags2;
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
 target_phys_addr_t vpa;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 99f572a..95813f2 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -201,6 +201,8 @@ struct opc_handler_t {
 uint32_t inval;
 /* instruction type */
 uint64_t type;
+/* extended instruction type */
+uint64_t type2;
 /* handler */
 void (*handler)(DisasContext *ctx);
 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
@@ -314,10 +316,16 @@ static inline void gen_sync_exception(DisasContext *ctx)
 }
 
 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)  \
-GEN_OPCODE(name, opc1, opc2, opc3, inval, type)
+GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
+
+#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \
+GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
 
 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)   \
-GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type)
+GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
+
+#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)  \
+GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
 
 typedef struct opcode_t {
 unsigned char opc1, opc2, opc3;
@@ -457,7 +465,7 @@ static inline target_ulong MASK(uint32_t start, uint32_t 
end)
 /* PowerPC instructions table*/
 
 #if defined(DO_PPC_STATISTICS)
-#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)   \
+#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)\
 { \
 .opc1 = op1,  \
 .opc2 = op2,  \
@@ -466,12 +474,13 @@ static inline target_ulong MASK(uint32_t start, uint32_t 
end)
 .handler = {  \
 .inval   = invl,  \
 .type = _typ, \
+.type2 = _typ2,   \
 .handler = &gen_##name,   \
 .oname = stringify(name), \
 },\
 .oname = stringify(name), \
 }
-#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)\
+#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
 { \
 .opc1 = op1,  \
 .opc2 = op2,  \
@@ -480,13 +489,14 @@ static inline target_ulong MASK(uint32_t start, uint32_t 
end)
 .handler = {  \
 .inval   = invl,  \
 .type = _typ, \
+.type2 = _typ2,   \
 .handler = &gen_##name,   \
 .oname = onam,\
 },\
 .oname = onam,\
 }
 #else
-#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)

[Qemu-devel] [PATCH 7/7] PPC: Qdev'ify e500 pci

2011-05-09 Thread Alexander Graf
The e500 PCI controller isn't qdev'ified yet. This leads to severe issues
when running with -drive.

To be able to use a virtio disk with an e500 VM, let's convert the PCI
controller over to qdev.

Reviewed-by: Paul Brook 
Signed-off-by: Alexander Graf 

---

v2 -> v3:

  - rebase to current code base
  - fix endian issue
  - use sysbus helpers

v3 -> v4:

  - drop base_addr

v4 -> v5:

  - model qdev conversion similar to versatilepb (pbrook)

v5 -> v6:

  - use qdev.vmsd for vmstate registration (pbrook)
---
 hw/ppce500.h   |   22 
 hw/ppce500_mpc8544ds.c |   16 +++---
 hw/ppce500_pci.c   |  136 +++-
 3 files changed, 84 insertions(+), 90 deletions(-)
 delete mode 100644 hw/ppce500.h

diff --git a/hw/ppce500.h b/hw/ppce500.h
deleted file mode 100644
index 24d49bb..000
--- a/hw/ppce500.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * QEMU PowerPC E500 emulation shared definitions
- *
- * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Yu Liu, 
- *
- * This file is derived from hw/ppc440.h
- * the copyright for that material belongs to the original owners.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of  the GNU General  Public License as published by
- * the Free Software Foundation;  either version 2 of the  License, or
- * (at your option) any later version.
- */
-
-#if !defined(PPC_E500_H)
-#define PPC_E500_H
-
-PCIBus *ppce500_pci_init(qemu_irq *pic, target_phys_addr_t registers);
-
-#endif /* !defined(PPC_E500_H) */
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 96c37df..17b0165 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -29,9 +29,9 @@
 #include "device_tree.h"
 #include "openpic.h"
 #include "ppc.h"
-#include "ppce500.h"
 #include "loader.h"
 #include "elf.h"
+#include "sysbus.h"
 
 #define BINARY_DEVICE_TREE_FILE"mpc8544ds.dtb"
 #define UIMAGE_LOAD_BASE   0
@@ -222,7 +222,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
 target_long initrd_size=0;
 int i=0;
 unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
-qemu_irq *irqs, *mpic, *pci_irqs;
+qemu_irq *irqs, *mpic;
+DeviceState *dev;
 struct boot_info *boot_info;
 
 /* Setup CPU */
@@ -270,12 +271,11 @@ static void mpc8544ds_init(ram_addr_t ram_size,
 }
 
 /* PCI */
-pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
-pci_irqs[0] = mpic[pci_irq_nrs[0]];
-pci_irqs[1] = mpic[pci_irq_nrs[1]];
-pci_irqs[2] = mpic[pci_irq_nrs[2]];
-pci_irqs[3] = mpic[pci_irq_nrs[3]];
-pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE);
+dev = sysbus_create_varargs("e500-pcihost", MPC8544_PCI_REGS_BASE,
+mpic[pci_irq_nrs[0]], mpic[pci_irq_nrs[1]],
+mpic[pci_irq_nrs[2]], mpic[pci_irq_nrs[3]],
+NULL);
+pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
 if (!pci_bus)
 printf("couldn't create PCI controller!\n");
 
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 83a20e4..069af96 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -15,7 +15,6 @@
  */
 
 #include "hw.h"
-#include "ppce500.h"
 #include "pci.h"
 #include "pci_host.h"
 #include "bswap.h"
@@ -29,7 +28,8 @@
 #define PCIE500_CFGADDR   0x0
 #define PCIE500_CFGDATA   0x4
 #define PCIE500_REG_BASE  0xC00
-#define PCIE500_REG_SIZE  (0x1000 - PCIE500_REG_BASE)
+#define PCIE500_ALL_SIZE  0x1000
+#define PCIE500_REG_SIZE  (PCIE500_ALL_SIZE - PCIE500_REG_BASE)
 
 #define PPCE500_PCI_CONFIG_ADDR 0x0
 #define PPCE500_PCI_CONFIG_DATA 0x4
@@ -73,11 +73,15 @@ struct pci_inbound {
 };
 
 struct PPCE500PCIState {
+PCIHostState pci_state;
 struct pci_outbound pob[PPCE500_PCI_NR_POBS];
 struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
 uint32_t gasket_time;
-PCIHostState pci_state;
-PCIDevice *pci_dev;
+qemu_irq irq[4];
+/* mmio maps */
+int cfgaddr;
+int cfgdata;
+int reg;
 };
 
 typedef struct PPCE500PCIState PPCE500PCIState;
@@ -250,7 +254,6 @@ static const VMStateDescription vmstate_ppce500_pci = {
 .minimum_version_id = 1,
 .minimum_version_id_old = 1,
 .fields  = (VMStateField[]) {
-VMSTATE_PCI_DEVICE_POINTER(pci_dev, PPCE500PCIState),
 VMSTATE_STRUCT_ARRAY(pob, PPCE500PCIState, PPCE500_PCI_NR_POBS, 1,
  vmstate_pci_outbound, struct pci_outbound),
 VMSTATE_STRUCT_ARRAY(pib, PPCE500PCIState, PPCE500_PCI_NR_PIBS, 1,
@@ -260,60 +263,73 @@ static const VMStateDescription vmstate_ppce500_pci = {
 }
 };
 
-PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
+static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
+{
+PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h)

[Qemu-devel] [PATCH 0/7] PPC: Add FSL (e500) MMU emulation v6

2011-05-09 Thread Alexander Graf
In a global effort to get rid of KVM-only targets, this is the next
important piece of the puzzle: e500 emulation :).

We had support for running an e500 KVM guest for a while now, but the
code could not be tested without a real e500 machine, because it required
KVM to work. This patchset adds emulation for the e500 MMU, enabling
anyone to use the MPC8544DS emulation.

v1 -> v2:

  - fix linux-user build
  - optimize tlb invalidate & search

v2 -> v3:

  - add qdev patch (enables -drive if=virtio)
  - fix mpc initial tlb size comment
  - enable cpu reset

v3 -> v4:

  - remove tlb_nbs
  - rename BOOKE_FSL to BOOKE206
  - generalize implementation to be extensible for future MMUs
  - check if tsize should be set
  - check if iprot should be set
  - set RPN on tlb miss
  - implement tlb_invalidate_all
  - use specific helper to set PIDs
  - create generic booke206 tlb flushing function
  - drop base_addr
  - new patch: MPC7544DS: Use new TLB helper function

v4 -> v5:

  - dont check iprot during tlb flush on reset (scott)
  - model qdev conversion similar to versatilepb (pbrook)

v5 -> v6:

  - use dynamically allocated boot_info struct (blue)
  - implement rA for tlbsx (scott)
  - use qdev.vmsd for vmstate registration (pbrook)

Alexander Graf (7):
  PPC: Make MPC8544DS obey -cpu switch
  PPC: Make MPC8544DS emulation work w/o KVM
  PPC: Add GS MSR definition
  PPC: Add another 64 bits to instruction feature mask
  PPC: Implement e500 (FSL) MMU
  PPC MPC7544DS: Use new TLB helper function
  PPC: Qdev'ify e500 pci

 hw/ppce500.h|   22 ---
 hw/ppce500_mpc8544ds.c  |  113 
 hw/ppce500_pci.c|  136 +++-
 target-ppc/cpu.h|  307 ++-
 target-ppc/helper.c |  269 ++
 target-ppc/helper.h |6 +
 target-ppc/op_helper.c  |  296 +
 target-ppc/translate.c  |  120 +++--
 target-ppc/translate_init.c |  282 ---
 9 files changed, 1293 insertions(+), 258 deletions(-)
 delete mode 100644 hw/ppce500.h




[Qemu-devel] [PATCH 1/7] PPC: Make MPC8544DS obey -cpu switch

2011-05-09 Thread Alexander Graf
The MPC8544DS board emulation code ignored the user defined -cpu switch.
This patch enables it to only provide a sane default, not force an e500v2
CPU inside.

Signed-off-by: Alexander Graf 
---
 hw/ppce500_mpc8544ds.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index e111dda..1b8a1c4 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -178,7 +178,11 @@ static void mpc8544ds_init(ram_addr_t ram_size,
 qemu_irq *irqs, *mpic, *pci_irqs;
 
 /* Setup CPU */
-env = cpu_ppc_init("e500v2_v30");
+if (cpu_model == NULL) {
+cpu_model = "e500v2_v30";
+}
+
+env = cpu_ppc_init(cpu_model);
 if (!env) {
 fprintf(stderr, "Unable to initialize CPU!\n");
 exit(1);
-- 
1.6.0.2




[Qemu-devel] [PATCH 31/35] target-alpha: Implement HALT IPR.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/helper.h|1 +
 target-alpha/op_helper.c |   10 ++
 target-alpha/translate.c |5 +
 3 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 2dec57e..c352c24 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -113,6 +113,7 @@ DEF_HELPER_2(stq_c_phys, i64, i64, i64)
 
 DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64)
+DEF_HELPER_1(halt, void, i64);
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index d332719..80656f5 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -21,6 +21,7 @@
 #include "host-utils.h"
 #include "softfloat.h"
 #include "helper.h"
+#include "sysemu.h"
 #include "qemu-timer.h"
 
 /*/
@@ -1215,6 +1216,15 @@ void helper_tbis(uint64_t p)
 {
 tlb_flush_page(env, p);
 }
+
+void helper_halt(uint64_t restart)
+{
+if (restart) {
+qemu_system_reset_request();
+} else {
+qemu_system_shutdown_request();
+}
+}
 #endif
 
 /*/
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 7b976be..9edcd74 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1649,6 +1649,11 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, 
int regno)
 tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUState, halted));
 return gen_excp(ctx, EXCP_HLT, 0);
 
+case 252:
+/* HALT */
+gen_helper_halt(tmp);
+return EXIT_PC_STALE;
+
 default:
 /* The basic registers are data only, and unknown registers
are read-zero, write-ignore.  */
-- 
1.7.4.4




[Qemu-devel] [PATCH 32/35] target-alpha: Add high-resolution access to wall clock and an alarm.

2011-05-09 Thread Richard Henderson
The alarm is a fully general one-shot time comparator, which will be
usable under Linux as a hrtimer source.  It's much more flexible than
the RTC source available on real hardware.

The wall clock allows the guest access to the host timekeeping.  Much
like the KVM wall clock source for other guests.

Both are accessed via the PALcode Cserve entry point.

Signed-off-by: Richard Henderson 
---
 hw/alpha_typhoon.c   |   22 --
 target-alpha/cpu.h   |4 
 target-alpha/helper.h|4 
 target-alpha/op_helper.c |   15 +++
 target-alpha/translate.c |   14 ++
 5 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index 7cdf7d3..731b6ea 100644
--- a/hw/alpha_typhoon.c
+++ b/hw/alpha_typhoon.c
@@ -681,6 +681,16 @@ static void typhoon_set_timer_irq(void *opaque, int irq, 
int level)
 }
 }
 
+static void typhoon_alarm_timer(void *opaque)
+{
+TyphoonState *s = (TyphoonState *)((uintptr_t)opaque & ~3);
+int cpu = (uintptr_t)opaque & 3;
+
+/* Set the ITI bit for this cpu.  */
+s->cchip.misc |= 1 << (cpu + 4);
+cpu_interrupt(s->cchip.cpu[cpu], CPU_INTERRUPT_TIMER);
+}
+
 PCIBus *typhoon_init(qemu_irq *p_isa_irq, qemu_irq *p_rtc_irq,
  CPUState *cpus[3], pci_map_irq_fn sys_map_irq)
 {
@@ -689,14 +699,22 @@ PCIBus *typhoon_init(qemu_irq *p_isa_irq, qemu_irq 
*p_rtc_irq,
 PCIHostState *p;
 TyphoonState *s;
 PCIBus *b;
-int region;
+int i, region;
 
 dev = qdev_create(NULL, "typhoon-pcihost");
 p = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
 s = container_of(p, TyphoonState, host);
 
 /* Remember the CPUs so that we can deliver interrupts to them.  */
-memcpy(s->cchip.cpu, cpus, 4 * sizeof(CPUState *));
+for (i = 0; i < 4; i++) {
+CPUState *env = cpus[i];
+s->cchip.cpu[i] = env;
+if (env) {
+env->alarm_timer = qemu_new_timer_ns(rtc_clock,
+ typhoon_alarm_timer,
+ (void *)((uintptr_t)s + i));
+}
+}
 
 *p_isa_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
 *p_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1);
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index c94becf..72efbbd 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -266,6 +266,10 @@ struct CPUAlphaState {
 uint64_t shadow[8];
 uint64_t scratch[24];
 
+/* This alarm doesn't exist in real hardware; we wish it did.  */
+struct QEMUTimer *alarm_timer;
+uint64_t alarm_expire;
+
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* temporary fixed-point registers
  * used to emulate 64 bits target on 32 bits hosts
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index c352c24..b693cee 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -113,7 +113,11 @@ DEF_HELPER_2(stq_c_phys, i64, i64, i64)
 
 DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void)
 DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64)
+
 DEF_HELPER_1(halt, void, i64);
+
+DEF_HELPER_FLAGS_0(get_time, TCG_CALL_CONST, i64)
+DEF_HELPER_FLAGS_1(set_alarm, TCG_CALL_CONST, void, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 80656f5..c37fb5f 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1225,6 +1225,21 @@ void helper_halt(uint64_t restart)
 qemu_system_shutdown_request();
 }
 }
+
+uint64_t helper_get_time(void)
+{
+return qemu_get_clock_ns(rtc_clock);
+}
+
+void helper_set_alarm(uint64_t expire)
+{
+if (expire) {
+env->alarm_expire = expire;
+qemu_mod_timer(env->alarm_timer, expire);
+} else {
+qemu_del_timer(env->alarm_timer);
+}
+}
 #endif
 
 /*/
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 9edcd74..f34c53e 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1594,6 +1594,9 @@ static int cpu_pr_data(int pr)
 return offsetof(CPUAlphaState, shadow[pr - 32]);
 case 40 ... 63:
 return offsetof(CPUAlphaState, scratch[pr - 40]);
+
+case 251:
+return offsetof(CPUAlphaState, alarm_expire);
 }
 return 0;
 }
@@ -1608,6 +1611,12 @@ static void gen_mfpr(int ra, int regno)
 return;
 }
 
+if (regno == 250) {
+/* WALL_TIME */
+gen_helper_get_time(cpu_ir[ra]);
+return;
+}
+
 /* The basic registers are data only, and unknown registers
are read-zero, write-ignore.  */
 if (data == 0) {
@@ -1654,6 +1663,11 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, 
int regno)
 gen_helper_halt(tmp);
 return EXIT_PC_STALE;
 
+case 251:
+/* ALARM */
+gen_helper_set_alarm(tmp);
+break;
+
 default:
 /*

[Qemu-devel] [PATCH 34/35] target-alpha: Enable PCI IDE

2011-05-09 Thread Richard Henderson
The CMD646 is the candidate that might be closest to something
that may have existed on real Alpha hardware.

Signed-off-by: Richard Henderson 
---
 default-configs/alpha-softmmu.mak |1 +
 hw/alpha_dp264.c  |   10 ++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/default-configs/alpha-softmmu.mak 
b/default-configs/alpha-softmmu.mak
index abadcff..32167cd 100644
--- a/default-configs/alpha-softmmu.mak
+++ b/default-configs/alpha-softmmu.mak
@@ -7,3 +7,4 @@ CONFIG_VGA_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_IDE_QDEV=y
 CONFIG_VMWARE_VGA=y
+CONFIG_IDE_CMD646=y
diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index dea0ef6..30ae567 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -13,7 +13,9 @@
 #include "alpha_sys.h"
 #include "sysemu.h"
 #include "mc146818rtc.h"
+#include "ide.h"
 
+#define MAX_IDE_BUS 2
 
 static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
 {
@@ -97,6 +99,14 @@ static void clipper_init(ram_addr_t ram_size,
 pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
 }
 
+/* IDE disk setup.  */
+{
+DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+ide_drive_get(hd, MAX_IDE_BUS);
+
+pci_cmd646_ide_init(pci_bus, hd, 0);
+}
+
 /* Load PALcode.  Given that this is not "real" cpu palcode,
but one explicitly written for the emulation, we might as
well load it directly from and ELF image.  */
-- 
1.7.4.4




[Qemu-devel] [PATCH 24/35] target-alpha: Trap for unassigned and unaligned addresses.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 exec-all.h   |2 +-
 exec.c   |   12 ++--
 target-alpha/cpu.h   |6 +-
 target-alpha/op_helper.c |   26 ++
 4 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 7c2d29f..6d3ae77 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -322,7 +322,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState 
*env1, target_ulong add
 }
 pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
-#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
+#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
 do_unassigned_access(addr, 0, 1, 0, 4);
 #else
 cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" 
TARGET_FMT_lx "\n", addr);
diff --git a/exec.c b/exec.c
index 0b8ab5b..8627500 100644
--- a/exec.c
+++ b/exec.c
@@ -3112,7 +3112,7 @@ uint32_t unassigned_mem_readb(void *opaque, 
target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 0, 0, 0, 1);
 #endif
 return 0;
@@ -3123,7 +3123,7 @@ uint32_t unassigned_mem_readw(void *opaque, 
target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 0, 0, 0, 2);
 #endif
 return 0;
@@ -3134,7 +3134,7 @@ uint32_t unassigned_mem_readl(void *opaque, 
target_phys_addr_t addr)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 0, 0, 0, 4);
 #endif
 return 0;
@@ -3145,7 +3145,7 @@ void unassigned_mem_writeb(void *opaque, 
target_phys_addr_t addr, uint32_t val)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 1, 0, 0, 1);
 #endif
 }
@@ -3155,7 +3155,7 @@ void unassigned_mem_writew(void *opaque, 
target_phys_addr_t addr, uint32_t val)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 1, 0, 0, 2);
 #endif
 }
@@ -3165,7 +3165,7 @@ void unassigned_mem_writel(void *opaque, 
target_phys_addr_t addr, uint32_t val)
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
+#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || 
defined(TARGET_MICROBLAZE)
 do_unassigned_access(addr, 1, 0, 0, 4);
 #endif
 }
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index fc0cd61..d26a870 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -435,7 +435,11 @@ void do_interrupt (CPUState *env);
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
-extern void swap_shadow_regs(CPUState *env);
+#ifndef CONFIG_USER_ONLY
+void swap_shadow_regs(CPUState *env);
+extern QEMU_NORETURN void do_unassigned_access(target_phys_addr_t addr,
+   int, int, int, int);
+#endif
 
 /* Bits in TB->FLAGS that control how translation is processed.  */
 enum {
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 03b5091..91ef90a 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1265,7 +1265,33 @@ uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
 return ret;
 }
 
+static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
+  int is_user, void *retaddr)
+{
+uint64_t pc;
+uint32_t insn;
+
+do_restore_state(retaddr);
+
+pc = env->pc;
+insn = ldl_code(pc);
+
+env->trap_arg0 = addr;
+env->trap_arg1 = insn >> 26;/* opcode */
+env->trap_arg2 = (insn >> 21) & 31; /* dest regno */
+helper_excp(EXCP_UNALIGN, 0);
+}
+
+void QEMU_NORETURN do_unassigned_access(target_phys_addr_t addr, int is_write,
+int is_exec, int unused, int size)
+{
+env->trap_arg0 = addr;
+env->trap_arg1 = is_write;
+dynamic_excp(EXCP

[Qemu-devel] [PATCH 28/35] target-alpha: Add custom PALcode image for CLIPPER emulation.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 .gitmodules |3 +++
 Makefile|3 ++-
 configure   |8 +++-
 pc-bios/README  |3 +++
 pc-bios/palcode-clipper |  Bin 0 -> 176851 bytes
 roms/qemu-palcode   |1 +
 6 files changed, 16 insertions(+), 2 deletions(-)
 create mode 100755 pc-bios/palcode-clipper
 create mode 16 roms/qemu-palcode

diff --git a/.gitmodules b/.gitmodules
index 7884471..528743d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -10,3 +10,6 @@
 [submodule "roms/ipxe"]
path = roms/ipxe
url = git://git.qemu.org/ipxe.git
+[submodule "roms/qemu-palcode"]
+   path = roms/qemu-palcode
+   url = git://repo.or.cz/qemu-palcode.git
diff --git a/Makefile b/Makefile
index 67c0268..c7eb076 100644
--- a/Makefile
+++ b/Makefile
@@ -185,7 +185,8 @@ pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin \
 s390-zipl.rom \
-spapr-rtas.bin slof.bin
+spapr-rtas.bin slof.bin \
+palcode-sx164
 else
 BLOBS=
 endif
diff --git a/configure b/configure
index 214aabc..47aa1f3 100755
--- a/configure
+++ b/configure
@@ -3464,7 +3464,13 @@ FILES="Makefile tests/Makefile"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
-for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom 
$source_path/pc-bios/*.dtb $source_path/pc-bios/openbios-*; do
+for bios_file in \
+$source_path/pc-bios/*.bin \
+$source_path/pc-bios/*.rom \
+$source_path/pc-bios/*.dtb \
+$source_path/pc-bios/openbios-* \
+$source_path/pc-bios/palcode-*
+do
 FILES="$FILES pc-bios/`basename $bios_file`"
 done
 mkdir -p $DIRS
diff --git a/pc-bios/README b/pc-bios/README
index fe221a9..339eebd 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -31,3 +31,6 @@
 - The S390 zipl loader is an addition to the official IBM s390-tools
   package. That fork is maintained in its own git repository at:
   git://repo.or.cz/s390-tools.git
+
+- The Alpha palcode image is available from:
+  git://repo.or.cz/qemu-palcode.git
diff --git a/pc-bios/palcode-clipper b/pc-bios/palcode-clipper
new file mode 100755
index 
..26045ce48ea82e032a93353bc2200fee2d42f34d
GIT binary patch
literal 176851
zcmeFadw5jU^*+A$naRxLLYRaA;hHm(009Cd2pSN`Bm@X(H6kkBNWw)?QKBHAs077J
zD=I1~eyR{4D799pMWred6)kP4(#pqLKVHD1;-wlZA}W&a`|e9JiPYB4^ZV!boIFo*
z_T^n`ul??|*WPEJGm|CbP8{z@DeR9U`mSin9d2%pnTq;lj)jPrC>9R>b`oJhY*5v-
zNC^QsRfOw~bG6vJ4f-mSgb=5^H-Bcp7X1g;(0_pOARYrA10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&10Dk&
z10Dk&10Dk&10Dk&10Dk&1BozD|AG`-`>lLyYwl3--NK+KafR5sutO{-TKJ@IQe8NF
zNw`*w7jB8`3=?HiL{Ajr+`QS>mbtzC(b$Z%*sB2{4*EpSd45rHUXrLfuetf^ercyI
z&J}gvE@rxRs!k_j<^NZ*0rAc(^fi+Iq;FzfIRE10T6bJ>R-{yls>p!gM3hxrEkw?&
zl&~Df}w;+^w%HNTxJMDNE#;_b)7;@Ky&MeiqEG3JSUG3|-a?mZKP*uQWf
zbQg+k=R-a!L
ze_yxhUwmJWp3a#?4t|r`_&GWDfny<>7yc(a55l;Zwp)Bp)b0PT+D~5DSbE35wPDQn
z#yUS?8+8BK{$>9~`~6M(VUEdw|SFS7Pb*!Wjb*60t91Fg?(>J^Gq1VS;Ke_Rwt
z^S?~;-oO4dQC1ri2gESm$Ne~eDoN1(AqmRIpWh_I{uG>*rK~J1?H?S#^Q5c)U4J?z
z*nV>$G5;Sda%PGqU-`eY^Ir{Ms7Z_;EJ|i2%lvVnuy1^FM((&|fBv|^;=_giiOyFN
zw0~QI@{cAcza~NX+Y*#tlA!$D1m&v|ls`E^`H}?Xha@PUlc0RZ1m&BP5}W^@B`E(+
zg7U8J5MBC-A#{#R|bGMJX2d?I5<
zE8tTJjekjk{*PzBuKT2~qAo1vh+2%{kMzZmIPw6V|2|kK-i{6t2N!n9+KXqu2l4#!
zo%6e1x@Wwo`|1bpkH4eu;vVY9wrfX_b61Gf8$#mQ4YUK#p&!6==m+o|`T^LK+u_ps
zajD^@<0kp5zf5bY!#&z3m?Qs)vuT@p{yN_8zS{CUP1*CGK1bE^$HvR6`?&v1{uN(>
z@k{9TL*cdK{6f6f1$GQD&n5Xha`0V^r9FSZM;=YE{WS^7|F`3A$A3wJ?axh6zA8ca
zlM|FLNl<=Bg7P^D%6CjqzS&7^{(P38{5uKCzmlN*wglxLO;CPKg7UW|D8D2@`MC+o
zS0yNaa)R!vjpYeNl^Zk1m(9S
zDF0}J@@o>5zb!%eB?-#UO;ElnLHUytlrKq8en^7yISI;lOiq!;<7nz_>MXG;m78r;j;zNCrc|r;@yS0a(2uSe_xm)
z_AN{*tS^`1y@fo>>+b)2LJ$0ky3ZGj@Gj^H&rK7DfXg}G#rdO)dDQv{q
z@49q#dLkq{H+9oWmB0H8{&zGAlJ)gZ8S`
zXAMH(ol6|l(;k8J%{ZS;6~Dy!?3}Apuy(rPhw+Trws&Mmom1l01*+US-x5~@*SJZQ
zV*GRdb>%Pk8_JV#PTuFQ^%c_JC+73digk!>bNf8Gz9l~rV{<&lL)LwB(MWujLxhVi
zIse;|_b&~6K5x^PeakYkqGdQ^c|Rmd`W})+(W0)olY}U`r05=Zk_Z(=l^x^{zfwHi
zFZRo=xr^$0Js|e*GbKlcG^x)_OnWke{^nLin{&d^u#os{Nuj%_ZuI6eQ(~_YC&aV|
zc@5+IindVKfrqx{>d#z^&dV3iK0fJp5$N37CoHBtPTAS(2Dz?S{rG@`xfQe5-GcM5
zF^?z1hoTG1CT5Fk9*52+Q~ga7WJZ~LD5rFDK-9gryvwqQ&CMll!IMiTM$YI{k>+1o
z8UWXSX|8%Ta?pqTo(YkK(F&OnaiM>+kZBG0tjoT-F8&J2xlhUp$_c-WB|&bxk+U*F
z7Hn3Zm3cnu=EAPLh0~#H8SJjxylnKI3A3M{zWI!bs=N)u>tdCY%iL(!@(

[Qemu-devel] [PATCH 29/35] target-alpha: Add CLIPPER emulation.

2011-05-09 Thread Richard Henderson
This is a DP264 variant, SMP capable, no unusual hardware present.

The emulation does not currently include any PCI IOMMU code.
Hopefully the generic support for that can be merged to HEAD soon.

Signed-off-by: Richard Henderson 
---
 Makefile.target|1 +
 hw/alpha_dp264.c   |  177 
 hw/alpha_pci.c |  327 ++
 hw/alpha_sys.h |   42 +++
 hw/alpha_typhoon.c |  781 
 5 files changed, 1328 insertions(+), 0 deletions(-)
 create mode 100644 hw/alpha_dp264.c
 create mode 100644 hw/alpha_pci.c
 create mode 100644 hw/alpha_sys.h
 create mode 100644 hw/alpha_typhoon.c

diff --git a/Makefile.target b/Makefile.target
index 2f842c1..7f69f72 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -366,6 +366,7 @@ obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
 obj-alpha-y += i8259.o mc146818rtc.o
 obj-alpha-y += vga.o cirrus_vga.o
+obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
new file mode 100644
index 000..c061b0a
--- /dev/null
+++ b/hw/alpha_dp264.c
@@ -0,0 +1,177 @@
+/*
+ * QEMU Alpha DP264/CLIPPER hardware system emulator.
+ *
+ * Choose CLIPPER IRQ mappings over, say, DP264, MONET, or WEBBRICK
+ * variants because CLIPPER doesn't have an SMC669 SuperIO controler
+ * that we need to emulate as well.
+ */
+
+#include "hw.h"
+#include "elf.h"
+#include "loader.h"
+#include "boards.h"
+#include "alpha_sys.h"
+#include "sysemu.h"
+#include "mc146818rtc.h"
+
+
+static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
+{
+if (((addr >> 41) & 3) == 2) {
+addr &= 0xffull;
+}
+return addr;
+}
+
+/* Note that there are at least 3 viewpoints of IRQ numbers on Alpha systems.
+(0) The dev_irq_n lines into the cpu, which we totally ignore,
+(1) The DRIR lines in the typhoon chipset,
+(2) The "vector" aka mangled interrupt number reported by SRM PALcode,
+(3) The interrupt number assigned by the kernel.
+   The following function is concerned with (1) only.  */
+
+static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
+{
+int slot = d->devfn >> 3;
+
+assert(irq_num >= 0 && irq_num <= 3);
+
+return (slot + 1) * 4 + irq_num;
+}
+
+static void clipper_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ const char *cpu_model)
+{
+CPUState *cpus[4];
+ram_addr_t ram_offset;
+PCIBus *pci_bus;
+ISABus *isa_bus;
+qemu_irq isa_pci_irq, rtc_irq, *isa_irqs;
+long size, i;
+const char *palcode_filename;
+uint64_t palcode_entry, palcode_low, palcode_high;
+uint64_t kernel_entry, kernel_low, kernel_high;
+
+/* Create up to 4 cpus.  */
+memset(cpus, 0, sizeof(cpus));
+for (i = 0; i < smp_cpus; ++i) {
+cpus[i] = cpu_init(cpu_model ? cpu_model : "ev67");
+}
+
+cpus[0]->trap_arg0 = ram_size;
+cpus[0]->trap_arg1 = 0;
+cpus[0]->trap_arg2 = smp_cpus;
+
+ram_offset = qemu_ram_alloc(NULL, "ram", ram_size);
+cpu_register_physical_memory(0, ram_size, ram_offset);
+
+/* Init the chipset.  */
+pci_bus = typhoon_init(&isa_pci_irq, &rtc_irq, cpus, clipper_pci_map_irq);
+
+/* Init the ISA bus.  */
+isa_bus = isa_bus_new(NULL);
+isa_mem_base = pci_to_cpu_addr(pci_bus, 0);
+
+isa_irqs = i8259_init(isa_pci_irq);
+isa_bus_irqs(isa_irqs);
+
+rtc_init(1980, rtc_irq);
+pit_init(0x40, 0);
+
+/* VGA setup.  Don't bother loading the bios.  */
+pci_vga_init(pci_bus);
+
+/* Serial code setup.  */
+for (i = 0; i < MAX_SERIAL_PORTS; ++i) {
+if (serial_hds[i]) {
+serial_isa_init(i, serial_hds[i]);
+}
+}
+
+/* Network setup.  e1000 is good enough, failing Tulip support.  */
+for (i = 0; i < nb_nics; i++) {
+pci_nic_init_nofail(&nd_table[i], "e1000", NULL);
+}
+
+/* Load PALcode.  Given that this is not "real" cpu palcode,
+   but one explicitly written for the emulation, we might as
+   well load it directly from and ELF image.  */
+palcode_filename = (bios_name ? bios_name : "palcode-clipper");
+palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename);
+if (palcode_filename == NULL) {
+hw_error("no palcode provided\n");
+exit(1);
+}
+size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,
+NULL, &palcode_entry, &palcode_low, &palcode_high,
+0, EM_ALPHA, 0);
+if (size < 0) {
+hw_error("could not load palcode '%s'\n", palcode_filename);
+exit(1);
+}
+
+/* Start all cpus at the PALcode RESET entry point.  */
+for (i = 0; i < smp_cpus; ++i) {
+cpus[i]->pc = palcode_

[Qemu-devel] [PATCH 22/35] target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.

2011-05-09 Thread Richard Henderson
Reads the page table how PALcode would, except that the virtual
page table base register is not used.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h|   13 +
 target-alpha/helper.c |  129 +++--
 2 files changed, 138 insertions(+), 4 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index b439751..fc0cd61 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -321,6 +321,19 @@ enum {
 #define CPU_INTERRUPT_SMP  CPU_INTERRUPT_TGT_EXT_1
 #define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2
 
+/* OSF/1 Page table bits.  */
+enum {
+PTE_VALID = 0x0001,
+PTE_FOR   = 0x0002,  /* used for page protection (fault on read) */
+PTE_FOW   = 0x0004,  /* used for page protection (fault on write) */
+PTE_FOE   = 0x0008,  /* used for page protection (fault on exec) */
+PTE_ASM   = 0x0010,
+PTE_KRE   = 0x0100,
+PTE_URE   = 0x0200,
+PTE_KWE   = 0x1000,
+PTE_UWE   = 0x2000
+};
+
 /* Hardware interrupt (entInt) constants.  */
 enum {
 INT_K_IP,
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 4f706f2..96b407b 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -200,14 +200,135 @@ void swap_shadow_regs(CPUState *env)
 env->shadow[7] = i7;
 }
 
-target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
+/* Returns the OSF/1 entMM failure indication, or -1 on success.  */
+static int get_physical_address(CPUState *env, target_ulong addr,
+int prot_need, int mmu_idx,
+target_ulong *pphys, int *pprot)
 {
-return -1;
+target_long saddr = addr;
+target_ulong phys = 0;
+target_ulong L1pte, L2pte, L3pte;
+target_ulong pt, index;
+int prot = 0;
+int ret = MM_K_ACV;
+
+/* Ensure that the virtual address is properly sign-extended from
+   the last implemented virtual address bit.  */
+if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) {
+goto exit;
+}
+
+/* Translate the superpage.  */
+/* ??? When we do more than emulate Unix PALcode, we'll need to
+   determine which superpage is actually active.  */
+if (saddr < 0 && (saddr >> (TARGET_VIRT_ADDR_SPACE_BITS - 2) & 3) == 2) {
+/* User-space cannot access kseg addresses.  */
+if (mmu_idx != MMU_KERNEL_IDX) {
+goto exit;
+}
+
+phys = saddr & ((1ull << 40) - 1);
+prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ret = -1;
+goto exit;
+}
+
+/* Interpret the page table exactly like PALcode does.  */
+
+pt = env->ptbr;
+
+/* L1 page table read.  */
+index = (addr >> (TARGET_PAGE_BITS + 20)) & 0x3ff;
+L1pte = ldq_phys(pt + index*8);
+
+if (unlikely((L1pte & PTE_VALID) == 0)) {
+ret = MM_K_TNV;
+goto exit;
+}
+if (unlikely((L1pte & PTE_KRE) == 0)) {
+goto exit;
+}
+pt = L1pte >> 32 << TARGET_PAGE_BITS;
+
+/* L2 page table read.  */
+index = (addr >> (TARGET_PAGE_BITS + 10)) & 0x3ff;
+L2pte = ldq_phys(pt + index*8);
+
+if (unlikely((L2pte & PTE_VALID) == 0)) {
+ret = MM_K_TNV;
+goto exit;
+}
+if (unlikely((L2pte & PTE_KRE) == 0)) {
+goto exit;
+}
+pt = L2pte >> 32 << TARGET_PAGE_BITS;
+
+/* L3 page table read.  */
+index = (addr >> TARGET_PAGE_BITS) & 0x3ff;
+L3pte = ldq_phys(pt + index*8);
+
+phys = L3pte >> 32 << TARGET_PAGE_BITS;
+if (unlikely((L3pte & PTE_VALID) == 0)) {
+ret = MM_K_TNV;
+goto exit;
+}
+
+#if PAGE_READ != 1 || PAGE_WRITE != 2 || PAGE_EXEC != 4
+# error page bits out of date
+#endif
+
+/* Check access violations.  */
+if (L3pte & (PTE_KRE << mmu_idx)) {
+prot |= PAGE_READ | PAGE_EXEC;
+}
+if (L3pte & (PTE_KWE << mmu_idx)) {
+prot |= PAGE_WRITE;
+}
+if (unlikely((prot & prot_need) == 0 && prot_need)) {
+goto exit;
+}
+
+/* Check fault-on-operation violations.  */
+prot &= ~(L3pte >> 1);
+ret = -1;
+if (unlikely((prot & prot_need) == 0)) {
+ret = (prot_need & PAGE_EXEC ? MM_K_FOE :
+   prot_need & PAGE_WRITE ? MM_K_FOW :
+   prot_need & PAGE_READ ? MM_K_FOR : -1);
+}
+
+ exit:
+*pphys = phys;
+*pprot = prot;
+return ret;
 }
 
-int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-int mmu_idx, int is_softmmu)
+target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+target_ulong phys;
+int prot, fail;
+
+fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
+return (fail >= 0 ? -1 : phys);
+}
+
+int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw,
+   int mmu_idx, int is_softmmu)
 {
+target_ulong phys;
+int prot, fail;
+
+fail = get_physical_address(env, addr, 1 << rw, 

[Qemu-devel] [PATCH 35/35] target-alpha: Add ps2 keyboard.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 default-configs/alpha-softmmu.mak |1 +
 hw/alpha_dp264.c  |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/default-configs/alpha-softmmu.mak 
b/default-configs/alpha-softmmu.mak
index 32167cd..be86d0c 100644
--- a/default-configs/alpha-softmmu.mak
+++ b/default-configs/alpha-softmmu.mak
@@ -3,6 +3,7 @@
 include pci.mak
 CONFIG_SERIAL=y
 CONFIG_I8254=y
+CONFIG_PCKBD=y
 CONFIG_VGA_PCI=y
 CONFIG_IDE_CORE=y
 CONFIG_IDE_QDEV=y
diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index 30ae567..73a88fa 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -83,6 +83,7 @@ static void clipper_init(ram_addr_t ram_size,
 
 rtc_init(1980, rtc_irq);
 pit_init(0x40, 0);
+isa_create_simple("i8042");
 
 /* VGA setup.  Don't bother loading the bios.  */
 alpha_pci_vga_setup(pci_bus);
-- 
1.7.4.4




[Qemu-devel] [PATCH 30/35] target-alpha: Implement WAIT IPR.

2011-05-09 Thread Richard Henderson
---
 target-alpha/translate.c |   31 +--
 1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 8107d19..7b976be 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1621,9 +1621,10 @@ static void gen_mfpr(int ra, int regno)
 }
 }
 
-static void gen_mtpr(int rb, int regno)
+static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
 {
 TCGv tmp;
+int data;
 
 if (rb == 31) {
 tmp = tcg_const_i64(0);
@@ -1631,19 +1632,27 @@ static void gen_mtpr(int rb, int regno)
 tmp = cpu_ir[rb];
 }
 
-/* These two register numbers perform a TLB cache flush.  Thankfully we
-   can only do this inside PALmode, which means that the current basic
-   block cannot be affected by the change in mappings.  */
-if (regno == 255) {
+switch (regno) {
+case 255:
 /* TBIA */
 gen_helper_tbia();
-} else if (regno == 254) {
+break;
+
+case 254:
 /* TBIS */
 gen_helper_tbis(tmp);
-} else {
+break;
+
+case 253:
+/* WAIT */
+tmp = tcg_const_i64(1);
+tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUState, halted));
+return gen_excp(ctx, EXCP_HLT, 0);
+
+default:
 /* The basic registers are data only, and unknown registers
are read-zero, write-ignore.  */
-int data = cpu_pr_data(regno);
+data = cpu_pr_data(regno);
 if (data != 0) {
 if (data & PR_BYTE) {
 tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
@@ -1653,11 +1662,14 @@ static void gen_mtpr(int rb, int regno)
 tcg_gen_st_i64(tmp, cpu_env, data);
 }
 }
+break;
 }
 
 if (rb == 31) {
 tcg_temp_free(tmp);
 }
+
+return NO_EXIT;
 }
 #endif /* !USER_ONLY*/
 
@@ -3052,8 +3064,7 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 /* HW_MTPR (PALcode) */
 #ifndef CONFIG_USER_ONLY
 if (ctx->tb->flags & TB_FLAGS_PAL_MODE) {
-gen_mtpr(rb, insn & 0x);
-break;
+return gen_mtpr(ctx, rb, insn & 0x);
 }
 #endif
 goto invalid_opc;
-- 
1.7.4.4




[Qemu-devel] [PATCH 21/35] target-alpha: Implement more CALL_PAL values inline.

2011-05-09 Thread Richard Henderson
In particular, SWPIPL is used quite a lot by the Linux kernel.
Doing this inline makes it significantly easier to step through
without the debugger getting confused by the mode switch.

Signed-off-by: Richard Henderson 
---
 target-alpha/translate.c |  141 --
 1 files changed, 110 insertions(+), 31 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 28ccf6b..8b9dded 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -85,8 +85,10 @@ static TCGv cpu_pc;
 static TCGv cpu_lock_addr;
 static TCGv cpu_lock_st_addr;
 static TCGv cpu_lock_value;
-#ifdef CONFIG_USER_ONLY
-static TCGv cpu_uniq;
+static TCGv cpu_unique;
+#ifndef CONFIG_USER_ONLY
+static TCGv cpu_sysval;
+static TCGv cpu_usp;
 #endif
 
 /* register names */
@@ -131,9 +133,13 @@ static void alpha_translate_init(void)
offsetof(CPUState, lock_value),
"lock_value");
 
-#ifdef CONFIG_USER_ONLY
-cpu_uniq = tcg_global_mem_new_i64(TCG_AREG0,
-  offsetof(CPUState, unique), "uniq");
+cpu_unique = tcg_global_mem_new_i64(TCG_AREG0,
+offsetof(CPUState, unique), "unique");
+#ifndef CONFIG_USER_ONLY
+cpu_sysval = tcg_global_mem_new_i64(TCG_AREG0,
+offsetof(CPUState, sysval), "sysval");
+cpu_usp = tcg_global_mem_new_i64(TCG_AREG0,
+ offsetof(CPUState, usp), "usp");
 #endif
 
 /* register helpers */
@@ -1464,6 +1470,104 @@ static void gen_rx(int ra, int set)
 tcg_temp_free_i32(tmp);
 }
 
+static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
+{
+/* We're emulating OSF/1 PALcode.  Many of these are trivial access
+   to internal cpu registers.  */
+
+/* Unprivileged PAL call */
+if (palcode >= 0x80 && palcode < 0xC0) {
+switch (palcode) {
+case 0x86:
+/* IMB */
+/* No-op inside QEMU.  */
+break;
+case 0x9E:
+/* RDUNIQUE */
+tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique);
+break;
+case 0x9F:
+/* WRUNIQUE */
+tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
+break;
+default:
+return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
+}
+return NO_EXIT;
+}
+
+#ifndef CONFIG_USER_ONLY
+/* Privileged PAL code */
+if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) {
+switch (palcode) {
+case 0x01:
+/* CFLUSH */
+/* No-op inside QEMU.  */
+break;
+case 0x02:
+/* DRAINA */
+/* No-op inside QEMU.  */
+break;
+case 0x2D:
+/* WRVPTPTR */
+tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUState, vptptr));
+break;
+case 0x31:
+/* WRVAL */
+tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]);
+break;
+case 0x32:
+/* RDVAL */
+tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval);
+break;
+
+case 0x35: {
+/* SWPIPL */
+TCGv tmp;
+
+/* Note that we already know we're in kernel mode, so we know
+   that PS only contains the 3 IPL bits.  */
+tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUState, ps));
+
+/* But make sure and store only the 3 IPL bits from the user.  */
+tmp = tcg_temp_new();
+tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK);
+tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUState, ps));
+tcg_temp_free(tmp);
+break;
+}
+
+case 0x36:
+/* RDPS */
+tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env,
+ offsetof(CPUAlphaState, ps));
+break;
+case 0x38:
+/* WRUSP */
+tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]);
+break;
+case 0x3A:
+/* RDUSP */
+tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp);
+break;
+
+/* TODO:
+ 0x3C Whami
+These merely need more cooperation in designation of
+internal processor registers w/ palcode.  These are
+currently stored in palcode scratch registers and
+should be treated like UNIQUE.  */
+
+default:
+return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
+}
+return NO_EXIT;
+}
+#endif
+
+return gen_invalid(ctx);
+}
+
 #ifndef CONFIG_USER_ONLY
 
 #define PR_BYTE 0x10
@@ -1582,32 +1686,7 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 switch (opc) {
 case 0x00:
 /* CALL_PAL */
-#ifdef CONFIG_USER_ONLY
-if (palcode == 0x9E) {
-   

[Qemu-devel] [PATCH 25/35] target-alpha: Include the PCC_OFS in the RPCC return value.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/op_helper.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 91ef90a..42fec07 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -66,7 +66,8 @@ static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
 uint64_t helper_load_pcc (void)
 {
 /* ??? This isn't a timer for which we have any rate info.  */
-return (uint32_t)cpu_get_real_ticks();
+uint64_t ret = env->pcc_ofs;
+return ret << 32 | (uint32_t)cpu_get_real_ticks();
 }
 
 uint64_t helper_load_fpcr (void)
-- 
1.7.4.4




[Qemu-devel] [PATCH 27/35] target-alpha: Implement TLB flush primitives.

2011-05-09 Thread Richard Henderson
Expose these via MTPR, more or less like the real HW does.

Signed-off-by: Richard Henderson 
---
 target-alpha/helper.h|3 +++
 target-alpha/op_helper.c |   11 ++-
 target-alpha/translate.c |   32 +---
 3 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 9ffc372..2dec57e 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -110,6 +110,9 @@ DEF_HELPER_2(stl_phys, void, i64, i64)
 DEF_HELPER_2(stq_phys, void, i64, i64)
 DEF_HELPER_2(stl_c_phys, i64, i64, i64)
 DEF_HELPER_2(stq_c_phys, i64, i64, i64)
+
+DEF_HELPER_FLAGS_0(tbia, TCG_CALL_CONST, void)
+DEF_HELPER_FLAGS_1(tbis, TCG_CALL_CONST, void, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 36b8289..d332719 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1205,6 +1205,16 @@ void helper_hw_ret (uint64_t a)
 swap_shadow_regs(env);
 }
 }
+
+void helper_tbia(void)
+{
+tlb_flush(env, 1);
+}
+
+void helper_tbis(uint64_t p)
+{
+tlb_flush_page(env, p);
+}
 #endif
 
 /*/
@@ -1335,5 +1345,4 @@ void tlb_fill (target_ulong addr, int is_write, int 
mmu_idx, void *retaddr)
 }
 env = saved_env;
 }
-
 #endif
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 8b9dded..8107d19 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1624,7 +1624,6 @@ static void gen_mfpr(int ra, int regno)
 static void gen_mtpr(int rb, int regno)
 {
 TCGv tmp;
-int data;
 
 if (rb == 31) {
 tmp = tcg_const_i64(0);
@@ -1632,16 +1631,27 @@ static void gen_mtpr(int rb, int regno)
 tmp = cpu_ir[rb];
 }
 
-/* The basic registers are data only, and unknown registers
-   are read-zero, write-ignore.  */
-data = cpu_pr_data(regno);
-if (data != 0) {
-if (data & PR_BYTE) {
-tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
-} else if (data & PR_LONG) {
-tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
-} else {
-tcg_gen_st_i64(tmp, cpu_env, data);
+/* These two register numbers perform a TLB cache flush.  Thankfully we
+   can only do this inside PALmode, which means that the current basic
+   block cannot be affected by the change in mappings.  */
+if (regno == 255) {
+/* TBIA */
+gen_helper_tbia();
+} else if (regno == 254) {
+/* TBIS */
+gen_helper_tbis(tmp);
+} else {
+/* The basic registers are data only, and unknown registers
+   are read-zero, write-ignore.  */
+int data = cpu_pr_data(regno);
+if (data != 0) {
+if (data & PR_BYTE) {
+tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
+} else if (data & PR_LONG) {
+tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
+} else {
+tcg_gen_st_i64(tmp, cpu_env, data);
+}
 }
 }
 
-- 
1.7.4.4




[Qemu-devel] [PATCH 33/35] target-alpha: Properly select the VGA controler to use.

2011-05-09 Thread Richard Henderson
The existing code for this really shouldn't be in pc.c.

Signed-off-by: Richard Henderson 
---
 hw/alpha_dp264.c |2 +-
 hw/alpha_pci.c   |   33 -
 hw/alpha_sys.h   |2 ++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index c061b0a..dea0ef6 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -83,7 +83,7 @@ static void clipper_init(ram_addr_t ram_size,
 pit_init(0x40, 0);
 
 /* VGA setup.  Don't bother loading the bios.  */
-pci_vga_init(pci_bus);
+alpha_pci_vga_setup(pci_bus);
 
 /* Serial code setup.  */
 for (i = 0; i < MAX_SERIAL_PORTS; ++i) {
diff --git a/hw/alpha_pci.c b/hw/alpha_pci.c
index d0d727c..b321772 100644
--- a/hw/alpha_pci.c
+++ b/hw/alpha_pci.c
@@ -1,8 +1,15 @@
-/* There's nothing in here that's Alpha specific, really.  */
+/*
+ * QEMU Alpha PCI support functions.
+ *
+ * Some of this isn't very Alpha specific at all.  Some of this is specific
+ * to sparse PCI access support for older Alpha systems.
+ */
 
 #include "config.h"
 #include "alpha_sys.h"
 #include "qemu-log.h"
+#include "sysemu.h"
+#include "vmware_vga.h"
 
 
 /* PCI IO reads, to byte-word addressable memory.  */
@@ -325,3 +332,27 @@ CPUWriteMemoryFunc * const alpha_pci_special_writes[] = {
 unassigned_mem_writew,
 special_writel,
 };
+
+void alpha_pci_vga_setup(PCIBus *pci_bus)
+{
+switch (vga_interface_type) {
+#ifdef CONFIG_SPICE
+case VGA_QXL:
+pci_create_simple(pci_bus, -1, "qxl-vga");
+return;
+#endif
+case VGA_CIRRUS:
+pci_cirrus_vga_init(pci_bus);
+return;
+case VGA_VMWARE:
+if (pci_vmsvga_init(pci_bus)) {
+return;
+}
+break;
+}
+/* If VGA is enabled at all, and one of the above didn't work, then
+   fallback to Standard VGA.  */
+if (vga_interface_type != VGA_NONE) {
+pci_vga_init(pci_bus);
+}
+}
diff --git a/hw/alpha_sys.h b/hw/alpha_sys.h
index 272a107..98e5351 100644
--- a/hw/alpha_sys.h
+++ b/hw/alpha_sys.h
@@ -39,4 +39,6 @@ extern void alpha_sparse_mem_write(PCIBus *, 
target_phys_addr_t, uint32_t);
 extern uint32_t alpha_sparse_conf1_read(PCIBus *, target_phys_addr_t);
 extern void alpha_sparse_conf1_write(PCIBus *, target_phys_addr_t, uint32_t);
 
+void alpha_pci_vga_setup(PCIBus *pci_bus);
+
 #endif
-- 
1.7.4.4




[Qemu-devel] [PATCH 19/35] target-alpha: All ISA checks to use TB->FLAGS.

2011-05-09 Thread Richard Henderson
We had two different methods in use, both of which referenced ENV,
and neither of which indicated to the generic code when different
compilation modes are not compatible.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |   32 -
 target-alpha/translate.c |  396 --
 2 files changed, 239 insertions(+), 189 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 88281bb..c1ccf01 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -419,12 +419,40 @@ uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
 extern void swap_shadow_regs(CPUState *env);
 
+/* Bits in TB->FLAGS that control how translation is processed.  */
+enum {
+TB_FLAGS_PAL_MODE = 1,
+TB_FLAGS_FEN = 2,
+TB_FLAGS_USER_MODE = 8,
+
+TB_FLAGS_AMASK_SHIFT = 4,
+TB_FLAGS_AMASK_BWX = AMASK_BWX << TB_FLAGS_AMASK_SHIFT,
+TB_FLAGS_AMASK_FIX = AMASK_FIX << TB_FLAGS_AMASK_SHIFT,
+TB_FLAGS_AMASK_CIX = AMASK_CIX << TB_FLAGS_AMASK_SHIFT,
+TB_FLAGS_AMASK_MVI = AMASK_MVI << TB_FLAGS_AMASK_SHIFT,
+TB_FLAGS_AMASK_TRAP = AMASK_TRAP << TB_FLAGS_AMASK_SHIFT,
+TB_FLAGS_AMASK_PREFETCH = AMASK_PREFETCH << TB_FLAGS_AMASK_SHIFT,
+};
+
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
-target_ulong *cs_base, int *flags)
+target_ulong *cs_base, int *pflags)
 {
+int flags = 0;
+
 *pc = env->pc;
 *cs_base = 0;
-*flags = env->ps;
+
+if (env->pal_mode) {
+flags = TB_FLAGS_PAL_MODE;
+} else {
+flags = env->ps & PS_USER_MODE;
+}
+if (env->fen) {
+flags |= TB_FLAGS_FEN;
+}
+flags |= env->amask << TB_FLAGS_AMASK_SHIFT;
+
+*pflags = flags;
 }
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 42a80e6..28ccf6b 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -47,10 +47,6 @@ struct DisasContext {
 CPUAlphaState *env;
 uint64_t pc;
 int mem_idx;
-#if !defined (CONFIG_USER_ONLY)
-int pal_mode;
-#endif
-uint32_t amask;
 
 /* Current rounding mode for this TB.  */
 int tb_rm;
@@ -1653,20 +1649,22 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 break;
 case 0x0A:
 /* LDBU */
-if (!(ctx->amask & AMASK_BWX))
-goto invalid_opc;
-gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
-break;
+if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
+gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
+break;
+}
+goto invalid_opc;
 case 0x0B:
 /* LDQ_U */
 gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
 break;
 case 0x0C:
 /* LDWU */
-if (!(ctx->amask & AMASK_BWX))
-goto invalid_opc;
-gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
-break;
+if (ctx->tb->flags & TB_FLAGS_AMASK_BWX) {
+gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
+break;
+}
+goto invalid_opc;
 case 0x0D:
 /* STW */
 gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
@@ -2070,20 +2068,12 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 case 0x61:
 /* AMASK */
 if (likely(rc != 31)) {
-if (islit)
-tcg_gen_movi_i64(cpu_ir[rc], lit);
-else
-tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
-switch (ctx->env->implver) {
-case IMPLVER_2106x:
-/* EV4, EV45, LCA, LCA45 & EV5 */
-break;
-case IMPLVER_21164:
-case IMPLVER_21264:
-case IMPLVER_21364:
-tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rc],
- ~(uint64_t)ctx->amask);
-break;
+uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT;
+
+if (islit) {
+tcg_gen_movi_i64(cpu_ir[rc], lit & ~amask);
+} else {
+tcg_gen_andi_i64(cpu_ir[rc], cpu_ir[rb], ~amask);
 }
 }
 break;
@@ -2297,8 +2287,9 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 switch (fpfn) { /* fn11 & 0x3F */
 case 0x04:
 /* ITOFS */
-if (!(ctx->amask & AMASK_FIX))
+if ((ctx->tb->flags & TB_FLAGS_AMASK_FIX) == 0) {
 goto invalid_opc;
+}
 if (likely(rc != 31)) {
 if (ra != 31) {
 TCGv_i32 tmp = tcg_temp_new_i32();
@@ -2311,20 +2302,23 @@ static ExitStatus translate_one(DisasContext *ctx, 

[Qemu-devel] [PATCH 23/35] target-alpha: Remap PIO space for 43-bit KSEG for EV6.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/helper.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 96b407b..bd3af38 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -220,14 +220,18 @@ static int get_physical_address(CPUState *env, 
target_ulong addr,
 
 /* Translate the superpage.  */
 /* ??? When we do more than emulate Unix PALcode, we'll need to
-   determine which superpage is actually active.  */
-if (saddr < 0 && (saddr >> (TARGET_VIRT_ADDR_SPACE_BITS - 2) & 3) == 2) {
-/* User-space cannot access kseg addresses.  */
+   determine which KSEG is actually active.  */
+if (saddr < 0 && ((saddr >> 41) & 3) == 2) {
+/* User-space cannot access KSEG addresses.  */
 if (mmu_idx != MMU_KERNEL_IDX) {
 goto exit;
 }
 
+/* For the benefit of the Typhoon chipset, move bit 40 to bit 43.
+   We would not do this if the 48-bit KSEG is enabled.  */
 phys = saddr & ((1ull << 40) - 1);
+phys |= (saddr & (1ull << 40)) << 3;
+
 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 ret = -1;
 goto exit;
-- 
1.7.4.4




[Qemu-devel] [PATCH 26/35] target-alpha: Use a fixed frequency for the RPCC in system mode.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |2 --
 target-alpha/op_helper.c |   14 +++---
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index d26a870..c94becf 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -256,7 +256,6 @@ struct CPUAlphaState {
 uint64_t trap_arg1;
 uint64_t trap_arg2;
 
-#if !defined(CONFIG_USER_ONLY)
 /* The internal data required by our emulation of the Unix PALcode.  */
 uint64_t exc_addr;
 uint64_t palbr;
@@ -266,7 +265,6 @@ struct CPUAlphaState {
 uint64_t usp;
 uint64_t shadow[8];
 uint64_t scratch[24];
-#endif
 
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* temporary fixed-point registers
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 42fec07..36b8289 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -65,9 +65,17 @@ static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
 
 uint64_t helper_load_pcc (void)
 {
-/* ??? This isn't a timer for which we have any rate info.  */
-uint64_t ret = env->pcc_ofs;
-return ret << 32 | (uint32_t)cpu_get_real_ticks();
+#ifndef CONFIG_USER_ONLY
+/* In system mode we have access to a decent high-resolution clock.
+   In order to make OS-level time accounting work with the RPCC,
+   present it with a well-timed clock fixed at 250MHz.  */
+return (((uint64_t)env->pcc_ofs << 32)
+| (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
+#else
+/* In user-mode, vm_clock doesn't exist.  Just pass through the host cpu
+   clock ticks.  Also, don't bother taking PCC_OFS into account.  */
+return (uint32_t)cpu_get_real_ticks();
+#endif
 }
 
 uint64_t helper_load_fpcr (void)
-- 
1.7.4.4




[Qemu-devel] [PATCH 16/35] target-alpha: Swap shadow registers moving to/from PALmode.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |1 +
 target-alpha/helper.c|   37 -
 target-alpha/op_helper.c |5 -
 3 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 60445dc..7e4c46f 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -381,6 +381,7 @@ void do_interrupt (CPUState *env);
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env);
 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
+extern void swap_shadow_regs(CPUState *env);
 
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 target_ulong *cs_base, int *flags)
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index a49f632..4f706f2 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -168,6 +168,38 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, 
target_ulong address, int rw,
 return 1;
 }
 #else
+void swap_shadow_regs(CPUState *env)
+{
+uint64_t i0, i1, i2, i3, i4, i5, i6, i7;
+
+i0 = env->ir[8];
+i1 = env->ir[9];
+i2 = env->ir[10];
+i3 = env->ir[11];
+i4 = env->ir[12];
+i5 = env->ir[13];
+i6 = env->ir[14];
+i7 = env->ir[25];
+
+env->ir[8]  = env->shadow[0];
+env->ir[9]  = env->shadow[1];
+env->ir[10] = env->shadow[2];
+env->ir[11] = env->shadow[3];
+env->ir[12] = env->shadow[4];
+env->ir[13] = env->shadow[5];
+env->ir[14] = env->shadow[6];
+env->ir[25] = env->shadow[7];
+
+env->shadow[0] = i0;
+env->shadow[1] = i1;
+env->shadow[2] = i2;
+env->shadow[3] = i3;
+env->shadow[4] = i4;
+env->shadow[5] = i5;
+env->shadow[6] = i6;
+env->shadow[7] = i7;
+}
+
 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 {
 return -1;
@@ -290,7 +322,10 @@ void do_interrupt (CPUState *env)
 env->pc = env->palbr + i;
 
 /* Switch to PALmode.  */
-env->pal_mode = 1;
+if (!env->pal_mode) {
+env->pal_mode = 1;
+swap_shadow_regs(env);
+}
 #endif /* !USER_ONLY */
 }
 
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index fc5020a..03b5091 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1189,9 +1189,12 @@ uint64_t helper_cvtqg (uint64_t a)
 void helper_hw_ret (uint64_t a)
 {
 env->pc = a & ~3;
-env->pal_mode = a & 1;
 env->intr_flag = 0;
 env->lock_addr = -1;
+if ((a & 1) == 0) {
+env->pal_mode = 0;
+swap_shadow_regs(env);
+}
 }
 #endif
 
-- 
1.7.4.4




[Qemu-devel] [PATCH 05/35] target-alpha: Remove partial support for palcode emulation.

2011-05-09 Thread Richard Henderson
This code does not work, and will be replaced by a bios image.

Signed-off-by: Richard Henderson 
---
 Makefile.target  |2 +-
 hw/alpha_palcode.c   | 1048 --
 target-alpha/cpu.h   |   35 --
 target-alpha/helper.c|2 +-
 target-alpha/translate.c |2 -
 5 files changed, 2 insertions(+), 1087 deletions(-)
 delete mode 100644 hw/alpha_palcode.c

diff --git a/Makefile.target b/Makefile.target
index 21f864a..3abecd2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -364,7 +364,7 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
 
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
-obj-alpha-y = alpha_palcode.o
+obj-alpha-y = 
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/hw/alpha_palcode.c b/hw/alpha_palcode.c
deleted file mode 100644
index 033b542..000
--- a/hw/alpha_palcode.c
+++ /dev/null
@@ -1,1048 +0,0 @@
-/*
- *  Alpha emulation - PALcode emulation for qemu.
- *
- *  Copyright (c) 2007 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see .
- */
-
-#include 
-#include 
-#include 
-
-#include "cpu.h"
-#include "exec-all.h"
-
-/* Shared handlers */
-static void pal_reset (CPUState *env);
-/* Console handlers */
-static void pal_console_call (CPUState *env, uint32_t palcode);
-/* OpenVMS handlers */
-static void pal_openvms_call (CPUState *env, uint32_t palcode);
-/* UNIX / Linux handlers */
-static void pal_unix_call (CPUState *env, uint32_t palcode);
-
-pal_handler_t pal_handlers[] = {
-/* Console handler */
-{
-.reset = &pal_reset,
-.call_pal = &pal_console_call,
-},
-/* OpenVMS handler */
-{
-.reset = &pal_reset,
-.call_pal = &pal_openvms_call,
-},
-/* UNIX / Linux handler */
-{
-.reset = &pal_reset,
-.call_pal = &pal_unix_call,
-},
-};
-
-#if 0
-/* One must explicitly check that the TB is valid and the FOE bit is reset */
-static void update_itb (void)
-{
-/* This writes into a temp register, not the actual one */
-mtpr(TB_TAG);
-mtpr(TB_CTL);
-/* This commits the TB update */
-mtpr(ITB_PTE);
-}
-
-static void update_dtb (void);
-{
-mtpr(TB_CTL);
-/* This write into a temp register, not the actual one */
-mtpr(TB_TAG);
-/* This commits the TB update */
-mtpr(DTB_PTE);
-}
-#endif
-
-static void pal_reset (CPUState *env)
-{
-}
-
-static void do_swappal (CPUState *env, uint64_t palid)
-{
-pal_handler_t *pal_handler;
-
-switch (palid) {
-case 0 ... 2:
-pal_handler = &pal_handlers[palid];
-env->pal_handler = pal_handler;
-env->ipr[IPR_PAL_BASE] = -1ULL;
-(*pal_handler->reset)(env);
-break;
-case 3 ... 255:
-/* Unknown identifier */
-env->ir[0] = 1;
-return;
-default:
-/* We were given the entry point address */
-env->pal_handler = NULL;
-env->ipr[IPR_PAL_BASE] = palid;
-env->pc = env->ipr[IPR_PAL_BASE];
-cpu_loop_exit();
-}
-}
-
-static void pal_console_call (CPUState *env, uint32_t palcode)
-{
-uint64_t palid;
-
-if (palcode < 0x0080) {
-/* Privileged palcodes */
-if (!(env->ps >> 3)) {
-/* TODO: generate privilege exception */
-}
-}
-switch (palcode) {
-case 0x:
-/* HALT */
-/* REQUIRED */
-break;
-case 0x0001:
-/* CFLUSH */
-break;
-case 0x0002:
-/* DRAINA */
-/* REQUIRED */
-/* Implemented as no-op */
-break;
-case 0x0009:
-/* CSERVE */
-/* REQUIRED */
-break;
-case 0x000A:
-/* SWPPAL */
-/* REQUIRED */
-palid = env->ir[16];
-do_swappal(env, palid);
-break;
-case 0x0080:
-/* BPT */
-/* REQUIRED */
-break;
-case 0x0081:
-/* BUGCHK */
-/* REQUIRED */
-break;
-case 0x0086:
-/* IMB */
-/* REQUIRED */
-/* Implemented as no-op */
-break;
-case 0x009E:
-/* RDUNIQUE */
-/* REQUIRED */
-break;
-case 0x009F:
-/* WRUNIQUE */
-/* REQUIRED */
-break;
-case 0x00AA:
-/* GENTRAP */
-/* REQUIRED */
-break;
-default:
-break;
-   

[Qemu-devel] [PATCH 20/35] target-alpha: Disable interrupts properly.

2011-05-09 Thread Richard Henderson
Interrupts are disabled in PALmode, and when the PS IL is high enough.

Signed-off-by: Richard Henderson 
---
 cpu-exec.c  |   33 ++---
 target-alpha/cpu.h  |5 +
 target-alpha/exec.h |   12 +++-
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 6d43726..fbaa21e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -525,9 +525,36 @@ int cpu_exec(CPUState *env1)
 next_tb = 0;
 }
 #elif defined(TARGET_ALPHA)
-if (interrupt_request & CPU_INTERRUPT_HARD) {
-do_interrupt(env);
-next_tb = 0;
+{
+int idx = -1;
+/* ??? This hard-codes the OSF/1 interrupt levels.  */
+   switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
+case 0 ... 3:
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+idx = EXCP_DEV_INTERRUPT;
+}
+/* FALLTHRU */
+case 4:
+if (interrupt_request & CPU_INTERRUPT_TIMER) {
+idx = EXCP_CLK_INTERRUPT;
+}
+/* FALLTHRU */
+case 5:
+if (interrupt_request & CPU_INTERRUPT_SMP) {
+idx = EXCP_SMP_INTERRUPT;
+}
+/* FALLTHRU */
+case 6:
+if (interrupt_request & CPU_INTERRUPT_MCHK) {
+idx = EXCP_MCHK;
+}
+}
+if (idx >= 0) {
+env->exception_index = idx;
+env->error_code = 0;
+do_interrupt(env);
+next_tb = 0;
+}
 }
 #elif defined(TARGET_CRIS)
 if (interrupt_request & CPU_INTERRUPT_HARD
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index c1ccf01..b439751 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -316,6 +316,11 @@ enum {
 EXCP_STQ_C,
 };
 
+/* Alpha-specific interrupt pending bits.  */
+#define CPU_INTERRUPT_TIMERCPU_INTERRUPT_TGT_EXT_0
+#define CPU_INTERRUPT_SMP  CPU_INTERRUPT_TGT_EXT_1
+#define CPU_INTERRUPT_MCHK CPU_INTERRUPT_TGT_EXT_2
+
 /* Hardware interrupt (entInt) constants.  */
 enum {
 INT_K_IP,
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index 6ae96d1..7a325e7 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -39,7 +39,17 @@ register struct CPUAlphaState *env asm(AREG0);
 
 static inline int cpu_has_work(CPUState *env)
 {
-return (env->interrupt_request & CPU_INTERRUPT_HARD);
+/* Here we are checking to see if the CPU should wake up from HALT.
+   We will have gotten into this state only for WTINT from PALmode.  */
+/* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+   asleep even if (some) interrupts have been asserted.  For now, 
+   assume that if a CPU really wants to stay asleep, it will mask
+   interrupts at the chipset level, which will prevent these bits
+   from being set in the first place.  */
+return env->interrupt_request & (CPU_INTERRUPT_HARD
+ | CPU_INTERRUPT_TIMER
+ | CPU_INTERRUPT_SMP
+ | CPU_INTERRUPT_MCHK);
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-- 
1.7.4.4




[Qemu-devel] [PATCH 15/35] target-alpha: Implement do_interrupt for system mode.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/helper.c |  121 +
 1 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index c5479fd..a49f632 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -160,7 +160,6 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
 }
 
 #if defined(CONFIG_USER_ONLY)
-
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 int mmu_idx, int is_softmmu)
 {
@@ -168,14 +167,7 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, 
target_ulong address, int rw,
 env->trap_arg0 = address;
 return 1;
 }
-
-void do_interrupt (CPUState *env)
-{
-env->exception_index = -1;
-}
-
 #else
-
 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 {
 return -1;
@@ -186,12 +178,121 @@ int cpu_alpha_handle_mmu_fault (CPUState *env, 
target_ulong address, int rw,
 {
 return 0;
 }
+#endif /* USER_ONLY */
 
 void do_interrupt (CPUState *env)
 {
-abort();
+int i = env->exception_index;
+
+if (qemu_loglevel_mask(CPU_LOG_INT)) {
+static int count;
+const char *name = "";
+
+switch (i) {
+case EXCP_RESET:
+name = "reset";
+break;
+case EXCP_MCHK:
+name = "mchk";
+break;
+case EXCP_SMP_INTERRUPT:
+name = "smp_interrupt";
+break;
+case EXCP_CLK_INTERRUPT:
+name = "clk_interrupt";
+break;
+case EXCP_DEV_INTERRUPT:
+name = "dev_interrupt";
+break;
+case EXCP_MMFAULT:
+name = "mmfault";
+break;
+case EXCP_UNALIGN:
+name = "unalign";
+break;
+case EXCP_OPCDEC:
+name = "opcdec";
+break;
+case EXCP_ARITH:
+name = "arith";
+break;
+case EXCP_FEN:
+name = "fen";
+break;
+case EXCP_CALL_PAL:
+name = "call_pal";
+break;
+case EXCP_STL_C:
+name = "stl_c";
+break;
+case EXCP_STQ_C:
+name = "stq_c";
+break;
+}
+qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n",
+ ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
+}
+
+env->exception_index = -1;
+
+#if !defined(CONFIG_USER_ONLY)
+switch (i) {
+case EXCP_RESET:
+i = 0x;
+break;
+case EXCP_MCHK:
+i = 0x0080;
+break;
+case EXCP_SMP_INTERRUPT:
+i = 0x0100;
+break;
+case EXCP_CLK_INTERRUPT:
+i = 0x0180;
+break;
+case EXCP_DEV_INTERRUPT:
+i = 0x0200;
+break;
+case EXCP_MMFAULT:
+i = 0x0280;
+break;
+case EXCP_UNALIGN:
+i = 0x0300;
+break;
+case EXCP_OPCDEC:
+i = 0x0380;
+break;
+case EXCP_ARITH:
+i = 0x0400;
+break;
+case EXCP_FEN:
+i = 0x0480;
+break;
+case EXCP_CALL_PAL:
+i = env->error_code;
+/* There are 64 entry points for both privilaged and unprivlaged,
+   with bit 0x80 indicating unprivlaged.  Each entry point gets
+   64 bytes to do its job.  */
+if (i & 0x80) {
+i = 0x2000 + (i - 0x80) * 64;
+} else {
+i = 0x1000 + i * 64;
+}
+break;
+default:
+cpu_abort(env, "Unhandled CPU exception");
+}
+
+/* Remember where the exception happened.  Emulate real hardware in
+   that the low bit of the PC indicates PALmode.  */
+env->exc_addr = env->pc | env->pal_mode;
+
+/* Continue execution at the PALcode entry point.  */
+env->pc = env->palbr + i;
+
+/* Switch to PALmode.  */
+env->pal_mode = 1;
+#endif /* !USER_ONLY */
 }
-#endif
 
 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
  int flags)
-- 
1.7.4.4




[Qemu-devel] [PATCH 08/35] target-alpha: Rationalize internal processor registers.

2011-05-09 Thread Richard Henderson
Delete all the code that tried to emulate the real IPRs of some
unnamed CPU.  Replace those with just 3 slots that we can use to
communicate trap information between the helper functions that
signal exceptions and the OS trap handler.

Signed-off-by: Richard Henderson 
---
 linux-user/main.c|6 +-
 target-alpha/cpu.h   |  147 ++--
 target-alpha/helper.c|  348 +-
 target-alpha/helper.h|2 -
 target-alpha/op_helper.c |   17 +--
 target-alpha/translate.c |   31 +
 6 files changed, 20 insertions(+), 531 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 2a29088..839c547 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2536,9 +2536,9 @@ void cpu_loop (CPUState *env)
 env->lock_addr = -1;
 info.si_signo = TARGET_SIGSEGV;
 info.si_errno = 0;
-info.si_code = (page_get_flags(env->ipr[IPR_EXC_ADDR]) & PAGE_VALID
+info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID
 ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR);
-info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
+info._sifields._sigfault._addr = env->trap_arg0;
 queue_signal(env, info.si_signo, &info);
 break;
 case EXCP_UNALIGN:
@@ -2546,7 +2546,7 @@ void cpu_loop (CPUState *env)
 info.si_signo = TARGET_SIGBUS;
 info.si_errno = 0;
 info.si_code = TARGET_BUS_ADRALN;
-info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
+info._sifields._sigfault._addr = env->trap_arg0;
 queue_signal(env, info.si_signo, &info);
 break;
 case EXCP_OPCDEC:
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 8c73d5d..1fc21dc 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -192,141 +192,12 @@ enum {
 
 #define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
 
-/* Internal processor registers */
-/* XXX: TOFIX: most of those registers are implementation dependant */
-enum {
-#if defined(CONFIG_USER_ONLY)
-IPR_EXC_ADDR,
-IPR_EXC_SUM,
-IPR_EXC_MASK,
-#else
-/* Ebox IPRs */
-IPR_CC   = 0xC0,/* 21264 */
-IPR_CC_CTL   = 0xC1,/* 21264 */
-#define IPR_CC_CTL_ENA_SHIFT 32
-#define IPR_CC_CTL_COUNTER_MASK 0xfff0UL
-IPR_VA   = 0xC2,/* 21264 */
-IPR_VA_CTL   = 0xC4,/* 21264 */
-#define IPR_VA_CTL_VA_48_SHIFT 1
-#define IPR_VA_CTL_VPTB_SHIFT 30
-IPR_VA_FORM  = 0xC3,/* 21264 */
-/* Ibox IPRs */
-IPR_ITB_TAG  = 0x00,/* 21264 */
-IPR_ITB_PTE  = 0x01,/* 21264 */
-IPR_ITB_IAP  = 0x02,
-IPR_ITB_IA   = 0x03,/* 21264 */
-IPR_ITB_IS   = 0x04,/* 21264 */
-IPR_PMPC = 0x05,
-IPR_EXC_ADDR = 0x06,/* 21264 */
-IPR_IVA_FORM = 0x07,/* 21264 */
-IPR_CM   = 0x09,/* 21264 */
-#define IPR_CM_SHIFT 3
-#define IPR_CM_MASK (3ULL << IPR_CM_SHIFT)  /* 21264 */
-IPR_IER  = 0x0A,/* 21264 */
-#define IPR_IER_MASK 0x007fe000ULL
-IPR_IER_CM   = 0x0B,/* 21264: = CM | IER */
-IPR_SIRR = 0x0C,/* 21264 */
-#define IPR_SIRR_SHIFT 14
-#define IPR_SIRR_MASK 0x7fff
-IPR_ISUM = 0x0D,/* 21264 */
-IPR_HW_INT_CLR   = 0x0E,/* 21264 */
-IPR_EXC_SUM  = 0x0F,
-IPR_PAL_BASE = 0x10,
-IPR_I_CTL= 0x11,
-#define IPR_I_CTL_CHIP_ID_SHIFT 24  /* 21264 */
-#define IPR_I_CTL_BIST_FAIL (1 << 23)   /* 21264 */
-#define IPR_I_CTL_IC_EN_SHIFT 2 /* 21264 */
-#define IPR_I_CTL_SDE1_SHIFT 7  /* 21264 */
-#define IPR_I_CTL_HWE_SHIFT 12  /* 21264 */
-#define IPR_I_CTL_VA_48_SHIFT 15/* 21264 */
-#define IPR_I_CTL_SPE_SHIFT 3   /* 21264 */
-#define IPR_I_CTL_CALL_PAL_R23_SHIFT 20 /* 21264 */
-IPR_I_STAT   = 0x16,/* 21264 */
-IPR_IC_FLUSH = 0x13,/* 21264 */
-IPR_IC_FLUSH_ASM = 0x12,/* 21264 */
-IPR_CLR_MAP  = 0x15,
-IPR_SLEEP= 0x17,
-IPR_PCTX = 0x40,
-IPR_PCTX_ASN   = 0x01,  /* field */
-#define IPR_PCTX_ASN_SHIFT 39
-IPR_PCTX_ASTER = 0x02,  /* field */
-#define IPR_PCTX_ASTER_SHIFT 5
-IPR_PCTX_ASTRR = 0x04,  /* field */
-#define IPR_PCTX_ASTRR_SHIFT 9
-IPR_PCTX_PPCE  = 0x08,  /* field */
-#define IPR_PCTX_PPCE_SHIFT 1
-IPR_PCTX_FPE   = 0x10,  /* field */
-#define IPR_PCTX_FPE_SHIFT 2
-IPR_PCTX_ALL   = 0x5f,  /* all fields */
-IPR_PCTR_CTL = 0x14,/* 21264 */
-/* Mbox IPRs */
-IPR_DTB_TAG0 = 0x20,/* 21264 */
-IPR_DTB_TAG1 = 0xA0,/* 21264 */
-IPR_DTB_PTE0 = 0x21,/* 21264 *

[Qemu-devel] [PATCH 18/35] target-alpha: Use kernel mmu_idx for pal_mode.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 50a8109..88281bb 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -357,7 +357,13 @@ enum {
 
 static inline int cpu_mmu_index (CPUState *env)
 {
-return (env->ps & PS_USER_MODE) != 0;
+if (env->pal_mode) {
+return MMU_KERNEL_IDX;
+} else if (env->ps & PS_USER_MODE) {
+return MMU_USER_IDX;
+} else {
+return MMU_KERNEL_IDX;
+}
 }
 
 enum {
-- 
1.7.4.4




[Qemu-devel] [PATCH 10/35] target-alpha: Fixup translation of PALmode instructions.

2011-05-09 Thread Richard Henderson
All of the "raw" memory accesses should be "phys" instead.  Fix
some confusion about argument ordering of the store routines.
Fix the implementation of store-conditional.

Delete the "alt-mode" helpers.  Because we only implement two
mmu modes, let /a imply user-mode unconditionally.

For the moment, stub out HW_MTPR and HW_MFPR.

Merge hw_rei with hw_ret.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |4 +
 target-alpha/helper.h|   27 +++-
 target-alpha/op_helper.c |  159 ++
 target-alpha/translate.c |  130 ++
 4 files changed, 82 insertions(+), 238 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index bdd396c..60b753f 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -192,6 +192,8 @@ enum {
 
 #define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
 
+#define CPU_SAVE_VERSION1
+
 /* MMU modes definitions */
 
 /* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
@@ -243,6 +245,8 @@ struct CPUAlphaState {
exist for use in user-mode.  */
 uint8_t ps;
 uint8_t intr_flag;
+uint8_t fen;
+uint8_t pal_mode;
 
 /* These pass data from the exception logic in the translator and
helpers to the OS entry point.  This is used for both system
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 7435c61..9ffc372 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -100,25 +100,16 @@ DEF_HELPER_1(ieee_input_cmp, i64, i64)
 DEF_HELPER_1(ieee_input_s, i64, i64)
 
 #if !defined (CONFIG_USER_ONLY)
-DEF_HELPER_0(hw_rei, void)
 DEF_HELPER_1(hw_ret, void, i64)
-DEF_HELPER_0(set_alt_mode, void)
-DEF_HELPER_0(restore_mode, void)
-
-DEF_HELPER_1(ld_virt_to_phys, i64, i64)
-DEF_HELPER_1(st_virt_to_phys, i64, i64)
-DEF_HELPER_2(ldl_raw, void, i64, i64)
-DEF_HELPER_2(ldq_raw, void, i64, i64)
-DEF_HELPER_2(ldl_l_raw, void, i64, i64)
-DEF_HELPER_2(ldq_l_raw, void, i64, i64)
-DEF_HELPER_2(ldl_kernel, void, i64, i64)
-DEF_HELPER_2(ldq_kernel, void, i64, i64)
-DEF_HELPER_2(ldl_data, void, i64, i64)
-DEF_HELPER_2(ldq_data, void, i64, i64)
-DEF_HELPER_2(stl_raw, void, i64, i64)
-DEF_HELPER_2(stq_raw, void, i64, i64)
-DEF_HELPER_2(stl_c_raw, i64, i64, i64)
-DEF_HELPER_2(stq_c_raw, i64, i64, i64)
+
+DEF_HELPER_1(ldl_phys, i64, i64)
+DEF_HELPER_1(ldq_phys, i64, i64)
+DEF_HELPER_1(ldl_l_phys, i64, i64)
+DEF_HELPER_1(ldq_l_phys, i64, i64)
+DEF_HELPER_2(stl_phys, void, i64, i64)
+DEF_HELPER_2(stq_phys, void, i64, i64)
+DEF_HELPER_2(stl_c_phys, i64, i64, i64)
+DEF_HELPER_2(stq_c_phys, i64, i64, i64)
 #endif
 
 #include "def-helper.h"
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index fde14c4..73e5805 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1156,167 +1156,78 @@ uint64_t helper_cvtqg (uint64_t a)
 
 /* PALcode support special instructions */
 #if !defined (CONFIG_USER_ONLY)
-void helper_hw_rei (void)
-{
-env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
-env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
-env->intr_flag = 0;
-env->lock_addr = -1;
-/* XXX: re-enable interrupts and memory mapping */
-}
-
 void helper_hw_ret (uint64_t a)
 {
 env->pc = a & ~3;
-env->ipr[IPR_EXC_ADDR] = a & 1;
+env->pal_mode = a & 1;
 env->intr_flag = 0;
 env->lock_addr = -1;
-/* XXX: re-enable interrupts and memory mapping */
-}
-
-void helper_set_alt_mode (void)
-{
-env->saved_mode = env->ps & 0xC;
-env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
-}
-
-void helper_restore_mode (void)
-{
-env->ps = (env->ps & ~0xC) | env->saved_mode;
 }
-
 #endif
 
 /*/
 /* Softmmu support */
 #if !defined (CONFIG_USER_ONLY)
-
-/* XXX: the two following helpers are pure hacks.
- *  Hopefully, we emulate the PALcode, then we should never see
- *  HW_LD / HW_ST instructions.
- */
-uint64_t helper_ld_virt_to_phys (uint64_t virtaddr)
-{
-uint64_t tlb_addr, physaddr;
-int index, mmu_idx;
-void *retaddr;
-
-mmu_idx = cpu_mmu_index(env);
-index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
-if ((virtaddr & TARGET_PAGE_MASK) ==
-(tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-physaddr = virtaddr + env->tlb_table[mmu_idx][index].addend;
-} else {
-/* the page is not in the TLB : fill it */
-retaddr = GETPC();
-tlb_fill(virtaddr, 0, mmu_idx, retaddr);
-goto redo;
-}
-return physaddr;
-}
-
-uint64_t helper_st_virt_to_phys (uint64_t virtaddr)
-{
-uint64_t tlb_addr, physaddr;
-int index, mmu_idx;
-void *retaddr;
-
-mmu_idx = cpu_mmu_index(env);
-index = (virtaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-   

[Qemu-devel] [PATCH 13/35] target-alpha: Use do_restore_state for arithmetic exceptions.

2011-05-09 Thread Richard Henderson
This gets the PC right after an arithmetic exception.  Also tidies
the code in the TLB fault handlers to use common code.

Signed-off-by: Richard Henderson 
---
 target-alpha/op_helper.c |   49 -
 1 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 672940e..fc5020a 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -25,20 +25,42 @@
 
 /*/
 /* Exceptions processing helpers */
-void QEMU_NORETURN helper_excp (int excp, int error)
+
+/* This should only be called from translate, via gen_excp.
+   We expect that ENV->PC has already been updated.  */
+void QEMU_NORETURN helper_excp(int excp, int error)
+{
+env->exception_index = excp;
+env->error_code = error;
+cpu_loop_exit();
+}
+
+static void do_restore_state(void *retaddr)
+{
+unsigned long pc = (unsigned long)retaddr;
+
+if (pc) {
+TranslationBlock *tb = tb_find_pc(pc);
+if (tb) {
+cpu_restore_state(tb, env, pc);
+}
+}
+}
+
+/* This may be called from any of the helpers to set up EXCEPTION_INDEX.  */
+static void QEMU_NORETURN dynamic_excp(int excp, int error)
 {
 env->exception_index = excp;
 env->error_code = error;
+do_restore_state(GETPC());
 cpu_loop_exit();
 }
 
 static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
 {
-env->exception_index = EXCP_ARITH;
-env->error_code = 0;
 env->trap_arg0 = exc;
 env->trap_arg1 = mask;
-cpu_loop_exit();
+dynamic_excp(EXCP_ARITH, 0);
 }
 
 uint64_t helper_load_pcc (void)
@@ -521,7 +543,7 @@ static inline float32 f_to_float32(uint64_t a)
 
 if (unlikely(!exp && mant_sig)) {
 /* Reserved operands / Dirty zero */
-helper_excp(EXCP_OPCDEC, 0);
+dynamic_excp(EXCP_OPCDEC, 0);
 }
 
 if (exp < 3) {
@@ -651,7 +673,7 @@ static inline float64 g_to_float64(uint64_t a)
 
 if (!exp && mant_sig) {
 /* Reserved operands / Dirty zero */
-helper_excp(EXCP_OPCDEC, 0);
+dynamic_excp(EXCP_OPCDEC, 0);
 }
 
 if (exp < 3) {
@@ -1260,9 +1282,7 @@ uint64_t helper_stq_c_phys(uint64_t p, uint64_t v)
 /* XXX: fix it to restore all registers */
 void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 {
-TranslationBlock *tb;
 CPUState *saved_env;
-unsigned long pc;
 int ret;
 
 /* XXX: hack to restore env in all cases, even if not called from
@@ -1270,17 +1290,8 @@ void tlb_fill (target_ulong addr, int is_write, int 
mmu_idx, void *retaddr)
 saved_env = env;
 env = cpu_single_env;
 ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
-if (!likely(ret == 0)) {
-if (likely(retaddr)) {
-/* now we have a real cpu fault */
-pc = (unsigned long)retaddr;
-tb = tb_find_pc(pc);
-if (likely(tb)) {
-/* the PC is inside the translated code. It means that we have
-   a virtual CPU fault */
-cpu_restore_state(tb, env, pc);
-}
-}
+if (unlikely(ret != 0)) {
+do_restore_state(retaddr);
 /* Exception index and error code are already set */
 cpu_loop_exit();
 }
-- 
1.7.4.4




[Qemu-devel] [PATCH 17/35] target-alpha: Add various symbolic constants.

2011-05-09 Thread Richard Henderson
The EXC_M_* constants were being set for the EV6, not as set for
the Unix kernel entry point.

Use PS_USER_MODE instead of hard-coding access to the PS register.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |   56 +++--
 target-alpha/translate.c |2 +-
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 7e4c46f..50a8109 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -290,11 +290,6 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
-static inline int cpu_mmu_index (CPUState *env)
-{
-return (env->ps >> 3) & 1;
-}
-
 #include "cpu-all.h"
 
 enum {
@@ -321,14 +316,49 @@ enum {
 EXCP_STQ_C,
 };
 
-/* Arithmetic exception */
-#define EXC_M_IOV   (1<<16) /* Integer Overflow */
-#define EXC_M_INE   (1<<15) /* Inexact result */
-#define EXC_M_UNF   (1<<14) /* Underflow */
-#define EXC_M_FOV   (1<<13) /* Overflow */
-#define EXC_M_DZE   (1<<12) /* Division by zero */
-#define EXC_M_INV   (1<<11) /* Invalid operation */
-#define EXC_M_SWC   (1<<10) /* Software completion */
+/* Hardware interrupt (entInt) constants.  */
+enum {
+INT_K_IP,
+INT_K_CLK,
+INT_K_MCHK,
+INT_K_DEV,
+INT_K_PERF,
+};
+
+/* Memory management (entMM) constants.  */
+enum {
+MM_K_TNV,
+MM_K_ACV,
+MM_K_FOR,
+MM_K_FOE,
+MM_K_FOW
+};
+
+/* Arithmetic exception (entArith) constants.  */
+enum {
+EXC_M_SWC = 1,  /* Software completion */
+EXC_M_INV = 2,  /* Invalid operation */
+EXC_M_DZE = 4,  /* Division by zero */
+EXC_M_FOV = 8,  /* Overflow */
+EXC_M_UNF = 16, /* Underflow */
+EXC_M_INE = 32, /* Inexact result */
+EXC_M_IOV = 64  /* Integer Overflow */
+};
+
+/* Processor status constants.  */
+enum {
+/* Low 3 bits are interrupt mask level.  */
+PS_INT_MASK = 7,
+
+/* Bits 4 and 5 are the mmu mode.  The VMS PALcode uses all 4 modes;
+   The Unix PALcode only uses bit 4.  */
+PS_USER_MODE = 8
+};
+
+static inline int cpu_mmu_index (CPUState *env)
+{
+return (env->ps & PS_USER_MODE) != 0;
+}
 
 enum {
 IR_V0   = 0,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 09edb0f..42a80e6 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3359,7 +3359,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 env->amask = amask;
 
 #if defined (CONFIG_USER_ONLY)
-env->ps = 1 << 3;
+env->ps = PS_USER_MODE;
 cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
| FPCR_UNFD | FPCR_INED | FPCR_DNOD));
 #else
-- 
1.7.4.4




[Qemu-devel] [PATCH 12/35] target-alpha: Tidy up arithmetic exceptions.

2011-05-09 Thread Richard Henderson
Introduce and use arith_excp, filling in the trap_arg[01] IPRs.

Signed-off-by: Richard Henderson 
---
 target-alpha/op_helper.c |   34 +-
 1 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index 73e5805..672940e 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -32,6 +32,15 @@ void QEMU_NORETURN helper_excp (int excp, int error)
 cpu_loop_exit();
 }
 
+static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
+{
+env->exception_index = EXCP_ARITH;
+env->error_code = 0;
+env->trap_arg0 = exc;
+env->trap_arg1 = mask;
+cpu_loop_exit();
+}
+
 uint64_t helper_load_pcc (void)
 {
 /* ??? This isn't a timer for which we have any rate info.  */
@@ -53,7 +62,7 @@ uint64_t helper_addqv (uint64_t op1, uint64_t op2)
 uint64_t tmp = op1;
 op1 += op2;
 if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return op1;
 }
@@ -63,7 +72,7 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2)
 uint64_t tmp = op1;
 op1 = (uint32_t)(op1 + op2);
 if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return op1;
 }
@@ -73,7 +82,7 @@ uint64_t helper_subqv (uint64_t op1, uint64_t op2)
 uint64_t res;
 res = op1 - op2;
 if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return res;
 }
@@ -83,7 +92,7 @@ uint64_t helper_sublv (uint64_t op1, uint64_t op2)
 uint32_t res;
 res = op1 - op2;
 if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return res;
 }
@@ -93,7 +102,7 @@ uint64_t helper_mullv (uint64_t op1, uint64_t op2)
 int64_t res = (int64_t)op1 * (int64_t)op2;
 
 if (unlikely((int32_t)res != res)) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return (int64_t)((int32_t)res);
 }
@@ -105,7 +114,7 @@ uint64_t helper_mulqv (uint64_t op1, uint64_t op2)
 muls64(&tl, &th, op1, op2);
 /* If th != 0 && th != -1, then we had an overflow */
 if (unlikely((th + 1) > 1)) {
-helper_excp(EXCP_ARITH, EXC_M_IOV);
+arith_excp(EXC_M_IOV, 0);
 }
 return tl;
 }
@@ -373,8 +382,6 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
 if (exc) {
 uint32_t hw_exc = 0;
 
-env->trap_arg1 = 1ull << regno;
-
 if (exc & float_flag_invalid) {
 hw_exc |= EXC_M_INV;
 }
@@ -390,7 +397,8 @@ void helper_fp_exc_raise(uint32_t exc, uint32_t regno)
 if (exc & float_flag_inexact) {
 hw_exc |= EXC_M_INE;
 }
-helper_excp(EXCP_ARITH, hw_exc);
+
+arith_excp(hw_exc, 1ull << regno);
 }
 }
 
@@ -420,7 +428,7 @@ uint64_t helper_ieee_input(uint64_t val)
 if (env->fpcr_dnz) {
 val &= 1ull << 63;
 } else {
-helper_excp(EXCP_ARITH, EXC_M_UNF);
+arith_excp(EXC_M_UNF, 0);
 }
 }
 } else if (exp == 0x7ff) {
@@ -428,7 +436,7 @@ uint64_t helper_ieee_input(uint64_t val)
 /* ??? I'm not sure these exception bit flags are correct.  I do
know that the Linux kernel, at least, doesn't rely on them and
just emulates the insn to figure out what exception to use.  */
-helper_excp(EXCP_ARITH, frac ? EXC_M_INV : EXC_M_FOV);
+arith_excp(frac ? EXC_M_INV : EXC_M_FOV, 0);
 }
 return val;
 }
@@ -445,12 +453,12 @@ uint64_t helper_ieee_input_cmp(uint64_t val)
 if (env->fpcr_dnz) {
 val &= 1ull << 63;
 } else {
-helper_excp(EXCP_ARITH, EXC_M_UNF);
+arith_excp(EXC_M_UNF, 0);
 }
 }
 } else if (exp == 0x7ff && frac) {
 /* NaN.  */
-helper_excp(EXCP_ARITH, EXC_M_INV);
+arith_excp(EXC_M_INV, 0);
 }
 return val;
 }
-- 
1.7.4.4




[Qemu-devel] [PATCH 06/35] target-alpha: Enable the alpha-softmmu target.

2011-05-09 Thread Richard Henderson
Compiles, but no machine defined yet, so this will crash on startup.

Signed-off-by: Richard Henderson 
---
 Makefile.target   |3 +-
 configure |1 +
 default-configs/alpha-softmmu.mak |9 
 target-alpha/machine.c|   87 +
 4 files changed, 99 insertions(+), 1 deletions(-)
 create mode 100644 default-configs/alpha-softmmu.mak
 create mode 100644 target-alpha/machine.c

diff --git a/Makefile.target b/Makefile.target
index 3abecd2..2f842c1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -364,7 +364,8 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
 
 obj-s390x-y = s390-virtio-bus.o s390-virtio.o
 
-obj-alpha-y = 
+obj-alpha-y += i8259.o mc146818rtc.o
+obj-alpha-y += vga.o cirrus_vga.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/configure b/configure
index 6f75e2e..214aabc 100755
--- a/configure
+++ b/configure
@@ -1011,6 +1011,7 @@ if test -z "$target_list" ; then
 target_list="\
 i386-softmmu \
 x86_64-softmmu \
+alpha-softmmu \
 arm-softmmu \
 cris-softmmu \
 lm32-softmmu \
diff --git a/default-configs/alpha-softmmu.mak 
b/default-configs/alpha-softmmu.mak
new file mode 100644
index 000..abadcff
--- /dev/null
+++ b/default-configs/alpha-softmmu.mak
@@ -0,0 +1,9 @@
+# Default configuration for alpha-softmmu
+
+include pci.mak
+CONFIG_SERIAL=y
+CONFIG_I8254=y
+CONFIG_VGA_PCI=y
+CONFIG_IDE_CORE=y
+CONFIG_IDE_QDEV=y
+CONFIG_VMWARE_VGA=y
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
new file mode 100644
index 000..a13b66a
--- /dev/null
+++ b/target-alpha/machine.c
@@ -0,0 +1,87 @@
+#include "hw/hw.h"
+#include "hw/boards.h"
+
+static int get_fpcr(QEMUFile *f, void *opaque, size_t size)
+{
+CPUAlphaState *env = opaque;
+cpu_alpha_store_fpcr(env, qemu_get_be64(f));
+return 0;
+}
+
+static void put_fpcr(QEMUFile *f, void *opaque, size_t size)
+{
+CPUAlphaState *env = opaque;
+qemu_put_be64(f, cpu_alpha_load_fpcr(env));
+}
+
+static const VMStateInfo vmstate_fpcr = {
+.name = "fpcr",
+.get = get_fpcr,
+.put = put_fpcr,
+};
+
+static VMStateField vmstate_cpu_fields[] = {
+VMSTATE_UINTTL_ARRAY(ir, CPUState, 31),
+VMSTATE_UINTTL_ARRAY(fir, CPUState, 31),
+/* Save the architecture value of the fpcr, not the internally
+   expanded version.  Since this architecture value does not
+   exist in memory to be stored, this requires a but of hoop
+   jumping.  We want OFFSET=0 so that we effectively pass ENV
+   to the helper functions, and we need to fill in the name by
+   hand since there's no field of that name.  */
+{
+.name = "fpcr",
+.version_id = 0,
+.size = sizeof(uint64_t),
+.info = &vmstate_fpcr,
+.flags = VMS_SINGLE,
+.offset = 0
+},
+VMSTATE_UINTTL(pc, CPUState),
+VMSTATE_UINTTL(unique, CPUState),
+VMSTATE_UINTTL(lock_addr, CPUState),
+VMSTATE_UINTTL(lock_value, CPUState),
+/* Note that lock_st_addr is not saved; it is a temporary
+   used during the execution of the st[lq]_c insns.  */
+
+VMSTATE_UINT8(ps, CPUState),
+VMSTATE_UINT8(intr_flag, CPUState),
+VMSTATE_UINT8(fen, CPUState),
+VMSTATE_UINT8(pal_mode, CPUState),
+
+VMSTATE_UINT32(pcc_ofs, CPUState),
+
+VMSTATE_UINTTL(trap_arg0, CPUState),
+VMSTATE_UINTTL(trap_arg1, CPUState),
+VMSTATE_UINTTL(trap_arg2, CPUState),
+
+VMSTATE_UINTTL(exc_addr, CPUState),
+VMSTATE_UINTTL(palbr, CPUState),
+VMSTATE_UINTTL(ptbr, CPUState),
+VMSTATE_UINTTL(vptptr, CPUState),
+VMSTATE_UINTTL(sysval, CPUState),
+VMSTATE_UINTTL(usp, CPUState),
+
+VMSTATE_UINTTL_ARRAY(shadow, CPUState, 8),
+VMSTATE_UINTTL_ARRAY(scratch, CPUState, 24),
+
+VMSTATE_END_OF_LIST()
+};
+
+static const VMStateDescription vmstate_cpu = {
+.name = "cpu",
+.version_id = CPU_SAVE_VERSION,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = vmstate_cpu_fields,
+};
+
+void cpu_save(QEMUFile *f, void *opaque)
+{
+vmstate_save_state(f, &vmstate_cpu, opaque);
+}
+
+int cpu_load(QEMUFile *f, void *opaque, int version_id)
+{
+return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
+}
-- 
1.7.4.4




[Qemu-devel] [PATCH 09/35] target-alpha: Cleanup MMU modes.

2011-05-09 Thread Richard Henderson
Don't bother including executive and supervisor modes.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h |   36 
 1 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 1fc21dc..bdd396c 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -192,6 +192,33 @@ enum {
 
 #define SWCR_MASK  (SWCR_TRAP_ENABLE_MASK | SWCR_MAP_MASK | SWCR_STATUS_MASK)
 
+/* MMU modes definitions */
+
+/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
+   The Unix PALcode only exposes the kernel and user modes; presumably
+   executive and supervisor are used by VMS.
+
+   PALcode itself uses physical mode for code and kernel mode for data;
+   there are PALmode instructions that can access data via physical mode
+   or via an os-installed "alternate mode", which is one of the 4 above.
+
+   QEMU does not currently properly distinguish between code/data when
+   looking up addresses.  To avoid having to address this issue, our
+   emulated PALcode will cheat and use the KSEG mapping for its code+data
+   rather than physical addresses.
+
+   Moreover, we're only emulating Unix PALcode, and not attempting VMS.
+
+   All of which allows us to drop all but kernel and user modes.
+   Elide the unused MMU modes to save space.  */
+
+#define NB_MMU_MODES 2
+
+#define MMU_MODE0_SUFFIX _kernel
+#define MMU_MODE1_SUFFIX _user
+#define MMU_KERNEL_IDX   0
+#define MMU_USER_IDX 1
+
 typedef struct CPUAlphaState CPUAlphaState;
 
 struct CPUAlphaState {
@@ -246,16 +273,9 @@ struct CPUAlphaState {
 #define cpu_gen_code cpu_alpha_gen_code
 #define cpu_signal_handler cpu_alpha_signal_handler
 
-/* MMU modes definitions */
-#define NB_MMU_MODES 4
-#define MMU_MODE0_SUFFIX _kernel
-#define MMU_MODE1_SUFFIX _executive
-#define MMU_MODE2_SUFFIX _supervisor
-#define MMU_MODE3_SUFFIX _user
-#define MMU_USER_IDX 3
 static inline int cpu_mmu_index (CPUState *env)
 {
-return (env->ps >> 3) & 3;
+return (env->ps >> 3) & 1;
 }
 
 #include "cpu-all.h"
-- 
1.7.4.4




[Qemu-devel] [PATCH 07/35] target-alpha: Tidy exception constants.

2011-05-09 Thread Richard Henderson
There's no need to attempt to match EXCP_* values with PALcode entry
point offsets.  Instead, compress all the values to make for more
efficient switch statements within QEMU.

We will be doing TLB fill within QEMU proper, not within the PALcode,
so all of the ITB/DTB miss, double fault, and access exceptions can
be compressed to EXCP_MMFAULT.

Compress all of the EXCP_CALL_PAL exceptions into one.
Use env->error_code to store the specific entry point.
---
 linux-user/main.c|   44 ++--
 target-alpha/cpu.h   |   34 ++
 target-alpha/helper.c|6 +-
 target-alpha/translate.c |4 ++--
 4 files changed, 31 insertions(+), 57 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index a1e37e4..2a29088 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2526,19 +2526,13 @@ void cpu_loop (CPUState *env)
 fprintf(stderr, "Machine check exception. Exit\n");
 exit(1);
 break;
-case EXCP_ARITH:
-env->lock_addr = -1;
-info.si_signo = TARGET_SIGFPE;
-info.si_errno = 0;
-info.si_code = TARGET_FPE_FLTINV;
-info._sifields._sigfault._addr = env->pc;
-queue_signal(env, info.si_signo, &info);
-break;
-case EXCP_HW_INTERRUPT:
+case EXCP_SMP_INTERRUPT:
+case EXCP_CLK_INTERRUPT:
+case EXCP_DEV_INTERRUPT:
 fprintf(stderr, "External interrupt. Exit\n");
 exit(1);
 break;
-case EXCP_DFAULT:
+case EXCP_MMFAULT:
 env->lock_addr = -1;
 info.si_signo = TARGET_SIGSEGV;
 info.si_errno = 0;
@@ -2547,22 +2541,6 @@ void cpu_loop (CPUState *env)
 info._sifields._sigfault._addr = env->ipr[IPR_EXC_ADDR];
 queue_signal(env, info.si_signo, &info);
 break;
-case EXCP_DTB_MISS_PAL:
-fprintf(stderr, "MMU data TLB miss in PALcode\n");
-exit(1);
-break;
-case EXCP_ITB_MISS:
-fprintf(stderr, "MMU instruction TLB miss\n");
-exit(1);
-break;
-case EXCP_ITB_ACV:
-fprintf(stderr, "MMU instruction access violation\n");
-exit(1);
-break;
-case EXCP_DTB_MISS_NATIVE:
-fprintf(stderr, "MMU data TLB miss\n");
-exit(1);
-break;
 case EXCP_UNALIGN:
 env->lock_addr = -1;
 info.si_signo = TARGET_SIGBUS;
@@ -2580,12 +2558,20 @@ void cpu_loop (CPUState *env)
 info._sifields._sigfault._addr = env->pc;
 queue_signal(env, info.si_signo, &info);
 break;
+case EXCP_ARITH:
+env->lock_addr = -1;
+info.si_signo = TARGET_SIGFPE;
+info.si_errno = 0;
+info.si_code = TARGET_FPE_FLTINV;
+info._sifields._sigfault._addr = env->pc;
+queue_signal(env, info.si_signo, &info);
+break;
 case EXCP_FEN:
 /* No-op.  Linux simply re-enables the FPU.  */
 break;
-case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
+case EXCP_CALL_PAL:
 env->lock_addr = -1;
-switch ((trapnr >> 6) | 0x80) {
+switch (env->error_code) {
 case 0x80:
 /* BPT */
 info.si_signo = TARGET_SIGTRAP;
@@ -2676,8 +2662,6 @@ void cpu_loop (CPUState *env)
 goto do_sigill;
 }
 break;
-case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
-goto do_sigill;
 case EXCP_DEBUG:
 info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
 if (info.si_signo) {
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 0daa556..8c73d5d 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -391,26 +391,20 @@ enum {
 };
 
 enum {
-EXCP_RESET= 0x,
-EXCP_MCHK = 0x0020,
-EXCP_ARITH= 0x0060,
-EXCP_HW_INTERRUPT = 0x00E0,
-EXCP_DFAULT   = 0x01E0,
-EXCP_DTB_MISS_PAL = 0x09E0,
-EXCP_ITB_MISS = 0x03E0,
-EXCP_ITB_ACV  = 0x07E0,
-EXCP_DTB_MISS_NATIVE  = 0x08E0,
-EXCP_UNALIGN  = 0x11E0,
-EXCP_OPCDEC   = 0x13E0,
-EXCP_FEN  = 0x17E0,
-EXCP_CALL_PAL = 0x2000,
-EXCP_CALL_PALP= 0x3000,
-EXCP_CALL_PALE= 0x4000,
-/* Pseudo exception for console */
-EXCP_CONSOLE_DISPATCH = 0x4001,
-EXCP_CONSOLE_FIXUP= 0x4002,
-EXCP_STL_C= 0x4003,
-EXCP_STQ_C= 0x4004,
+EXCP_RESET,
+EXCP_MCHK,
+EXCP_SMP_INTERRUPT,
+EXCP_CLK_INTERRUPT,
+EXCP_DEV_INTERRUPT,
+EXCP_MMFAULT,
+EXCP_UNALIGN,
+EXCP_OPCDEC,
+EXCP_ARITH,
+EXCP_FEN,
+EXCP_CALL_PAL,
+/* For Usermode emulation.  */
+EXCP_S

[Qemu-devel] [PATCH 14/35] target-alpha: Merge HW_REI and HW_RET implementations.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-alpha/translate.c |   16 +---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 9e1576d..09edb0f 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2943,14 +2943,24 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 break;
 #endif
 case 0x1E:
-/* HW_REI (PALcode) */
+/* HW_RET (PALcode) */
 #if defined (CONFIG_USER_ONLY)
 goto invalid_opc;
 #else
 if (!ctx->pal_mode)
 goto invalid_opc;
-gen_helper_hw_ret(cpu_ir[rb]);
-break;
+if (rb == 31) {
+/* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
+   address from EXC_ADDR.  This turns out to be useful for our
+   emulation PALcode, so continue to accept it.  */
+TCGv tmp = tcg_temp_new();
+tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUState, exc_addr));
+gen_helper_hw_ret(tmp);
+tcg_temp_free(tmp);
+} else {
+gen_helper_hw_ret(cpu_ir[rb]);
+}
+return EXIT_PC_UPDATED;
 #endif
 case 0x1F:
 /* HW_ST (PALcode) */
-- 
1.7.4.4




[Qemu-devel] [PATCH 03/35] pci: Export pci_to_cpu_addr.

2011-05-09 Thread Richard Henderson
This is, more or less, the read accessor to pci_bus_set_mem_base
as a write accessor.  It will be needed for implementing sparse
memory spaces for Alpha.

Signed-off-by: Richard Henderson 
---
 hw/pci.c |3 +--
 hw/pci.h |1 +
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 0875654..0b2b943 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -800,8 +800,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char 
*name,
 return pci_dev;
 }
 
-static target_phys_addr_t pci_to_cpu_addr(PCIBus *bus,
-  target_phys_addr_t addr)
+target_phys_addr_t pci_to_cpu_addr(PCIBus *bus, target_phys_addr_t addr)
 {
 return addr + bus->mem_base;
 }
diff --git a/hw/pci.h b/hw/pci.h
index c6a6eb6..8615cc2 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -246,6 +246,7 @@ void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
 
 void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base);
+target_phys_addr_t pci_to_cpu_addr(PCIBus *bus, target_phys_addr_t addr);
 
 PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
 const char *default_devaddr);
-- 
1.7.4.4




[Qemu-devel] [PATCH 04/35] target-alpha: Single-step properly across branches.

2011-05-09 Thread Richard Henderson
We were failing to generate EXC_DEBUG in the EXIT_PC_UPDATED path.
This caused us not to stop at the instruction after a branch, but
on the instruction afterward.

Signed-off-by: Richard Henderson 
---
 target-alpha/translate.c |   35 ---
 1 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 456ba51..194a286 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -147,17 +147,21 @@ static void alpha_translate_init(void)
 done_init = 1;
 }
 
-static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
+static void gen_excp_1(int exception, int error_code)
 {
 TCGv_i32 tmp1, tmp2;
 
-tcg_gen_movi_i64(cpu_pc, ctx->pc);
 tmp1 = tcg_const_i32(exception);
 tmp2 = tcg_const_i32(error_code);
 gen_helper_excp(tmp1, tmp2);
 tcg_temp_free_i32(tmp2);
 tcg_temp_free_i32(tmp1);
+}
 
+static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
+{
+tcg_gen_movi_i64(cpu_pc, ctx->pc);
+gen_excp_1(exception, error_code);
 return EXIT_NORETURN;
 }
 
@@ -3211,18 +3215,15 @@ static inline void 
gen_intermediate_code_internal(CPUState *env,
 ctx.pc += 4;
 ret = translate_one(ctxp, insn);
 
-if (ret == NO_EXIT) {
-/* If we reach a page boundary, are single stepping,
-   or exhaust instruction count, stop generation.  */
-if (env->singlestep_enabled) {
-gen_excp(&ctx, EXCP_DEBUG, 0);
-ret = EXIT_PC_UPDATED;
-} else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
-   || gen_opc_ptr >= gen_opc_end
-   || num_insns >= max_insns
-   || singlestep) {
-ret = EXIT_PC_STALE;
-}
+/* If we reach a page boundary, are single stepping,
+   or exhaust instruction count, stop generation.  */
+if (ret == NO_EXIT
+&& ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
+|| gen_opc_ptr >= gen_opc_end
+|| num_insns >= max_insns
+|| singlestep
+|| env->singlestep_enabled)) {
+ret = EXIT_PC_STALE;
 }
 } while (ret == NO_EXIT);
 
@@ -3238,7 +3239,11 @@ static inline void 
gen_intermediate_code_internal(CPUState *env,
 tcg_gen_movi_i64(cpu_pc, ctx.pc);
 /* FALLTHRU */
 case EXIT_PC_UPDATED:
-tcg_gen_exit_tb(0);
+if (env->singlestep_enabled) {
+gen_excp_1(EXCP_DEBUG, 0);
+} else {
+tcg_gen_exit_tb(0);
+}
 break;
 default:
 abort();
-- 
1.7.4.4




[Qemu-devel] [PATCH 11/35] target-alpha: Add IPRs to be used by the emulation PALcode.

2011-05-09 Thread Richard Henderson
These aren't actually used yet, but we can at least access
them via the HW_MFPR and HW_MTPR instructions.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h   |   13 +++
 target-alpha/translate.c |   87 -
 2 files changed, 98 insertions(+), 2 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 60b753f..60445dc 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -247,6 +247,7 @@ struct CPUAlphaState {
 uint8_t intr_flag;
 uint8_t fen;
 uint8_t pal_mode;
+uint32_t pcc_ofs;
 
 /* These pass data from the exception logic in the translator and
helpers to the OS entry point.  This is used for both system
@@ -255,6 +256,18 @@ struct CPUAlphaState {
 uint64_t trap_arg1;
 uint64_t trap_arg2;
 
+#if !defined(CONFIG_USER_ONLY)
+/* The internal data required by our emulation of the Unix PALcode.  */
+uint64_t exc_addr;
+uint64_t palbr;
+uint64_t ptbr;
+uint64_t vptptr;
+uint64_t sysval;
+uint64_t usp;
+uint64_t shadow[8];
+uint64_t scratch[24];
+#endif
+
 #if TARGET_LONG_BITS > HOST_LONG_BITS
 /* temporary fixed-point registers
  * used to emulate 64 bits target on 32 bits hosts
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index b14b8fc..9e1576d 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1468,6 +1468,89 @@ static void gen_rx(int ra, int set)
 tcg_temp_free_i32(tmp);
 }
 
+#ifndef CONFIG_USER_ONLY
+
+#define PR_BYTE 0x10
+#define PR_LONG 0x20
+
+static int cpu_pr_data(int pr)
+{
+switch (pr) {
+case  0: return offsetof(CPUAlphaState, ps) | PR_BYTE;
+case  1: return offsetof(CPUAlphaState, fen) | PR_BYTE;
+case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
+case  3: return offsetof(CPUAlphaState, trap_arg0);
+case  4: return offsetof(CPUAlphaState, trap_arg1);
+case  5: return offsetof(CPUAlphaState, trap_arg2);
+case  6: return offsetof(CPUAlphaState, exc_addr);
+case  7: return offsetof(CPUAlphaState, palbr);
+case  8: return offsetof(CPUAlphaState, ptbr);
+case  9: return offsetof(CPUAlphaState, vptptr);
+case 10: return offsetof(CPUAlphaState, unique);
+case 11: return offsetof(CPUAlphaState, sysval);
+case 12: return offsetof(CPUAlphaState, usp);
+
+case 32 ... 39:
+return offsetof(CPUAlphaState, shadow[pr - 32]);
+case 40 ... 63:
+return offsetof(CPUAlphaState, scratch[pr - 40]);
+}
+return 0;
+}
+
+static void gen_mfpr(int ra, int regno)
+{
+int data = cpu_pr_data(regno);
+
+/* In our emulated PALcode, these processor registers have no
+   side effects from reading.  */
+if (ra == 31) {
+return;
+}
+
+/* The basic registers are data only, and unknown registers
+   are read-zero, write-ignore.  */
+if (data == 0) {
+tcg_gen_movi_i64(cpu_ir[ra], 0);
+} else if (data & PR_BYTE) {
+tcg_gen_ld8u_i64(cpu_ir[ra], cpu_env, data & ~PR_BYTE);
+} else if (data & PR_LONG) {
+tcg_gen_ld32s_i64(cpu_ir[ra], cpu_env, data & ~PR_LONG);
+} else {
+tcg_gen_ld_i64(cpu_ir[ra], cpu_env, data);
+}
+}
+
+static void gen_mtpr(int rb, int regno)
+{
+TCGv tmp;
+int data;
+
+if (rb == 31) {
+tmp = tcg_const_i64(0);
+} else {
+tmp = cpu_ir[rb];
+}
+
+/* The basic registers are data only, and unknown registers
+   are read-zero, write-ignore.  */
+data = cpu_pr_data(regno);
+if (data != 0) {
+if (data & PR_BYTE) {
+tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);
+} else if (data & PR_LONG) {
+tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);
+} else {
+tcg_gen_st_i64(tmp, cpu_env, data);
+}
+}
+
+if (rb == 31) {
+tcg_temp_free(tmp);
+}
+}
+#endif /* !USER_ONLY*/
+
 static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
 {
 uint32_t palcode;
@@ -2580,7 +2663,7 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 #else
 if (!ctx->pal_mode)
 goto invalid_opc;
-tcg_abort();
+gen_mfpr(ra, insn & 0x);
 break;
 #endif
 case 0x1A:
@@ -2856,7 +2939,7 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 #else
 if (!ctx->pal_mode)
 goto invalid_opc;
-abort();
+gen_mtpr(rb, insn & 0x);
 break;
 #endif
 case 0x1E:
-- 
1.7.4.4




[Qemu-devel] [PATCH 02/35] target-alpha: Disassemble EV6 PALcode instructions.

2011-05-09 Thread Richard Henderson
The QEMU emulation PALcode will use EV6 PALcode insns regardless
of the "real" cpu instruction set being emulated.

Signed-off-by: Richard Henderson 
---
 alpha-dis.c |4 
 dis-asm.h   |3 +++
 disas.c |2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/alpha-dis.c b/alpha-dis.c
index 8a2411e..ae331b3 100644
--- a/alpha-dis.c
+++ b/alpha-dis.c
@@ -238,10 +238,6 @@ extern const unsigned alpha_num_operands;
 #define AXP_REG_SP 30
 #define AXP_REG_ZERO   31
 
-#define bfd_mach_alpha_ev4  0x10
-#define bfd_mach_alpha_ev5  0x20
-#define bfd_mach_alpha_ev6  0x30
-
 enum bfd_reloc_code_real {
 BFD_RELOC_23_PCREL_S2,
 BFD_RELOC_ALPHA_HINT
diff --git a/dis-asm.h b/dis-asm.h
index 296537a..5b07d7f 100644
--- a/dis-asm.h
+++ b/dis-asm.h
@@ -184,6 +184,9 @@ enum bfd_architecture
 #define bfd_mach_sh50x50
   bfd_arch_alpha,  /* Dec Alpha */
 #define bfd_mach_alpha 1
+#define bfd_mach_alpha_ev4  0x10
+#define bfd_mach_alpha_ev5  0x20
+#define bfd_mach_alpha_ev6  0x30
   bfd_arch_arm,/* Advanced Risc Machines ARM */
 #define bfd_mach_arm_unknown   0
 #define bfd_mach_arm_2 1
diff --git a/disas.c b/disas.c
index 223606c..d208c52 100644
--- a/disas.c
+++ b/disas.c
@@ -205,7 +205,7 @@ void target_disas(FILE *out, target_ulong code, 
target_ulong size, int flags)
 disasm_info.mach = bfd_mach_sh4;
 print_insn = print_insn_sh;
 #elif defined(TARGET_ALPHA)
-disasm_info.mach = bfd_mach_alpha;
+disasm_info.mach = bfd_mach_alpha_ev6;
 print_insn = print_insn_alpha;
 #elif defined(TARGET_CRIS)
 if (flags != 32) {
-- 
1.7.4.4




[Qemu-devel] [PATCH 00/35] Alpha system emulation, v4

2011-05-09 Thread Richard Henderson

Since virtio devices intentionally access memory directly, we
are not actually dependant on the iommu patches in order to 
make progress.  Merely fixing the PCI interrupt setup was 
enough to get the virtio-pci interface working.

We now make it quite a long way into the Debian Lenny install.

At some random point during the install, it hangs.  I assume
we're somehow losing an interrupt or something, but it's very
hard to tell.  The cpu is still running, servicing timer
interrupts, but the userland process is stuck.

I hope to get the vga console working next.  That should allow
me multiple vt's, which should allow me to poke at the install
process from within the VM.

I still havn't gotten any substantive review of the hw/ side
of the patches, which is the part of Qemu that I'm least
familiar with.  Pretty please?



r~



Changes from v3 -> v4

  * Rebased vs mainline (85097db).
  * PCI IDE, VGA devices added;
  * PS2 keyboard device added.
  * PCI interrupt setup fixed.
  * Git submodule and blob updated to current.
- Copyright notices added, as appropritate
- PCI initialization added.
- Very beginnings of an SRM prompt.

Changes from v2 -> v3

  * Emulation target is now CLIPPER instead of SX164.
  * Allow the CPU to halt til the next interrupt.
  * Allow the CPU access to the host clock, and a high-res alarm.
  * Fix gdb single-stepping in the presence of timer interrupts.
  * Fix gdb single-stepping past branches.
  * We now make it all the way into userland.

Richard Henderson (35):
  Export the unassigned_mem read/write functions.
  target-alpha: Disassemble EV6 PALcode instructions.
  pci: Export pci_to_cpu_addr.
  target-alpha: Single-step properly across branches.
  target-alpha: Remove partial support for palcode emulation.
  target-alpha: Enable the alpha-softmmu target.
  target-alpha: Tidy exception constants.
  target-alpha: Rationalize internal processor registers.
  target-alpha: Cleanup MMU modes.
  target-alpha: Fixup translation of PALmode instructions.
  target-alpha: Add IPRs to be used by the emulation PALcode.
  target-alpha: Tidy up arithmetic exceptions.
  target-alpha: Use do_restore_state for arithmetic exceptions.
  target-alpha: Merge HW_REI and HW_RET implementations.
  target-alpha: Implement do_interrupt for system mode.
  target-alpha: Swap shadow registers moving to/from PALmode.
  target-alpha: Add various symbolic constants.
  target-alpha: Use kernel mmu_idx for pal_mode.
  target-alpha: All ISA checks to use TB->FLAGS.
  target-alpha: Disable interrupts properly.
  target-alpha: Implement more CALL_PAL values inline.
  target-alpha: Implement cpu_alpha_handle_mmu_fault for system mode.
  target-alpha: Remap PIO space for 43-bit KSEG for EV6.
  target-alpha: Trap for unassigned and unaligned addresses.
  target-alpha: Include the PCC_OFS in the RPCC return value.
  target-alpha: Use a fixed frequency for the RPCC in system mode.
  target-alpha: Implement TLB flush primitives.
  target-alpha: Add custom PALcode image for CLIPPER emulation.
  target-alpha: Add CLIPPER emulation.
  target-alpha: Implement WAIT IPR.
  target-alpha: Implement HALT IPR.
  target-alpha: Add high-resolution access to wall clock and an alarm.
  target-alpha: Properly select the VGA controler to use.
  target-alpha: Enable PCI IDE
  target-alpha: Add ps2 keyboard.

 .gitmodules   |3 +
 Makefile  |3 +-
 Makefile.target   |4 +-
 alpha-dis.c   |4 -
 configure |9 +-
 cpu-common.h  |7 +
 cpu-exec.c|   33 +-
 default-configs/alpha-softmmu.mak |   11 +
 dis-asm.h |3 +
 disas.c   |2 +-
 exec-all.h|2 +-
 exec.c|   24 +-
 hw/alpha_dp264.c  |  188 +++
 hw/alpha_palcode.c| 1048 -
 hw/alpha_pci.c|  358 +
 hw/alpha_sys.h|   44 ++
 hw/alpha_typhoon.c|  799 
 hw/pci.c  |3 +-
 hw/pci.h  |1 +
 linux-user/main.c |   50 +--
 pc-bios/README|3 +
 pc-bios/palcode-clipper   |  Bin 0 -> 176851 bytes
 roms/qemu-palcode |1 +
 target-alpha/cpu.h|  378 ++
 target-alpha/exec.h   |   12 +-
 target-alpha/helper.c |  589 +
 target-alpha/helper.h |   37 +-
 target-alpha/machine.c|   87 +++
 target-alpha/op_helper.c  |  289 +--
 target-alpha/translate.c  |  836 +
 30 files changed, 2659 insertions(+), 2169 deletions(-)
 create mode 100644 default-configs/alpha-softmmu.mak
 create mode 100644 hw/alpha_dp264

[Qemu-devel] [PATCH 01/35] Export the unassigned_mem read/write functions.

2011-05-09 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cpu-common.h |7 +++
 exec.c   |   12 ++--
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index 6410ccc..6e48917 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -56,6 +56,13 @@ static inline void 
cpu_register_physical_memory(target_phys_addr_t start_addr,
 cpu_register_physical_memory_offset(start_addr, size, phys_offset, 0);
 }
 
+extern CPUReadMemoryFunc unassigned_mem_readb;
+extern CPUReadMemoryFunc unassigned_mem_readw;
+extern CPUReadMemoryFunc unassigned_mem_readl;
+extern CPUWriteMemoryFunc unassigned_mem_writeb;
+extern CPUWriteMemoryFunc unassigned_mem_writew;
+extern CPUWriteMemoryFunc unassigned_mem_writel;
+
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
 ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
 ram_addr_t size, void *host);
diff --git a/exec.c b/exec.c
index 308a86d..0b8ab5b 100644
--- a/exec.c
+++ b/exec.c
@@ -3107,7 +3107,7 @@ ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
 return ram_addr;
 }
 
-static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
+uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
@@ -3118,7 +3118,7 @@ static uint32_t unassigned_mem_readb(void *opaque, 
target_phys_addr_t addr)
 return 0;
 }
 
-static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
+uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
@@ -3129,7 +3129,7 @@ static uint32_t unassigned_mem_readw(void *opaque, 
target_phys_addr_t addr)
 return 0;
 }
 
-static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
+uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
@@ -3140,7 +3140,7 @@ static uint32_t unassigned_mem_readl(void *opaque, 
target_phys_addr_t addr)
 return 0;
 }
 
-static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
@@ -3150,7 +3150,7 @@ static void unassigned_mem_writeb(void *opaque, 
target_phys_addr_t addr, uint32_
 #endif
 }
 
-static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
@@ -3160,7 +3160,7 @@ static void unassigned_mem_writew(void *opaque, 
target_phys_addr_t addr, uint32_
 #endif
 }
 
-static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef DEBUG_UNASSIGNED
 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
-- 
1.7.4.4




Re: [Qemu-devel] [RFC] live snapshot, live merge, live block migration

2011-05-09 Thread Dor Laor

On 05/09/2011 06:23 PM, Anthony Liguori wrote:

On 05/09/2011 08:40 AM, Dor Laor wrote:

No patch here (sorry) but collection of thoughts about these features
and their potential building blocks. Please review (also on
http://wiki.qemu.org/Features/LiveBlockMigration)

Future qemu is expected to support these features (some already
implemented):

* Live block copy

Ability to copy 1+ virtual disk from the source backing file/block
device to a new target that is accessible by the host. The copy
supposed to be executed while the VM runs in a transparent way.

Status: code exists (by Marcelo) today in qemu but needs refactoring
due to a race condition at the end of the copy operation. We agreed
that a re-implementation of the copy operation should take place
that makes sure the image is completely mirrored until management
decides what copy to keep.


Live block copy is growing on me. It can actually be used (with an
intermediate network storage) to do live block migration.


I'm not sure that we can relay on such storage. While it looks that 
anyway can get such temporal storage, it makes failure cases complex, it 
will need additional locking, security permissions, etc.


That said, the main gap is the block copy protocol and using qemu as 
iScsi target/initiator might be a good solution.






* Live snapshots and live snapshot merge

Live snapshot is already incorporated (by Jes) in qemu (still need
qemu-agent work to freeze the guest FS).


Live snapshot is unfortunately not really "live". It runs a lot of
operations synchronously which will cause the guest to incur downtime.

We really need to refactor it to truly be live.


Well live migration is not really live too.
It can be thought as implementation details and improved later on.




* Copy on read (image streaming)
Ability to start guest execution while the parent image reside
remotely and each block access is replicated to a local copy (image
format snapshot)

It should be nice to have a general mechanism that will be used for
all image formats. What about the protocol to access these blocks
over the net? We can reuse existing ones (nbd/iscsi).


I think the image format is really the best place to have this logic. Of
course, if we have live snapshot merge, we could use a temporary
QED/QCOW2 file and then merge afterwards.


* Using external dirty block bitmap

FVD has an option to use external dirty block bitmap file in
addition to the regular mapping/data files.

We can consider using it for live block migration and live merge too.
It can also allow additional usages of 3rd party tools to calculate
diffs between the snapshots.
There is a big down side thought since it will make management
complicated and there is the risky of the image and its bitmap file
get out of sync. It's much better choice to have qemu-img tool to be
the single interface to the dirty block bitmap data.


Does the dirty block bitmap need to exist outside of QEMU?

IOW, if it goes away after a guest shuts down, is that problematic?


I admit I didn't give it enough thought, I think that sharing the code 
w/ qemu-img should be enough for us. If we have a live block operation 
and suddenly the guest shuts down in the middle we need to finish the 
block copy.




I think it potentially greatly simplifies the problem which makes it
appealing from my perspective.

Regards,

Anthony Liguori






Re: [Qemu-devel] [RFC 18/28] target-xtensa: implement exceptions

2011-05-09 Thread Richard Henderson
On 05/09/2011 12:38 PM, Max Filippov wrote:
> do I understand it right that if I use tb->flags or mem_index to make
> decisions during translation, then I must issue exit_tb on
> instructions that can change state they reflect?

Yes.

Quite often it's some sort of branch instruction anyway, such as
return-from-interrupt changing from kernel mode back to user mode.
However, there are some non-branch instructions that may require
the TB to end, such as TLB flushes.


r~



Re: [Qemu-devel] [PATCH 5/7] PPC: Implement e500 (FSL) MMU

2011-05-09 Thread Scott Wood
On Mon, 9 May 2011 21:36:12 +0200
Alexander Graf  wrote:

> 
> On 09.05.2011, at 21:27, Scott Wood wrote:
> 
> > On Sat, 7 May 2011 23:36:29 +0200
> > Alexander Graf  wrote:
> > 
> >> On 07.05.2011, at 00:25, Scott Wood wrote:
>  +void helper_booke206_tlbsx(target_ulong address_hi, target_ulong 
>  address_lo)
> >>> 
> >>> What is address_hi?
> >>> 
> >>> From gen_tlbsx_booke206() it looks like these two arguments correspond to
> >>> the two operands, so shouldn't they be added together?  I only see
> >>> address_lo used.
> >> 
> >> Yup. According to the e500 spec:
> >> 
> >>  Note that rA = 0 is the preferred form for tlbsx and that some Freescale 
> >> implementations, such as the e500, take an illegal instruction exception 
> >> program interrupt if rA!=0.
> >> 
> >> So I figured that we're architecturally close enough if we just ignore it 
> >> for now :).
> > 
> > Architecturally, ignoring it and taking a trap are significantly
> > different. :-)
> > 
> > In practice it won't matter much, but it seems simple to handle it (why
> > handle it in tlbivax but not here?), especially if this is to be general
> > book3e code rather than e500.  I'm still confused about the "address_hi/lo"
> > naming.
> 
> So what would you prefer? Just do whatever the 2.06 spec says and ignore e500 
> specifics? :) Or always do what the e500 spec says?

Do what the architecture says.  I doubt any software is going to be worse
off if this instruction form succeeds rather than traps -- if such a
situation actually turns up, we can deal with it then.

-Scott




Re: [Qemu-devel] [RFC 18/28] target-xtensa: implement exceptions

2011-05-09 Thread Max Filippov
> > This is a case where you almost certainly want to check this 
> > condition inside QEMU and translate the opcode differently.
> > 
> > See cpu_get_tb_cpu_state, which sets bits in *flags.  These
> > flags can then be checked in tb->flags while translating.
> > At which point you'd avoid all the conditionalization on
> > the value in PS here in check_privilege and merely issue
> > the exception_cause.
> > 
> > The ARM port is a good example for testing these sorts of bits.
> 
> Actually, while the tb flags are useful, privileged instructions
> are usually checked by testing mmu_index, since we already have
> to generate different code for the TB based on which TLB entry we
> need to access.

Richard,
do I understand it right that if I use tb->flags or mem_index to make decisions 
during translation, then I must issue exit_tb on instructions that can change 
state they reflect?

Thanks.
-- Max



Re: [Qemu-devel] [PATCH 5/7] PPC: Implement e500 (FSL) MMU

2011-05-09 Thread Alexander Graf

On 09.05.2011, at 21:27, Scott Wood wrote:

> On Sat, 7 May 2011 23:36:29 +0200
> Alexander Graf  wrote:
> 
>> On 07.05.2011, at 00:25, Scott Wood wrote:
 +void helper_booke206_tlbsx(target_ulong address_hi, target_ulong 
 address_lo)
>>> 
>>> What is address_hi?
>>> 
>>> From gen_tlbsx_booke206() it looks like these two arguments correspond to
>>> the two operands, so shouldn't they be added together?  I only see
>>> address_lo used.
>> 
>> Yup. According to the e500 spec:
>> 
>>  Note that rA = 0 is the preferred form for tlbsx and that some Freescale 
>> implementations, such as the e500, take an illegal instruction exception 
>> program interrupt if rA!=0.
>> 
>> So I figured that we're architecturally close enough if we just ignore it 
>> for now :).
> 
> Architecturally, ignoring it and taking a trap are significantly
> different. :-)
> 
> In practice it won't matter much, but it seems simple to handle it (why
> handle it in tlbivax but not here?), especially if this is to be general
> book3e code rather than e500.  I'm still confused about the "address_hi/lo"
> naming.

So what would you prefer? Just do whatever the 2.06 spec says and ignore e500 
specifics? :) Or always do what the e500 spec says?


Alex




Re: [Qemu-devel] [PATCH 5/7] PPC: Implement e500 (FSL) MMU

2011-05-09 Thread Scott Wood
On Sat, 7 May 2011 23:36:29 +0200
Alexander Graf  wrote:

> On 07.05.2011, at 00:25, Scott Wood wrote:
> >> +void helper_booke206_tlbsx(target_ulong address_hi, target_ulong 
> >> address_lo)
> > 
> > What is address_hi?
> > 
> > From gen_tlbsx_booke206() it looks like these two arguments correspond to
> > the two operands, so shouldn't they be added together?  I only see
> > address_lo used.
> 
> Yup. According to the e500 spec:
> 
>   Note that rA = 0 is the preferred form for tlbsx and that some Freescale 
> implementations, such as the e500, take an illegal instruction exception 
> program interrupt if rA!=0.
> 
> So I figured that we're architecturally close enough if we just ignore it for 
> now :).

Architecturally, ignoring it and taking a trap are significantly
different. :-)

In practice it won't matter much, but it seems simple to handle it (why
handle it in tlbivax but not here?), especially if this is to be general
book3e code rather than e500.  I'm still confused about the "address_hi/lo"
naming.

-Scott




[Qemu-devel] Hi

2011-05-09 Thread silmara
how are you?
i bought an iphone from this website, and received it, very amazing, they also 
sell blackberry.conon camera,laptop.tv and so on.the price is much lower.

Web :   eorol.com

2:43:24




Re: [Qemu-devel] [PATCH] target-lm32: Remove unused local variables

2011-05-09 Thread Michael Walle
Am Samstag 07 Mai 2011, 22:49:33 schrieb Stefan Weil:
> cppcheck report:
> target-lm32/translate.c:587: style:
> Variable 't0' is assigned a value that is never used
> target-lm32/translate.c:588: style:
> Variable 'l1' is assigned a value that is never used
> 
> Remove both variables. Please check whether that is the correct solution.
> 
> Cc: Michael Walle 
> Cc: Edgar E. Iglesias 
> Signed-off-by: Stefan Weil 

Leftovers from ecbe1de823 therefore:

Acked-by: Michael Walle 

> ---
>  target-lm32/translate.c |6 --
>  1 files changed, 0 insertions(+), 6 deletions(-)
> 
> diff --git a/target-lm32/translate.c b/target-lm32/translate.c
> index bcd52fe..eb21158 100644
> --- a/target-lm32/translate.c
> +++ b/target-lm32/translate.c
> @@ -584,9 +584,6 @@ static void dec_orhi(DisasContext *dc)
> 
>  static void dec_scall(DisasContext *dc)
>  {
> -TCGv t0;
> -int l1;
> -
>  if (dc->imm5 == 7) {
>  LOG_DIS("scall\n");
>  } else if (dc->imm5 == 2) {
> @@ -595,9 +592,6 @@ static void dec_scall(DisasContext *dc)
>  cpu_abort(dc->env, "invalid opcode\n");
>  }
> 
> -t0 = tcg_temp_new();
> -l1 = gen_new_label();
> -
>  if (dc->imm5 == 7) {
>  tcg_gen_movi_tl(cpu_pc, dc->pc);
>  t_gen_raise_exception(dc, EXCP_SYSTEMCALL);



Re: [Qemu-devel] [PULL] usb: build fixes.

2011-05-09 Thread Anthony Liguori

On 05/09/2011 09:25 AM, Gerd Hoffmann wrote:

On 05/09/11 14:50, Peter Maydell wrote:

On 9 May 2011 14:11, Gerd Hoffmann wrote:

Here are the fixes.

pleae pull,



Stefan Weil (1):
usb-linux: Add missing break statement


The commit comment for this change looks like it still
includes the remark:

# Please check whether adding a break statement is the correct
# solution for this warning.


Zapped, pushed usb.9.pull branch with the rewritten comment.\


Pulled.  Thanks.

Regards,

Anthony Liguori



cheers,
Gerd







[Qemu-devel] [PULL] Xen HVM support

2011-05-09 Thread Alexander Graf
Hi Anthony,

These are Anthony's patches for Xen HVM support, nicely signed off,
rebased to fit today's HEAD and compile tested.

Please pull.


Alex

The following changes since commit 85097db6956bc86e2377b63a8309cb8b24d54139:
  Richard Henderson (1):
irq: Privatize CPU_INTERRUPT_NMI.

are available in the git repository at:

  git://repo.or.cz/qemu/agraf.git xen-next

Anthony PERARD (16):
  Introduce -machine command option.
  machine, Add default_machine_opts to QEMUMachine.
  xen: Replace some tab-indents with spaces (clean-up).
  xen: Make Xen build once.
  xen: Support new libxc calls from xen unstable.
  xen: Add initialisation of Xen
  pc_memory_init: Move memory calculation to the caller.
  xen: Add xenfv machine
  pc, Disable vmport initialisation with Xen.
  piix_pci: Introduces Xen specific call for irq.
  xen: Introduce Xen Interrupt Controller
  Introduce qemu_put_ram_ptr
  configure: Always use 64bits target physical addresses with xen enabled.
  vl.c: Introduce getter for shutdown_requested and reset_requested.
  xen: Set running state in xenstore.
  xen: Add Xen hypercall for sleep state in the cmos_s3 callback.

Arun Sharma (1):
  xen: Initialize event channels and io rings

John Baboval (2):
  xen: Adds a cap to the number of map cache entries.
  pci: Use of qemu_put_ram_ptr in pci_add_option_rom.

Jun Nakajima (1):
  xen: Introduce the Xen mapcache

 Makefile.target  |   14 +-
 arch_init.c  |5 +
 arch_init.h  |1 +
 configure|   71 ++-
 cpu-common.h |1 +
 exec.c   |   86 +++-
 hw/boards.h  |1 +
 hw/pc.c  |   28 +--
 hw/pc.h  |   11 +-
 hw/pc_piix.c |   71 ++-
 hw/pci.c |2 +
 hw/piix_pci.c|   49 -
 hw/xen.h |   41 
 hw/xen_backend.c |  421 +++
 hw/xen_backend.h |6 +-
 hw/xen_common.h  |  106 --
 hw/xen_disk.c|  496 ++---
 hw/xen_domainbuild.c |3 +-
 hw/xen_machine_pv.c  |1 +
 hw/xen_nic.c |  265 --
 qemu-config.c|   14 ++
 qemu-options.hx  |   10 +
 sysemu.h |2 +
 trace-events |   13 +
 vl.c |  136 ++-
 xen-all.c|  605 ++
 xen-mapcache-stub.c  |   44 
 xen-mapcache.c   |  375 +++
 xen-mapcache.h   |   37 +++
 xen-stub.c   |   41 
 30 files changed, 2343 insertions(+), 613 deletions(-)
 create mode 100644 xen-all.c
 create mode 100644 xen-mapcache-stub.c
 create mode 100644 xen-mapcache.c
 create mode 100644 xen-mapcache.h
 create mode 100644 xen-stub.c




Re: [Qemu-devel] [PATCH V4 00/10] Qemu Trusted Platform Module (TPM) integration

2011-05-09 Thread Stefan Berger

On 05/09/2011 10:21 AM, Serge E. Hallyn wrote:

Quoting Stefan Berger (stef...@linux.vnet.ibm.com):

The following series of patches adds a TPM (Trusted Platform Module)
TIS (TPM Interface Spec) interface to Qemu and with that provides
means to access a backend implementing the actual TPM functionality.
This frontend enables for example Linux's TPM TIS (tpm_tis) driver.

I am also posting the implementation of a backend implementation that is based
on a library (libtpms) providing TPM functionality. This library is currently
undergoing further testing but is now available via Fedora Rawhide:

http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/x86_64/os/Packages/libtpms-0.5.1-5.x86_64.rpm
http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/x86_64/os/Packages/libtpms-devel-0.5.1-5.x86_64.rpm

Hi,

where is the source for these?


http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/source/SRPMS/libtpms-0.5.1-5.src.rpm

   Stefan




[Qemu-devel] [RFC PATCH] virtio-balloon: Re-register memory as balloon deflates

2011-05-09 Thread Alex Williamson
When we balloon a guest, we currently use madvise to let the
underlying VM know our intentions for those pages.  As the balloon
inflates (pages given back to the host), MMU notifiers in the host
let us detach the pages.  When we deflate the balloon and retrieve
pages back from the host, I'm not sure how we inform drivers about
this.

It seems like we need something like below to re-map these pages
in qemu.  Ideally we might also map them to IO_MEM_UNASSIGNED when
we madvise DONTNEED, but that would probably blow-up kvm's slot
map.  With something like this, I can support ballooning with
vfio assigned devices.  An MMU notifier in the vfio kernel module
unmaps pages as they get marked DONTNEED, and this allows us to
re-map them as they get marked WILLNEED.  If there's already
something in place to handle this, please send a pointer.  Thanks,

Alex

Signed-off-by: Alex Williamson 
---

 hw/virtio-balloon.c |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 70a8710..96b7d7b 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -108,16 +108,20 @@ static void virtio_balloon_handle_output(VirtIODevice 
*vdev, VirtQueue *vq)
 uint32_t pfn;
 
 while (iov_to_buf(elem.out_sg, elem.out_num, &pfn, offset, 4) == 4) {
-ram_addr_t pa;
+target_phys_addr_t pa;
 ram_addr_t addr;
 
-pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT;
+pa = (target_phys_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT;
 offset += 4;
 
 addr = cpu_get_physical_page_desc(pa);
 if ((addr & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
 continue;
 
+if (vq == s->dvq) {
+cpu_register_physical_memory(pa, TARGET_PAGE_SIZE, addr);
+}
+
 /* Using qemu_get_ram_ptr is bending the rules a bit, but
should be OK because we only want a single page.  */
 balloon_page(qemu_get_ram_ptr(addr), !!(vq == s->dvq));




Re: [Qemu-devel] Allow ARMv7M to be started without a kernel

2011-05-09 Thread Peter Maydell
On 9 May 2011 16:11, Alexander Graf  wrote:
[about -kernel, unless I've got confused]
> The issue is that this is not how it works on real hardware. Grub won't just
> load a vmlinux file and boot it. I'm not even sure how much exactly the
> early entry code handles in Linux before it jumps to the ELF entry point.
>
> Either way, if you get something rolling that also ensures that it fails
> when it's an ELF file that's not Linux, I'd be very open to it :).

If we do that we need to document what the new way of doing "just load
and jump to the entry point of my not-a-linux-kernel ELF image" is; at
the moment for ARM that use case is supported by -kernel (the code
specifically handles ELF images as not-kernels), so changing that would
be a back-compatibility break...

(maybe this should be '-bios' but that seems a bit of an obscure name.)

-- PMM



[Qemu-devel] [RFC] Specification for qcow2 version 3

2011-05-09 Thread Kevin Wolf
Hi all,

this is a first draft for what I think could be added when we increase qcow2's
version number to 3. This includes points that have been made by several people
over the past few months. We're probably not going to implement this next week,
but I think it's important to get discussions started early, so here it is.

I hope the intentions of each change are clear, but feel free to ask if they
aren't. Also when I wasn't if/how exactly to specify things, I left a TODO in
some places.

Kevin
---
 docs/specs/qcow2.txt |   98 +++---
 1 files changed, 77 insertions(+), 21 deletions(-)

diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 8fc3cb2..adf5616 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -18,7 +18,7 @@ The first cluster of a qcow2 image contains the file header:
 QCOW magic string ("QFI\xfb")
 
   4 -  7:   version
-Version number (only valid value is 2)
+Version number (valid values are 2 and 3)
 
   8 - 15:   backing_file_offset
 Offset into the image file at which the backing file name
@@ -67,6 +67,42 @@ The first cluster of a qcow2 image contains the file header:
 Offset into the image file at which the snapshot table
 starts. Must be aligned to a cluster boundary.
 
+If the version is 3 or higher, the header has the following additional fields.
+For version 2, the values are assumed to be zero, unless specified otherwise
+in the description of a field.
+
+ 72 - 75:   incompatible_features
+Bitmask of incompatible features. An implementation must
+fail to open an image if an unknown bit is set.
+
+Bit 0:  The reference counts in the image file may be
+inaccurate. Implementations must check/rebuild
+them if they rely on them.
+
+Bit 1:  Enable subclusters. This affects the L2 table
+format.
+
+Bits 2-31:  Reserved (set to 0)
+
+ 76 - 79:   compatible_features
+Bitmask of compatible features. An implementation can
+safely ignore any unknown bits that are set.
+No compatible feature bits are defined yet.
+
+ 80 - 83:   autoclear_features
+Bitmask of auto-clear features. An implementation may only
+write to an image with unknown auto-clear features if it
+clears the respective bits from this field first.
+No auto-clear feature bits are defined yet.
+
+ 84 - 87:   refcount_bits
+Size of a reference count block entry in bits. For version 
2
+images, the size is always 16 bits.
+[ TODO: Define order in sub-byte sizes ]
+
+[ TODO: Add per-L2-table dirty flag to L1? ]
+[ TODO: Add per-refcount-block full flag to refcount table? ]
+
 Directly after the image header, optional sections called header extensions can
 be stored. Each extension has a structure like the following:
 
@@ -87,6 +123,8 @@ The remaining space between the end of the header extension 
area and the end of
 the first cluster can be used for other data. Usually, the backing file name is
 stored there.
 
+[ TODO Feature name table? ]
+
 
 == Host cluster management ==
 
@@ -138,7 +176,8 @@ guest clusters to host clusters. They are called L1 and L2 
table.
 
 The L1 table has a variable size (stored in the header) and may use multiple
 clusters, however it must be contiguous in the image file. L2 tables are
-exactly one cluster in size.
+exactly one cluster in size if subclusters are disabled, and two clusters if
+they are enabled.
 
 Given a offset into the virtual disk, the offset into the image file can be
 obtained as follows:
@@ -168,9 +207,32 @@ L1 table entry:
 refcount is exactly one. This information is only accurate
 in the active L1 table.
 
-L2 table entry (for normal clusters):
+L2 table entry:
 
-Bit  0 -  8:Reserved (set to 0)
+Bit  0 -  61:   Cluster descriptor
+
+  62:   0 for standard clusters
+1 for compressed clusters
+
+  63:   0 for a cluster that is unused or requires COW, 1 if its
+refcount is exactly one. This information is only accurate
+in L2 tables that are reachable from the the active L1
+table.
+
+64 - 127:   If subclusters are enabled, this contains a bitmask that
+describes the allocation status of all 64 subclusters. The
+first subcluster is represented by the LSB. A 0 bit means
+that the subcluster is unallocated.
+
+Standard Cluster

[Qemu-devel] [PATCH] ahci: Fix crashes on duplicate BH registration

2011-05-09 Thread Jan Kiszka
If ahci_dma_set_inactive is called a while there is still a pending BH
from a previous run, we will crash on the second run of
ahci_check_cmd_bh as it overwrites AHCIDevice::check_bh. Avoid this
broken and redundant duplicate registration.

Signed-off-by: Jan Kiszka 
---
 hw/ide/ahci.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index c6e0c77..744d19d 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1066,9 +1066,11 @@ static int ahci_dma_set_inactive(IDEDMA *dma)
 
 ad->dma_cb = NULL;
 
-/* maybe we still have something to process, check later */
-ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
-qemu_bh_schedule(ad->check_bh);
+if (!ad->check_bh) {
+/* maybe we still have something to process, check later */
+ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
+qemu_bh_schedule(ad->check_bh);
+}
 
 return 0;
 }
-- 
1.7.1



[Qemu-devel] [PATCH v2 2/2] qed: Periodically flush and clear need check bit

2011-05-09 Thread Stefan Hajnoczi
One strategy to limit the startup delay of consistency check when
opening image files is to ensure that the file is marked dirty for as
little time as possible.

QED currently marks the image dirty when the first allocating write
request is issued and clears the dirty bit again when the image is
cleanly closed.  In practice that means the image is marked dirty for
most of a guest's lifetime and prone to being in a dirty state upon
crash or power failure.

It is safe to clear the dirty bit after all allocating write requests
have completed and a flush has been performed.  This patch adds a timer
after the last allocating write request completes.  When the timer fires
it will flush and then clear the dirty bit.  The timer is set to 5
seconds and is cancelled upon arrival of a new allocating write request.

Signed-off-by: Stefan Hajnoczi 
---
 block/qed.c  |  104 -
 block/qed.h  |7 
 trace-events |3 ++
 3 files changed, 112 insertions(+), 2 deletions(-)

diff --git a/block/qed.c b/block/qed.c
index c8c5930..d8d6ea2 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -12,6 +12,7 @@
  *
  */
 
+#include "qemu-timer.h"
 #include "trace.h"
 #include "qed.h"
 #include "qerror.h"
@@ -291,6 +292,88 @@ static CachedL2Table *qed_new_l2_table(BDRVQEDState *s)
 
 static void qed_aio_next_io(void *opaque, int ret);
 
+static void qed_plug_allocating_write_reqs(BDRVQEDState *s)
+{
+assert(!s->allocating_write_reqs_plugged);
+
+s->allocating_write_reqs_plugged = true;
+}
+
+static void qed_unplug_allocating_write_reqs(BDRVQEDState *s)
+{
+QEDAIOCB *acb;
+
+assert(s->allocating_write_reqs_plugged);
+
+s->allocating_write_reqs_plugged = false;
+
+acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
+if (acb) {
+qed_aio_next_io(acb, 0);
+}
+}
+
+static void qed_finish_clear_need_check(void *opaque, int ret)
+{
+/* Do nothing */
+}
+
+static void qed_flush_after_clear_need_check(void *opaque, int ret)
+{
+BDRVQEDState *s = opaque;
+
+bdrv_aio_flush(s->bs, qed_finish_clear_need_check, s);
+
+/* No need to wait until flush completes */
+qed_unplug_allocating_write_reqs(s);
+}
+
+static void qed_clear_need_check(void *opaque, int ret)
+{
+BDRVQEDState *s = opaque;
+
+if (ret) {
+qed_unplug_allocating_write_reqs(s);
+return;
+}
+
+s->header.features &= ~QED_F_NEED_CHECK;
+qed_write_header(s, qed_flush_after_clear_need_check, s);
+}
+
+static void qed_need_check_timer_cb(void *opaque)
+{
+BDRVQEDState *s = opaque;
+
+/* The timer should only fire when allocating writes have drained */
+assert(!QSIMPLEQ_FIRST(&s->allocating_write_reqs));
+
+trace_qed_need_check_timer_cb(s);
+
+qed_plug_allocating_write_reqs(s);
+
+/* Ensure writes are on disk before clearing flag */
+bdrv_aio_flush(s->bs, qed_clear_need_check, s);
+}
+
+static void qed_start_need_check_timer(BDRVQEDState *s)
+{
+trace_qed_start_need_check_timer(s);
+
+/* Use vm_clock so we don't alter the image file while suspended for
+ * migration.
+ */
+qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
+   get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
+}
+
+/* It's okay to call this multiple times or when no timer is started */
+static void qed_cancel_need_check_timer(BDRVQEDState *s)
+{
+trace_qed_cancel_need_check_timer(s);
+qemu_del_timer(s->need_check_timer);
+}
+
 static int bdrv_qed_open(BlockDriverState *bs, int flags)
 {
 BDRVQEDState *s = bs->opaque;
@@ -406,7 +489,10 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
 BdrvCheckResult result = {0};
 
 ret = qed_check(s, &result, true);
-if (!ret && !result.corruptions && !result.check_errors) {
+if (ret) {
+goto out;
+}
+if (!result.corruptions && !result.check_errors) {
 /* Ensure fixes reach storage before clearing check bit */
 bdrv_flush(s->bs);
 
@@ -416,6 +502,9 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
 }
 }
 
+s->need_check_timer = qemu_new_timer_ns(vm_clock,
+qed_need_check_timer_cb, s);
+
 out:
 if (ret) {
 qed_free_l2_cache(&s->l2_cache);
@@ -428,6 +517,9 @@ static void bdrv_qed_close(BlockDriverState *bs)
 {
 BDRVQEDState *s = bs->opaque;
 
+qed_cancel_need_check_timer(s);
+qemu_free_timer(s->need_check_timer);
+
 /* Ensure writes reach stable storage */
 bdrv_flush(bs->file);
 
@@ -809,6 +901,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
 acb = QSIMPLEQ_FIRST(&s->allocating_write_reqs);
 if (acb) {
 qed_aio_next_io(acb, 0);
+} else if (s->header.features & QED_F_NEED_CHECK) {
+qed_start_need_check_timer(s);
 }
 }
 }
@@ -1014,11 +1108,17 @@ static void qed_aio

[Qemu-devel] [PATCH v2 0/2] qed: Periodically flush and clear need check bit

2011-05-09 Thread Stefan Hajnoczi
This patch marks QED images as clean periodically when it is safe to do so.
This reduces the chance of having to perform a consistency check at startup.
Previously we left the image dirty even when it was consistent, therefore
risking an unnecessary consistency check after crash.

The first patch stubs out qemu-timer.c functions for qemu-tool.c, which is
needed since block drivers get built into qemu-img and friends.  In the long
run having timers in qemu-tool too would be good, but for now they are not
critical and the stub implementation works.




[Qemu-devel] [PATCH v2 1/2] qemu-tool: Stub out qemu-timer functions

2011-05-09 Thread Stefan Hajnoczi
Block drivers may use timers for flushing metadata to disk or
reconnecting to a network drive.  Stub out the following functions in
qemu-tool.c:

QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, int scale,
 QEMUTimerCB *cb, void *opaque)
void qemu_free_timer(QEMUTimer *ts)
void qemu_del_timer(QEMUTimer *ts)
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
int64_t qemu_get_clock_ns(QEMUClock *clock)

They will result in timers never firing when linked against qemu-tool.o.

Signed-off-by: Stefan Hajnoczi 
---
 qemu-tool.c |   25 +
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/qemu-tool.c b/qemu-tool.c
index f4a6ad0..41e5c41 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -19,6 +19,7 @@
 #include 
 
 QEMUClock *rt_clock;
+QEMUClock *vm_clock;
 
 FILE *logfile;
 
@@ -71,3 +72,27 @@ int qemu_set_fd_handler2(int fd,
 void qemu_notify_event(void)
 {
 }
+
+QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
+  QEMUTimerCB *cb, void *opaque)
+{
+return qemu_malloc(1);
+}
+
+void qemu_free_timer(QEMUTimer *ts)
+{
+qemu_free(ts);
+}
+
+void qemu_del_timer(QEMUTimer *ts)
+{
+}
+
+void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
+{
+}
+
+int64_t qemu_get_clock_ns(QEMUClock *clock)
+{
+return 0;
+}
-- 
1.7.4.4




[Qemu-devel] [PATCH replacement 1/1] Add documentation for qemu_progress_{init, print}()

2011-05-09 Thread Jes . Sorensen
From: Jes Sorensen 

Signed-off-by: Jes Sorensen 
---
 qemu-common.h   |2 +-
 qemu-progress.c |   24 +---
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/qemu-common.h b/qemu-common.h
index f9f705d..78b7a4a 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -346,7 +346,7 @@ void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, 
size_t count,
 
 void qemu_progress_init(int enabled, float min_skip);
 void qemu_progress_end(void);
-void qemu_progress_print(float percent, int max);
+void qemu_progress_print(float delta, int max);
 
 #define QEMU_FILE_TYPE_BIOS   0
 #define QEMU_FILE_TYPE_KEYMAP 1
diff --git a/qemu-progress.c b/qemu-progress.c
index a4894c0..8ebe8ef 100644
--- a/qemu-progress.c
+++ b/qemu-progress.c
@@ -96,6 +96,13 @@ static void progress_dummy_init(void)
 state.end = progress_dummy_end;
 }
 
+/*
+ * Initialize progress reporting.
+ * If @enabled is false, actual reporting is suppressed.  The user can
+ * still trigger a report by sending a SIGUSR1.
+ * Reports are also suppressed unless we've had at least @min_skip
+ * percent progress since the last report.
+ */
 void qemu_progress_init(int enabled, float min_skip)
 {
 state.min_skip = min_skip;
@@ -111,14 +118,25 @@ void qemu_progress_end(void)
 state.end();
 }
 
-void qemu_progress_print(float percent, int max)
+/*
+ * Report progress.
+ * @delta is how much progress we made.
+ * If @max is zero, @delta is an absolut value of the total job done.
+ * Else, @delta is a progress delta since the last call, as a fraction
+ * of @max.  I.e. the delta is @delta * @max / 100. This allows
+ * relative accounting of functions which may be a different fraction of
+ * the full job, depending on the context they are called in. I.e.
+ * a function might be considered 40% of the full job if used from
+ * bdrv_img_create() but only 20% if called from img_convert().
+ */
+void qemu_progress_print(float delta, int max)
 {
 float current;
 
 if (max == 0) {
-current = percent;
+current = delta;
 } else {
-current = state.current + percent / 100 * max;
+current = state.current + delta / 100 * max;
 }
 if (current > 100) {
 current = 100;
-- 
1.7.4.4




Re: [Qemu-devel] [RFC] live snapshot, live merge, live block migration

2011-05-09 Thread Anthony Liguori

On 05/09/2011 08:40 AM, Dor Laor wrote:

No patch here (sorry) but collection of thoughts about these features
and their potential building blocks. Please review (also on
http://wiki.qemu.org/Features/LiveBlockMigration)

Future qemu is expected to support these features (some already
implemented):

* Live block copy

Ability to copy 1+ virtual disk from the source backing file/block
device to a new target that is accessible by the host. The copy
supposed to be executed while the VM runs in a transparent way.

Status: code exists (by Marcelo) today in qemu but needs refactoring
due to a race condition at the end of the copy operation. We agreed
that a re-implementation of the copy operation should take place
that makes sure the image is completely mirrored until management
decides what copy to keep.


Live block copy is growing on me.  It can actually be used (with an 
intermediate network storage) to do live block migration.




* Live snapshots and live snapshot merge

Live snapshot is already incorporated (by Jes) in qemu (still need
qemu-agent work to freeze the guest FS).


Live snapshot is unfortunately not really "live".  It runs a lot of 
operations synchronously which will cause the guest to incur downtime.


We really need to refactor it to truly be live.



* Copy on read (image streaming)
Ability to start guest execution while the parent image reside
remotely and each block access is replicated to a local copy (image
format snapshot)

It should be nice to have a general mechanism that will be used for
all image formats. What about the protocol to access these blocks
over the net? We can reuse existing ones (nbd/iscsi).


I think the image format is really the best place to have this logic. 
Of course, if we have live snapshot merge, we could use a temporary 
QED/QCOW2 file and then merge afterwards.



* Using external dirty block bitmap

FVD has an option to use external dirty block bitmap file in
addition to the regular mapping/data files.

We can consider using it for live block migration and live merge too.
It can also allow additional usages of 3rd party tools to calculate
diffs between the snapshots.
There is a big down side thought since it will make management
complicated and there is the risky of the image and its bitmap file
get out of sync. It's much better choice to have qemu-img tool to be
the single interface to the dirty block bitmap data.


Does the dirty block bitmap need to exist outside of QEMU?

IOW, if it goes away after a guest shuts down, is that problematic?

I think it potentially greatly simplifies the problem which makes it 
appealing from my perspective.


Regards,

Anthony Liguori



Re: [Qemu-devel] ahci: crash after duplicate bh registration

2011-05-09 Thread Jan Kiszka
On 2011-05-09 16:31, Alexander Graf wrote:
> On 05/09/2011 04:26 PM, Kevin Wolf wrote:
>> Am 09.05.2011 16:12, schrieb Alexander Graf:
>>> On 05/08/2011 09:10 PM, Jan Kiszka wrote:
 Hi Alex,

 I've seen crashes caused by ahci_check_cmd_bh unregistering a NULL bh.
 It looks like ahci_dma_set_inactive can a called while there is already
 a bh hanging around. Patch below cures the issue, but I have no clue if
 such an invocation order is valid at all.
>>> It's certainly guest triggerable, so yes, let's check here.
>>>
>>> Acked-by: Alexander Graf
>> Yes, the change makes sense to me. Please resend this as a proper patch,
>> Jan.

Will do.

>>
>> However, I still think Jan's question is valid: Is the AHCI emulation
>> supposed to run multiple DMA requests at once using the core.c
>> functions? I'd find it surprising if this actually worked well.
> 
> Not through the IDE core, no. There it can process a queue of IDE
> commands after each other or do NCQ, but that goes a different code
> patch, can do multiple requests at once though.
> 
> I'm not sure how this got triggered.

Forgot to mention: With a hacked-up q35 series. I may have broken
something there, or it was already broken (there are definitely bugs in
that series), so upstream might not expose the problem at all.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



Re: [Qemu-devel] ahci: crash after duplicate bh registration

2011-05-09 Thread Alexander Graf

On 05/09/2011 04:26 PM, Kevin Wolf wrote:

Am 09.05.2011 16:12, schrieb Alexander Graf:

On 05/08/2011 09:10 PM, Jan Kiszka wrote:

Hi Alex,

I've seen crashes caused by ahci_check_cmd_bh unregistering a NULL bh.
It looks like ahci_dma_set_inactive can a called while there is already
a bh hanging around. Patch below cures the issue, but I have no clue if
such an invocation order is valid at all.

It's certainly guest triggerable, so yes, let's check here.

Acked-by: Alexander Graf

Yes, the change makes sense to me. Please resend this as a proper patch,
Jan.

However, I still think Jan's question is valid: Is the AHCI emulation
supposed to run multiple DMA requests at once using the core.c
functions? I'd find it surprising if this actually worked well.


Not through the IDE core, no. There it can process a queue of IDE 
commands after each other or do NCQ, but that goes a different code 
patch, can do multiple requests at once though.


I'm not sure how this got triggered.


Alex




Re: [Qemu-devel] [PATCH V15 00/18] Xen device model support

2011-05-09 Thread Anthony Liguori

On 05/09/2011 08:58 AM, Alexander Graf wrote:

On 05/05/2011 12:58 PM, anthony.per...@citrix.com wrote:

From: Anthony PERARD

Hi all,

Here is an update on the series that add the support of a Xen HVM
guest to
QEMU.


It doesn't introduce regressions and I really don't want to keep this
patch set hanging more than it should be. If we encounter anything that
needs changes later, we can change them later and as long as the patches
don't affect anything but Xen, I'm perfectly fine with the Xen folks
breaking their own support :).

So from my side this set is:

Acked-by: Alexander Graf 

Anthony, feel like pulling?


Feel like doing a pull request?

I'd prefer if you did that and added your Signed-off-by.

Regards,

Anthony Liguori




Alex






Re: [Qemu-devel] [PULL] usb: build fixes.

2011-05-09 Thread Gerd Hoffmann

On 05/09/11 14:50, Peter Maydell wrote:

On 9 May 2011 14:11, Gerd Hoffmann  wrote:

Here are the fixes.

pleae pull,



Stefan Weil (1):
  usb-linux: Add missing break statement


The commit comment for this change looks like it still
includes the remark:

# Please check whether adding a break statement is the correct
# solution for this warning.


Zapped, pushed usb.9.pull branch with the rewritten comment.

cheers,
  Gerd



Re: [Qemu-devel] ahci: crash after duplicate bh registration

2011-05-09 Thread Kevin Wolf
Am 09.05.2011 16:12, schrieb Alexander Graf:
> On 05/08/2011 09:10 PM, Jan Kiszka wrote:
>> Hi Alex,
>>
>> I've seen crashes caused by ahci_check_cmd_bh unregistering a NULL bh.
>> It looks like ahci_dma_set_inactive can a called while there is already
>> a bh hanging around. Patch below cures the issue, but I have no clue if
>> such an invocation order is valid at all.
> 
> It's certainly guest triggerable, so yes, let's check here.
> 
> Acked-by: Alexander Graf 

Yes, the change makes sense to me. Please resend this as a proper patch,
Jan.

However, I still think Jan's question is valid: Is the AHCI emulation
supposed to run multiple DMA requests at once using the core.c
functions? I'd find it surprising if this actually worked well.

Kevin



Re: [Qemu-devel] [PATCH V4 00/10] Qemu Trusted Platform Module (TPM) integration

2011-05-09 Thread Serge E. Hallyn
Quoting Stefan Berger (stef...@linux.vnet.ibm.com):
> The following series of patches adds a TPM (Trusted Platform Module)
> TIS (TPM Interface Spec) interface to Qemu and with that provides
> means to access a backend implementing the actual TPM functionality.
> This frontend enables for example Linux's TPM TIS (tpm_tis) driver.
> 
> I am also posting the implementation of a backend implementation that is based
> on a library (libtpms) providing TPM functionality. This library is currently
> undergoing further testing but is now available via Fedora Rawhide:
> 
> http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/x86_64/os/Packages/libtpms-0.5.1-5.x86_64.rpm
> http://download.fedora.redhat.com/pub/fedora/linux/development/rawhide/x86_64/os/Packages/libtpms-devel-0.5.1-5.x86_64.rpm

Hi,

where is the source for these?

thanks,
-serge



Re: [Qemu-devel] ahci: crash after duplicate bh registration

2011-05-09 Thread Alexander Graf

On 05/08/2011 09:10 PM, Jan Kiszka wrote:

Hi Alex,

I've seen crashes caused by ahci_check_cmd_bh unregistering a NULL bh.
It looks like ahci_dma_set_inactive can a called while there is already
a bh hanging around. Patch below cures the issue, but I have no clue if
such an invocation order is valid at all.


It's certainly guest triggerable, so yes, let's check here.

Acked-by: Alexander Graf 


Alex


Jan

---

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index e2ed2ad..7870030 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1066,9 +1066,11 @@ static int ahci_dma_set_inactive(IDEDMA *dma)

  ad->dma_cb = NULL;

-/* maybe we still have something to process, check later */
-ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
-qemu_bh_schedule(ad->check_bh);
+if (!ad->check_bh) {
+/* maybe we still have something to process, check later */
+ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
+qemu_bh_schedule(ad->check_bh);
+}

  return 0;
  }






Re: [Qemu-devel] Allow ARMv7M to be started without a kernel

2011-05-09 Thread Alexander Graf

On 05/08/2011 08:25 PM, Rob Landley wrote:

On 05/08/2011 09:10 AM, Andreas Färber wrote:

Am 06.05.2011 um 14:48 schrieb Alexander Graf:


On 06.05.2011, at 01:50, Rob Landley wrote:


On 05/05/2011 06:26 PM, Alexander Graf wrote:

As an aside: I think QEMU should have an option which is "just load
a plain ELF or raw binary, with no funny Linux-kernel-specific
behaviour" rather than overloading -kernel to mean "if it's a raw
image it's Linux and if it's an ELF file it's not".

Traditionally, -bios has been that one. -kernel is more of a real
bootloader replacement, including all the weirdness a bootloader does
:).

Except that neither "qemu-system-x86_64 -bios vmlinux" nor
qemu-system-x86_64 -kernel vmlinux" will load an ELF kernel on x86-64.

The code to do this _exists_ within qemu, it's just not hooked up
consistently on all targets.  We have a universal cross-platform image
format, and we have support in qemu for loading that format, and for
some reason it's only enabled on certain targets.  I've never understood
why...

Unfortunately, booting isn't that easy :). The kernel needs some more
data than just itself and an entry point to properly load. On some
architectures, it requires a device tree (and pointer to it in a
register), it might require page tables / TLB entries to be set up, if
you want -initrd and -append to work you also need to tell the kernel
where to find those.

So while ELF is a nice container for binaries, there are still some
pieces missing to actually make it a kernel loader. But that's what
multiboot was invented for. I haven't seen too much effort going on
around multiboot on non-x86, but it basically fills exactly the gap
you're wondering about. It uses ELF and adds a simple boot protocol
for all the other fancy stuff a kernel needs.

I guess Rob meant something different: -bios does not load ELF files for
all machines (raw neither). For example, for raw-only PReP I had posted
a patch that enables loading ELF firmware like OpenBIOS that you turned
down.

I actually wrote a long reply and then save-as-draft rather than sending
it because it boils down to "I need to do the work myself and send you a
patch".

What I meant was that the build for every Linux architecture produces a
vmlinux file, which it often then packs into another format but on mips
and powerpc the file I feed to -kernel is the elf vmlinux file.
(Doesn't even have to be stripped.)

Which is nice, because when I debug stuff with the -s option I need to
feed the vmlinux file to gdb, so just having to keep track of one of the
suckers is incredibly convenient.  Being able to build 5 architectures
without having to record an arbitrary path to whatever the output file
is called this time is also nice.

Yes, -kernel is linux-specific: so is vmlinux.  Yes -kernel does various
other stuff to boot a linux kernel, but at least half of it is obsolete
things for 2.2 and earlier kernels, as described in the rdev man page.
(And if you want to use such ancient kernels, you can always make a boot
floppy image and use rdev, just just make a disk image with a bootloader
in it from one of the install cds on
http://archive.download.redhat.com/pub/redhat/linux or something.)

Pretty much everything the kernel needs is on the command line these
days, including vga settings and the physical starting address of the
initial ram disk ("ramdisk_start=", see init/do_mounts_rd.c in the
kernel).  On most platforms the one thing it needs is a device tree
pointer (in a register) and then it finds the command line data blob
through that.

I have no interest in GNU/multiboot, and neither does most of the rest
of the Linux community from what I've seen.  The GNU/hurd is welcome to
it, the FSF has nothing to do with Linux.  The people porting device
trees to x86 soo the mechanism will be properly universal (that went
into the 2.6.39 development series, by the way) are not referencing
GNU/multiboot.  I want to teach -kernel to accept a vmlinux file, not
introduce crazy FSF code dependencies, which don't seem to be supported
on any non-x86 platform yet despite being designed with Solaris in mind,
into my build.

What I want to do is actually somewhat straightforward, load_elf() is
already used directly on several platforms like mips_r4k.c, the hard
parts of making it work on x86 are A) properly editing the kernel
command line instead of trying to recreate rdev, B) figuring out where
to splice the kernel command line start address into a vmlinux instead
of a bzImage, and C) starting in the right mode.

C) requires more research, because I have to make sure the entry point
is either doing the 16->32 (or 64) bit startup dance or that it's being
launched in the right mode (which the bios isn't doing), but vmlinux
doesn't need to be decompressed and copied so it's just making sure
we're expecting the right layer of stuff.  Which means reading through
arch/x86/boot to see what the vmlinux->bzImage packaging is adding, I
suppose.


The issue is that this is

Re: [Qemu-devel] [RFC] darwin: work around sigfd

2011-05-09 Thread Alexander Graf

On 05/08/2011 12:10 PM, Andreas Färber wrote:

Alex,

Am 08.05.2011 um 11:15 schrieb Andreas Färber:


Am 05.05.2011 um 15:15 schrieb Alexander Graf:


On 05.05.2011, at 14:56, Paolo Bonzini wrote:


On 05/05/2011 11:36 AM, Alexander Graf wrote:
When running qemu-system on Darwin, the vcpu processes guest code, 
but

I don't get to see anything on the cocoa screen.


Out of curiosity, does it work with iothread?


Seems to work with -nographic, yes. With cocoa it doesn't seem as 
happy :o. It certainly gets a lot further than without.


-nographic has issues with --enable-io-thread, too. It gets further 
than Cocoa though before it bails out.


Actually, I'm still seeing issues with your patch as well. Might be 
multiple independent issues that have cropped up?


In particular I'm observing that AIX on qemu-system-ppc - as reported 
by Kenneth - doesn't reach the point where it tells us the 32-bit CPU 
is incompatible. With your patch it is now possible to exit the QEMU 
process though.


Any ppc64 guests don't even seem to enter OpenBIOS at all, whether 
OpenBIOS/ppc or OpenBIOS/ppc64.


It seems there is a DSI exception when turning on the MMU in OpenBIOS 
(before any serial output occurs). Does that ring a bell with you, 
some pSeries change maybe?


The pSeries changes did some cleanups to the MMU code, yes, but they 
looked pretty much sane to me. Are you running on a ppc64 host? Maybe 
there's some undefined corner case shifting happening :).



Alex




Re: [Qemu-devel] [PATCH V15 00/18] Xen device model support

2011-05-09 Thread Alexander Graf

On 05/05/2011 12:58 PM, anthony.per...@citrix.com wrote:

From: Anthony PERARD

Hi all,

Here is an update on the series that add the support of a Xen HVM guest to
QEMU.


It doesn't introduce regressions and I really don't want to keep this 
patch set hanging more than it should be. If we encounter anything that 
needs changes later, we can change them later and as long as the patches 
don't affect anything but Xen, I'm perfectly fine with the Xen folks 
breaking their own support :).


So from my side this set is:

Acked-by: Alexander Graf 

Anthony, feel like pulling?


Alex




Re: [Qemu-devel] [PATCH] virtio: guard against negative vq notifies

2011-05-09 Thread Stefan Hajnoczi
On Sun, May 8, 2011 at 10:29 PM, Stefan Hajnoczi
 wrote:
> The virtio_queue_notify() function checks that the virtqueue number is
> less than the maximum number of virtqueues.  A signed comparison is used
> but the virtqueue number could be negative if a buggy or malicious guest
> is run.  This results in memory accesses outside of the virtqueue array.
>
> It is risky doing input validation in common code instead of at the
> guest<->host boundary.  Note that virtio_queue_set_addr(),
> virtio_queue_get_addr(), virtio_queue_get_num(), and many other virtio
> functions do *not* validate the virtqueue number argument.
>
> Instead of fixing the comparison in virtio_queue_notify(), move the
> comparison to the virtio bindings (just like VIRTIO_PCI_QUEUE_SEL) where
> we have a uint32_t value and can avoid ever calling into common virtio
> code if the virtqueue number is invalid.
>
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/syborg_virtio.c |    4 +++-
>  hw/virtio-pci.c    |    4 +++-
>  hw/virtio.c        |    4 +---
>  3 files changed, 7 insertions(+), 5 deletions(-)

Please consider this patch for the stable tree once Michael is happy:
http://patchwork.ozlabs.org/patch/94604/

Stefan



Re: [Qemu-devel] [PATCH 7/7] PPC: Qdev'ify e500 pci

2011-05-09 Thread Paul Brook
> The e500 PCI controller isn't qdev'ified yet. This leads to severe issues
> when running with -drive.
> 
> To be able to use a virtio disk with an e500 VM, let's convert the PCI
> controller over to qdev.
> 
> Signed-off-by: Alexander Graf 
Reviewed-by: Paul Brook 



[Qemu-devel] [RFC] live snapshot, live merge, live block migration

2011-05-09 Thread Dor Laor
No patch here (sorry) but collection of thoughts about these features 
and their potential building blocks. Please review (also on 
http://wiki.qemu.org/Features/LiveBlockMigration)


Future qemu is expected to support these features (some already 
implemented):


 * Live block copy

   Ability to copy 1+ virtual disk from the source backing file/block
   device to a new target that is accessible by the host. The copy
   supposed to be executed while the VM runs in a transparent way.

   Status: code exists (by Marcelo) today in qemu but needs refactoring
   due to a race condition at the end of the copy operation. We agreed
   that a re-implementation of the copy operation should take place
   that makes sure the image is completely mirrored until management
   decides what copy to keep.

 * Live snapshots and live snapshot merge

   Live snapshot is already incorporated (by Jes) in qemu (still need
   qemu-agent work to freeze the guest FS).

   Live snapshot merge is required in order of reducing the overhead
   caused by the additional snapshots (sometimes over raw device).
   Currently not implemented for a live running guest

   Possibility: enhance live copy to be used for live snapshot merge.
It is almost the same mechanism.

 * Copy on read (image streaming)
   Ability to start guest execution while the parent image reside
   remotely and each block access is replicated to a local copy (image
   format snapshot)

   It should be nice to have a general mechanism that will be used for
   all image formats. What about the protocol to access these blocks
   over the net? We can reuse existing ones (nbd/iscsi).

   Such functionality can be hooked together with live block migration
   instead of the 'post copy' method.

 * Live block migration (pre/post)

   Beyond live block copy we'll sometimes need to move both the storage
   and the guest. There are two main approached here:
   - pre copy
 First live copy the image and only then live migration the VM.
 It is simple but if the purpose of the whole live block migration
 was to balance the cpu load, it won't be practical to use since
 copying an image of 100GB will take too long.
   - post copy
 First live migrate the VM, then live copy it's blocks.
 It's better approach for HA/load balancing but it might make
 management complex (need to keep the source VM alive, what happens
 on failures?)
 Using copy on read might simplify it -
 post copy = live snapshot + copy on read.

   In addition there are two cases for the storage access:
   1. The source block device is shared and can be easily accessed by
  the destination qemu-kvm process.
  That's the easy case, no special protocol needed for the block
  devices copying.
   2. There is no shared storage at all.
  This means we should implement a block access protocol over the
  live migration fd :(

  We need to chose whether to implement a new one, or re-use NBD or
  iScsi (target&initiator)

 * Using external dirty block bitmap

   FVD has an option to use external dirty block bitmap file in
   addition to the regular mapping/data files.

   We can consider using it for live block migration and live merge too.
   It can also allow additional usages of 3rd party tools to calculate
   diffs between the snapshots.
   There is a big down side thought since it will make management
   complicated and there is the risky of the image and its bitmap file
   get out of sync. It's much better choice to have qemu-img tool to be
   the single interface to the dirty block bitmap data.

Summary:
  * We need Marcelo's new (to come) block copy implementation
* should work in parallel to migration and hotplug
  * General copy on read is desirable
  * Live snapshot merge to be implemented using block copy
  * Need to utilize a remote block access protocol (iscsi/nbd/other)
Which one is the best?
  * Keep qemu-img the single interface for dirty block mappings.
  * Live block migration pre copy == live copy + block access protocol
+ live migration
  * Live block migration post copy == live migration + block access
protocol/copy on read.

Comments?

Regards,
Dor



Re: [Qemu-devel] [PATCH 0/3]: QMP: Introduce inject-nmi command

2011-05-09 Thread Luiz Capitulino
On Fri, 6 May 2011 18:36:31 +0300
Blue Swirl  wrote:

> On Fri, May 6, 2011 at 12:08 PM, Markus Armbruster  wrote:
> > Blue Swirl  writes:
> >
> >> On Mon, May 2, 2011 at 6:57 PM, Luiz Capitulino  
> >> wrote:
> >>> On Sat, 30 Apr 2011 09:33:15 +0300
> >>> Blue Swirl  wrote:
> >>>
>  On Sat, Apr 30, 2011 at 1:40 AM, Luiz Capitulino 
>   wrote:
>  > This series introduces the inject-nmi command for QMP, which sends an
>  > NMI to _all_ guest's CPUs.
>  >
>  > Also note that this series changes the human monitor nmi command to use
>  > the QMP implementation, which means that it now has a DIFFERENT 
>  > behavior.
>  > Please, check patch 3/3 for details.
> 
>  As discussed earlier, please change the QMP version for future
>  expandability so that instead of single command 'inject-nmi', 'inject'
>  takes parameter 'nmi'. HMP command 'nmi' can remain for now, but
>  'inject' should be added.
> >>>
> >>> I'm not sure I agree with this, because we risky overloading 'inject' the
> >>> same way we did with the 'change' command.
> >>>
> >>> What's 'inject' supposed to do in the future?
> >>
> >> Inject other IRQs, for example inject nmi could become an alias to
> >> something like
> >> inject /apic@fee0:l1int
> >> which would be a shorthand for
> >> raise /apic@fee0:l1int
> >> lower /apic@fee0:l1int
> >>
> >> I think we only need a registration framework for IRQs and other signals.
> >
> > Yes, we could use nicer infrastructure for modeling IRQs.  No, we
> > shouldn't reject Lai's work because it doesn't get us there.  Perfect is
> > the enemy of good.
> >
> > Pick one:
> >
> > 1. We take inject-nmi now.  Should we get a more general inject command
> > like the one you envisage later, we can deprecate inject-nmi, and remove
> > it after a suitable grace time.  Big deal.  We get the special problem
> > solved now, without really compromising future solutions for the general
> > problem.
> >
> > 2. We reject inject-nmi now.  The itch Lai tries to scratch remains
> > unscratched until we get a more general inject command.
> >
> > 2a. Rejection "motivates" Lai to solve the general problem[*].  Or maybe
> > it motivates somebody else.  We get the general problem solved sooner.
> > And maybe I get a pony for my birthday, too.
> >
> > 2b. The general problem remains unsolved along with the special problem.
> > We get nothing.
> 
> 2c. Don't add full generic IRQ registration and aliases just now but
> handle 'inject' with only 'nmi'. That way we introduce no legacy
> baggage to the syntax.

Can you give an example on how this is supposed to look like?



Re: [Qemu-devel] [PATCH 1/2] Add documentation for qemu_progres_print()

2011-05-09 Thread Markus Armbruster
Jes Sorensen  writes:

> On 05/06/11 17:10, Markus Armbruster wrote:
>> Jes Sorensen  writes:
>>> What you add is a delta, which is relative to the max. We can change the
>>> argument name of the function to be delta instead if that makes it
>>> easier to follow.
>> 
>> Here's my try:
>> 
>> /*
>>  * Report progress.
>>  * @percent is how much progress we made.
>>  * If @max is zero, @percent is how much of the job is done.
>>  * Else, @percent is a progress delta since the last call, as a fraction
>>  * of @max.  I.e. delta is @percent * @max / 100.  This is for
>>  * convenience, it lets you account for @max% of the total work in some
>>  * function, and still count @percent from 0 to 100.
>>  */
>
> Thanks! I made it a little more explicit based on your input:
>
> /*
>  * Report progress.
>  * @delta is how much progress we made.
>  * If @max is zero, @delta is an absolut value of the total job done.
>  * Else, @delta is a progress delta since the last call, as a fraction
>  * of @max.  I.e. the delta is @delta * @max / 100. This allows
>  * relative accounting of functions which may be a different fraction of
>  * the full job, depending on the context they are called in. I.e.
>  * a function might be considered 40% of the full job if used from
>  * bdrv_img_create() but only 20% if called from img_convert().
>  */

Looks good.

>> Document min_skip with qemu_progress_init():
>> 
>> /*
>>  * Initialize progress reporting.
>>  * If @enabled is false, actual reporting is suppressed.  The user can
>>  * still trigger a report by sending SIGUSR1.
>>  * Reports are also suppressed unless we've had at least @min_skip
>>  * percent progress since the last report.
>>  */
>
> excellent!
>
>> To be honest, the @max feature is a pain to document.  I'd ditch it.
>> 
>> For non-zero max,
>> 
>> qemu_progress_report(x, max)
>> 
>> becomes
>> 
>> qemu_progress_report(x * max/100)
>
> I have to say I prefer having the max setting here - what would be an
> option would be to keep the max value as a state, and then have a
> qemu_progress_set_current_max() or something like that, so you wouldn't
> have to type it every time?

I guess that could make it actually convenient, because...

>> Not much of an inconvenience, in my opinion.  None at all when max is
>> 100, which is the case for all non-zero max arguments so far.
>
> The reason for introducing this is that some functions are called in
> different ways, and to keep the same accounting code, it would be
> possible to add the 'max' argument to those functions when they do their
> counting.

... you wouldn't have to pass around these max arguments then.

>   It is an attempt to be forward compatible for when it happens :)

Based on my own track record at predicting the future, I've come to
refrain from providing convenience features for future needs, in
particular when it complicates things.

>> The only use of the absolute feature (zero max) so far is setting it to
>> "all done", like this:
>> 
>> qemu_progress_print(100, 0);
>> 
>> Can be done just as well with a delta >= 100, e.g.
>> 
>> qemu_progress_print(100);
>> 
>> If a need for setting other absolute progress arises, I'd consider
>> adding second function.
>
> Getting rid of the absolute setting would be fine with me. You're right
> that it is quite easy to set it that way.
>
> Cheers,
> Jes



Re: [Qemu-devel] [PATCH 1/2] Add documentation for qemu_progres_print()

2011-05-09 Thread Jes Sorensen
On 05/06/11 17:10, Markus Armbruster wrote:
> Jes Sorensen  writes:
>> What you add is a delta, which is relative to the max. We can change the
>> argument name of the function to be delta instead if that makes it
>> easier to follow.
> 
> Here's my try:
> 
> /*
>  * Report progress.
>  * @percent is how much progress we made.
>  * If @max is zero, @percent is how much of the job is done.
>  * Else, @percent is a progress delta since the last call, as a fraction
>  * of @max.  I.e. delta is @percent * @max / 100.  This is for
>  * convenience, it lets you account for @max% of the total work in some
>  * function, and still count @percent from 0 to 100.
>  */

Thanks! I made it a little more explicit based on your input:

/*
 * Report progress.
 * @delta is how much progress we made.
 * If @max is zero, @delta is an absolut value of the total job done.
 * Else, @delta is a progress delta since the last call, as a fraction
 * of @max.  I.e. the delta is @delta * @max / 100. This allows
 * relative accounting of functions which may be a different fraction of
 * the full job, depending on the context they are called in. I.e.
 * a function might be considered 40% of the full job if used from
 * bdrv_img_create() but only 20% if called from img_convert().
 */

> Document min_skip with qemu_progress_init():
> 
> /*
>  * Initialize progress reporting.
>  * If @enabled is false, actual reporting is suppressed.  The user can
>  * still trigger a report by sending SIGUSR1.
>  * Reports are also suppressed unless we've had at least @min_skip
>  * percent progress since the last report.
>  */

excellent!

> To be honest, the @max feature is a pain to document.  I'd ditch it.
> 
> For non-zero max,
> 
> qemu_progress_report(x, max)
> 
> becomes
> 
> qemu_progress_report(x * max/100)

I have to say I prefer having the max setting here - what would be an
option would be to keep the max value as a state, and then have a
qemu_progress_set_current_max() or something like that, so you wouldn't
have to type it every time?

> Not much of an inconvenience, in my opinion.  None at all when max is
> 100, which is the case for all non-zero max arguments so far.

The reason for introducing this is that some functions are called in
different ways, and to keep the same accounting code, it would be
possible to add the 'max' argument to those functions when they do their
counting. It is an attempt to be forward compatible for when it happens :)

> The only use of the absolute feature (zero max) so far is setting it to
> "all done", like this:
> 
> qemu_progress_print(100, 0);
> 
> Can be done just as well with a delta >= 100, e.g.
> 
> qemu_progress_print(100);
> 
> If a need for setting other absolute progress arises, I'd consider
> adding second function.

Getting rid of the absolute setting would be fine with me. You're right
that it is quite easy to set it that way.

Cheers,
Jes



Re: [Qemu-devel] [PULL] usb: build fixes.

2011-05-09 Thread Peter Maydell
On 9 May 2011 14:11, Gerd Hoffmann  wrote:
> Here are the fixes.
>
> pleae pull,

> Stefan Weil (1):
>      usb-linux: Add missing break statement

The commit comment for this change looks like it still
includes the remark:

# Please check whether adding a break statement is the correct
# solution for this warning.

...I think that should be removed since we have actually
done the check during review, right?

thanks
-- PMM



Re: [Qemu-devel] [PATCH] ide: Turn debug messages into assertions

2011-05-09 Thread Stefan Hajnoczi
On Mon, May 9, 2011 at 10:52 AM, Kevin Wolf  wrote:
> These printfs aren't really debug messages, but clearly indicate a bug if they
> ever become effective. Noone uses DEBUG_IDE, let's re-enable the check
> unconditionally and make it an assertion instead of printfs in the device
> emulation.
>
> Signed-off-by: Kevin Wolf 
> ---
>  hw/ide/pci.c |    8 ++--
>  1 files changed, 2 insertions(+), 6 deletions(-)

Reviewed-by: Stefan Hajnoczi 



[Qemu-devel] [PATCH 2/2] usb-linux: Add missing break statement

2011-05-09 Thread Gerd Hoffmann
From: Stefan Weil 

cppcheck report:
usb-linux.c:661: warning: Redundant assignment of "len" in switch

Please check whether adding a break statement
is the correct solution for this warning.

Cc: Hans de Goede 
Cc: Gerd Hoffmann 
Signed-off-by: Stefan Weil 
Signed-off-by: Gerd Hoffmann 
---
 usb-linux.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index 36a01ea..0ef1d26 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -659,6 +659,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, 
USBPacket *p, int in)
 switch(errno) {
 case ETIMEDOUT:
 len = USB_RET_NAK;
+break;
 case EPIPE:
 default:
 len = USB_RET_STALL;
-- 
1.7.1




[Qemu-devel] [PULL] usb: build fixes.

2011-05-09 Thread Gerd Hoffmann
  Hi,

Two build issues slipped through with the last usb patch queue pull.
Looks like I should do test builds with a more recent gcc ...

Here are the fixes.

pleae pull,
  Gerd

The following changes since commit 85097db6956bc86e2377b63a8309cb8b24d54139:

  irq: Privatize CPU_INTERRUPT_NMI. (2011-05-08 16:55:24 +)

are available in the git repository at:
  git://git.kraxel.org/qemu usb.8.pull

Gerd Hoffmann (1):
  usb-musb: uninline functions

Stefan Weil (1):
  usb-linux: Add missing break statement

 hw/usb-musb.c |8 
 usb-linux.c   |1 +
 2 files changed, 5 insertions(+), 4 deletions(-)



[Qemu-devel] [PATCH 1/2] usb-musb: uninline functions

2011-05-09 Thread Gerd Hoffmann
Prototype without "inline" keyword breaks the build with some gcc
versions.  Noticed by Alexander Graf.

Fix this by removing the inline keywork everywhere.  Some functions
can't be inlined anyway as the are referenced using function pointers.
Beside that gcc does a pretty good job on auto-inlining these days.

Signed-off-by: Gerd Hoffmann 
---
 hw/usb-musb.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index b30caeb..38986d3 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -497,14 +497,14 @@ static void musb_detach(USBPort *port)
 musb_session_update(s, 1, s->session);
 }
 
-static inline void musb_cb_tick0(void *opaque)
+static void musb_cb_tick0(void *opaque)
 {
 MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
 
 ep->delayed_cb[0](&ep->packey[0].p, opaque);
 }
 
-static inline void musb_cb_tick1(void *opaque)
+static void musb_cb_tick1(void *opaque)
 {
 MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
 
@@ -513,7 +513,7 @@ static inline void musb_cb_tick1(void *opaque)
 
 #define musb_cb_tick   (dir ? musb_cb_tick1 : musb_cb_tick0)
 
-static inline void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
+static void musb_schedule_cb(USBDevice *dev, USBPacket *packey)
 {
 MUSBPacket *p = container_of(packey, MUSBPacket, p);
 MUSBEndPoint *ep = p->ep;
@@ -572,7 +572,7 @@ static int musb_timeout(int ttype, int speed, int val)
 hw_error("bad interval\n");
 }
 
-static inline void musb_packet(MUSBState *s, MUSBEndPoint *ep,
+static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
 int epnum, int pid, int len, USBCallback cb, int dir)
 {
 int ret;
-- 
1.7.1




Re: [Qemu-devel] [PATCH v2 0/5] Split ide-drive and scsi-disk qdevs, and more

2011-05-09 Thread Gerd Hoffmann

On 05/09/11 11:51, Markus Armbruster wrote:

This patch series is about purging the "type hint" from the block
layer.  My previous series cleaned up improper uses it.  Remaining
uses are info block and qdevs ide-drive, scsi-disk.


Nice cleanup, looks good to me.

Acked-by: Gerd Hoffmann 

cheers,
  Gerd




Re: [Qemu-devel] [PATCH v2 1/5] ide: Split qdev "ide-drive" into "ide-hd" and "ide-cd"

2011-05-09 Thread Gerd Hoffmann

  Hi,


+#define DEFINE_IDE_DEV_PROPERTIES() \
+DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1), \
+DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),\
+DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
+DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial)


This can also be done this way:

static Property ide_properties[] = {
DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
[ ... ]
DEFINE_PROP_END_OF_LIST(),
};


+static IDEDeviceInfo ide_dev_info[] = {
+{
+.qdev.name= "ide-hd",
+.qdev.fw_name = "drive",
+.qdev.desc= "virtual IDE disk",
+.qdev.size= sizeof(IDEDrive),
+.init = ide_hd_initfn,


   .qdev.props   = ide_properties,

Works only as long as all devices have exactly the same set (i.e. for 
scsi it wouldn't work as not all devices have the "removable" property).


I tend to like this more than the #define.  YMMV, matter of taste.

cheers,
  Gerd



[Qemu-devel] KVM call agenda for May 10th

2011-05-09 Thread Juan Quintela

Please send in any agenda items you are interested in covering.

>From last week, we have already:

 - import kvm headers into qemu, drop #ifdef maze (Jan)

Thanks, Juan.



Re: [Qemu-devel] Bug #757654: UHCI fails to signal stall response patch

2011-05-09 Thread Gerd Hoffmann

On 05/09/11 12:16, Jan Vesely wrote:

UHCI host controller status register indicates error and
an interrupt is triggered on BABBLE and STALL errors.


Queued up.

thanks,
  Gerd




Re: [Qemu-devel] Bug #757654: UHCI fails to signal stall response patch

2011-05-09 Thread Jan Vesely
UHCI host controller status register indicates error and
an interrupt is triggered on BABBLE and STALL errors.

Signed-off-by: Jan Vesely 
---
 hw/usb-uhci.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index a65e0b3..1e9c1e7 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -702,11 +702,15 @@ out:
 case USB_RET_STALL:
 td->ctrl |= TD_CTRL_STALL;
 td->ctrl &= ~TD_CTRL_ACTIVE;
+s->status |= UHCI_STS_USBERR;
+uhci_update_irq(s);
 return 1;

 case USB_RET_BABBLE:
 td->ctrl |= TD_CTRL_BABBLE | TD_CTRL_STALL;
 td->ctrl &= ~TD_CTRL_ACTIVE;
+s->status |= UHCI_STS_USBERR;
+uhci_update_irq(s);
 /* frame interrupted */
 return -1;

-- 
1.7.3.4



[Qemu-devel] [PATCH v2 1/5] ide: Split qdev "ide-drive" into "ide-hd" and "ide-cd"

2011-05-09 Thread Markus Armbruster
An "ide-drive" is either a hard disk or a CD-ROM, depending on the
associated BlockDriverState's type hint.  Unclean; disk vs. CD belongs
to the guest part, not the host part.

Have separate qdevs "ide-hd" and "ide-cd" to model disk vs. CD in
the guest part.

Keep ide-drive for backward compatibility.

"ide-disk" would perhaps be a nicer name than "ide-hd", but there's
already "scsi-disk", which is like "ide-drive", and will be likewise
split in the next commit.  {ide,scsi}-{hd,cd} is the best consistent
set of names I could find within the backward compatibility
straightjacket.

Signed-off-by: Markus Armbruster 
---
 hw/ide/core.c |   11 --
 hw/ide/internal.h |2 +-
 hw/ide/qdev.c |   83 ++---
 3 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 90f553b..542ed65 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1592,13 +1592,15 @@ void ide_bus_reset(IDEBus *bus)
 bus->dma->ops->reset(bus->dma);
 }
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs,
+int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
const char *version, const char *serial)
 {
 int cylinders, heads, secs;
 uint64_t nb_sectors;
 
 s->bs = bs;
+s->drive_kind = kind;
+
 bdrv_get_geometry(bs, &nb_sectors);
 bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
 if (cylinders < 1 || cylinders > 16383) {
@@ -1623,8 +1625,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
 s->smart_autosave = 1;
 s->smart_errors = 0;
 s->smart_selftest_count = 0;
-if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
-s->drive_kind = IDE_CD;
+if (kind == IDE_CD) {
 bdrv_set_change_cb(bs, cdrom_change_cb, s);
 bs->buffer_alignment = 2048;
 } else {
@@ -1729,7 +1730,9 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, 
DriveInfo *hd0,
 dinfo = i == 0 ? hd0 : hd1;
 ide_init1(bus, i);
 if (dinfo) {
-if (ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL,
+if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
+   bdrv_get_type_hint(dinfo->bdrv) == 
BDRV_TYPE_CDROM ? IDE_CD : IDE_HD,
+   NULL,
*dinfo->serial ? dinfo->serial : NULL) < 0) {
 error_report("Can't set up IDE drive %s", dinfo->id);
 exit(1);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index aa198b6..c2b35ec 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -558,7 +558,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
 void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
-int ide_init_drive(IDEState *s, BlockDriverState *bs,
+int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
const char *version, const char *serial);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 2bb5c27..89cf86a 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -98,7 +98,9 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo 
*drive)
 {
 DeviceState *dev;
 
-dev = qdev_create(&bus->qbus, "ide-drive");
+dev = qdev_create(&bus->qbus,
+  bdrv_get_type_hint(drive->bdrv) == BDRV_TYPE_CDROM
+  ? "ide-hd" : "ide-cd");
 qdev_prop_set_uint32(dev, "unit", unit);
 qdev_prop_set_drive_nofail(dev, "drive", drive->bdrv);
 qdev_init_nofail(dev);
@@ -118,7 +120,7 @@ typedef struct IDEDrive {
 IDEDevice dev;
 } IDEDrive;
 
-static int ide_drive_initfn(IDEDevice *dev)
+static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
 {
 IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
 IDEState *s = bus->ifs + dev->unit;
@@ -134,7 +136,7 @@ static int ide_drive_initfn(IDEDevice *dev)
 }
 }
 
-if (ide_init_drive(s, dev->conf.bs, dev->version, serial) < 0) {
+if (ide_init_drive(s, dev->conf.bs, kind, dev->version, serial) < 0) {
 return -1;
 }
 
@@ -151,22 +153,69 @@ static int ide_drive_initfn(IDEDevice *dev)
 return 0;
 }
 
-static IDEDeviceInfo ide_drive_info = {
-.qdev.name  = "ide-drive",
-.qdev.fw_name  = "drive",
-.qdev.size  = sizeof(IDEDrive),
-.init   = ide_drive_initfn,
-.qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("unit", IDEDrive, dev.unit, -1),
-DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),
-DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),
-DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),
-DEFINE_PROP_END_OF_LIST(),
+static int ide_hd_initfn(IDEDevice *dev)
+{
+return ide_dev_initfn(dev, IDE_HD);
+}
+
+static int ide_cd_initfn(IDEDevice *dev)
+{
+return ide_dev_initfn(dev, IDE_CD);
+}
+
+static int ide_driv

  1   2   >