aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-05-08 17:03:26 -0500
committerRichard Henderson <richard.henderson@linaro.org>2022-05-08 17:03:26 -0500
commit554623226f800acf48a2ed568900c1c968ec9a8b (patch)
tree45a268e82093ef2c2cd032a64d816dd069641fa7
parentf1336649156cf57f5d874a98e619fb362e3fcb59 (diff)
parent1f110516190f146df40f49aef2f1ef5903b8f540 (diff)
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging
qemu-sparc queue # -----BEGIN PGP SIGNATURE----- # # iQFSBAABCgA8FiEEzGIauY6CIA2RXMnEW8LFb64PMh8FAmJ4A6ceHG1hcmsuY2F2 # ZS1heWxhbmRAaWxhbmRlLmNvLnVrAAoJEFvCxW+uDzIf4SAH+weljMrdObceJ4vg # MedvVXUGmr0Uzk0iSkac1FGLCwEC/9bzBMrxMxNCsGHwVWjuX7S9Vikj/4mMi15U # 6iJ56QzVbsxZknr2+gGtB4QEAWHlQSuSrvcFVFc+Vc9enCBZNZoaehF0HzUSUFxU # nMnZQqDWrc4H9D2E+YK4OLgv3IMqOy3uKWMgIZ7JJX6YebLMXqZV1mq2G9LjKf9X # zM3HM6V9yd+1UEzb5biHkorBcdyt5F8P/V1VtiGZYFws27UwSBxW9EEDV3XcSGYD # kS9RpYka4qmC0saj5cBUR/AYQ/jwSbI9kEs4VsBzRQ/eX25F5TPEbyXp6bJZ75Gi # tsOhvvg= # =Qnnm # -----END PGP SIGNATURE----- # gpg: Signature made Sun 08 May 2022 12:53:43 PM CDT # gpg: using RSA key CC621AB98E82200D915CC9C45BC2C56FAE0F321F # gpg: issuer "mark.cave-ayland@ilande.co.uk" # gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: CC62 1AB9 8E82 200D 915C C9C4 5BC2 C56F AE0F 321F * tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu: (53 commits) artist: only render dirty scanlines on the display surface artist: remove unused ROP8OFF() macro artist: checkpatch and newline style fixes hppa: simplify machine function names in machine.c hppa: fold machine_hppa_machine_init() into machine_hppa_machine_init_class_init() hppa: use MACHINE QOM macros for defining the hppa machine hppa: remove the empty hppa_sys.h file hppa: move enable_lan() define from hppa_sys.h to machine.c hppa: remove unused trace-events from from hw/hppa hppa: remove hw/hppa/pci.c hppa: move hppa_pci_ignore_ops from pci.c to machine.c lasi: move from hw/hppa to hw/misc hppa: move device headers from hppa_sys.h into individual .c files lasi: use numerical constant for iar reset value lasi: use constants for device register offsets lasi: move lasi_initfn() to machine.c lasi: remove address space parameter from lasi_initfn() lasi: move PS2 initialisation to machine.c lasi: move second serial port initialisation to machine.c lasi: move parallel port initialisation to machine.c ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--MAINTAINERS4
-rw-r--r--configs/devices/hppa-softmmu/default.mak2
-rw-r--r--hw/display/artist.c33
-rw-r--r--hw/hppa/Kconfig5
-rw-r--r--hw/hppa/hppa_hardware.h5
-rw-r--r--hw/hppa/hppa_sys.h24
-rw-r--r--hw/hppa/machine.c124
-rw-r--r--hw/hppa/meson.build2
-rw-r--r--hw/hppa/pci.c88
-rw-r--r--hw/hppa/trace-events14
-rw-r--r--hw/misc/Kconfig3
-rw-r--r--hw/misc/lasi.c (renamed from hw/hppa/lasi.c)161
-rw-r--r--hw/misc/meson.build3
-rw-r--r--hw/misc/trace-events5
-rw-r--r--hw/pci-host/Kconfig4
-rw-r--r--hw/pci-host/dino.c (renamed from hw/hppa/dino.c)231
-rw-r--r--hw/pci-host/meson.build3
-rw-r--r--hw/pci-host/trace-events5
-rw-r--r--include/hw/misc/lasi.h78
-rw-r--r--include/hw/pci-host/dino.h146
-rw-r--r--meson.build1
21 files changed, 477 insertions, 464 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 218c9459b6..662ec47246 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1113,7 +1113,11 @@ S: Odd Fixes
F: configs/devices/hppa-softmmu/default.mak
F: hw/hppa/
F: hw/net/*i82596*
+F: hw/misc/lasi.c
+F: hw/pci-host/dino.c
+F: include/hw/misc/lasi.h
F: include/hw/net/lasi_82596.h
+F: include/hw/pci-host/dino.h
F: pc-bios/hppa-firmware.img
M68K Machines
diff --git a/configs/devices/hppa-softmmu/default.mak b/configs/devices/hppa-softmmu/default.mak
index b64c5eb3ff..b0364bb88f 100644
--- a/configs/devices/hppa-softmmu/default.mak
+++ b/configs/devices/hppa-softmmu/default.mak
@@ -6,4 +6,4 @@
# Boards:
#
-CONFIG_DINO=y
+CONFIG_HPPA_B160L=y
diff --git a/hw/display/artist.c b/hw/display/artist.c
index 8e121bb0b4..39fc0c4ca5 100644
--- a/hw/display/artist.c
+++ b/hw/display/artist.c
@@ -25,12 +25,6 @@
#define TYPE_ARTIST "artist"
OBJECT_DECLARE_SIMPLE_TYPE(ARTISTState, ARTIST)
-#if HOST_BIG_ENDIAN
-#define ROP8OFF(_i) (3 - (_i))
-#else
-#define ROP8OFF
-#endif
-
struct vram_buffer {
MemoryRegion mr;
uint8_t *data;
@@ -211,8 +205,9 @@ static void artist_invalidate_lines(struct vram_buffer *buf,
int start = starty * buf->width;
int size;
- if (starty + height > buf->height)
+ if (starty + height > buf->height) {
height = buf->height - starty;
+ }
size = height * buf->width;
@@ -321,8 +316,9 @@ static void artist_get_cursor_pos(ARTISTState *s, int *x, int *y)
}
lx = artist_get_x(s->cursor_pos);
- if (lx < offset)
+ if (lx < offset) {
offset = lx;
+ }
*x = (lx - offset) / 2;
*y = 1146 - artist_get_y(s->cursor_pos);
@@ -343,6 +339,7 @@ static void artist_get_cursor_pos(ARTISTState *s, int *x, int *y)
static void artist_invalidate_cursor(ARTISTState *s)
{
int x, y;
+
artist_get_cursor_pos(s, &x, &y);
artist_invalidate_lines(&s->vram_buffer[ARTIST_BUFFER_AP],
y, s->cursor_height);
@@ -470,10 +467,9 @@ static void draw_line(ARTISTState *s,
if ((x1 >= buf->width && x2 >= buf->width) ||
(y1 >= buf->height && y2 >= buf->height)) {
- return;
+ return;
}
-
if (update_start) {
s->vram_start = (x2 << 16) | y2;
}
@@ -553,15 +549,15 @@ static void draw_line(ARTISTState *s,
x++;
} while (x <= x2 && (max_pix == -1 || --max_pix > 0));
- if (c1)
+ if (c1) {
artist_invalidate_lines(buf, x1, x2 - x1);
- else
+ } else {
artist_invalidate_lines(buf, y1 > y2 ? y2 : y1, x2 - x1);
+ }
}
static void draw_line_pattern_start(ARTISTState *s)
{
-
int startx = artist_get_x(s->vram_start);
int starty = artist_get_y(s->vram_start);
int endx = artist_get_x(s->blockmove_size);
@@ -574,7 +570,6 @@ static void draw_line_pattern_start(ARTISTState *s)
static void draw_line_pattern_next(ARTISTState *s)
{
-
int startx = artist_get_x(s->vram_start);
int starty = artist_get_y(s->vram_start);
int endx = artist_get_x(s->blockmove_size);
@@ -589,7 +584,6 @@ static void draw_line_pattern_next(ARTISTState *s)
static void draw_line_size(ARTISTState *s, bool update_start)
{
-
int startx = artist_get_x(s->vram_start);
int starty = artist_get_y(s->vram_start);
int endx = artist_get_x(s->line_size);
@@ -600,7 +594,6 @@ static void draw_line_size(ARTISTState *s, bool update_start)
static void draw_line_xy(ARTISTState *s, bool update_start)
{
-
int startx = artist_get_x(s->vram_start);
int starty = artist_get_y(s->vram_start);
int sizex = artist_get_x(s->blockmove_size);
@@ -650,7 +643,6 @@ static void draw_line_xy(ARTISTState *s, bool update_start)
static void draw_line_end(ARTISTState *s, bool update_start)
{
-
int startx = artist_get_x(s->vram_start);
int starty = artist_get_y(s->vram_start);
int endx = artist_get_x(s->line_end);
@@ -835,6 +827,7 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
{
ARTISTState *s = opaque;
+
s->vram_char_y = 0;
trace_artist_vram_write(size, addr, val);
vram_bit_write(opaque, addr, 0, val, size);
@@ -1244,20 +1237,22 @@ static void artist_update_display(void *opaque)
DisplaySurface *surface = qemu_console_surface(s->con);
int first = 0, last;
-
framebuffer_update_display(surface, &s->fbsection, s->width, s->height,
s->width, s->width * 4, 0, 0, artist_draw_line,
s, &first, &last);
artist_draw_cursor(s);
- dpy_gfx_update(s->con, 0, 0, s->width, s->height);
+ if (first >= 0) {
+ dpy_gfx_update(s->con, 0, first, s->width, last - first + 1);
+ }
}
static void artist_invalidate(void *opaque)
{
ARTISTState *s = ARTIST(opaque);
struct vram_buffer *buf = &s->vram_buffer[ARTIST_BUFFER_AP];
+
memory_region_set_dirty(&buf->mr, 0, buf->size);
}
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig
index 22948db025..5dd8b5b21e 100644
--- a/hw/hppa/Kconfig
+++ b/hw/hppa/Kconfig
@@ -1,9 +1,10 @@
-config DINO
+config HPPA_B160L
bool
imply PCI_DEVICES
imply E1000_PCI
imply VIRTIO_VGA
- select PCI
+ select DINO
+ select LASI
select SERIAL
select ISA_BUS
select I8259
diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h
index 5edf577563..8b6b9222cb 100644
--- a/hw/hppa/hppa_hardware.h
+++ b/hw/hppa/hppa_hardware.h
@@ -30,11 +30,6 @@
#define PCI_HPA DINO_HPA /* PCI bus */
#define IDE_HPA 0xf9000000 /* Boot disc controller */
-/* offsets to DINO HPA: */
-#define DINO_PCI_ADDR 0x064
-#define DINO_CONFIG_DATA 0x068
-#define DINO_IO_DATA 0x06c
-
#define PORT_PCI_CMD (PCI_HPA + DINO_PCI_ADDR)
#define PORT_PCI_DATA (PCI_HPA + DINO_CONFIG_DATA)
diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h
deleted file mode 100644
index 0b18271cc9..0000000000
--- a/hw/hppa/hppa_sys.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* HPPA cores and system support chips. */
-
-#ifndef HW_HPPA_SYS_H
-#define HW_HPPA_SYS_H
-
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_host.h"
-#include "hw/boards.h"
-#include "hw/intc/i8259.h"
-
-#include "hppa_hardware.h"
-
-PCIBus *dino_init(MemoryRegion *, qemu_irq *, qemu_irq *);
-DeviceState *lasi_init(MemoryRegion *);
-#define enable_lasi_lan() 0
-
-#define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
-
-/* hppa_pci.c. */
-extern const MemoryRegionOps hppa_pci_ignore_ops;
-extern const MemoryRegionOps hppa_pci_conf1_ops;
-extern const MemoryRegionOps hppa_pci_iack_ops;
-
-#endif
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index f7595c0857..ae0bc07e75 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -15,9 +15,15 @@
#include "hw/rtc/mc146818rtc.h"
#include "hw/timer/i8254.h"
#include "hw/char/serial.h"
+#include "hw/char/parallel.h"
+#include "hw/intc/i8259.h"
+#include "hw/input/lasips2.h"
#include "hw/net/lasi_82596.h"
#include "hw/nmi.h"
-#include "hppa_sys.h"
+#include "hw/pci/pci.h"
+#include "hw/pci-host/dino.h"
+#include "hw/misc/lasi.h"
+#include "hppa_hardware.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "net/net.h"
@@ -30,6 +36,9 @@
#define HPA_POWER_BUTTON (FIRMWARE_END - 0x10)
+#define enable_lasi_lan() 0
+
+
static void hppa_powerdown_req(Notifier *n, void *opaque)
{
hwaddr soft_power_reg = HPA_POWER_BUTTON;
@@ -51,6 +60,29 @@ static Notifier hppa_system_powerdown_notifier = {
.notify = hppa_powerdown_req
};
+/* Fallback for unassigned PCI I/O operations. Avoids MCHK. */
+static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
+{
+ return 0;
+}
+
+static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
+{
+}
+
+static const MemoryRegionOps hppa_pci_ignore_ops = {
+ .read = ignore_read,
+ .write = ignore_write,
+ .endianness = DEVICE_BIG_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+};
static ISABus *hppa_isa_bus(void)
{
@@ -121,15 +153,36 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
return fw_cfg;
}
+static LasiState *lasi_init(void)
+{
+ DeviceState *dev;
+
+ dev = qdev_new(TYPE_LASI_CHIP);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ return LASI_CHIP(dev);
+}
+
+static DinoState *dino_init(MemoryRegion *addr_space)
+{
+ DeviceState *dev;
+
+ dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
+ object_property_set_link(OBJECT(dev), "memory-as", OBJECT(addr_space),
+ &error_fatal);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ return DINO_PCI_HOST_BRIDGE(dev);
+}
+
static void machine_hppa_init(MachineState *machine)
{
const char *kernel_filename = machine->kernel_filename;
const char *kernel_cmdline = machine->kernel_cmdline;
const char *initrd_filename = machine->initrd_filename;
- DeviceState *dev;
+ DeviceState *dev, *dino_dev, *lasi_dev;
PCIBus *pci_bus;
ISABus *isa_bus;
- qemu_irq rtc_irq, serial_irq;
char *firmware_filename;
uint64_t firmware_low, firmware_high;
long size;
@@ -163,10 +216,17 @@ static void machine_hppa_init(MachineState *machine)
/* Init Lasi chip */
- lasi_init(addr_space);
+ lasi_dev = DEVICE(lasi_init());
+ memory_region_add_subregion(addr_space, LASI_HPA,
+ sysbus_mmio_get_region(
+ SYS_BUS_DEVICE(lasi_dev), 0));
/* Init Dino (PCI host bus chip). */
- pci_bus = dino_init(addr_space, &rtc_irq, &serial_irq);
+ dino_dev = DEVICE(dino_init(addr_space));
+ memory_region_add_subregion(addr_space, DINO_HPA,
+ sysbus_mmio_get_region(
+ SYS_BUS_DEVICE(dino_dev), 0));
+ pci_bus = PCI_BUS(qdev_get_child_bus(dino_dev, "pci"));
assert(pci_bus);
/* Create ISA bus. */
@@ -174,15 +234,28 @@ static void machine_hppa_init(MachineState *machine)
assert(isa_bus);
/* Realtime clock, used by firmware for PDC_TOD call. */
- mc146818_rtc_init(isa_bus, 2000, rtc_irq);
+ mc146818_rtc_init(isa_bus, 2000, NULL);
/* Serial code setup. */
if (serial_hd(0)) {
uint32_t addr = DINO_UART_HPA + 0x800;
- serial_mm_init(addr_space, addr, 0, serial_irq,
+ serial_mm_init(addr_space, addr, 0,
+ qdev_get_gpio_in(dino_dev, DINO_IRQ_RS232INT),
115200, serial_hd(0), DEVICE_BIG_ENDIAN);
}
+ if (serial_hd(1)) {
+ /* Serial port */
+ serial_mm_init(addr_space, LASI_UART_HPA + 0x800, 0,
+ qdev_get_gpio_in(lasi_dev, LASI_IRQ_UART_HPA), 8000000 / 16,
+ serial_hd(1), DEVICE_BIG_ENDIAN);
+ }
+
+ /* Parallel port */
+ parallel_mm_init(addr_space, LASI_LPT_HPA + 0x800, 0,
+ qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA),
+ parallel_hds[0]);
+
/* fw_cfg configuration interface */
create_fw_cfg(machine);
@@ -200,12 +273,21 @@ static void machine_hppa_init(MachineState *machine)
}
/* Network setup. */
+ if (enable_lasi_lan()) {
+ lasi_82596_init(addr_space, LASI_LAN_HPA,
+ qdev_get_gpio_in(lasi_dev, LASI_IRQ_LAN_HPA));
+ }
+
for (i = 0; i < nb_nics; i++) {
if (!enable_lasi_lan()) {
pci_nic_init_nofail(&nd_table[i], pci_bus, "tulip", NULL);
}
}
+ /* PS/2 Keyboard/Mouse */
+ lasips2_init(addr_space, LASI_PS2KBD_HPA,
+ qdev_get_gpio_in(lasi_dev, LASI_IRQ_PS2KBD_HPA));
+
/* register power switch emulation */
qemu_register_powerdown_notifier(&hppa_system_powerdown_notifier);
@@ -364,9 +446,12 @@ static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)
}
}
-static void machine_hppa_machine_init(MachineClass *mc)
+static void hppa_machine_init_class_init(ObjectClass *oc, void *data)
{
- mc->desc = "HPPA generic machine";
+ MachineClass *mc = MACHINE_CLASS(oc);
+ NMIClass *nc = NMI_CLASS(oc);
+
+ mc->desc = "HPPA B160L machine";
mc->default_cpu_type = TYPE_HPPA_CPU;
mc->init = machine_hppa_init;
mc->reset = hppa_machine_reset;
@@ -377,30 +462,23 @@ static void machine_hppa_machine_init(MachineClass *mc)
mc->default_ram_size = 512 * MiB;
mc->default_boot_order = "cd";
mc->default_ram_id = "ram";
-}
-static void machine_hppa_machine_init_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
- machine_hppa_machine_init(mc);
-
- NMIClass *nc = NMI_CLASS(oc);
nc->nmi_monitor_handler = hppa_nmi;
}
-static const TypeInfo machine_hppa_machine_init_typeinfo = {
- .name = ("hppa" "-machine"),
- .parent = "machine",
- .class_init = machine_hppa_machine_init_class_init,
+static const TypeInfo hppa_machine_init_typeinfo = {
+ .name = MACHINE_TYPE_NAME("hppa"),
+ .parent = TYPE_MACHINE,
+ .class_init = hppa_machine_init_class_init,
.interfaces = (InterfaceInfo[]) {
{ TYPE_NMI },
{ }
},
};
-static void machine_hppa_machine_init_register_types(void)
+static void hppa_machine_init_register_types(void)
{
- type_register_static(&machine_hppa_machine_init_typeinfo);
+ type_register_static(&hppa_machine_init_typeinfo);
}
-type_init(machine_hppa_machine_init_register_types)
+type_init(hppa_machine_init_register_types)
diff --git a/hw/hppa/meson.build b/hw/hppa/meson.build
index 1deae83aee..3d0c586c30 100644
--- a/hw/hppa/meson.build
+++ b/hw/hppa/meson.build
@@ -1,4 +1,4 @@
hppa_ss = ss.source_set()
-hppa_ss.add(when: 'CONFIG_DINO', if_true: files('pci.c', 'machine.c', 'dino.c', 'lasi.c'))
+hppa_ss.add(when: 'CONFIG_HPPA_B160L', if_true: files('machine.c'))
hw_arch += {'hppa': hppa_ss}
diff --git a/hw/hppa/pci.c b/hw/hppa/pci.c
deleted file mode 100644
index 32609aba63..0000000000
--- a/hw/hppa/pci.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * QEMU HP-PARISC PCI support functions.
- *
- */
-
-#include "qemu/osdep.h"
-#include "hppa_sys.h"
-#include "qemu/log.h"
-#include "trace.h"
-
-
-/* Fallback for unassigned PCI I/O operations. Avoids MCHK. */
-
-static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
-{
- return 0;
-}
-
-static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
-{
-}
-
-const MemoryRegionOps hppa_pci_ignore_ops = {
- .read = ignore_read,
- .write = ignore_write,
- .endianness = DEVICE_BIG_ENDIAN,
- .valid = {
- .min_access_size = 1,
- .max_access_size = 8,
- },
- .impl = {
- .min_access_size = 1,
- .max_access_size = 8,
- },
-};
-
-
-/* PCI config space reads/writes, to byte-word addressable memory. */
-static uint64_t bw_conf1_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- PCIBus *b = opaque;
- return pci_data_read(b, addr, size);
-}
-
-static void bw_conf1_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- PCIBus *b = opaque;
- pci_data_write(b, addr, val, size);
-}
-
-const MemoryRegionOps hppa_pci_conf1_ops = {
- .read = bw_conf1_read,
- .write = bw_conf1_write,
- .endianness = DEVICE_BIG_ENDIAN,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 4,
- },
-};
-
-/* PCI/EISA Interrupt Acknowledge Cycle. */
-
-static uint64_t iack_read(void *opaque, hwaddr addr, unsigned size)
-{
- return pic_read_irq(isa_pic);
-}
-
-static void special_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- trace_hppa_pci_iack_write();
-}
-
-const MemoryRegionOps hppa_pci_iack_ops = {
- .read = iack_read,
- .write = special_write,
- .endianness = DEVICE_BIG_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
diff --git a/hw/hppa/trace-events b/hw/hppa/trace-events
deleted file mode 100644
index 3f42be9056..0000000000
--- a/hw/hppa/trace-events
+++ /dev/null
@@ -1,14 +0,0 @@
-# See docs/devel/tracing.rst for syntax documentation.
-
-# pci.c
-hppa_pci_iack_write(void) ""
-
-# dino.c
-dino_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" is %d"
-dino_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
-dino_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
-
-# lasi.c
-lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" is %d"
-lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
-lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 507058d8bf..cbabe9f78c 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -171,4 +171,7 @@ config SIFIVE_U_PRCI
config VIRT_CTRL
bool
+config LASI
+ bool
+
source macio/Kconfig
diff --git a/hw/hppa/lasi.c b/hw/misc/lasi.c
index 88c3791eb6..23a7634a8c 100644
--- a/hw/hppa/lasi.c
+++ b/hw/misc/lasi.c
@@ -17,57 +17,10 @@
#include "hw/irq.h"
#include "sysemu/sysemu.h"
#include "sysemu/runstate.h"
-#include "hppa_sys.h"
-#include "hw/net/lasi_82596.h"
-#include "hw/char/parallel.h"
-#include "hw/char/serial.h"
-#include "hw/input/lasips2.h"
#include "migration/vmstate.h"
#include "qom/object.h"
+#include "hw/misc/lasi.h"
-#define TYPE_LASI_CHIP "lasi-chip"
-
-#define LASI_IRR 0x00 /* RO */
-#define LASI_IMR 0x04
-#define LASI_IPR 0x08
-#define LASI_ICR 0x0c
-#define LASI_IAR 0x10
-
-#define LASI_PCR 0x0C000 /* LASI Power Control register */
-#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
-#define LASI_VER 0x0C008 /* LASI Version Control register */
-#define LASI_IORESET 0x0C00C /* LASI I/O Reset register */
-#define LASI_AMR 0x0C010 /* LASI Arbitration Mask register */
-#define LASI_IO_CONF 0x7FFFE /* LASI primary configuration register */
-#define LASI_IO_CONF2 0x7FFFF /* LASI secondary configuration register */
-
-#define LASI_BIT(x) (1ul << (x))
-#define LASI_IRQ_BITS (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) \
- | LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
- | LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
- | LASI_BIT(26))
-
-#define ICR_BUS_ERROR_BIT LASI_BIT(8) /* bit 8 in ICR */
-#define ICR_TOC_BIT LASI_BIT(1) /* bit 1 in ICR */
-
-OBJECT_DECLARE_SIMPLE_TYPE(LasiState, LASI_CHIP)
-
-struct LasiState {
- PCIHostState parent_obj;
-
- uint32_t irr;
- uint32_t imr;
- uint32_t ipr;
- uint32_t icr;
- uint32_t iar;
-
- uint32_t errlog;
- uint32_t amr;
- uint32_t rtc;
- time_t rtc_ref;
-
- MemoryRegion this_mem;
-};
static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
unsigned size, bool is_write,
@@ -82,10 +35,10 @@ static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
case LASI_ICR:
case LASI_IAR:
- case (LASI_LAN_HPA - LASI_HPA):
- case (LASI_LPT_HPA - LASI_HPA):
- case (LASI_UART_HPA - LASI_HPA):
- case (LASI_RTC_HPA - LASI_HPA):
+ case LASI_LPT:
+ case LASI_UART:
+ case LASI_LAN:
+ case LASI_RTC:
case LASI_PCR ... LASI_AMR:
ret = true;
@@ -122,12 +75,12 @@ static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr,
val = s->iar;
break;
- case (LASI_LAN_HPA - LASI_HPA):
- case (LASI_LPT_HPA - LASI_HPA):
- case (LASI_UART_HPA - LASI_HPA):
+ case LASI_LPT:
+ case LASI_UART:
+ case LASI_LAN:
val = 0;
break;
- case (LASI_RTC_HPA - LASI_HPA):
+ case LASI_RTC:
val = time(NULL);
val += s->rtc_ref;
break;
@@ -169,10 +122,11 @@ static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr,
break;
case LASI_IMR:
s->imr = val;
- if (((val & LASI_IRQ_BITS) != val) && (val != 0xffffffff))
+ if (((val & LASI_IRQ_BITS) != val) && (val != 0xffffffff)) {
qemu_log_mask(LOG_GUEST_ERROR,
"LASI: tried to set invalid %lx IMR value.\n",
(unsigned long) val);
+ }
break;
case LASI_IPR:
/* Any write to IPR clears the register. */
@@ -186,22 +140,23 @@ static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr,
s->iar = val;
break;
- case (LASI_LAN_HPA - LASI_HPA):
- /* XXX: reset LAN card */
- break;
- case (LASI_LPT_HPA - LASI_HPA):
+ case LASI_LPT:
/* XXX: reset parallel port */
break;
- case (LASI_UART_HPA - LASI_HPA):
+ case LASI_UART:
/* XXX: reset serial port */
break;
- case (LASI_RTC_HPA - LASI_HPA):
+ case LASI_LAN:
+ /* XXX: reset LAN card */
+ break;
+ case LASI_RTC:
s->rtc_ref = val - time(NULL);
break;
case LASI_PCR:
- if (val == 0x02) /* immediately power off */
+ if (val == 0x02) { /* immediately power off */
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+ }
break;
case LASI_ERRLOG:
s->errlog = val;
@@ -271,90 +226,42 @@ static void lasi_set_irq(void *opaque, int irq, int level)
}
}
-static int lasi_get_irq(unsigned long hpa)
-{
- switch (hpa) {
- case LASI_HPA:
- return 14;
- case LASI_UART_HPA:
- return 5;
- case LASI_LPT_HPA:
- return 7;
- case LASI_LAN_HPA:
- return 8;
- case LASI_SCSI_HPA:
- return 9;
- case LASI_AUDIO_HPA:
- return 13;
- case LASI_PS2KBD_HPA:
- case LASI_PS2MOU_HPA:
- return 26;
- default:
- g_assert_not_reached();
- }
-}
-
-DeviceState *lasi_init(MemoryRegion *address_space)
+static void lasi_reset(DeviceState *dev)
{
- DeviceState *dev;
- LasiState *s;
-
- dev = qdev_new(TYPE_LASI_CHIP);
- s = LASI_CHIP(dev);
- s->iar = CPU_HPA + 3;
-
- /* Lasi access from main memory. */
- memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops,
- s, "lasi", 0x100000);
- memory_region_add_subregion(address_space, LASI_HPA, &s->this_mem);
-
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ LasiState *s = LASI_CHIP(dev);
- /* LAN */
- if (enable_lasi_lan()) {
- qemu_irq lan_irq = qemu_allocate_irq(lasi_set_irq, s,
- lasi_get_irq(LASI_LAN_HPA));
- lasi_82596_init(address_space, LASI_LAN_HPA, lan_irq);
- }
-
- /* Parallel port */
- qemu_irq lpt_irq = qemu_allocate_irq(lasi_set_irq, s,
- lasi_get_irq(LASI_LPT_HPA));
- parallel_mm_init(address_space, LASI_LPT_HPA + 0x800, 0,
- lpt_irq, parallel_hds[0]);
+ s->iar = 0xFFFB0000 + 3; /* CPU_HPA + 3 */
/* Real time clock (RTC), it's only one 32-bit counter @9000 */
-
s->rtc = time(NULL);
s->rtc_ref = 0;
+}
- if (serial_hd(1)) {
- /* Serial port */
- qemu_irq serial_irq = qemu_allocate_irq(lasi_set_irq, s,
- lasi_get_irq(LASI_UART_HPA));
- serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0,
- serial_irq, 8000000 / 16,
- serial_hd(0), DEVICE_NATIVE_ENDIAN);
- }
+static void lasi_init(Object *obj)
+{
+ LasiState *s = LASI_CHIP(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+ memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops,
+ s, "lasi", 0x100000);
- /* PS/2 Keyboard/Mouse */
- qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s,
- lasi_get_irq(LASI_PS2KBD_HPA));
- lasips2_init(address_space, LASI_PS2KBD_HPA, ps2kbd_irq);
+ sysbus_init_mmio(sbd, &s->this_mem);
- return dev;
+ qdev_init_gpio_in(DEVICE(obj), lasi_set_irq, LASI_IRQS);
}
static void lasi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->reset = lasi_reset;
dc->vmsd = &vmstate_lasi;
}
static const TypeInfo lasi_pcihost_info = {
.name = TYPE_LASI_CHIP,
.parent = TYPE_SYS_BUS_DEVICE,
+ .instance_init = lasi_init,
.instance_size = sizeof(LasiState),
.class_init = lasi_class_init,
};
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 2ff05c7afa..132b7b7344 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -134,3 +134,6 @@ specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_cmgcr.c', 'mips_cp
specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files('mips_itu.c'))
specific_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c'))
+
+# HPPA devices
+softmmu_ss.add(when: 'CONFIG_LASI', if_true: files('lasi.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 4e0c7973a4..c5e37b0154 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -263,3 +263,8 @@ virt_ctrl_write(void *dev, unsigned int addr, unsigned int size, uint64_t value)
virt_ctrl_reset(void *dev) "ctrl: %p"
virt_ctrl_realize(void *dev) "ctrl: %p"
virt_ctrl_instance_init(void *dev) "ctrl: %p"
+
+# lasi.c
+lasi_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" is %d"
+lasi_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
+lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
index 2b5f7d58cc..38fd2ee8f3 100644
--- a/hw/pci-host/Kconfig
+++ b/hw/pci-host/Kconfig
@@ -77,3 +77,7 @@ config MV64361
bool
select PCI
select I8259
+
+config DINO
+ bool
+ select PCI
diff --git a/hw/hppa/dino.c b/hw/pci-host/dino.c
index eab96dd84e..f257c24e64 100644
--- a/hw/hppa/dino.c
+++ b/hw/pci-host/dino.c
@@ -17,118 +17,13 @@
#include "hw/irq.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_bus.h"
+#include "hw/qdev-properties.h"
+#include "hw/pci-host/dino.h"
#include "migration/vmstate.h"
-#include "hppa_sys.h"
#include "trace.h"
#include "qom/object.h"
-#define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
-
-#define DINO_IAR0 0x004
-#define DINO_IODC 0x008
-#define DINO_IRR0 0x00C /* RO */
-#define DINO_IAR1 0x010
-#define DINO_IRR1 0x014 /* RO */
-#define DINO_IMR 0x018
-#define DINO_IPR 0x01C
-#define DINO_TOC_ADDR 0x020
-#define DINO_ICR 0x024
-#define DINO_ILR 0x028 /* RO */
-#define DINO_IO_COMMAND 0x030 /* WO */
-#define DINO_IO_STATUS 0x034 /* RO */
-#define DINO_IO_CONTROL 0x038
-#define DINO_IO_GSC_ERR_RESP 0x040 /* RO */
-#define DINO_IO_ERR_INFO 0x044 /* RO */
-#define DINO_IO_PCI_ERR_RESP 0x048 /* RO */
-#define DINO_IO_FBB_EN 0x05c
-#define DINO_IO_ADDR_EN 0x060
-#define DINO_PCI_CONFIG_ADDR 0x064
-#define DINO_PCI_CONFIG_DATA 0x068
-#define DINO_PCI_IO_DATA 0x06c
-#define DINO_PCI_MEM_DATA 0x070 /* Dino 3.x only */
-#define DINO_GSC2X_CONFIG 0x7b4 /* RO */
-#define DINO_GMASK 0x800
-#define DINO_PAMR 0x804
-#define DINO_PAPR 0x808
-#define DINO_DAMODE 0x80c
-#define DINO_PCICMD 0x810
-#define DINO_PCISTS 0x814 /* R/WC */
-#define DINO_MLTIM 0x81c
-#define DINO_BRDG_FEAT 0x820
-#define DINO_PCIROR 0x824
-#define DINO_PCIWOR 0x828
-#define DINO_TLTIM 0x830
-
-#define DINO_IRQS 11 /* bits 0-10 are architected */
-#define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */
-#define DINO_LOCAL_IRQS (DINO_IRQS + 1)
-#define DINO_MASK_IRQ(x) (1 << (x))
-
-#define PCIINTA 0x001
-#define PCIINTB 0x002
-#define PCIINTC 0x004
-#define PCIINTD 0x008
-#define PCIINTE 0x010
-#define PCIINTF 0x020
-#define GSCEXTINT 0x040
-/* #define xxx 0x080 - bit 7 is "default" */
-/* #define xxx 0x100 - bit 8 not used */
-/* #define xxx 0x200 - bit 9 not used */
-#define RS232INT 0x400
-
-#define DINO_MEM_CHUNK_SIZE (8 * MiB)
-
-OBJECT_DECLARE_SIMPLE_TYPE(DinoState, DINO_PCI_HOST_BRIDGE)
-
-#define DINO800_REGS (1 + (DINO_TLTIM - DINO_GMASK) / 4)
-static const uint32_t reg800_keep_bits[DINO800_REGS] = {
- MAKE_64BIT_MASK(0, 1), /* GMASK */
- MAKE_64BIT_MASK(0, 7), /* PAMR */
- MAKE_64BIT_MASK(0, 7), /* PAPR */
- MAKE_64BIT_MASK(0, 8), /* DAMODE */
- MAKE_64BIT_MASK(0, 7), /* PCICMD */
- MAKE_64BIT_MASK(0, 9), /* PCISTS */
- MAKE_64BIT_MASK(0, 32), /* Undefined */
- MAKE_64BIT_MASK(0, 8), /* MLTIM */
- MAKE_64BIT_MASK(0, 30), /* BRDG_FEAT */
- MAKE_64BIT_MASK(0, 24), /* PCIROR */
- MAKE_64BIT_MASK(0, 22), /* PCIWOR */
- MAKE_64BIT_MASK(0, 32), /* Undocumented */
- MAKE_64BIT_MASK(0, 9), /* TLTIM */
-};
-
-struct DinoState {
- PCIHostState parent_obj;
-
- /* PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
- so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops. */
- uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
-
- uint32_t iar0;
- uint32_t iar1;
- uint32_t imr;
- uint32_t ipr;
- uint32_t icr;
- uint32_t ilr;
- uint32_t io_fbb_en;
- uint32_t io_addr_en;
- uint32_t io_control;
- uint32_t toc_addr;
-
- uint32_t reg800[DINO800_REGS];
-
- MemoryRegion this_mem;
- MemoryRegion pci_mem;
- MemoryRegion pci_mem_alias[32];
-
- AddressSpace bm_as;
- MemoryRegion bm;
- MemoryRegion bm_ram_alias;
- MemoryRegion bm_pci_alias;
- MemoryRegion bm_cpu_alias;
-};
-
/*
* Dino can forward memory accesses from the CPU in the range between
* 0xf0800000 and 0xff000000 to the PCI bus.
@@ -200,6 +95,7 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
MemTxAttrs attrs)
{
DinoState *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
MemTxResult ret = MEMTX_OK;
AddressSpace *io;
uint16_t ioaddr;
@@ -209,7 +105,7 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr,
case DINO_PCI_IO_DATA ... DINO_PCI_IO_DATA + 3:
/* Read from PCI IO space. */
io = &address_space_io;
- ioaddr = s->parent_obj.config_reg + (addr & 3);
+ ioaddr = phb->config_reg + (addr & 3);
switch (size) {
case 1:
val = address_space_ldub(io, ioaddr, attrs, &ret);
@@ -292,6 +188,7 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr,
MemTxAttrs attrs)
{
DinoState *s = opaque;
+ PCIHostState *phb = PCI_HOST_BRIDGE(s);
AddressSpace *io;
MemTxResult ret;
uint16_t ioaddr;
@@ -303,7 +200,7 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr,
case DINO_IO_DATA ... DINO_PCI_IO_DATA + 3:
/* Write into PCI IO space. */
io = &address_space_io;
- ioaddr = s->parent_obj.config_reg + (addr & 3);
+ ioaddr = phb->config_reg + (addr & 3);
switch (size) {
case 1:
address_space_stb(io, ioaddr, val, attrs, &ret);
@@ -501,52 +398,78 @@ static int dino_pci_map_irq(PCIDevice *d, int irq_num)
return slot & 0x03;
}
-static void dino_set_timer_irq(void *opaque, int irq, int level)
+static void dino_pcihost_reset(DeviceState *dev)
{
- /* ??? Not connected. */
+ DinoState *s = DINO_PCI_HOST_BRIDGE(dev);
+
+ s->iar0 = s->iar1 = 0xFFFB0000 + 3; /* CPU_HPA + 3 */
+ s->toc_addr = 0xFFFA0030; /* IO_COMMAND of CPU */
+}
+
+static void dino_pcihost_realize(DeviceState *dev, Error **errp)
+{
+ DinoState *s = DINO_PCI_HOST_BRIDGE(dev);
+
+ /* Set up PCI view of memory: Bus master address space. */
+ memory_region_init(&s->bm, OBJECT(s), "bm-dino", 4 * GiB);
+ memory_region_init_alias(&s->bm_ram_alias, OBJECT(s),
+ "bm-system", s->memory_as, 0,
+ 0xf0000000 + DINO_MEM_CHUNK_SIZE);
+ memory_region_init_alias(&s->bm_pci_alias, OBJECT(s),
+ "bm-pci", &s->pci_mem,
+ 0xf0000000 + DINO_MEM_CHUNK_SIZE,
+ 30 * DINO_MEM_CHUNK_SIZE);
+ memory_region_init_alias(&s->bm_cpu_alias, OBJECT(s),
+ "bm-cpu", s->memory_as, 0xfff00000,
+ 0xfffff);
+ memory_region_add_subregion(&s->bm, 0,
+ &s->bm_ram_alias);
+ memory_region_add_subregion(&s->bm,
+ 0xf0000000 + DINO_MEM_CHUNK_SIZE,
+ &s->bm_pci_alias);
+ memory_region_add_subregion(&s->bm, 0xfff00000,
+ &s->bm_cpu_alias);
+
+ address_space_init(&s->bm_as, &s->bm, "pci-bm");
}
-static void dino_set_serial_irq(void *opaque, int irq, int level)
+static void dino_pcihost_unrealize(DeviceState *dev)
{
- dino_set_irq(opaque, 10, level);
+ DinoState *s = DINO_PCI_HOST_BRIDGE(dev);
+
+ address_space_destroy(&s->bm_as);
}
-PCIBus *dino_init(MemoryRegion *addr_space,
- qemu_irq *p_rtc_irq, qemu_irq *p_ser_irq)
+static void dino_pcihost_init(Object *obj)
{
- DeviceState *dev;
- DinoState *s;
- PCIBus *b;
+ DinoState *s = DINO_PCI_HOST_BRIDGE(obj);
+ PCIHostState *phb = PCI_HOST_BRIDGE(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
int i;
- dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
- s = DINO_PCI_HOST_BRIDGE(dev);
- s->iar0 = s->iar1 = CPU_HPA + 3;
- s->toc_addr = 0xFFFA0030; /* IO_COMMAND of CPU */
-
/* Dino PCI access from main memory. */
memory_region_init_io(&s->this_mem, OBJECT(s), &dino_chip_ops,
s, "dino", 4096);
- memory_region_add_subregion(addr_space, DINO_HPA, &s->this_mem);
/* Dino PCI config. */
- memory_region_init_io(&s->parent_obj.conf_mem, OBJECT(&s->parent_obj),
- &dino_config_addr_ops, dev, "pci-conf-idx", 4);
- memory_region_init_io(&s->parent_obj.data_mem, OBJECT(&s->parent_obj),
- &dino_config_data_ops, dev, "pci-conf-data", 4);
+ memory_region_init_io(&phb->conf_mem, OBJECT(phb),
+ &dino_config_addr_ops, DEVICE(s),
+ "pci-conf-idx", 4);
+ memory_region_init_io(&phb->data_mem, OBJECT(phb),
+ &dino_config_data_ops, DEVICE(s),
+ "pci-conf-data", 4);
memory_region_add_subregion(&s->this_mem, DINO_PCI_CONFIG_ADDR,
- &s->parent_obj.conf_mem);
+ &phb->conf_mem);
memory_region_add_subregion(&s->this_mem, DINO_CONFIG_DATA,
- &s->parent_obj.data_mem);
+ &phb->data_mem);
/* Dino PCI bus memory. */
memory_region_init(&s->pci_mem, OBJECT(s), "pci-memory", 4 * GiB);
- b = pci_register_root_bus(dev, "pci", dino_set_irq, dino_pci_map_irq, s,
- &s->pci_mem, get_system_io(),
- PCI_DEVFN(0, 0), 32, TYPE_PCI_BUS);
- s->parent_obj.bus = b;
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ phb->bus = pci_register_root_bus(DEVICE(s), "pci",
+ dino_set_irq, dino_pci_map_irq, s,
+ &s->pci_mem, get_system_io(),
+ PCI_DEVFN(0, 0), 32, TYPE_PCI_BUS);
/* Set up windows into PCI bus memory. */
for (i = 1; i < 31; i++) {
@@ -558,44 +481,34 @@ PCIBus *dino_init(MemoryRegion *addr_space,
g_free(name);
}
- /* Set up PCI view of memory: Bus master address space. */
- memory_region_init(&s->bm, OBJECT(s), "bm-dino", 4 * GiB);
- memory_region_init_alias(&s->bm_ram_alias, OBJECT(s),
- "bm-system", addr_space, 0,
- 0xf0000000 + DINO_MEM_CHUNK_SIZE);
- memory_region_init_alias(&s->bm_pci_alias, OBJECT(s),
- "bm-pci", &s->pci_mem,
- 0xf0000000 + DINO_MEM_CHUNK_SIZE,
- 30 * DINO_MEM_CHUNK_SIZE);
- memory_region_init_alias(&s->bm_cpu_alias, OBJECT(s),
- "bm-cpu", addr_space, 0xfff00000,
- 0xfffff);
- memory_region_add_subregion(&s->bm, 0,
- &s->bm_ram_alias);
- memory_region_add_subregion(&s->bm,
- 0xf0000000 + DINO_MEM_CHUNK_SIZE,
- &s->bm_pci_alias);
- memory_region_add_subregion(&s->bm, 0xfff00000,
- &s->bm_cpu_alias);
- address_space_init(&s->bm_as, &s->bm, "pci-bm");
- pci_setup_iommu(b, dino_pcihost_set_iommu, s);
+ pci_setup_iommu(phb->bus, dino_pcihost_set_iommu, s);
- *p_rtc_irq = qemu_allocate_irq(dino_set_timer_irq, s, 0);
- *p_ser_irq = qemu_allocate_irq(dino_set_serial_irq, s, 0);
+ sysbus_init_mmio(sbd, &s->this_mem);
- return b;
+ qdev_init_gpio_in(DEVICE(obj), dino_set_irq, DINO_IRQS);
}
+static Property dino_pcihost_properties[] = {
+ DEFINE_PROP_LINK("memory-as", DinoState, memory_as, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void dino_pcihost_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->reset = dino_pcihost_reset;
+ dc->realize = dino_pcihost_realize;
+ dc->unrealize = dino_pcihost_unrealize;
+ device_class_set_props(dc, dino_pcihost_properties);
dc->vmsd = &vmstate_dino;
}
static const TypeInfo dino_pcihost_info = {
.name = TYPE_DINO_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
+ .instance_init = dino_pcihost_init,
.instance_size = sizeof(DinoState),
.class_init = dino_pcihost_class_init,
};
diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
index 4c4f39c15c..c07596d0d1 100644
--- a/hw/pci-host/meson.build
+++ b/hw/pci-host/meson.build
@@ -25,6 +25,9 @@ pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
# ARM devices
pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
+# HPPA devices
+pci_ss.add(when: 'CONFIG_DINO', if_true: files('dino.c'))
+
softmmu_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
specific_ss.add(when: 'CONFIG_PCI_POWERNV', if_true: files(
diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events
index 6e5d8d3355..437e66ff50 100644
--- a/hw/pci-host/trace-events
+++ b/hw/pci-host/trace-events
@@ -34,3 +34,8 @@ unin_read(uint64_t addr, uint64_t value) "addr=0x%" PRIx64 " val=0x%"PRIx64
pnv_phb4_xive_notify(uint64_t notif_port, uint64_t data) "notif=@0x%"PRIx64" data=0x%"PRIx64
pnv_phb4_xive_notify_ic(uint64_t addr, uint64_t data) "addr=@0x%"PRIx64" data=0x%"PRIx64
pnv_phb4_xive_notify_abt(uint64_t notif_port, uint64_t data) "notif=@0x%"PRIx64" data=0x%"PRIx64
+
+# dino.c
+dino_chip_mem_valid(uint64_t addr, uint32_t val) "access to addr 0x%"PRIx64" is %d"
+dino_chip_read(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
+dino_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
diff --git a/include/hw/misc/lasi.h b/include/hw/misc/lasi.h
new file mode 100644
index 0000000000..ecc7065ce8
--- /dev/null
+++ b/include/hw/misc/lasi.h
@@ -0,0 +1,78 @@
+/*
+ * HP-PARISC Lasi chipset emulation.
+ *
+ * (C) 2019 by Helge Deller <deller@gmx.de>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
+ */
+
+#ifndef LASI_H
+#define LASI_H
+
+#include "exec/address-spaces.h"
+#include "hw/pci/pci_host.h"
+#include "hw/boards.h"
+
+#define TYPE_LASI_CHIP "lasi-chip"
+OBJECT_DECLARE_SIMPLE_TYPE(LasiState, LASI_CHIP)
+
+#define LASI_IRR 0x00 /* RO */
+#define LASI_IMR 0x04
+#define LASI_IPR 0x08
+#define LASI_ICR 0x0c
+#define LASI_IAR 0x10
+
+#define LASI_LPT 0x02000
+#define LASI_UART 0x05000
+#define LASI_LAN 0x07000
+#define LASI_RTC 0x09000
+
+#define LASI_PCR 0x0C000 /* LASI Power Control register */
+#define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */
+#define LASI_VER 0x0C008 /* LASI Version Control register */
+#define LASI_IORESET 0x0C00C /* LASI I/O Reset register */
+#define LASI_AMR 0x0C010 /* LASI Arbitration Mask register */
+#define LASI_IO_CONF 0x7FFFE /* LASI primary configuration register */
+#define LASI_IO_CONF2 0x7FFFF /* LASI secondary configuration register */
+
+#define LASI_BIT(x) (1ul << (x))
+#define LASI_IRQ_BITS (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) \
+ | LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \
+ | LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \
+ | LASI_BIT(26))
+
+#define ICR_BUS_ERROR_BIT LASI_BIT(8) /* bit 8 in ICR */
+#define ICR_TOC_BIT LASI_BIT(1) /* bit 1 in ICR */
+
+#define LASI_IRQS 27
+
+#define LASI_IRQ_HPA 14
+#define LASI_IRQ_UART_HPA 5
+#define LASI_IRQ_LPT_HPA 7
+#define LASI_IRQ_LAN_HPA 8
+#define LASI_IRQ_SCSI_HPA 9
+#define LASI_IRQ_AUDIO_HPA 13
+#define LASI_IRQ_PS2KBD_HPA 26
+#define LASI_IRQ_PS2MOU_HPA 26
+
+struct LasiState {
+ PCIHostState parent_obj;
+
+ uint32_t irr;
+ uint32_t imr;
+ uint32_t ipr;
+ uint32_t icr;
+ uint32_t iar;
+
+ uint32_t errlog;
+ uint32_t amr;
+ uint32_t rtc;
+ time_t rtc_ref;
+
+ MemoryRegion this_mem;
+};
+
+#endif
diff --git a/include/hw/pci-host/dino.h b/include/hw/pci-host/dino.h
new file mode 100644
index 0000000000..a1b0184940
--- /dev/null
+++ b/include/hw/pci-host/dino.h
@@ -0,0 +1,146 @@
+/*
+ * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines
+ *
+ * (C) 2017-2019 by Helge Deller <deller@gmx.de>
+ *
+ * This work is licensed under the GNU GPL license version 2 or later.
+ *
+ * Documentation available at:
+ * https://parisc.wiki.kernel.org/images-parisc/9/91/Dino_ers.pdf
+ * https://parisc.wiki.kernel.org/images-parisc/7/70/Dino_3_1_Errata.pdf
+ */
+
+#ifndef DINO_H
+#define DINO_H
+
+#include "hw/pci/pci_host.h"
+
+#define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost"
+OBJECT_DECLARE_SIMPLE_TYPE(DinoState, DINO_PCI_HOST_BRIDGE)
+
+#define DINO_IAR0 0x004
+#define DINO_IODC 0x008
+#define DINO_IRR0 0x00C /* RO */
+#define DINO_IAR1 0x010
+#define DINO_IRR1 0x014 /* RO */
+#define DINO_IMR 0x018
+#define DINO_IPR 0x01C
+#define DINO_TOC_ADDR 0x020
+#define DINO_ICR 0x024
+#define DINO_ILR 0x028 /* RO */
+#define DINO_IO_COMMAND 0x030 /* WO */
+#define DINO_IO_STATUS 0x034 /* RO */
+#define DINO_IO_CONTROL 0x038
+#define DINO_IO_GSC_ERR_RESP 0x040 /* RO */
+#define DINO_IO_ERR_INFO 0x044 /* RO */
+#define DINO_IO_PCI_ERR_RESP 0x048 /* RO */
+#define DINO_IO_FBB_EN 0x05c
+#define DINO_IO_ADDR_EN 0x060
+#define DINO_PCI_CONFIG_ADDR 0x064
+#define DINO_PCI_CONFIG_DATA 0x068
+#define DINO_PCI_IO_DATA 0x06c
+#define DINO_PCI_MEM_DATA 0x070 /* Dino 3.x only */
+#define DINO_GSC2X_CONFIG 0x7b4 /* RO */
+#define DINO_GMASK 0x800
+#define DINO_PAMR 0x804
+#define DINO_PAPR 0x808
+#define DINO_DAMODE 0x80c
+#define DINO_PCICMD 0x810
+#define DINO_PCISTS 0x814 /* R/WC */
+#define DINO_MLTIM 0x81c
+#define DINO_BRDG_FEAT 0x820
+#define DINO_PCIROR 0x824
+#define DINO_PCIWOR 0x828
+#define DINO_TLTIM 0x830
+
+#define DINO_IRQS 11 /* bits 0-10 are architected */
+#define DINO_IRR_MASK 0x5ff /* only 10 bits are implemented */
+#define DINO_LOCAL_IRQS (DINO_IRQS + 1)
+#define DINO_MASK_IRQ(x) (1 << (x))
+
+#define DINO_IRQ_PCIINTA 0
+#define DINO_IRQ_PCIINTB 1
+#define DINO_IRQ_PCIINTC 2
+#define DINO_IRQ_PCIINTD 3
+#define DINO_IRQ_PCIINTE 4
+#define DINO_IRQ_PCIINTF 5
+#define DINO_IRQ_GSCEXTINT 6
+#define DINO_IRQ_BUSERRINT 7
+#define DINO_IRQ_PS2INT 8
+#define DINO_IRQ_UNUSED 9
+#define DINO_IRQ_RS232INT 10
+
+#define PCIINTA 0x001
+#define PCIINTB 0x002
+#define PCIINTC 0x004
+#define PCIINTD 0x008
+#define PCIINTE 0x010
+#define PCIINTF 0x020
+#define GSCEXTINT 0x040
+/* #define xxx 0x080 - bit 7 is "default" */
+/* #define xxx 0x100 - bit 8 not used */
+/* #define xxx 0x200 - bit 9 not used */
+#define RS232INT 0x400
+
+#define DINO_MEM_CHUNK_SIZE (8 * MiB)
+
+#define DINO800_REGS (1 + (DINO_TLTIM - DINO_GMASK) / 4)
+static const uint32_t reg800_keep_bits[DINO800_REGS] = {
+ MAKE_64BIT_MASK(0, 1), /* GMASK */
+ MAKE_64BIT_MASK(0, 7), /* PAMR */
+ MAKE_64BIT_MASK(0, 7), /* PAPR */
+ MAKE_64BIT_MASK(0, 8), /* DAMODE */
+ MAKE_64BIT_MASK(0, 7), /* PCICMD */
+ MAKE_64BIT_MASK(0, 9), /* PCISTS */
+ MAKE_64BIT_MASK(0, 32), /* Undefined */
+ MAKE_64BIT_MASK(0, 8), /* MLTIM */
+ MAKE_64BIT_MASK(0, 30), /* BRDG_FEAT */
+ MAKE_64BIT_MASK(0, 24), /* PCIROR */
+ MAKE_64BIT_MASK(0, 22), /* PCIWOR */
+ MAKE_64BIT_MASK(0, 32), /* Undocumented */
+ MAKE_64BIT_MASK(0, 9), /* TLTIM */
+};
+
+/* offsets to DINO HPA: */
+#define DINO_PCI_ADDR 0x064
+#define DINO_CONFIG_DATA 0x068
+#define DINO_IO_DATA 0x06c
+
+struct DinoState {
+ PCIHostState parent_obj;
+
+ /*
+ * PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops,
+ * so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops.
+ */
+ uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */
+
+ uint32_t iar0;
+ uint32_t iar1;
+ uint32_t imr;
+ uint32_t ipr;
+ uint32_t icr;
+ uint32_t ilr;
+ uint32_t io_fbb_en;
+ uint32_t io_addr_en;
+ uint32_t io_control;
+ uint32_t toc_addr;
+
+ uint32_t reg800[DINO800_REGS];
+
+ MemoryRegion this_mem;
+ MemoryRegion pci_mem;
+ MemoryRegion pci_mem_alias[32];
+
+ MemoryRegion *memory_as;
+
+ AddressSpace bm_as;
+ MemoryRegion bm;
+ MemoryRegion bm_ram_alias;
+ MemoryRegion bm_pci_alias;
+ MemoryRegion bm_cpu_alias;
+
+ qemu_irq irqs[DINO_IRQS];
+};
+
+#endif
diff --git a/meson.build b/meson.build
index 40132b4804..fa672e57bc 100644
--- a/meson.build
+++ b/meson.build
@@ -2944,7 +2944,6 @@ if have_system
'hw/char',
'hw/display',
'hw/dma',
- 'hw/hppa',
'hw/hyperv',
'hw/i2c',
'hw/i386',