All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9
@ 2011-08-25 21:45 Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
                   ` (6 more replies)
  0 siblings, 7 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

Changes v8->v9
  * Updates for memory api.

Please pull from 

  git://repo.or.cz/qemu/rth.git axp-system-7


r~


Richard Henderson (6):
  target-alpha: Add custom PALcode image for CLIPPER emulation.
  target-alpha: Add 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.

 .gitmodules                       |    3 +
 Makefile                          |    3 +-
 Makefile.target                   |    1 +
 configure                         |    8 +-
 default-configs/alpha-softmmu.mak |    2 +
 hw/alpha_dp264.c                  |  177 ++++++++
 hw/alpha_pci.c                    |  134 ++++++
 hw/alpha_sys.h                    |   24 ++
 hw/alpha_typhoon.c                |  813 +++++++++++++++++++++++++++++++++++++
 pc-bios/README                    |    3 +
 pc-bios/palcode-clipper           |  Bin 0 -> 185703 bytes
 roms/qemu-palcode                 |    1 +
 target-alpha/cpu.h                |    4 +
 target-alpha/helper.h             |    5 +
 target-alpha/op_helper.c          |   25 ++
 target-alpha/translate.c          |   50 ++-
 16 files changed, 1241 insertions(+), 12 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
 create mode 100755 pc-bios/palcode-clipper
 create mode 160000 roms/qemu-palcode

-- 
1.7.4.4

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-26  4:09   ` Peter Maydell
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 2/6] target-alpha: Add " Richard Henderson
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 .gitmodules             |    3 +++
 Makefile                |    3 ++-
 configure               |    8 +++++++-
 pc-bios/README          |    3 +++
 pc-bios/palcode-clipper |  Bin 0 -> 185703 bytes
 roms/qemu-palcode       |    1 +
 6 files changed, 16 insertions(+), 2 deletions(-)
 create mode 100755 pc-bios/palcode-clipper
 create mode 160000 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 8606849..578d853 100644
--- a/Makefile
+++ b/Makefile
@@ -247,7 +247,8 @@ bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 mpc8544ds.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 1340c33..d826a48 100755
--- a/configure
+++ b/configure
@@ -3606,7 +3606,13 @@ FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 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 f74b246..861227a 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -32,3 +32,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 0000000000000000000000000000000000000000..a92372c107af72071e265e1ca94b9ae5573bd317
GIT binary patch
literal 185703
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

literal 0
HcmV?d00001

diff --git a/roms/qemu-palcode b/roms/qemu-palcode
new file mode 160000
index 0000000..7abb12f
--- /dev/null
+++ b/roms/qemu-palcode
@@ -0,0 +1 @@
+Subproject commit 7abb12f60eb3069019e9497e193733d77d8f0722
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 2/6] target-alpha: Add CLIPPER emulation.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 3/6] " Richard Henderson
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

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 <rth@twiddle.net>
---
 hw/alpha_typhoon.c |  794 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 794 insertions(+), 0 deletions(-)
 create mode 100644 hw/alpha_typhoon.c

diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
new file mode 100644
index 0000000..3637efc
--- /dev/null
+++ b/hw/alpha_typhoon.c
@@ -0,0 +1,794 @@
+/*
+ * DEC 21272 (TSUNAMI/TYPHOON) chipset emulation.
+ *
+ * Written by Richard Henderson.
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ */
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "hw.h"
+#include "devices.h"
+#include "sysemu.h"
+#include "alpha_sys.h"
+#include "exec-memory.h"
+
+
+typedef struct TyphoonCchip {
+    MemoryRegion region;
+    uint64_t misc;
+    uint64_t drir;
+    uint64_t dim[4];
+    uint32_t iic[4];
+    CPUState *cpu[4];
+} TyphoonCchip;
+
+typedef struct TyphoonWindow {
+    uint32_t base_addr;
+    uint32_t mask;
+    uint32_t translated_base_pfn;
+} TyphoonWindow;
+ 
+typedef struct TyphoonPchip {
+    MemoryRegion region;
+    MemoryRegion reg_iack;
+    MemoryRegion reg_mem;
+    MemoryRegion reg_io;
+    MemoryRegion reg_conf;
+    uint64_t ctl;
+    TyphoonWindow win[4];
+} TyphoonPchip;
+
+typedef struct TyphoonState {
+    PCIHostState host;
+    TyphoonCchip cchip;
+    TyphoonPchip pchip;
+    MemoryRegion dchip_region;
+    MemoryRegion ram_region;
+
+    /* QEMU emulation state.  */
+    uint32_t latch_tmp;
+} TyphoonState;
+
+/* Called when one of DRIR or DIM changes.  */
+static void cpu_irq_change(CPUState *env, uint64_t req)
+{
+    /* If there are any non-masked interrupts, tell the cpu.  */
+    if (env) {
+        if (req) {
+            cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        } else {
+            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+        }
+    }
+}
+
+static uint64_t cchip_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    CPUState *env = cpu_single_env;
+    TyphoonState *s = opaque;
+    uint64_t ret = 0;
+
+    if (addr & 4) {
+        return s->latch_tmp;
+    }
+
+    switch (addr) {
+    case 0x0000:
+        /* CSC: Cchip System Configuration Register.  */
+        /* All sorts of data here; probably the only thing relevant is
+           PIP<14> Pchip 1 Present = 0.  */
+        break;
+
+    case 0x0040:
+        /* MTR: Memory Timing Register.  */
+        /* All sorts of stuff related to real DRAM.  */
+        break;
+
+    case 0x0080:
+        /* MISC: Miscellaneous Register.  */
+        ret = s->cchip.misc | (env->cpu_index & 3);
+        break;
+
+    case 0x00c0:
+        /* MPD: Memory Presence Detect Register.  */
+        break;
+
+    case 0x0100: /* AAR0 */
+    case 0x0140: /* AAR1 */
+    case 0x0180: /* AAR2 */
+    case 0x01c0: /* AAR3 */
+        /* AAR: Array Address Register.  */
+        /* All sorts of information about DRAM.  */
+        break;
+
+    case 0x0200:
+        /* DIM0: Device Interrupt Mask Register, CPU0.  */
+        ret = s->cchip.dim[0];
+        break;
+    case 0x0240:
+        /* DIM1: Device Interrupt Mask Register, CPU1.  */
+        ret = s->cchip.dim[1];
+        break;
+    case 0x0280:
+        /* DIR0: Device Interrupt Request Register, CPU0.  */
+        ret = s->cchip.dim[0] & s->cchip.drir;
+        break;
+    case 0x02c0:
+        /* DIR1: Device Interrupt Request Register, CPU1.  */
+        ret = s->cchip.dim[1] & s->cchip.drir;
+        break;
+    case 0x0300:
+        /* DRIR: Device Raw Interrupt Request Register.  */
+        ret = s->cchip.drir;
+        break;
+
+    case 0x0340:
+        /* PRBEN: Probe Enable Register.  */
+        break;
+
+    case 0x0380:
+        /* IIC0: Interval Ignore Count Register, CPU0.  */
+        ret = s->cchip.iic[0];
+        break;
+    case 0x03c0:
+        /* IIC1: Interval Ignore Count Register, CPU1.  */
+        ret = s->cchip.iic[1];
+        break;
+
+    case 0x0400: /* MPR0 */
+    case 0x0440: /* MPR1 */
+    case 0x0480: /* MPR2 */
+    case 0x04c0: /* MPR3 */
+        /* MPR: Memory Programming Register.  */
+        break;
+
+    case 0x0580:
+        /* TTR: TIGbus Timing Register.  */
+        /* All sorts of stuff related to interrupt delivery timings.  */
+        break;
+    case 0x05c0:
+        /* TDR: TIGbug Device Timing Register.  */
+        break;
+
+    case 0x0600:
+        /* DIM2: Device Interrupt Mask Register, CPU2.  */
+        ret = s->cchip.dim[2];
+        break;
+    case 0x0640:
+        /* DIM3: Device Interrupt Mask Register, CPU3.  */
+        ret = s->cchip.dim[3];
+        break;
+    case 0x0680:
+        /* DIR2: Device Interrupt Request Register, CPU2.  */
+        ret = s->cchip.dim[2] & s->cchip.drir;
+        break;
+    case 0x06c0:
+        /* DIR3: Device Interrupt Request Register, CPU3.  */
+        ret = s->cchip.dim[3] & s->cchip.drir;
+        break;
+
+    case 0x0700:
+        /* IIC2: Interval Ignore Count Register, CPU2.  */
+        ret = s->cchip.iic[2];
+        break;
+    case 0x0740:
+        /* IIC3: Interval Ignore Count Register, CPU3.  */
+        ret = s->cchip.iic[3];
+        break;
+
+    case 0x0780:
+        /* PWR: Power Management Control.   */
+        break;
+    
+    case 0x0c00: /* CMONCTLA */
+    case 0x0c40: /* CMONCTLB */
+    case 0x0c80: /* CMONCNT01 */
+    case 0x0cc0: /* CMONCNT23 */
+        break;
+
+    default:
+        cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
+        return -1;
+    }
+
+    s->latch_tmp = ret >> 32;
+    return ret;
+}
+
+static uint64_t dchip_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    /* Skip this.  It's all related to DRAM timing and setup.  */
+    return 0;
+}
+
+static uint64_t pchip_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    TyphoonState *s = opaque;
+    uint64_t ret = 0;
+
+    if (addr & 4) {
+        return s->latch_tmp;
+    }
+
+    switch (addr) {
+    case 0x0000:
+        /* WSBA0: Window Space Base Address Register.  */
+        ret = s->pchip.win[0].base_addr;
+        break;
+    case 0x0040:
+        /* WSBA1 */
+        ret = s->pchip.win[1].base_addr;
+        break;
+    case 0x0080:
+        /* WSBA2 */
+        ret = s->pchip.win[2].base_addr;
+        break;
+    case 0x00c0:
+        /* WSBA3 */
+        ret = s->pchip.win[3].base_addr;
+        break;
+
+    case 0x0100:
+        /* WSM0: Window Space Mask Register.  */
+        ret = s->pchip.win[0].mask;
+        break;
+    case 0x0140:
+        /* WSM1 */
+        ret = s->pchip.win[1].mask;
+        break;
+    case 0x0180:
+        /* WSM2 */
+        ret = s->pchip.win[2].mask;
+        break;
+    case 0x01c0:
+        /* WSM3 */
+        ret = s->pchip.win[3].mask;
+        break;
+
+    case 0x0200:
+        /* TBA0: Translated Base Address Register.  */
+        ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10;
+        break;
+    case 0x0240:
+        /* TBA1 */
+        ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10;
+        break;
+    case 0x0280:
+        /* TBA2 */
+        ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10;
+        break;
+    case 0x02c0:
+        /* TBA3 */
+        ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10;
+        break;
+
+    case 0x0300:
+        /* PCTL: Pchip Control Register.  */
+        ret = s->pchip.ctl;
+        break;
+    case 0x0340:
+        /* PLAT: Pchip Master Latency Register.  */
+        break;
+    case 0x03c0:
+        /* PERROR: Pchip Error Register.  */
+        break;
+    case 0x0400:
+        /* PERRMASK: Pchip Error Mask Register.  */
+        break;
+    case 0x0440:
+        /* PERRSET: Pchip Error Set Register.  */
+        break;
+    case 0x0480:
+        /* TLBIV: Translation Buffer Invalidate Virtual Register (WO).  */
+        break;
+    case 0x04c0:
+        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
+        break;
+    case 0x0500: /* PMONCTL */
+    case 0x0540: /* PMONCNT */
+    case 0x0800: /* SPRST */
+        break;
+
+    default:
+        cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
+        return -1;
+    }
+
+    s->latch_tmp = ret >> 32;
+    return ret;
+}
+
+static void cchip_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t v32, unsigned size)
+{
+    TyphoonState *s = opaque;
+    uint64_t val, oldval, newval;
+
+    if (addr & 4) {
+        val = v32 << 32 | s->latch_tmp;
+        addr ^= 4;
+    } else {
+        s->latch_tmp = v32;
+        return;
+    }
+
+    switch (addr) {
+    case 0x0000:
+        /* CSC: Cchip System Configuration Register.  */
+        /* All sorts of data here; nothing relevant RW.  */
+        break;
+
+    case 0x0040:
+        /* MTR: Memory Timing Register.  */
+        /* All sorts of stuff related to real DRAM.  */
+        break;
+
+    case 0x0080:
+        /* MISC: Miscellaneous Register.  */
+        newval = oldval = s->cchip.misc;
+        newval &= ~(val & 0x10000ff0);     /* W1C fields */
+        if (val & 0x100000) {
+            newval &= ~0xff0000ull;        /* ACL clears ABT and ABW */
+        } else {
+            newval |= val & 0x00f00000;    /* ABT field is W1S */
+            if ((newval & 0xf0000) == 0) {
+                newval |= val & 0xf0000;   /* ABW field is W1S iff zero */
+            }
+        }
+        newval |= (val & 0xf000) >> 4;     /* IPREQ field sets IPINTR.  */
+
+        newval &= ~0xf0000000000ull;       /* WO and RW fields */
+        newval |= val & 0xf0000000000ull;
+        s->cchip.misc = newval;
+
+        /* Pass on changes to IPI and ITI state.  */
+        if ((newval ^ oldval) & 0xff0) {
+            int i;
+            for (i = 0; i < 4; ++i) {
+                CPUState *env = s->cchip.cpu[i];
+                if (env) {
+                    /* IPI can be either cleared or set by the write.  */
+                    if (newval & (1 << (i + 8))) {
+                        cpu_interrupt(env, CPU_INTERRUPT_SMP);
+                    } else {
+                        cpu_reset_interrupt(env, CPU_INTERRUPT_SMP);
+                    }
+
+                    /* ITI can only be cleared by the write.  */
+                    if ((newval & (1 << (i + 4))) == 0) {
+                        cpu_reset_interrupt(env, CPU_INTERRUPT_TIMER);
+                    }
+                }
+            }
+        }
+        break;
+
+    case 0x00c0:
+        /* MPD: Memory Presence Detect Register.  */
+        break;
+
+    case 0x0100: /* AAR0 */
+    case 0x0140: /* AAR1 */
+    case 0x0180: /* AAR2 */
+    case 0x01c0: /* AAR3 */
+        /* AAR: Array Address Register.  */
+        /* All sorts of information about DRAM.  */
+        break;
+
+    case 0x0200: /* DIM0 */
+        /* DIM: Device Interrupt Mask Register, CPU0.  */
+        s->cchip.dim[0] = val;
+        cpu_irq_change(s->cchip.cpu[0], val & s->cchip.drir);
+        break;
+    case 0x0240: /* DIM1 */
+        /* DIM: Device Interrupt Mask Register, CPU1.  */
+        s->cchip.dim[0] = val;
+        cpu_irq_change(s->cchip.cpu[1], val & s->cchip.drir);
+        break;
+
+    case 0x0280: /* DIR0 (RO) */
+    case 0x02c0: /* DIR1 (RO) */
+    case 0x0300: /* DRIR (RO) */
+        break;
+
+    case 0x0340:
+        /* PRBEN: Probe Enable Register.  */
+        break;
+
+    case 0x0380: /* IIC0 */
+        s->cchip.iic[0] = val & 0xffffff;
+        break;
+    case 0x03c0: /* IIC1 */
+        s->cchip.iic[1] = val & 0xffffff;
+        break;
+
+    case 0x0400: /* MPR0 */
+    case 0x0440: /* MPR1 */
+    case 0x0480: /* MPR2 */
+    case 0x04c0: /* MPR3 */
+        /* MPR: Memory Programming Register.  */
+        break;
+
+    case 0x0580:
+        /* TTR: TIGbus Timing Register.  */
+        /* All sorts of stuff related to interrupt delivery timings.  */
+        break;
+    case 0x05c0:
+        /* TDR: TIGbug Device Timing Register.  */
+        break;
+
+    case 0x0600:
+        /* DIM2: Device Interrupt Mask Register, CPU2.  */
+        s->cchip.dim[2] = val;
+        cpu_irq_change(s->cchip.cpu[2], val & s->cchip.drir);
+        break;
+    case 0x0640:
+        /* DIM3: Device Interrupt Mask Register, CPU3.  */
+        s->cchip.dim[3] = val;
+        cpu_irq_change(s->cchip.cpu[3], val & s->cchip.drir);
+        break;
+
+    case 0x0680: /* DIR2 (RO) */
+    case 0x06c0: /* DIR3 (RO) */
+        break;
+
+    case 0x0700: /* IIC2 */
+        s->cchip.iic[2] = val & 0xffffff;
+        break;
+    case 0x0740: /* IIC3 */
+        s->cchip.iic[3] = val & 0xffffff;
+        break;
+
+    case 0x0780:
+        /* PWR: Power Management Control.   */
+        break;
+    
+    case 0x0c00: /* CMONCTLA */
+    case 0x0c40: /* CMONCTLB */
+    case 0x0c80: /* CMONCNT01 */
+    case 0x0cc0: /* CMONCNT23 */
+        break;
+
+    default:
+        cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
+        return;
+    }
+}
+
+static void dchip_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
+{
+    /* Skip this.  It's all related to DRAM timing and setup.  */
+}
+
+static void pchip_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t v32, unsigned size)
+{
+    TyphoonState *s = opaque;
+    uint64_t val, oldval;
+
+    if (addr & 4) {
+        val = v32 << 32 | s->latch_tmp;
+        addr ^= 4;
+    } else {
+        s->latch_tmp = v32;
+        return;
+    }
+
+    switch (addr) {
+    case 0x0000:
+        /* WSBA0: Window Space Base Address Register.  */
+        s->pchip.win[0].base_addr = val;
+        break;
+    case 0x0040:
+        /* WSBA1 */
+        s->pchip.win[1].base_addr = val;
+        break;
+    case 0x0080:
+        /* WSBA2 */
+        s->pchip.win[2].base_addr = val;
+        break;
+    case 0x00c0:
+        /* WSBA3 */
+        s->pchip.win[3].base_addr = val;
+        break;
+
+    case 0x0100:
+        /* WSM0: Window Space Mask Register.  */
+        s->pchip.win[0].mask = val;
+        break;
+    case 0x0140:
+        /* WSM1 */
+        s->pchip.win[1].mask = val;
+        break;
+    case 0x0180:
+        /* WSM2 */
+        s->pchip.win[2].mask = val;
+        break;
+    case 0x01c0:
+        /* WSM3 */
+        s->pchip.win[3].mask = val;
+        break;
+
+    case 0x0200:
+        /* TBA0: Translated Base Address Register.  */
+        s->pchip.win[0].translated_base_pfn = val >> 10;
+        break;
+    case 0x0240:
+        /* TBA1 */
+        s->pchip.win[1].translated_base_pfn = val >> 10;
+        break;
+    case 0x0280:
+        /* TBA2 */
+        s->pchip.win[2].translated_base_pfn = val >> 10;
+        break;
+    case 0x02c0:
+        /* TBA3 */
+        s->pchip.win[3].translated_base_pfn = val >> 10;
+        break;
+
+    case 0x0300:
+        /* PCTL: Pchip Control Register.  */
+        oldval = s->pchip.ctl;
+        oldval &= ~0x00001cff0fc7ffull;       /* RW fields */
+        oldval |= val & 0x00001cff0fc7ffull;
+
+        s->pchip.ctl = oldval;
+        break;
+
+    case 0x0340:
+        /* PLAT: Pchip Master Latency Register.  */
+        break;
+    case 0x03c0:
+        /* PERROR: Pchip Error Register.  */
+        break;
+    case 0x0400:
+        /* PERRMASK: Pchip Error Mask Register.  */
+        break;
+    case 0x0440:
+        /* PERRSET: Pchip Error Set Register.  */
+        break;
+
+    case 0x0480:
+        /* TLBIV: Translation Buffer Invalidate Virtual Register.  */
+        break;
+
+    case 0x04c0:
+        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
+        break;
+
+    case 0x0500:
+        /* PMONCTL */
+    case 0x0540:
+        /* PMONCNT */
+    case 0x0800:
+        /* SPRST */
+        break;
+
+    default:
+        cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
+        return;
+    }
+}
+
+static const MemoryRegionOps cchip_ops = {
+    .read = cchip_read,
+    .write = cchip_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,  /* ??? Should be 8.  */
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static const MemoryRegionOps dchip_ops = {
+    .read = dchip_read,
+    .write = dchip_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,  /* ??? Should be 8.  */
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 8,
+    },
+};
+
+static const MemoryRegionOps pchip_ops = {
+    .read = pchip_read,
+    .write = pchip_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,  /* ??? Should be 8.  */
+        .max_access_size = 8,
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static void typhoon_set_irq(void *opaque, int irq, int level)
+{
+    TyphoonState *s = opaque;
+    uint64_t drir;
+    int i;
+
+    /* Set/Reset the bit in CCHIP.DRIR based on IRQ+LEVEL.  */
+    drir = s->cchip.drir;
+    if (level) {
+        drir |= 1ull << irq;
+    } else {
+        drir &= ~(1ull << irq);
+    }
+    s->cchip.drir = drir;
+
+    for (i = 0; i < 4; ++i) {
+        cpu_irq_change(s->cchip.cpu[i], s->cchip.dim[i] & drir);
+    }
+}
+
+static void typhoon_set_isa_irq(void *opaque, int irq, int level)
+{
+    typhoon_set_irq(opaque, 55, level);
+}
+
+static void typhoon_set_timer_irq(void *opaque, int irq, int level)
+{
+    TyphoonState *s = opaque;
+    int i;
+
+    /* Thankfully, the mc146818rtc code doesn't track the IRQ state,
+       and so we don't have to worry about missing interrupts just
+       because we never actually ACK the interrupt.  Just ignore any
+       case of the interrupt level going low.  */
+    if (level == 0) {
+        return;
+    }
+
+    /* Deliver the interrupt to each CPU, considering each CPU's IIC.  */
+    for (i = 0; i < 4; ++i) {
+        CPUState *env = s->cchip.cpu[i];
+        if (env) {
+            uint32_t iic = s->cchip.iic[i];
+
+            /* ??? The verbage in Section 10.2.2.10 isn't 100% clear.
+               Bit 24 is the OverFlow bit, RO, and set when the count
+               decrements past 0.  When is OF cleared?  My guess is that
+               OF is actually cleared when the IIC is written, and that
+               the ICNT field always decrements.  At least, that's an
+               interpretation that makes sense, and "allows the CPU to
+               determine exactly how mant interval timer ticks were
+               skipped".  At least within the next 4M ticks...  */
+
+            iic = ((iic - 1) & 0x1ffffff) | (iic & 0x1000000);
+            s->cchip.iic[i] = iic;
+
+            if (iic & 0x1000000) {
+                /* Set the ITI bit for this cpu.  */
+                s->cchip.misc |= 1 << (i + 4);
+                /* And signal the interrupt.  */
+                cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+            }
+        }
+    }
+}
+
+PCIBus *typhoon_init(ram_addr_t ram_size, qemu_irq *p_rtc_irq,
+                     CPUState *cpus[4], pci_map_irq_fn sys_map_irq)
+{
+    const uint64_t MB = 1024 * 1024;
+    const uint64_t GB = 1024 * MB;
+    MemoryRegion *addr_space = get_system_memory();
+    MemoryRegion *addr_space_io = get_system_io();
+    DeviceState *dev;
+    PCIHostState *p;
+    TyphoonState *s;
+    PCIBus *b;
+
+    dev = qdev_create(NULL, "typhoon-pcihost");
+    qdev_init_nofail(dev);
+
+    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 *));
+
+    *p_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1);
+
+    /* Main memory region, 0x00.0000.0000.  Real hardware supports 32GB,
+       but the address space hole reserved at this point is 8TB.  */
+    memory_region_init_ram(&s->ram_region, NULL, "ram", ram_size);
+    memory_region_add_subregion(addr_space, 0, &s->ram_region);
+
+    /* TIGbus, 0x801.0000.0000, 1GB.  */
+    /* ??? The TIGbus is used for delivering interrupts, and access to
+       the flash ROM.  I'm not sure that we need to implement it at all.  */
+
+    /* Pchip0 CSRs, 0x801.8000.0000, 256MB.  */
+    memory_region_init_io(&s->pchip.region, &pchip_ops, s, "pchip0", 256*MB);
+    memory_region_add_subregion(addr_space, 0x80180000000, &s->pchip.region);
+
+    /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
+    memory_region_init_io(&s->cchip.region, &cchip_ops, s, "cchip0", 256*MB);
+    memory_region_add_subregion(addr_space, 0x801a0000000, &s->cchip.region);
+
+    /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
+    memory_region_init_io(&s->dchip_region, &dchip_ops, s, "dchip0", 256*MB);
+    memory_region_add_subregion(addr_space, 0x801b0000000, &s->dchip_region);
+
+    /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
+    memory_region_init(&s->pchip.reg_mem, "pci0-mem", 4*GB);
+    memory_region_add_subregion(addr_space, 0x80000000000, &s->pchip.reg_mem);
+
+    /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
+    /* ??? Ideally we drop the "system" i/o space on the floor and give the
+       PCI subsystem the full address space reserved by the chipset.
+       We can't do that until the MEM and IO paths in memory.c are unified.  */
+    memory_region_init_io(&s->pchip.reg_io, &alpha_pci_bw_io_ops, NULL,
+                          "pci0-io", 32*MB);
+    memory_region_add_subregion(addr_space, 0x801fc000000, &s->pchip.reg_io);
+
+    b = pci_register_bus(&s->host.busdev.qdev, "pci",
+                         typhoon_set_irq, sys_map_irq, s,
+                         &s->pchip.reg_mem, addr_space_io, 0, 64);
+    s->host.bus = b;
+
+    /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
+    memory_region_init_io(&s->pchip.reg_iack, &alpha_pci_iack_ops, b,
+                          "pci0-iack", 64*MB);
+    memory_region_add_subregion(addr_space, 0x801f8000000, &s->pchip.reg_iack);
+
+    /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
+    memory_region_init_io(&s->pchip.reg_conf, &alpha_pci_conf1_ops, b,
+                          "pci0-conf", 16*MB);
+    memory_region_add_subregion(addr_space, 0x801fe000000, &s->pchip.reg_conf);
+
+    /* For the record, these are the mappings for the second PCI bus.
+       We can get away with not implementing them because we indicate
+       via the Cchip.CSC<PIP> bit that Pchip1 is not present.  */
+    /* Pchip1 PCI memory, 0x802.0000.0000, 4GB.  */
+    /* Pchip1 CSRs, 0x802.8000.0000, 256MB.  */
+    /* Pchip1 PCI special/interrupt acknowledge, 0x802.F800.0000, 64MB.  */
+    /* Pchip1 PCI I/O, 0x802.FC00.0000, 32MB.  */
+    /* Pchip1 PCI configuration, 0x802.FE00.0000, 16MB.  */
+
+    /* Init the ISA bus.  */
+    /* ??? Technically there should be a cy82c693ub pci-isa bridge.  */
+    {
+        qemu_irq isa_pci_irq, *isa_irqs;
+
+        isa_bus_new(NULL);
+        isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
+        isa_irqs = i8259_init(isa_pci_irq);
+        isa_bus_irqs(isa_irqs);
+    }
+
+    return b;
+}
+
+static int typhoon_pcihost_init(SysBusDevice *dev)
+{
+    return 0;
+}
+
+static SysBusDeviceInfo typhoon_pcihost_info = {
+    .init = typhoon_pcihost_init,
+    .qdev.name = "typhoon-pcihost",
+    .qdev.size = sizeof(TyphoonState),
+    .qdev.no_user = 1
+};
+
+static void typhoon_register(void)
+{
+    sysbus_register_withprop(&typhoon_pcihost_info);
+}
+device_init(typhoon_register);
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 3/6] target-alpha: Add CLIPPER emulation.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 2/6] target-alpha: Add " Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 4/6] target-alpha: Implement WAIT IPR Richard Henderson
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

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 <rth@twiddle.net>
---
 Makefile.target                   |    1 +
 default-configs/alpha-softmmu.mak |    2 +
 hw/alpha_dp264.c                  |  177 +++++++++++++++++++++++++++++++++++++
 hw/alpha_pci.c                    |  134 ++++++++++++++++++++++++++++
 hw/alpha_sys.h                    |   24 +++++
 5 files changed, 338 insertions(+), 0 deletions(-)
 create mode 100644 hw/alpha_dp264.c
 create mode 100644 hw/alpha_pci.c
 create mode 100644 hw/alpha_sys.h

