All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/7] Alpha system emulation, v7
@ 2011-07-23 19:17 Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions Richard Henderson
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 UTC (permalink / raw)
  To: qemu-devel

Changes v6->v7

  * Rebase against master, which now includes 2 patches from v6.

The tree is available at

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

Please pull, review, or something.



r~



Richard Henderson (7):
  Export the unassigned_mem read/write functions.
  pci: Export pci_to_cpu_addr.
  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.

 .gitmodules                       |    3 +
 Makefile                          |    3 +-
 Makefile.target                   |    1 +
 configure                         |    8 +-
 cpu-common.h                      |    7 +
 default-configs/alpha-softmmu.mak |    2 +
 exec.c                            |   12 +-
 hw/alpha_dp264.c                  |  188 +++++++++
 hw/alpha_pci.c                    |  358 +++++++++++++++++
 hw/alpha_sys.h                    |   44 ++
 hw/alpha_typhoon.c                |  799 +++++++++++++++++++++++++++++++++++++
 hw/pci.c                          |    3 +-
 hw/pci.h                          |    1 +
 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 ++-
 20 files changed, 1497 insertions(+), 20 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] 17+ messages in thread

* [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-24 13:28   ` Anthony Liguori
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 2/7] pci: Export pci_to_cpu_addr Richard Henderson
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 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 44b04b3..78e1bad 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 2160ded..c00badd 100644
--- a/exec.c
+++ b/exec.c
@@ -3232,7 +3232,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);
@@ -3243,7 +3243,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);
@@ -3254,7 +3254,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);
@@ -3265,7 +3265,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);
@@ -3275,7 +3275,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);
@@ -3285,7 +3285,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

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

* [Qemu-devel] [PATCH 2/7] pci: Export pci_to_cpu_addr.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 3/7] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 UTC (permalink / raw)
  To: qemu-devel

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 <rth@twiddle.net>
---
 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 b904a4e..68e18d3 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -820,8 +820,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 c220745..458be00 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

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

* [Qemu-devel] [PATCH 3/7] target-alpha: Add custom PALcode image for CLIPPER emulation.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 2/7] pci: Export pci_to_cpu_addr Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 4/7] target-alpha: Add " Richard Henderson
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 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 f3a03ad..310608b 100644
--- a/Makefile
+++ b/Makefile
@@ -243,7 +243,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 6911c3b..6a8a4c8 100755
--- a/configure
+++ b/configure
@@ -3522,7 +3522,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] 17+ messages in thread

* [Qemu-devel] [PATCH 4/7] target-alpha: Add CLIPPER emulation.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
                   ` (2 preceding siblings ...)
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 3/7] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR Richard Henderson
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 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                  |  188 +++++++++
 hw/alpha_pci.c                    |  358 +++++++++++++++++
 hw/alpha_sys.h                    |   44 ++
 hw/alpha_typhoon.c                |  781 +++++++++++++++++++++++++++++++++++++
 6 files changed, 1374 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 cde509b..08fb2ec 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -371,6 +371,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..6fdfabe
