diff options
Diffstat (limited to 'hw/hppa')
| -rw-r--r-- | hw/hppa/Kconfig | 3 | ||||
| -rw-r--r-- | hw/hppa/Makefile.objs | 2 | ||||
| -rw-r--r-- | hw/hppa/dino.c | 97 | ||||
| -rw-r--r-- | hw/hppa/hppa_hardware.h | 1 | ||||
| -rw-r--r-- | hw/hppa/hppa_sys.h | 2 | ||||
| -rw-r--r-- | hw/hppa/lasi.c | 368 | ||||
| -rw-r--r-- | hw/hppa/machine.c | 33 | ||||
| -rw-r--r-- | hw/hppa/trace-events | 10 |
8 files changed, 492 insertions, 24 deletions
diff --git a/hw/hppa/Kconfig b/hw/hppa/Kconfig index 6e5d74a825..82178c7dcb 100644 --- a/hw/hppa/Kconfig +++ b/hw/hppa/Kconfig @@ -10,3 +10,6 @@ config DINO select IDE_CMD646 select MC146818RTC select LSI_SCSI_PCI + select LASI_82596 + select LASIPS2 + select ARTIST diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs index 67838f50a3..eac3467d8a 100644 --- a/hw/hppa/Makefile.objs +++ b/hw/hppa/Makefile.objs @@ -1 +1 @@ -obj-$(CONFIG_DINO) += pci.o machine.o dino.o +obj-$(CONFIG_DINO) += pci.o machine.o dino.o lasi.o diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c index ab6969b45f..9797a7f0d9 100644 --- a/hw/hppa/dino.c +++ b/hw/hppa/dino.c @@ -1,7 +1,7 @@ /* - * HP-PARISC Dino PCI chipset emulation. + * HP-PARISC Dino PCI chipset emulation, as in B160L and similiar machines * - * (C) 2017 by Helge Deller <deller@gmx.de> + * (C) 2017-2019 by Helge Deller <deller@gmx.de> * * This work is licensed under the GNU GPL license version 2 or later. * @@ -21,6 +21,7 @@ #include "migration/vmstate.h" #include "hppa_sys.h" #include "exec/address-spaces.h" +#include "trace.h" #define TYPE_DINO_PCI_HOST_BRIDGE "dino-pcihost" @@ -82,11 +83,28 @@ #define DINO_PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(DinoState, (obj), TYPE_DINO_PCI_HOST_BRIDGE) +#define DINO800_REGS ((DINO_TLTIM - DINO_GMASK) / 4) +static const uint32_t reg800_keep_bits[DINO800_REGS] = { + MAKE_64BIT_MASK(0, 1), + MAKE_64BIT_MASK(0, 7), + MAKE_64BIT_MASK(0, 7), + MAKE_64BIT_MASK(0, 8), + MAKE_64BIT_MASK(0, 7), + MAKE_64BIT_MASK(0, 9), + MAKE_64BIT_MASK(0, 32), + MAKE_64BIT_MASK(0, 8), + MAKE_64BIT_MASK(0, 30), + MAKE_64BIT_MASK(0, 25), + MAKE_64BIT_MASK(0, 22), + MAKE_64BIT_MASK(0, 9), +}; + typedef 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; @@ -94,8 +112,12 @@ typedef struct DinoState { 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; @@ -106,8 +128,6 @@ typedef struct DinoState { MemoryRegion bm_ram_alias; MemoryRegion bm_pci_alias; MemoryRegion bm_cpu_alias; - - MemoryRegion cpu0_eir_mem; } DinoState; /* @@ -122,6 +142,8 @@ static void gsc_to_pci_forwarding(DinoState *s) tmp = extract32(s->io_control, 7, 2); enabled = (tmp == 0x01); io_addr_en = s->io_addr_en; + /* Mask out first (=firmware) and last (=Dino) areas. */ + io_addr_en &= ~(BIT(31) | BIT(0)); memory_region_transaction_begin(); for (i = 1; i < 31; i++) { @@ -142,6 +164,8 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr, unsigned size, bool is_write, MemTxAttrs attrs) { + bool ret = false; + switch (addr) { case DINO_IAR0: case DINO_IAR1: @@ -152,16 +176,22 @@ static bool dino_chip_mem_valid(void *opaque, hwaddr addr, case DINO_ICR: case DINO_ILR: case DINO_IO_CONTROL: + case DINO_IO_FBB_EN: case DINO_IO_ADDR_EN: case DINO_PCI_IO_DATA: - return true; + case DINO_TOC_ADDR: + case DINO_GMASK ... DINO_TLTIM: + ret = true; + break; case DINO_PCI_IO_DATA + 2: - return size <= 2; + ret = (size <= 2); + break; case DINO_PCI_IO_DATA + 1: case DINO_PCI_IO_DATA + 3: - return size == 1; + ret = (size == 1); } - return false; + trace_dino_chip_mem_valid(addr, ret); + return ret; } static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr, @@ -194,6 +224,9 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr, } break; + case DINO_IO_FBB_EN: + val = s->io_fbb_en; + break; case DINO_IO_ADDR_EN: val = s->io_addr_en; break; @@ -227,12 +260,28 @@ static MemTxResult dino_chip_read_with_attrs(void *opaque, hwaddr addr, case DINO_IRR1: val = s->ilr & s->imr & s->icr; break; + case DINO_TOC_ADDR: + val = s->toc_addr; + break; + case DINO_GMASK ... DINO_TLTIM: + val = s->reg800[(addr - DINO_GMASK) / 4]; + if (addr == DINO_PAMR) { + val &= ~0x01; /* LSB is hardwired to 0 */ + } + if (addr == DINO_MLTIM) { + val &= ~0x07; /* 3 LSB are hardwired to 0 */ + } + if (addr == DINO_BRDG_FEAT) { + val &= ~(0x10710E0ul | 8); /* bits 5-7, 24 & 15 reserved */ + } + break; default: /* Controlled by dino_chip_mem_valid above. */ g_assert_not_reached(); } + trace_dino_chip_read(addr, val); *data = val; return ret; } @@ -245,6 +294,9 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr, AddressSpace *io; MemTxResult ret; uint16_t ioaddr; + int i; + + trace_dino_chip_write(addr, val); switch (addr) { case DINO_IO_DATA ... DINO_PCI_IO_DATA + 3: @@ -266,9 +318,11 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr, } return ret; + case DINO_IO_FBB_EN: + s->io_fbb_en = val & 0x03; + break; case DINO_IO_ADDR_EN: - /* Never allow first (=firmware) and last (=Dino) areas. */ - s->io_addr_en = val & 0x7ffffffe; + s->io_addr_en = val; gsc_to_pci_forwarding(s); break; case DINO_IO_CONTROL: @@ -292,6 +346,10 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr, /* Any write to IPR clears the register. */ s->ipr = 0; break; + case DINO_TOC_ADDR: + /* IO_COMMAND of CPU with client_id bits */ + s->toc_addr = 0xFFFA0030 | (val & 0x1e000); + break; case DINO_ILR: case DINO_IRR0: @@ -299,6 +357,12 @@ static MemTxResult dino_chip_write_with_attrs(void *opaque, hwaddr addr, /* These registers are read-only. */ break; + case DINO_GMASK ... DINO_TLTIM: + i = (addr - DINO_GMASK) / 4; + val &= reg800_keep_bits[i]; + s->reg800[i] = val; + break; + default: /* Controlled by dino_chip_mem_valid above. */ g_assert_not_reached(); @@ -323,7 +387,7 @@ static const MemoryRegionOps dino_chip_ops = { static const VMStateDescription vmstate_dino = { .name = "Dino", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_UINT32(iar0, DinoState), @@ -332,13 +396,14 @@ static const VMStateDescription vmstate_dino = { VMSTATE_UINT32(ipr, DinoState), VMSTATE_UINT32(icr, DinoState), VMSTATE_UINT32(ilr, DinoState), + VMSTATE_UINT32(io_fbb_en, DinoState), VMSTATE_UINT32(io_addr_en, DinoState), VMSTATE_UINT32(io_control, DinoState), + VMSTATE_UINT32(toc_addr, DinoState), VMSTATE_END_OF_LIST() } }; - /* Unlike pci_config_data_le_ops, no check of high bit set in config_reg. */ static uint64_t dino_config_data_read(void *opaque, hwaddr addr, unsigned len) @@ -362,14 +427,16 @@ static const MemoryRegionOps dino_config_data_ops = { static uint64_t dino_config_addr_read(void *opaque, hwaddr addr, unsigned len) { - PCIHostState *s = opaque; - return s->config_reg; + DinoState *s = opaque; + return s->config_reg_dino; } static void dino_config_addr_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) { PCIHostState *s = opaque; + DinoState *ds = opaque; + ds->config_reg_dino = val; /* keep a copy of original value */ s->config_reg = val & ~3U; } @@ -453,6 +520,8 @@ PCIBus *dino_init(MemoryRegion *addr_space, dev = qdev_create(NULL, 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, diff --git a/hw/hppa/hppa_hardware.h b/hw/hppa/hppa_hardware.h index 507f91e05d..4a2fe2df60 100644 --- a/hw/hppa/hppa_hardware.h +++ b/hw/hppa/hppa_hardware.h @@ -22,6 +22,7 @@ #define LASI_PS2KBD_HPA 0xffd08000 #define LASI_PS2MOU_HPA 0xffd08100 #define LASI_GFX_HPA 0xf8000000 +#define ARTIST_FB_ADDR 0xf9000000 #define CPU_HPA 0xfffb0000 #define MEMORY_HPA 0xfffbf000 diff --git a/hw/hppa/hppa_sys.h b/hw/hppa/hppa_sys.h index 4e5019695e..4d08501464 100644 --- a/hw/hppa/hppa_sys.h +++ b/hw/hppa/hppa_sys.h @@ -12,6 +12,8 @@ #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" diff --git a/hw/hppa/lasi.c b/hw/hppa/lasi.c new file mode 100644 index 0000000000..d8d03f95c0 --- /dev/null +++ b/hw/hppa/lasi.c @@ -0,0 +1,368 @@ +/* + * 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 + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "cpu.h" +#include "trace.h" +#include "hw/hw.h" +#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 "exec/address-spaces.h" +#include "migration/vmstate.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 */ + +#define LASI_CHIP(obj) \ + OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP) + +#define LASI_RTC_HPA (LASI_HPA + 0x9000) + +typedef 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; +} LasiState; + +static bool lasi_chip_mem_valid(void *opaque, hwaddr addr, + unsigned size, bool is_write, + MemTxAttrs attrs) +{ + bool ret = false; + + switch (addr) { + case LASI_IRR: + case LASI_IMR: + case LASI_IPR: + 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_PCR ... LASI_AMR: + ret = true; + } + + trace_lasi_chip_mem_valid(addr, ret); + return ret; +} + +static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ + LasiState *s = opaque; + MemTxResult ret = MEMTX_OK; + uint32_t val; + + switch (addr) { + case LASI_IRR: + val = s->irr; + break; + case LASI_IMR: + val = s->imr; + break; + case LASI_IPR: + val = s->ipr; + /* Any read to IPR clears the register. */ + s->ipr = 0; + break; + case LASI_ICR: + val = s->icr & ICR_BUS_ERROR_BIT; /* bus_error */ + break; + case LASI_IAR: + val = s->iar; + break; + + case (LASI_LAN_HPA - LASI_HPA): + case (LASI_LPT_HPA - LASI_HPA): + case (LASI_UART_HPA - LASI_HPA): + val = 0; + break; + case (LASI_RTC_HPA - LASI_HPA): + val = time(NULL); + val += s->rtc_ref; + break; + + case LASI_PCR: + case LASI_VER: /* only version 0 existed. */ + case LASI_IORESET: + val = 0; + break; + case LASI_ERRLOG: + val = s->errlog; + break; + case LASI_AMR: + val = s->amr; + break; + + default: + /* Controlled by lasi_chip_mem_valid above. */ + g_assert_not_reached(); + } + + trace_lasi_chip_read(addr, val); + + *data = val; + return ret; +} + +static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) +{ + LasiState *s = opaque; + + trace_lasi_chip_write(addr, val); + + switch (addr) { + case LASI_IRR: + /* read-only. */ + break; + case LASI_IMR: + s->imr = val; /* 0x20 ?? */ + assert((val & LASI_IRQ_BITS) == val); + break; + case LASI_IPR: + /* Any write to IPR clears the register. */ + s->ipr = 0; + break; + case LASI_ICR: + s->icr = val; + /* if (val & ICR_TOC_BIT) issue_toc(); */ + break; + case LASI_IAR: + s->iar = val; + break; + + case (LASI_LAN_HPA - LASI_HPA): + /* XXX: reset LAN card */ + break; + case (LASI_LPT_HPA - LASI_HPA): + /* XXX: reset parallel port */ + break; + case (LASI_UART_HPA - LASI_HPA): + /* XXX: reset serial port */ + break; + case (LASI_RTC_HPA - LASI_HPA): + s->rtc_ref = val - time(NULL); + break; + + case LASI_PCR: + if (val == 0x02) /* immediately power off */ + qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); + break; + case LASI_ERRLOG: + s->errlog = val; + break; + case LASI_VER: + /* read-only. */ + break; + case LASI_IORESET: + break; /* XXX: TODO: Reset various devices. */ + case LASI_AMR: + s->amr = val; + break; + + default: + /* Controlled by lasi_chip_mem_valid above. */ + g_assert_not_reached(); + } + return MEMTX_OK; +} + +static const MemoryRegionOps lasi_chip_ops = { + .read_with_attrs = lasi_chip_read_with_attrs, + .write_with_attrs = lasi_chip_write_with_attrs, + .endianness = DEVICE_BIG_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + .accepts = lasi_chip_mem_valid, + }, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static const VMStateDescription vmstate_lasi = { + .name = "Lasi", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(irr, LasiState), + VMSTATE_UINT32(imr, LasiState), + VMSTATE_UINT32(ipr, LasiState), + VMSTATE_UINT32(icr, LasiState), + VMSTATE_UINT32(iar, LasiState), + VMSTATE_UINT32(errlog, LasiState), + VMSTATE_UINT32(amr, LasiState), + VMSTATE_END_OF_LIST() + } +}; + + +static void lasi_set_irq(void *opaque, int irq, int level) +{ + LasiState *s = opaque; + uint32_t bit = 1u << irq; + + if (level) { + s->ipr |= bit; + if (bit & s->imr) { + uint32_t iar = s->iar; + s->irr |= bit; + if ((s->icr & ICR_BUS_ERROR_BIT) == 0) { + stl_be_phys(&address_space_memory, iar & -32, iar & 31); + } + } + } +} + +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) +{ + DeviceState *dev; + LasiState *s; + + dev = qdev_create(NULL, 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); + + qdev_init_nofail(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]); + + /* 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); + } + + /* 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); + + return dev; +} + +static void lasi_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_lasi; +} + +static const TypeInfo lasi_pcihost_info = { + .name = TYPE_LASI_CHIP, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(LasiState), + .class_init = lasi_class_init, +}; + +static void lasi_register_types(void) +{ + type_register_static(&lasi_pcihost_info); +} + +type_init(lasi_register_types) diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index 5d0de26140..2d62a248b8 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -16,6 +16,7 @@ #include "hw/ide.h" #include "hw/timer/i8254.h" #include "hw/char/serial.h" +#include "hw/net/lasi_82596.h" #include "hppa_sys.h" #include "qemu/units.h" #include "qapi/error.h" @@ -74,6 +75,7 @@ static void machine_hppa_init(MachineState *machine) MemoryRegion *cpu_region; long i; unsigned int smp_cpus = machine->smp.cpus; + SysBusDevice *s; ram_size = machine->ram_size; @@ -90,16 +92,18 @@ static void machine_hppa_init(MachineState *machine) g_free(name); } - /* Limit main memory. */ - if (ram_size > FIRMWARE_START) { - machine->ram_size = ram_size = FIRMWARE_START; - } - /* Main memory region. */ + if (machine->ram_size > 3 * GiB) { + error_report("RAM size is currently restricted to 3GB"); + exit(EXIT_FAILURE); + } ram_region = g_new(MemoryRegion, 1); memory_region_allocate_system_memory(ram_region, OBJECT(machine), "ram", ram_size); - memory_region_add_subregion(addr_space, 0, ram_region); + memory_region_add_subregion_overlap(addr_space, 0, ram_region, -1); + + /* Init Lasi chip */ + lasi_init(addr_space); /* Init Dino (PCI host bus chip). */ pci_bus = dino_init(addr_space, &rtc_irq, &serial_irq); @@ -123,9 +127,20 @@ static void machine_hppa_init(MachineState *machine) dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); lsi53c8xx_handle_legacy_cmdline(dev); - /* Network setup. e1000 is good enough, failing Tulip support. */ + /* Graphics setup. */ + if (machine->enable_graphics && vga_interface_type != VGA_NONE) { + dev = qdev_create(NULL, "artist"); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(s, 0, LASI_GFX_HPA); + sysbus_mmio_map(s, 1, ARTIST_FB_ADDR); + } + + /* Network setup. */ for (i = 0; i < nb_nics; i++) { - pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL); + if (!enable_lasi_lan()) { + pci_nic_init_nofail(&nd_table[i], pci_bus, "tulip", NULL); + } } /* Load firmware. Given that this is not "real" firmware, @@ -155,7 +170,7 @@ static void machine_hppa_init(MachineState *machine) qemu_log_mask(CPU_LOG_PAGE, "Firmware loaded at 0x%08" PRIx64 "-0x%08" PRIx64 ", entry at 0x%08" PRIx64 ".\n", firmware_low, firmware_high, firmware_entry); - if (firmware_low < ram_size || firmware_high >= FIRMWARE_END) { + if (firmware_low < FIRMWARE_START || firmware_high >= FIRMWARE_END) { error_report("Firmware overlaps with memory or IO space"); exit(1); } diff --git a/hw/hppa/trace-events b/hw/hppa/trace-events index 4e2acb6176..3ff620319a 100644 --- a/hw/hppa/trace-events +++ b/hw/hppa/trace-events @@ -2,3 +2,13 @@ # 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" |