diff --git a/Makefile.target b/Makefile.target
index e280bf6..7e8a6b4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -372,6 +372,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/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak
index abadcff..be86d0c 100644
--- a/default-configs/alpha-softmmu.mak
+++ b/default-configs/alpha-softmmu.mak
@@ -3,7 +3,9 @@
 include pci.mak
 CONFIG_SERIAL=y
 CONFIG_I8254=y
+CONFIG_PCKBD=y
 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
new file mode 100644
index 0000000..7c36b21
--- /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"
+#include "ide.h"
+
+#define MAX_IDE_BUS 2
+
+static uint64_t cpu_alpha_superpage_to_phys(void *opaque, uint64_t addr)
+{
+    if (((addr >> 41) & 3) == 2) {
+        addr &= 0xffffffffffull;
+    }
+    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];
+    PCIBus *pci_bus;
+    qemu_irq rtc_irq;
+    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;
+
+    /* Init the chipset.  */
+    pci_bus = typhoon_init(ram_size, &rtc_irq, cpus, clipper_pci_map_irq);
+
+    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);
+
+    /* 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);
+    }
+
+    /* 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.  */
+    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]->pal_mode = 1;
+        cpus[i]->pc = palcode_entry;
+        cpus[i]->palbr = palcode_entry;
+    }
+
+    /* Load a kernel.  */
+    if (kernel_filename) {
+        uint64_t param_offset;
+
+        size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,
+                        NULL, &kernel_entry, &kernel_low, &kernel_high,
+                        0, EM_ALPHA, 0);
+        if (size < 0) {
+            hw_error("could not load kernel '%s'\n", kernel_filename);
+            exit(1);
+        }
+
+        cpus[0]->trap_arg1 = kernel_entry;
+
+        param_offset = kernel_low - 0x6000;
+
+        if (kernel_cmdline) {
+            pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);
+        }
+
+        if (initrd_filename) {
+            long initrd_base, initrd_size;
+
+            initrd_size = get_image_size(initrd_filename);
+            if (initrd_size < 0) {
+                hw_error("could not load initial ram disk '%s'\n",
+                         initrd_filename);
+                exit(1);
+            }
+
+            /* Put the initrd image as high in memory as possible.  */
+            initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;
+            load_image_targphys(initrd_filename, initrd_base,
+                                ram_size - initrd_base);
+
+            stq_phys(param_offset + 0x100, initrd_base + 0xfffffc0000000000UL);
+            stq_phys(param_offset + 0x108, initrd_size);
+        }
+    }
+}
+
+static QEMUMachine clipper_machine = {
+    .name = "clipper",
+    .desc = "Alpha DP264/CLIPPER",
+    .init = clipper_init,
+    .max_cpus = 4,
+    .is_default = 1,
+};
+
+static void clipper_machine_init(void)
+{
+    qemu_register_machine(&clipper_machine);
+}
+
+machine_init(clipper_machine_init);
diff --git a/hw/alpha_pci.c b/hw/alpha_pci.c
new file mode 100644
index 0000000..e975702
--- /dev/null
+++ b/hw/alpha_pci.c
@@ -0,0 +1,134 @@
+/*
+ * QEMU Alpha PCI support functions.
+ *
+ * Some of this isn't very Alpha specific at all.
+ *
+ * ??? Sparse memory access not implemented.
+ */
+
+#include "config.h"
+#include "alpha_sys.h"
+#include "qemu-log.h"
+#include "sysemu.h"
+#include "vmware_vga.h"
+
+
+/* PCI IO reads/writes, to byte-word addressable memory.  */
+/* ??? Doesn't handle multiple PCI busses.  */
+
+static uint64_t bw_io_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    switch (size) {
+    case 1:
+        return cpu_inb(addr);
+    case 2:
+        return cpu_inw(addr);
+    case 4:
+        return cpu_inl(addr);
+    }
+    abort();
+}
+
+static void bw_io_write(void *opaque, target_phys_addr_t addr,
+                        uint64_t val, unsigned size)
+{
+    switch (size) {
+    case 1:
+        cpu_outb(addr, val);
+        break;
+    case 2:
+        cpu_outw(addr, val);
+        break;
+    case 4:
+        cpu_outl(addr, val);
+        break;
+    default:
+        abort();
+    }
+}
+
+const MemoryRegionOps alpha_pci_bw_io_ops = {
+    .read = bw_io_read,
+    .write = bw_io_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+/* PCI config space reads/writes, to byte-word addressable memory.  */
+static uint64_t bw_conf1_read(void *opaque, target_phys_addr_t addr,
+                              unsigned size)
+{
+    PCIBus *b = opaque;
+    return pci_data_read(b, addr, size);
+}
+
+static void bw_conf1_write(void *opaque, target_phys_addr_t addr,
+                           uint64_t val, unsigned size)
+{
+    PCIBus *b = opaque;
+    pci_data_write(b, addr, val, size);
+}
+
+const MemoryRegionOps alpha_pci_conf1_ops = {
+    .read = bw_conf1_read,
+    .write = bw_conf1_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+/* PCI/EISA Interrupt Acknowledge Cycle.  */
+
+static uint64_t iack_read(void *opaque, target_phys_addr_t addr, unsigned size)
+{
+    return pic_read_irq(isa_pic);
+}
+
+static void special_write(void *opaque, target_phys_addr_t addr,
+                          uint64_t val, unsigned size)
+{
+    qemu_log("pci: special write cycle");
+}
+
+const MemoryRegionOps alpha_pci_iack_ops = {
+    .read = iack_read,
+    .write = special_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+\f

+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
new file mode 100644
index 0000000..13f0177
--- /dev/null
+++ b/hw/alpha_sys.h
@@ -0,0 +1,24 @@
+/* Alpha cores and system support chips.  */
+
+#ifndef HW_ALPHA_H
+#define HW_ALPHA_H 1
+
+#include "pci.h"
+#include "pci_host.h"
+#include "ide.h"
+#include "net.h"
+#include "pc.h"
+#include "usb-ohci.h"
+#include "irq.h"
+
+
+PCIBus *typhoon_init(ram_addr_t, qemu_irq *, CPUState *[4], pci_map_irq_fn);
+
+/* alpha_pci.c.  */
+extern const MemoryRegionOps alpha_pci_bw_io_ops;
+extern const MemoryRegionOps alpha_pci_conf1_ops;
+extern const MemoryRegionOps alpha_pci_iack_ops;
+
+void alpha_pci_vga_setup(PCIBus *pci_bus);
+
+#endif
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 4/6] target-alpha: Implement WAIT IPR.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
                   ` (2 preceding siblings ...)
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 3/6] " Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 5/6] target-alpha: Implement HALT IPR Richard Henderson
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 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 1e224a2..86343df 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1617,9 +1617,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);
@@ -1627,19 +1628,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);
@@ -1649,11 +1658,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*/
 
@@ -3053,8 +3065,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 & 0xffff);
-            break;
+            return gen_mtpr(ctx, rb, insn & 0xffff);
         }
 #endif
         goto invalid_opc;
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 5/6] target-alpha: Implement HALT IPR.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
                   ` (3 preceding siblings ...)
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 4/6] target-alpha: Implement WAIT IPR Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
  2011-08-25 21:59 ` [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
  6 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 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 38be234..db5b9e7 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -22,6 +22,7 @@
 #include "host-utils.h"
 #include "softfloat.h"
 #include "helper.h"
+#include "sysemu.h"
 #include "qemu-timer.h"
 
 #define FP_STATUS (env->fp_status)
@@ -1218,6 +1219,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 86343df..842f915 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1645,6 +1645,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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
                   ` (4 preceding siblings ...)
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 5/6] target-alpha: Implement HALT IPR Richard Henderson
@ 2011-08-25 21:45 ` Richard Henderson
  2011-08-26  3:51   ` Peter Maydell
  2011-08-25 21:59 ` [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
  6 siblings, 1 reply; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:45 UTC (permalink / raw)
  To: qemu-devel

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 <rth@twiddle.net>
---
 hw/alpha_typhoon.c       |   21 ++++++++++++++++++++-
 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(+), 1 deletions(-)

diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
index 3637efc..3d30e0e 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(ram_addr_t ram_size, qemu_irq *p_rtc_irq,
                      CPUState *cpus[4], pci_map_irq_fn sys_map_irq)
 {
@@ -692,6 +702,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, qemu_irq *p_rtc_irq,
     PCIHostState *p;
     TyphoonState *s;
     PCIBus *b;
+    int i;
 
     dev = qdev_create(NULL, "typhoon-pcihost");
     qdev_init_nofail(dev);
@@ -700,7 +711,15 @@ PCIBus *typhoon_init(ram_addr_t ram_size, qemu_irq *p_rtc_irq,
     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_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1);
 
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index c2e7bb3..9d61d45 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -265,6 +265,10 @@ struct CPUAlphaState {
     uint64_t scratch[24];
 #endif
 
+    /* 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 db5b9e7..6832163 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1228,6 +1228,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 842f915..37f2f20 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1590,6 +1590,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;
 }
@@ -1604,6 +1607,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) {
@@ -1650,6 +1659,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:
         /* The basic registers are data only, and unknown registers
            are read-zero, write-ignore.  */
-- 
1.7.4.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9
  2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
                   ` (5 preceding siblings ...)
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
@ 2011-08-25 21:59 ` Richard Henderson
  6 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-25 21:59 UTC (permalink / raw)
  To: qemu-devel

On 08/25/2011 11:45 AM, Richard Henderson wrote:
> Changes v8->v9
>   * Updates for memory api.
> 
> Please pull from 
> 
>   git://repo.or.cz/qemu/rth.git axp-system-7
> 
> 
> r~
> 
> 
> Richard Henderson (6):
>   target-alpha: Add custom PALcode image for CLIPPER emulation.
>   target-alpha: Add 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.


I must have done something silly in between git-format-patch and
git-send-email; clearly patches 2 and 3 shouldn't be duplicates.

The git branch is correct, however.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
@ 2011-08-26  3:51   ` Peter Maydell
  2011-08-26  9:07     ` Paolo Bonzini
  0 siblings, 1 reply; 16+ messages in thread
From: Peter Maydell @ 2011-08-26  3:51 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Paolo Bonzini, qemu-devel

On 25 August 2011 22:45, Richard Henderson <rth@twiddle.net> wrote:
> @@ -1604,6 +1607,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) {
> @@ -1650,6 +1659,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:
>         /* The basic registers are data only, and unknown registers
>            are read-zero, write-ignore.  */

Don't you need some magic around helper calls that read/write
the time to keep -icount working? I don't understand this but
Paolo does...

-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation.
  2011-08-25 21:45 ` [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
@ 2011-08-26  4:09   ` Peter Maydell
  0 siblings, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2011-08-26  4:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

2011/8/25 Richard Henderson <rth@twiddle.net>:
> 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

We had a conversation on IRC about binary blobs the other day,
and I think Anthony said that all submodules referred to here
had to also be on git.qemu.org. But I could be misremembering.
(In particular I thought Anthony said these were all relative
references, which they clearly aren't...)

> diff --git a/Makefile b/Makefile
> index 8606849..578d853 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -247,7 +247,8 @@ bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
>  mpc8544ds.dtb \
>  multiboot.bin linuxboot.bin \
>  s390-zipl.rom \
> -spapr-rtas.bin slof.bin
> +spapr-rtas.bin slof.bin \
> +palcode-sx164
>  else
>  BLOBS=
>  endif

You don't update the list of blobs in the 'tarbin' target,
but I have a feeling that may be broken anyway. Does anybody
use it, and if not should we just nuke it?

> diff --git a/pc-bios/README b/pc-bios/README
> index f74b246..861227a 100644
> --- a/pc-bios/README
> +++ b/pc-bios/README
> @@ -32,3 +32,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

You mean "The Alpha palcode image sources"; the image will already
be in git :-)

-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26  3:51   ` Peter Maydell
@ 2011-08-26  9:07     ` Paolo Bonzini
  2011-08-26 16:28       ` Richard Henderson
  0 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2011-08-26  9:07 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Richard Henderson

On 08/26/2011 05:51 AM, Peter Maydell wrote:
> Don't you need some magic around helper calls that read/write
> the time to keep -icount working? I don't understand this but
> Paolo does...

Let's say I understand the theory (how icount relies on it) more than 
the practice (how the targets should do it). :)