--- /dev/null
+++ b/hw/alpha_dp264.c
@@ -0,0 +1,188 @@
+/*
+ * 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];
+    ram_addr_t ram_offset;
+    PCIBus *pci_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_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);
+    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..b321772
--- /dev/null
+++ b/hw/alpha_pci.c
@@ -0,0 +1,358 @@
+/*
+ * 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.  */
+/* ??? Doesn't handle multiple PCI busses.  */
+
+static uint32_t bw_io_readb(void *opaque, target_phys_addr_t addr)
+{
+    return cpu_inb(addr);
+}
+
+static uint32_t bw_io_readw(void *opaque, target_phys_addr_t addr)
+{
+    return cpu_inw(addr);
+}
+
+static uint32_t bw_io_readl(void *opaque, target_phys_addr_t addr)
+{
+    return cpu_inl(addr);
+}
+
+/* PCI IO writes, to byte-word addressable memory.  */
+/* ??? Doesn't handle multiple PCI busses.  */
+
+static void bw_io_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outb(addr, val);
+}
+
+static void bw_io_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outw(addr, val);
+}
+
+static void bw_io_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    cpu_outl(addr, val);
+}
+
+CPUReadMemoryFunc * const alpha_pci_bw_io_reads[] = {
+    bw_io_readb,
+    bw_io_readw,
+    bw_io_readl,
+};
+
+CPUWriteMemoryFunc * const alpha_pci_bw_io_writes[] = {
+    bw_io_writeb,
+    bw_io_writew,
+    bw_io_writel,
+};
+
+/* PCI config space reads, to byte-word addressable memory.  */
+static uint32_t bw_conf1_readb(void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *b = opaque;
+    return pci_data_read(b, addr, 1);
+}
+
+static uint32_t bw_conf1_readw(void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *b = opaque;
+    return pci_data_read(b, addr, 2);
+}
+
+static uint32_t bw_conf1_readl(void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *b = opaque;
+    return pci_data_read(b, addr, 4);
+}
+
+/* PCI config space writes, to byte-word addressable memory.  */
+static void bw_conf1_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *b = opaque;
+    pci_data_write(b, addr, val, 1);
+}
+
+static void bw_conf1_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *b = opaque;
+    pci_data_write(b, addr, val, 2);
+}
+
+static void bw_conf1_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *b = opaque;
+    pci_data_write(b, addr, val, 4);
+}
+
+CPUReadMemoryFunc * const alpha_pci_bw_conf1_reads[] = {
+    bw_conf1_readb,
+    bw_conf1_readw,
+    bw_conf1_readl,
+};
+
+CPUWriteMemoryFunc * const alpha_pci_bw_conf1_writes[] = {
+    bw_conf1_writeb,
+    bw_conf1_writew,
+    bw_conf1_writel,
+};
+
+/* PCI MEM access to dense (but not byte-word addressable) memory.  */
+static uint32_t dense_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *b = opaque;
+    return ldl_phys(pci_to_cpu_addr(b, addr));
+}
+
+static void dense_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t v)
+{
+    PCIBus *b = opaque;
+    stl_phys(pci_to_cpu_addr(b, addr), v);
+}
+
+CPUReadMemoryFunc * const alpha_pci_dense_mem_reads[] = {
+    unassigned_mem_readb,
+    unassigned_mem_readw,
+    dense_mem_readl,
+};
+
+CPUWriteMemoryFunc * const alpha_pci_dense_mem_writes[] = {
+    unassigned_mem_writeb,
+    unassigned_mem_writew,
+    dense_mem_writel,
+};
+
+/* PCI IO to sparse memory.  These are helper routines, which expect that the
+   relevant HAE has already been prepended to ADDR by the core-specific
+   routine that is actually registered with the memory region.  */
+
+uint32_t alpha_sparse_io_read(target_phys_addr_t addr)
+{
+    int size = (addr >> 3) & 3;
+    uint32_t val;
+
+    addr >>= 5;
+    switch (size) {
+    case 0:
+        /* byte access */
+        val = cpu_inb(addr);
+        break;
+    case 1:
+        /* word access */
+        val = cpu_inw(addr);
+        break;
+    case 2:
+        /* tri-byte access; apparently possible with real pci lines.  */
+        qemu_log("pci: tri-byte io read");
+        return ~0u;
+    default:
+        /* long access */
+        return cpu_inl(addr);
+    }
+
+    val <<= (addr & 3) * 8;
+    return val;
+}
+
+void alpha_sparse_io_write(target_phys_addr_t addr, uint32_t val)
+{
+    int size = (addr >> 3) & 3;
+
+    addr >>= 5;
+    switch (size) {
+    case 0:
+        /* byte access */
+        val >>= (addr & 3) * 8;
+        cpu_outb(addr, val);
+        break;
+    case 1:
+        /* word access */
+        val >>= (addr & 3) * 8;
+        cpu_outw(addr, val);
+        break;
+    case 2:
+        /* tri-byte access; apparently possible with real pci lines.  */
+        qemu_log("pci: tri-byte io write");
+        break;
+    default:
+        /* long access */
+        cpu_outl(addr, val);
+        break;
+    }
+}
+
+uint32_t alpha_sparse_mem_read(PCIBus *b, target_phys_addr_t addr)
+{
+    int size = (addr >> 3) & 3;
+    uint32_t val;
+
+    addr = pci_to_cpu_addr(b, addr >> 5);
+    switch (size) {
+    case 0:
+        /* byte access */
+        val = ldub_phys(addr);
+        break;
+    case 1:
+        /* word access */
+        val = lduw_phys(addr);
+        break;
+    case 2:
+        /* tri-byte access; apparently possible with real pci lines.  */
+        qemu_log("pci: tri-byte mem read");
+        return ~0u;
+    default:
+        /* long access */
+        return ldl_phys(addr);
+    }
+
+    val <<= (addr & 3) * 8;
+    return val;
+}
+
+void alpha_sparse_mem_write(PCIBus *b, target_phys_addr_t addr, uint32_t val)
+{
+    int size = (addr >> 3) & 3;
+
+    addr = pci_to_cpu_addr(b, addr >> 5);
+    switch (size) {
+    case 0:
+        /* byte access */
+        val >>= (addr & 3) * 8;
+        stb_phys(addr, val);
+        break;
+    case 1:
+        /* word access */
+        val >>= (addr & 3) * 8;
+        stw_phys(addr, val);
+        break;
+    case 2:
+        /* tri-byte access; apparently possible with real pci lines.  */
+        qemu_log("pci: tri-byte mem write");
+        break;
+    default:
+        /* long access */
+        stl_phys(addr, val);
+        break;
+    }
+}
+
+uint32_t alpha_sparse_conf1_read(PCIBus *b, target_phys_addr_t addr)
+{
+    int size = ((addr >> 3) & 3) + 1;
+    uint32_t val;
+
+    if (size == 3) {
+        qemu_log("pci: tri-byte configuration read");
+        return ~0u;
+    }
+
+    addr >>= 5;
+    val = pci_data_read(b, addr, size);
+    val <<= (addr & 3) * 8;
+
+    return val;
+}
+
+void alpha_sparse_conf1_write(PCIBus *b, target_phys_addr_t addr, uint32_t val)
+{
+    int size = ((addr >> 3) & 3) + 1;
+
+    if (size == 3) {
+        qemu_log("pci: tri-byte configuration write");
+        return;
+    }
+
+    addr >>= 5;
+    val >>= (addr & 3) * 8;
+    pci_data_write(b, addr, val, size);
+}
+
+/* Configuration space accesses do not normall use an HAE.  */
+static uint32_t sparse_conf1_readl(void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *b = opaque;
+    return alpha_sparse_conf1_read(b, addr);
+}
+
+static void sparse_conf1_writel(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    PCIBus *b = opaque;
+    alpha_sparse_conf1_write(b, addr, val);
+}
+
+CPUReadMemoryFunc * const alpha_pci_sparse_conf1_reads[] = {
+    unassigned_mem_readb,
+    unassigned_mem_readw,
+    sparse_conf1_readl,
+};
+
+CPUWriteMemoryFunc * const alpha_pci_sparse_conf1_writes[] = {
+    unassigned_mem_writeb,
+    unassigned_mem_writew,
+    sparse_conf1_writel,
+};
+
+/* PCI/EISA Interrupt Acknowledge Cycle.  */
+
+static uint32_t iack_readl(void *opaque, target_phys_addr_t addr)
+{
+    if (addr & 15) {
+        return unassigned_mem_readl(opaque, addr);
+    }
+    return pic_read_irq(isa_pic);
+}
+
+static void special_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    qemu_log("pci: special write cycle %08x", val);
+}
+
+CPUReadMemoryFunc * const alpha_pci_iack_reads[] = {
+    unassigned_mem_readb,
+    unassigned_mem_readw,
+    iack_readl,
+};
+
+CPUWriteMemoryFunc * const alpha_pci_special_writes[] = {
+    unassigned_mem_writeb,
+    unassigned_mem_writew,
+    special_writel,
+};
+\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..98e5351
--- /dev/null
+++ b/hw/alpha_sys.h
@@ -0,0 +1,44 @@
+/* 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"
+
+
+extern PCIBus *typhoon_init(qemu_irq *p_isa_irq, qemu_irq *p_rtc_irq,
+                            CPUState *cpus[3], pci_map_irq_fn sys_map_irq);
+
+/* alpha_pci.c.  */
+extern CPUReadMemoryFunc * const alpha_pci_bw_io_reads[];
+extern CPUWriteMemoryFunc * const alpha_pci_bw_io_writes[];
+extern CPUReadMemoryFunc * const alpha_pci_bw_conf1_reads[];
+extern CPUWriteMemoryFunc * const alpha_pci_bw_conf1_writes[];
+
+extern CPUReadMemoryFunc * const alpha_pci_dense_mem_reads[];
+extern CPUWriteMemoryFunc * const alpha_pci_dense_mem_writes[];
+
+extern CPUReadMemoryFunc * const alpha_pci_sparse_conf1_reads[];
+extern CPUWriteMemoryFunc * const alpha_pci_sparse_conf1_writes[];
+
+extern CPUReadMemoryFunc * const alpha_pci_iack_reads[];
+extern CPUWriteMemoryFunc * const alpha_pci_special_writes[];
+
+extern uint32_t alpha_sparse_io_read(target_phys_addr_t);
+extern void alpha_sparse_io_write(target_phys_addr_t, uint32_t);
+
+extern uint32_t alpha_sparse_mem_read(PCIBus *, target_phys_addr_t);
+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
diff --git a/hw/alpha_typhoon.c b/hw/alpha_typhoon.c
new file mode 100644
index 0000000..7cdf7d3
--- /dev/null
+++ b/hw/alpha_typhoon.c
@@ -0,0 +1,781 @@
+/*
+ * 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"
+
+typedef struct TyphoonCchip {
+    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 {
+    uint64_t ctl;
+    TyphoonWindow win[4];
+} TyphoonPchip;
+
+typedef struct TyphoonState {
+    PCIHostState host;
+
+    TyphoonCchip cchip;
+    TyphoonPchip pchip;
+
+    /* 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 uint32_t cchip_readl(void *opaque, target_phys_addr_t addr)
+{
+    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:
+        do_unassigned_access(addr, 0, 0, 0, 4);
+        return -1;
+    }
+
+    s->latch_tmp = ret >> 32;
+    return ret;
+}
+
+static uint32_t dchip_readl(void *opaque, target_phys_addr_t addr)
+{
+    /* Skip this.  It's all related to DRAM timing and setup.  */
+    return 0;
+}
+
+static uint32_t pchip_readl(void *opaque, target_phys_addr_t addr)
+{
+    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:
+        do_unassigned_access(addr, 0, 0, 0, 4);
+        return -1;
+    }
+
+    s->latch_tmp = ret >> 32;
+    return ret;
+}
+
+static void cchip_writel(void *opaque, target_phys_addr_t addr, uint32_t v32)
+{
+    TyphoonState *s = opaque;
+    uint64_t val, oldval, newval;
+
+    if (addr & 4) {
+        val = (uint64_t)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:
+        do_unassigned_access(addr, 1, 0, 0, 4);
+        return;
+    }
+}
+
+static void dchip_writel(void *opaque, target_phys_addr_t addr, uint32_t v32)
+{
+    /* Skip this.  It's all related to DRAM timing and setup.  */
+}
+
+static void pchip_writel(void *opaque, target_phys_addr_t addr, uint32_t v32)
+{
+    TyphoonState *s = opaque;
+    uint64_t val, oldval;
+
+    switch (addr) {
+    case 0x0000:
+        /* WSBA0: Window Space Base Address Register.  */
+        s->pchip.win[0].base_addr = v32;
+        break;
+    case 0x0040:
+        /* WSBA1 */
+        s->pchip.win[1].base_addr = v32;
+        break;
+    case 0x0080:
+        /* WSBA2 */
+        s->pchip.win[2].base_addr = v32;
+        break;
+    case 0x00c0:
+        /* WSBA3 */
+        s->pchip.win[3].base_addr = v32;
+        break;
+
+    case 0x0100:
+        /* WSM0: Window Space Mask Register.  */
+        s->pchip.win[0].mask = v32;
+        break;
+    case 0x0140:
+        /* WSM1 */
+        s->pchip.win[1].mask = v32;
+        break;
+    case 0x0180:
+        /* WSM2 */
+        s->pchip.win[2].mask = v32;
+        break;
+    case 0x01c0:
+        /* WSM3 */
+        s->pchip.win[3].mask = v32;
+        break;
+
+    case 0x0200:
+        /* TBA0: Translated Base Address Register.  */
+        s->pchip.win[0].translated_base_pfn = v32 >> 10;
+        break;
+    case 0x0240:
+        /* TBA1 */
+        s->pchip.win[1].translated_base_pfn = v32 >> 10;
+        break;
+    case 0x0280:
+        /* TBA2 */
+        s->pchip.win[2].translated_base_pfn = v32 >> 10;
+        break;
+    case 0x02c0:
+        /* TBA3 */
+        s->pchip.win[3].translated_base_pfn = v32 >> 10;
+        break;
+
+    case 0x0004:
+    case 0x0044:
+    case 0x0084:
+    case 0x00c4:
+    case 0x0104:
+    case 0x0144:
+    case 0x0184:
+    case 0x01c4:
+    case 0x0204:
+    case 0x0244:
+    case 0x0284:
+    case 0x02c4:
+        /* MBZ high-part portions of the above registers.  */
+        break;
+
+    case 0x0300:
+        /* PCTL: Pchip Control Register.  */
+        s->latch_tmp = v32;
+        break;
+    case 0x0304:
+        val = (uint64_t)v32 << 32 | s->latch_tmp;
+
+        oldval = s->pchip.ctl;
+        oldval &= ~0x00001cff0fc7ffull;       /* RW fields */
+        oldval |= val & 0x00001cff0fc7ffull;
+
+        s->pchip.ctl = oldval;
+        break;
+
+    case 0x0340: case 0x0344:
+        /* PLAT: Pchip Master Latency Register.  */
+        break;
+    case 0x03c0: case 0x03c4:
+        /* PERROR: Pchip Error Register.  */
+        break;
+    case 0x0400: case 0x0404:
+        /* PERRMASK: Pchip Error Mask Register.  */
+        break;
+    case 0x0440: case 0x0444:
+        /* PERRSET: Pchip Error Set Register.  */
+        break;
+
+    case 0x0480:
+        /* TLBIV: Translation Buffer Invalidate Virtual Register.  */
+        s->latch_tmp = v32;
+        break;
+    case 0x0484:
+        val = (uint64_t)v32 << 32 | s->latch_tmp;
+        break;
+
+    case 0x04c0:
+        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */
+        break;
+    case 0x04c4:
+        break;
+
+    case 0x0500: case 0x0504:
+        /* PMONCTL */
+    case 0x0540: case 0x0544:
+        /* PMONCNT */
+    case 0x0800: case 0x0804:
+        /* SPRST */
+        break;
+
+    default:
+        do_unassigned_access(addr, 1, 0, 0, 4);
+        return;
+    }
+}
+
+static CPUReadMemoryFunc * const cchip_reads[] = {
+    NULL,
+    NULL,
+    cchip_readl
+};
+
+static CPUWriteMemoryFunc * const cchip_writes[] = {
+    NULL,
+    NULL,
+    cchip_writel
+};
+
+static CPUReadMemoryFunc * const dchip_reads[] = {
+    NULL,
+    NULL,
+    dchip_readl
+};
+
+static CPUWriteMemoryFunc * const dchip_writes[] = {
+    NULL,
+    NULL,
+    dchip_writel
+};
+
+static CPUReadMemoryFunc * const pchip_reads[] = {
+    NULL,
+    NULL,
+    pchip_readl 
+};
+
+static CPUWriteMemoryFunc * const pchip_writes[] = {
+    NULL,
+    NULL,
+    pchip_writel
+};
+
+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(qemu_irq *p_isa_irq, qemu_irq *p_rtc_irq,
+                     CPUState *cpus[3], pci_map_irq_fn sys_map_irq)
+{
+    const uint64_t MB = 1024 * 1024;
+    DeviceState *dev;
+    PCIHostState *p;
+    TyphoonState *s;
+    PCIBus *b;
+    int 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 *));
+
+    *p_isa_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
+    *p_rtc_irq = *qemu_allocate_irqs(typhoon_set_timer_irq, s, 1);
+
+    b = pci_register_bus(&s->host.busdev.qdev, "pci", typhoon_set_irq,
+                         sys_map_irq, s, 0, 64);
+    s->host.bus = b;
+
+    qdev_init_nofail(dev);
+
+    /* Main memory region, 0x00.0000.0000.  Real hardware supports 32GB,
+       but the address space hole reserved at this point is 8TB.  */
+
+    /* Pchip0 PCI memory, 0x800.0000.0000, 4GB.  */
+    pci_bus_set_mem_base(b, 0x80000000000ull);
+
+    /* 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.  */
+    region = cpu_register_io_memory(pchip_reads, pchip_writes, s,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x80180000000, 256*MB, region);
+
+    /* Cchip CSRs, 0x801.A000.0000, 256MB.  */
+    region = cpu_register_io_memory(cchip_reads, cchip_writes, s,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x801a0000000, 256*MB, region);
+
+    /* Dchip CSRs, 0x801.B000.0000, 256MB.  */
+    region = cpu_register_io_memory(dchip_reads, dchip_writes, s,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x801b0000000, 256*MB, region);
+
+    /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
+    region = cpu_register_io_memory(alpha_pci_iack_reads,
+                                    alpha_pci_special_writes, b,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x801f8000000, 64*MB, region);
+
+    /* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB.  */
+    region = cpu_register_io_memory(alpha_pci_bw_io_reads,
+                                    alpha_pci_bw_io_writes, b,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x801fc000000, 32*MB, region);
+
+    /* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB.  */
+    region = cpu_register_io_memory(alpha_pci_bw_conf1_reads,
+                                    alpha_pci_bw_conf1_writes, b,
+                                    DEVICE_LITTLE_ENDIAN);
+    cpu_register_physical_memory(0x801fe000000, 16*MB, region);
+
+    /* 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.  */
+
+    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] 17+ messages in thread

