mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 03:59:52 +00:00
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----- 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>
This commit is contained in:
commit
554623226f
@ -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
|
||||
|
@ -6,4 +6,4 @@
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_DINO=y
|
||||
CONFIG_HPPA_B160L=y
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
@ -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)
|
||||
|
@ -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}
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
@ -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"
|
@ -171,4 +171,7 @@ config SIFIVE_U_PRCI
|
||||
config VIRT_CTRL
|
||||
bool
|
||||
|
||||
config LASI
|
||||
bool
|
||||
|
||||
source macio/Kconfig
|
||||
|
@ -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)
|
||||
static void lasi_reset(DeviceState *dev)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
LasiState *s = LASI_CHIP(dev);
|
||||
|
||||
DeviceState *lasi_init(MemoryRegion *address_space)
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops,
|
||||
s, "lasi", 0x100000);
|
||||
|
||||
return dev;
|
||||
sysbus_init_mmio(sbd, &s->this_mem);
|
||||
|
||||
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,
|
||||
};
|
@ -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'))
|
||||
|
@ -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"
|
||||
|
@ -77,3 +77,7 @@ config MV64361
|
||||
bool
|
||||
select PCI
|
||||
select I8259
|
||||
|
||||
config DINO
|
||||
bool
|
||||
select PCI
|
||||
|
@ -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);
|
||||
|
||||
static void dino_set_serial_irq(void *opaque, int irq, int level)
|
||||
{
|
||||
dino_set_irq(opaque, 10, level);
|
||||
}
|
||||
|
||||
PCIBus *dino_init(MemoryRegion *addr_space,
|
||||
qemu_irq *p_rtc_irq, qemu_irq *p_ser_irq)
|
||||
{
|
||||
DeviceState *dev;
|
||||
DinoState *s;
|
||||
PCIBus *b;
|
||||
int i;
|
||||
|
||||
dev = qdev_new(TYPE_DINO_PCI_HOST_BRIDGE);
|
||||
s = DINO_PCI_HOST_BRIDGE(dev);
|
||||
s->iar0 = s->iar1 = CPU_HPA + 3;
|
||||
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_pcihost_unrealize(DeviceState *dev)
|
||||
{
|
||||
DinoState *s = DINO_PCI_HOST_BRIDGE(dev);
|
||||
|
||||
address_space_destroy(&s->bm_as);
|
||||
}
|
||||
|
||||
static void dino_pcihost_init(Object *obj)
|
||||
{
|
||||
DinoState *s = DINO_PCI_HOST_BRIDGE(obj);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(obj);
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
int i;
|
||||
|
||||
/* 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,
|
||||
};
|
@ -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(
|
||||
|
@ -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"
|
||||
|
78
include/hw/misc/lasi.h
Normal file
78
include/hw/misc/lasi.h
Normal file
@ -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
|
146
include/hw/pci-host/dino.h
Normal file
146
include/hw/pci-host/dino.h
Normal file
@ -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
|
@ -2944,7 +2944,6 @@ if have_system
|
||||
'hw/char',
|
||||
'hw/display',
|
||||
'hw/dma',
|
||||
'hw/hppa',
|
||||
'hw/hyperv',
|
||||
'hw/i2c',
|
||||
'hw/i386',
|
||||
|
Loading…
Reference in New Issue
Block a user