Paolo

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26  9:07     ` Paolo Bonzini
@ 2011-08-26 16:28       ` Richard Henderson
  2011-08-26 16:36         ` Peter Maydell
  0 siblings, 1 reply; 16+ messages in thread
From: Richard Henderson @ 2011-08-26 16:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Maydell, qemu-devel

On 08/25/2011 11:07 PM, Paolo Bonzini wrote:
> On 08/26/2011 05:51 AM, Peter Maydell wrote:
>> Don't you need some magic around helper calls that read/write
>> the time to keep -icount working? I don't understand this but
>> Paolo does...
> 
> Let's say I understand the theory (how icount relies on it) more than the practice (how the targets should do it). :)

Heh.  Well, let's say that while I've aped the other targets in
how icount is treated in the translator, I have no idea what it
is really supposed to accomplish, and so have never used it.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26 16:28       ` Richard Henderson
@ 2011-08-26 16:36         ` Peter Maydell
  2011-08-26 20:03           ` Richard Henderson
                             ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Peter Maydell @ 2011-08-26 16:36 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Paolo Bonzini, qemu-devel

On 26 August 2011 17:28, Richard Henderson <rth@twiddle.net> wrote:
> On 08/25/2011 11:07 PM, Paolo Bonzini wrote:
>> On 08/26/2011 05:51 AM, Peter Maydell wrote:
>>> Don't you need some magic around helper calls that read/write
>>> the time to keep -icount working? I don't understand this but
>>> Paolo does...
>>
>> Let's say I understand the theory (how icount relies on it)
>> more than the practice (how the targets should do it). :)
>
> Heh.  Well, let's say that while I've aped the other targets in
> how icount is treated in the translator, I have no idea what it
> is really supposed to accomplish, and so have never used it.