* [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
                   ` (3 preceding siblings ...)
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 4/7] target-alpha: Add " Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-30 11:07   ` Blue Swirl
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 6/7] target-alpha: Implement HALT IPR Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 7/7] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
  6 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 UTC (permalink / raw)
  To: qemu-devel

---
 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 c61906a..fddaff8 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] 17+ messages in thread

* [Qemu-devel] [PATCH 6/7] target-alpha: Implement HALT IPR.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
                   ` (4 preceding siblings ...)
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 7/7] target-alpha: Add high-resolution access to wall clock and an alarm Richard Henderson
  6 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 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 8f39154..ad85e4c 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 fddaff8..b1609e3 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] 17+ messages in thread

* [Qemu-devel] [PATCH 7/7] target-alpha: Add high-resolution access to wall clock and an alarm.
  2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
                   ` (5 preceding siblings ...)
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 6/7] target-alpha: Implement HALT IPR Richard Henderson
@ 2011-07-23 19:17 ` Richard Henderson
  6 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-23 19:17 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       |   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 919be12..d0b569b 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 ad85e4c..623f1c3 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 b1609e3..f386d21 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] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions Richard Henderson
@ 2011-07-24 13:28   ` Anthony Liguori
  2011-07-24 16:42     ` Richard Henderson
  0 siblings, 1 reply; 17+ messages in thread
From: Anthony Liguori @ 2011-07-24 13:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On 07/23/2011 02:17 PM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson<rth@twiddle.net>

Why?

Regards,

Anthony Liguori

> ---
>   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 44b04b3..78e1bad 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 2160ded..c00badd 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -3232,7 +3232,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);
> @@ -3243,7 +3243,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);
> @@ -3254,7 +3254,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);
> @@ -3265,7 +3265,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);
> @@ -3275,7 +3275,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);
> @@ -3285,7 +3285,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);

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-24 13:28   ` Anthony Liguori
@ 2011-07-24 16:42     ` Richard Henderson
  2011-07-24 18:56       ` Anthony Liguori
  0 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2011-07-24 16:42 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 07/24/2011 06:28 AM, Anthony Liguori wrote:
> On 07/23/2011 02:17 PM, Richard Henderson wrote:
>> Signed-off-by: Richard Henderson<rth@twiddle.net>
> 
> Why?

So that I can write i/o functions like this:

  switch (addr) {
  case 0: ...
  case 64: ...
  case 128: ...
  ...
  default:
    unassigned_mem_readl(...)
  }

Perhaps Avi's rewrite makes this unnecessary; I browsed through
his patch set but didn't immediately see if there's a way for
the i/o function to return "failure".

What I certainly don't want to do is write this with 100 tiny
functions registering 8 bytes each, registered some tiny 
distance away from each other.


r~

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-24 16:42     ` Richard Henderson
@ 2011-07-24 18:56       ` Anthony Liguori
  2011-07-24 19:00         ` Richard Henderson
  2011-08-04 23:58         ` Edgar E. Iglesias
  0 siblings, 2 replies; 17+ messages in thread
From: Anthony Liguori @ 2011-07-24 18:56 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On 07/24/2011 11:42 AM, Richard Henderson wrote:
> On 07/24/2011 06:28 AM, Anthony Liguori wrote:
>> On 07/23/2011 02:17 PM, Richard Henderson wrote:
>>> Signed-off-by: Richard Henderson<rth@twiddle.net>
>>
>> Why?
>
> So that I can write i/o functions like this:
>
>    switch (addr) {
>    case 0: ...
>    case 64: ...
>    case 128: ...
>    ...
>    default:
>      unassigned_mem_readl(...)
>    }
>
> Perhaps Avi's rewrite makes this unnecessary; I browsed through
> his patch set but didn't immediately see if there's a way for
> the i/o function to return "failure".