Well, "what it's supposed to accomplish" is straightforward
enough, we want to keep a count of cycles executed (and I think
also maintain determinism, although that I'm less certain about).
Since we only update the count at the start of each basic block,
we (potentially) have to stop the basic block where we hit an
I/O operation which fiddles with the timer. For I/O via memory
accesses this is all dealt with by the generic code, but where
the CPU has some instruction which does things with timers not
via a memory access there needs to be a bit of special casing.

Look at the way target-i386 and target-mips use gen_io_start()
and gen_io_end() around x86 io insns and MIPS mtc0. I think
that what you need is (a) to bracket with gen_io_start/end
and (b) to end the translation block, but that's really just
guesswork from the existing code...

-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26 16:36         ` Peter Maydell
@ 2011-08-26 20:03           ` Richard Henderson
  2011-08-26 20:12           ` Richard Henderson
  2011-08-27 16:44           ` Edgar E. Iglesias
  2 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-26 20:03 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, qemu-devel

On 08/26/2011 06:36 AM, Peter Maydell wrote:
> Look at the way target-i386 and target-mips use gen_io_start()
> and gen_io_end() around x86 io insns and MIPS mtc0. I think
> that what you need is (a) to bracket with gen_io_start/end
> and (b) to end the translation block, but that's really just
> guesswork from the existing code...

I'll be applying this on top of 6/6.  Look sane?


r~

---
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 37f2f20..8f0dc3e 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1609,7 +1609,17 @@ static void gen_mfpr(int ra, int regno)
 
     if (regno == 250) {
         /* WALL_TIME */
-        gen_helper_get_time(cpu_ir[ra]);
+        if (use_iocount) {
+            /* Mark as an IO operation because we read the time.  */
+            gen_io_start();
+            gen_helper_get_time(cpu_ir[ra]);
+            gen_io_end();
+            /* Other targets break the TB to be able to take timer
+               interrupts immediately.  This doesn't apply to Alpha
+               because we never take interrupts in PALmode.  */
+        } else {
+            gen_helper_get_time(cpu_ir[ra]);
+        }
         return;
     }
 
@@ -1661,7 +1671,14 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
 
     case 251:
         /* ALARM */
-        gen_helper_set_alarm(tmp);
+        if (use_icount) {
+            /* Mark as an IO operation because we reference the time.  */
+            gen_io_start();
+            gen_helper_set_alarm(tmp);
+            gen_io_end();
+        } else {
+            gen_helper_set_alarm(tmp);
+        }
         break;
 
     default:

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26 16:36         ` Peter Maydell
  2011-08-26 20:03           ` Richard Henderson
@ 2011-08-26 20:12           ` Richard Henderson
  2011-08-27 16:44           ` Edgar E. Iglesias
  2 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2011-08-26 20:12 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, qemu-devel

On 08/26/2011 06:36 AM, Peter Maydell wrote:
> Look at the way target-i386 and target-mips use gen_io_start()
> and gen_io_end() around x86 io insns and MIPS mtc0. I think
> that what you need is (a) to bracket with gen_io_start/end
> and (b) to end the translation block, but that's really just
> guesswork from the existing code...

Hmph.  I suspect that the alpha port has never worked with
icount.  Trying to boot a kernel with it results in millions
of "Bad clock read" messages.

I'm 20 minutes from leaving for holidays.  I'll put this on
the to-do list for when I get back.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-08-26 16:36         ` Peter Maydell
  2011-08-26 20:03           ` Richard Henderson
  2011-08-26 20:12           ` Richard Henderson
@ 2011-08-27 16:44           ` Edgar E. Iglesias
  2 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2011-08-27 16:44 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, qemu-devel, Richard Henderson

On Fri, Aug 26, 2011 at 05:36:19PM +0100, Peter Maydell wrote:
> On 26 August 2011 17:28, Richard Henderson <rth@twiddle.net> wrote:
> > On 08/25/2011 11:07 PM, Paolo Bonzini wrote:
> >> On 08/26/2011 05:51 AM, Peter Maydell wrote:
> >>> Don't you need some magic around helper calls that read/write
> >>> the time to keep -icount working? I don't understand this but
> >>> Paolo does...
> >>
> >> Let's say I understand the theory (how icount relies on it)
> >> more than the practice (how the targets should do it). :)
> >
> > Heh.  Well, let's say that while I've aped the other targets in
> > how icount is treated in the translator, I have no idea what it
> > is really supposed to accomplish, and so have never used it.
> 
> Well, "what it's supposed to accomplish" is straightforward
> enough, we want to keep a count of cycles executed (and I think
> also maintain determinism, although that I'm less certain about).
> Since we only update the count at the start of each basic block,
> we (potentially) have to stop the basic block where we hit an
> I/O operation which fiddles with the timer. For I/O via memory
> accesses this is all dealt with by the generic code, but where
> the CPU has some instruction which does things with timers not
> via a memory access there needs to be a bit of special casing.
> 
> Look at the way target-i386 and target-mips use gen_io_start()
> and gen_io_end() around x86 io insns and MIPS mtc0. I think
> that what you need is (a) to bracket with gen_io_start/end
> and (b) to end the translation block, but that's really just
> guesswork from the existing code...

I think thats right, you need both.

If you forget the gen_io_start/end calls, you'll notice. Everytime
the timer is read you'll hit the "Bad clock read" from cpus.c.

IIUC, If you dont end the TB after timer reads, the read will return
a time in the future (i.e the insns beyond the read will be accounted
as already executed at the point where you read the time).

For alarm setups, you need to end the TB to get precise deliveries, otherwise
I think you risk executing insns beyond the point when the timer should
have fired. Maybe not so likely unless you're setting timers to very
short intervals though.

Cheers

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2011-08-27 16:44 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-25 21:45 [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson
2011-08-25 21:45 ` [Qemu-devel] [PATCH 1/6] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
2011-08-26  4:09   ` Peter Maydell
2011-08-25 21:45 ` [Qemu-devel] [PATCH 2/6] target-alpha: Add " Richard Henderson
2011-08-25 21:45 ` [Qemu-devel] [PATCH 3/6] " Richard Henderson
2011-08-25 21:45 ` [Qemu-devel] [PATCH 4/6] target-alpha: Implement WAIT IPR Richard Henderson
2011-08-25 21:45 ` [Qemu-devel] [PATCH 5/6] target-alpha: Implement HALT IPR Richard Henderson
2011-08-25 21:45 ` [Qemu-devel] [PATCH 6/6] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
2011-08-26  3:51   ` Peter Maydell
2011-08-26  9:07     ` Paolo Bonzini
2011-08-26 16:28       ` Richard Henderson
2011-08-26 16:36         ` Peter Maydell
2011-08-26 20:03           ` Richard Henderson
2011-08-26 20:12           ` Richard Henderson
2011-08-27 16:44           ` Edgar E. Iglesias
2011-08-25 21:59 ` [Qemu-devel] [PULL][PATCH 0/6] Alpha system emulation, v9 Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.