What is returned by totally unregistered MMIO is defined by the chipset. 
  What's returned by an empty space in the MMIO space of a device is 
device specific.

What does your device return if there's an access at 32?

Regards,

Anthony Liguori

>
> What I certainly don't want to do is write this with 100 tiny
> functions registering 8 bytes each, registered some tiny
> distance away from each other.
>
>
> r~
>

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-24 18:56       ` Anthony Liguori
@ 2011-07-24 19:00         ` Richard Henderson
  2011-07-25  1:47           ` Anthony Liguori
  2011-08-04 23:58         ` Edgar E. Iglesias
  1 sibling, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2011-07-24 19:00 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 07/24/2011 11:56 AM, Anthony Liguori wrote:
> What is returned by totally unregistered MMIO is defined by the
> chipset. What's returned by an empty space in the MMIO space of a
> device is device specific.

It's one and the same here, it's the chipset I'm implementing.

> What does your device return if there's an access at 32?

A machine check.


r~

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-24 19:00         ` Richard Henderson
@ 2011-07-25  1:47           ` Anthony Liguori
  2011-07-25  2:14             ` Richard Henderson
  0 siblings, 1 reply; 17+ messages in thread
From: Anthony Liguori @ 2011-07-25  1:47 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On 07/24/2011 02:00 PM, Richard Henderson wrote:
> On 07/24/2011 11:56 AM, Anthony Liguori wrote:
>> What is returned by totally unregistered MMIO is defined by the
>> chipset. What's returned by an empty space in the MMIO space of a
>> device is device specific.
>
> It's one and the same here, it's the chipset I'm implementing.

Sorry if its obvious, which patch in the series actually uses this?

Regards,

Anthony Liguori

>> What does your device return if there's an access at 32?
>
> A machine check.
>
>
> r~
>

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-25  1:47           ` Anthony Liguori
@ 2011-07-25  2:14             ` Richard Henderson
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-07-25  2:14 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

On 07/24/2011 06:47 PM, Anthony Liguori wrote:
> On 07/24/2011 02:00 PM, Richard Henderson wrote:
>> On 07/24/2011 11:56 AM, Anthony Liguori wrote:
>>> What is returned by totally unregistered MMIO is defined by the
>>> chipset. What's returned by an empty space in the MMIO space of a
>>> device is device specific.
>>
>> It's one and the same here, it's the chipset I'm implementing.
> 
> Sorry if its obvious, which patch in the series actually uses this?

4/7, see hw/alpha_typhoon.c.


r~

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

* Re: [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR.
  2011-07-23 19:17 ` [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR Richard Henderson
@ 2011-07-30 11:07   ` Blue Swirl
  0 siblings, 0 replies; 17+ messages in thread
From: Blue Swirl @ 2011-07-30 11:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Sat, Jul 23, 2011 at 10:17 PM, Richard Henderson <rth@twiddle.net> wrote:
> ---

Misses SoB and I don't know how to add it while pulling. Please fix or educate.

>  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 c61906a..fddaff8 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	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-07-24 18:56       ` Anthony Liguori
  2011-07-24 19:00         ` Richard Henderson
@ 2011-08-04 23:58         ` Edgar E. Iglesias
  2011-08-05 15:39           ` Richard Henderson
  1 sibling, 1 reply; 17+ messages in thread
From: Edgar E. Iglesias @ 2011-08-04 23:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Avi Kivity, qemu-devel, Richard Henderson

On Sun, Jul 24, 2011 at 01:56:00PM -0500, Anthony Liguori wrote:
> On 07/24/2011 11:42 AM, Richard Henderson wrote:
> >On 07/24/2011 06:28 AM, Anthony Liguori wrote:
> >>On 07/23/2011 02:17 PM, Richard Henderson wrote:
> >>>Signed-off-by: Richard Henderson<rth@twiddle.net>
> >>
> >>Why?
> >
> >So that I can write i/o functions like this:
> >
> >   switch (addr) {
> >   case 0: ...
> >   case 64: ...
> >   case 128: ...
> >   ...
> >   default:
> >     unassigned_mem_readl(...)
> >   }
> >
> >Perhaps Avi's rewrite makes this unnecessary; I browsed through
> >his patch set but didn't immediately see if there's a way for
> >the i/o function to return "failure".
> 
> What is returned by totally unregistered MMIO is defined by the
> chipset.  What's returned by an empty space in the MMIO space of a
> device is device specific.

Not really, IMO.

Im not going to say that HW does it this way or another because
different HW may do it different ways, but from my experience this
how most HW generally works:

Accesses to unmapped addresses are decoded, routed and finally handled
by the first node that realizes that the addr is unmapped. The action
might be to ignore or to signal some kind of error. AFAIK, most systems
will signal the error by sending an error back to the CPU via dedicated
control signals or by raising interrupts (the latter is very uncommon).

The common case is to signal an error via ctrl signals on the bus that
go back to the CPU and the final decision on what to do is made by the
CPU. QEMU currently doesnt model ctrl lines for bus accesses so entering
a per CPU xxx_unassigned_acceess function is pretty much in line with
most HW.

QEMU only models the data lanes so I think Richards patch is quite OK
because it brings the decission back to the CPU model.

I would prefer though, if the new Memory API would let devices pass
ctrl data back to the CPU in addition to the data lanes. That would
probably involve quite a bit of work though. CC:ing Avi, you might
have more input on this.

Cheers

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

* Re: [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions.
  2011-08-04 23:58         ` Edgar E. Iglesias
@ 2011-08-05 15:39           ` Richard Henderson
  0 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2011-08-05 15:39 UTC (permalink / raw)
  To: Edgar E. Iglesias; +Cc: Avi Kivity, qemu-devel

On 08/04/2011 04:58 PM, Edgar E. Iglesias wrote:
> QEMU only models the data lanes so I think Richards patch is quite OK
> because it brings the decission back to the CPU model.
> 
> I would prefer though, if the new Memory API would let devices pass
> ctrl data back to the CPU in addition to the data lanes. That would
> probably involve quite a bit of work though. CC:ing Avi, you might
> have more input on this.

Amusingly, after having updated my system to Avi's tree, I find
I don't need the unassigned_mem_read[bwl] helpers anymore, but
only the cpu_unassigned_access function, which is already exported.

It would be nice if the new api allowed signaling of errors, but
I can't think of a really nice way of doing that.


r~

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

end of thread, other threads:[~2011-08-05 15:39 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-23 19:17 [Qemu-devel] [PULL 0/7] Alpha system emulation, v7 Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 1/7] Export the unassigned_mem read/write functions Richard Henderson
2011-07-24 13:28   ` Anthony Liguori
2011-07-24 16:42     ` Richard Henderson
2011-07-24 18:56       ` Anthony Liguori
2011-07-24 19:00         ` Richard Henderson
2011-07-25  1:47           ` Anthony Liguori
2011-07-25  2:14             ` Richard Henderson
2011-08-04 23:58         ` Edgar E. Iglesias
2011-08-05 15:39           ` Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 2/7] pci: Export pci_to_cpu_addr Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 3/7] target-alpha: Add custom PALcode image for CLIPPER emulation Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 4/7] target-alpha: Add " Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 5/7] target-alpha: Implement WAIT IPR Richard Henderson
2011-07-30 11:07   ` Blue Swirl
2011-07-23 19:17 ` [Qemu-devel] [PATCH 6/7] target-alpha: Implement HALT IPR Richard Henderson
2011-07-23 19:17 ` [Qemu-devel] [PATCH 7/7] target-alpha: Add high-resolution access to wall clock and an alarm 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.