1376b8519SHelge Deller /* 2376b8519SHelge Deller * HP-PARISC Lasi chipset emulation. 3376b8519SHelge Deller * 4376b8519SHelge Deller * (C) 2019 by Helge Deller <deller@gmx.de> 5376b8519SHelge Deller * 6376b8519SHelge Deller * This work is licensed under the GNU GPL license version 2 or later. 7376b8519SHelge Deller * 8376b8519SHelge Deller * Documentation available at: 9376b8519SHelge Deller * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf 10376b8519SHelge Deller */ 11376b8519SHelge Deller 12376b8519SHelge Deller #include "qemu/osdep.h" 13376b8519SHelge Deller #include "qemu/units.h" 14b899fe41SHelge Deller #include "qemu/log.h" 15376b8519SHelge Deller #include "qapi/error.h" 16376b8519SHelge Deller #include "trace.h" 17376b8519SHelge Deller #include "hw/irq.h" 18376b8519SHelge Deller #include "sysemu/sysemu.h" 19376b8519SHelge Deller #include "sysemu/runstate.h" 20376b8519SHelge Deller #include "hppa_sys.h" 21376b8519SHelge Deller #include "hw/net/lasi_82596.h" 22376b8519SHelge Deller #include "hw/char/parallel.h" 23376b8519SHelge Deller #include "hw/char/serial.h" 242a6505b0SSven Schnelle #include "hw/input/lasips2.h" 25376b8519SHelge Deller #include "migration/vmstate.h" 26db1015e9SEduardo Habkost #include "qom/object.h" 27b514f432SMark Cave-Ayland #include "lasi.h" 28376b8519SHelge Deller 29376b8519SHelge Deller 30376b8519SHelge Deller static bool lasi_chip_mem_valid(void *opaque, hwaddr addr, 31376b8519SHelge Deller unsigned size, bool is_write, 32376b8519SHelge Deller MemTxAttrs attrs) 33376b8519SHelge Deller { 34376b8519SHelge Deller bool ret = false; 35376b8519SHelge Deller 36376b8519SHelge Deller switch (addr) { 37376b8519SHelge Deller case LASI_IRR: 38376b8519SHelge Deller case LASI_IMR: 39376b8519SHelge Deller case LASI_IPR: 40376b8519SHelge Deller case LASI_ICR: 41376b8519SHelge Deller case LASI_IAR: 42376b8519SHelge Deller 43376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 44376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 45376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 46376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 47376b8519SHelge Deller 48376b8519SHelge Deller case LASI_PCR ... LASI_AMR: 49376b8519SHelge Deller ret = true; 50376b8519SHelge Deller } 51376b8519SHelge Deller 52376b8519SHelge Deller trace_lasi_chip_mem_valid(addr, ret); 53376b8519SHelge Deller return ret; 54376b8519SHelge Deller } 55376b8519SHelge Deller 56376b8519SHelge Deller static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr, 57376b8519SHelge Deller uint64_t *data, unsigned size, 58376b8519SHelge Deller MemTxAttrs attrs) 59376b8519SHelge Deller { 60376b8519SHelge Deller LasiState *s = opaque; 61376b8519SHelge Deller MemTxResult ret = MEMTX_OK; 62376b8519SHelge Deller uint32_t val; 63376b8519SHelge Deller 64376b8519SHelge Deller switch (addr) { 65376b8519SHelge Deller case LASI_IRR: 66376b8519SHelge Deller val = s->irr; 67376b8519SHelge Deller break; 68376b8519SHelge Deller case LASI_IMR: 69376b8519SHelge Deller val = s->imr; 70376b8519SHelge Deller break; 71376b8519SHelge Deller case LASI_IPR: 72376b8519SHelge Deller val = s->ipr; 73376b8519SHelge Deller /* Any read to IPR clears the register. */ 74376b8519SHelge Deller s->ipr = 0; 75376b8519SHelge Deller break; 76376b8519SHelge Deller case LASI_ICR: 77376b8519SHelge Deller val = s->icr & ICR_BUS_ERROR_BIT; /* bus_error */ 78376b8519SHelge Deller break; 79376b8519SHelge Deller case LASI_IAR: 80376b8519SHelge Deller val = s->iar; 81376b8519SHelge Deller break; 82376b8519SHelge Deller 83376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 84376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 85376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 86376b8519SHelge Deller val = 0; 87376b8519SHelge Deller break; 88376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 89376b8519SHelge Deller val = time(NULL); 90376b8519SHelge Deller val += s->rtc_ref; 91376b8519SHelge Deller break; 92376b8519SHelge Deller 93376b8519SHelge Deller case LASI_PCR: 94376b8519SHelge Deller case LASI_VER: /* only version 0 existed. */ 95376b8519SHelge Deller case LASI_IORESET: 96376b8519SHelge Deller val = 0; 97376b8519SHelge Deller break; 98376b8519SHelge Deller case LASI_ERRLOG: 99376b8519SHelge Deller val = s->errlog; 100376b8519SHelge Deller break; 101376b8519SHelge Deller case LASI_AMR: 102376b8519SHelge Deller val = s->amr; 103376b8519SHelge Deller break; 104376b8519SHelge Deller 105376b8519SHelge Deller default: 106376b8519SHelge Deller /* Controlled by lasi_chip_mem_valid above. */ 107376b8519SHelge Deller g_assert_not_reached(); 108376b8519SHelge Deller } 109376b8519SHelge Deller 110376b8519SHelge Deller trace_lasi_chip_read(addr, val); 111376b8519SHelge Deller 112376b8519SHelge Deller *data = val; 113376b8519SHelge Deller return ret; 114376b8519SHelge Deller } 115376b8519SHelge Deller 116376b8519SHelge Deller static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr, 117376b8519SHelge Deller uint64_t val, unsigned size, 118376b8519SHelge Deller MemTxAttrs attrs) 119376b8519SHelge Deller { 120376b8519SHelge Deller LasiState *s = opaque; 121376b8519SHelge Deller 122376b8519SHelge Deller trace_lasi_chip_write(addr, val); 123376b8519SHelge Deller 124376b8519SHelge Deller switch (addr) { 125376b8519SHelge Deller case LASI_IRR: 126376b8519SHelge Deller /* read-only. */ 127376b8519SHelge Deller break; 128376b8519SHelge Deller case LASI_IMR: 129b899fe41SHelge Deller s->imr = val; 13063588da8SMark Cave-Ayland if (((val & LASI_IRQ_BITS) != val) && (val != 0xffffffff)) { 131b899fe41SHelge Deller qemu_log_mask(LOG_GUEST_ERROR, 132b899fe41SHelge Deller "LASI: tried to set invalid %lx IMR value.\n", 133b899fe41SHelge Deller (unsigned long) val); 13463588da8SMark Cave-Ayland } 135376b8519SHelge Deller break; 136376b8519SHelge Deller case LASI_IPR: 137376b8519SHelge Deller /* Any write to IPR clears the register. */ 138376b8519SHelge Deller s->ipr = 0; 139376b8519SHelge Deller break; 140376b8519SHelge Deller case LASI_ICR: 141376b8519SHelge Deller s->icr = val; 142376b8519SHelge Deller /* if (val & ICR_TOC_BIT) issue_toc(); */ 143376b8519SHelge Deller break; 144376b8519SHelge Deller case LASI_IAR: 145376b8519SHelge Deller s->iar = val; 146376b8519SHelge Deller break; 147376b8519SHelge Deller 148376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 149376b8519SHelge Deller /* XXX: reset LAN card */ 150376b8519SHelge Deller break; 151376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 152376b8519SHelge Deller /* XXX: reset parallel port */ 153376b8519SHelge Deller break; 154376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 155376b8519SHelge Deller /* XXX: reset serial port */ 156376b8519SHelge Deller break; 157376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 158376b8519SHelge Deller s->rtc_ref = val - time(NULL); 159376b8519SHelge Deller break; 160376b8519SHelge Deller 161376b8519SHelge Deller case LASI_PCR: 16263588da8SMark Cave-Ayland if (val == 0x02) { /* immediately power off */ 163376b8519SHelge Deller qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 16463588da8SMark Cave-Ayland } 165376b8519SHelge Deller break; 166376b8519SHelge Deller case LASI_ERRLOG: 167376b8519SHelge Deller s->errlog = val; 168376b8519SHelge Deller break; 169376b8519SHelge Deller case LASI_VER: 170376b8519SHelge Deller /* read-only. */ 171376b8519SHelge Deller break; 172376b8519SHelge Deller case LASI_IORESET: 173376b8519SHelge Deller break; /* XXX: TODO: Reset various devices. */ 174376b8519SHelge Deller case LASI_AMR: 175376b8519SHelge Deller s->amr = val; 176376b8519SHelge Deller break; 177376b8519SHelge Deller 178376b8519SHelge Deller default: 179376b8519SHelge Deller /* Controlled by lasi_chip_mem_valid above. */ 180376b8519SHelge Deller g_assert_not_reached(); 181376b8519SHelge Deller } 182376b8519SHelge Deller return MEMTX_OK; 183376b8519SHelge Deller } 184376b8519SHelge Deller 185376b8519SHelge Deller static const MemoryRegionOps lasi_chip_ops = { 186376b8519SHelge Deller .read_with_attrs = lasi_chip_read_with_attrs, 187376b8519SHelge Deller .write_with_attrs = lasi_chip_write_with_attrs, 188376b8519SHelge Deller .endianness = DEVICE_BIG_ENDIAN, 189376b8519SHelge Deller .valid = { 190376b8519SHelge Deller .min_access_size = 1, 191376b8519SHelge Deller .max_access_size = 4, 192376b8519SHelge Deller .accepts = lasi_chip_mem_valid, 193376b8519SHelge Deller }, 194376b8519SHelge Deller .impl = { 195376b8519SHelge Deller .min_access_size = 1, 196376b8519SHelge Deller .max_access_size = 4, 197376b8519SHelge Deller }, 198376b8519SHelge Deller }; 199376b8519SHelge Deller 200376b8519SHelge Deller static const VMStateDescription vmstate_lasi = { 201376b8519SHelge Deller .name = "Lasi", 202376b8519SHelge Deller .version_id = 1, 203376b8519SHelge Deller .minimum_version_id = 1, 204376b8519SHelge Deller .fields = (VMStateField[]) { 205376b8519SHelge Deller VMSTATE_UINT32(irr, LasiState), 206376b8519SHelge Deller VMSTATE_UINT32(imr, LasiState), 207376b8519SHelge Deller VMSTATE_UINT32(ipr, LasiState), 208376b8519SHelge Deller VMSTATE_UINT32(icr, LasiState), 209376b8519SHelge Deller VMSTATE_UINT32(iar, LasiState), 210376b8519SHelge Deller VMSTATE_UINT32(errlog, LasiState), 211376b8519SHelge Deller VMSTATE_UINT32(amr, LasiState), 212376b8519SHelge Deller VMSTATE_END_OF_LIST() 213376b8519SHelge Deller } 214376b8519SHelge Deller }; 215376b8519SHelge Deller 216376b8519SHelge Deller 217376b8519SHelge Deller static void lasi_set_irq(void *opaque, int irq, int level) 218376b8519SHelge Deller { 219376b8519SHelge Deller LasiState *s = opaque; 220376b8519SHelge Deller uint32_t bit = 1u << irq; 221376b8519SHelge Deller 222376b8519SHelge Deller if (level) { 223376b8519SHelge Deller s->ipr |= bit; 224376b8519SHelge Deller if (bit & s->imr) { 225376b8519SHelge Deller uint32_t iar = s->iar; 226376b8519SHelge Deller s->irr |= bit; 227376b8519SHelge Deller if ((s->icr & ICR_BUS_ERROR_BIT) == 0) { 228376b8519SHelge Deller stl_be_phys(&address_space_memory, iar & -32, iar & 31); 229376b8519SHelge Deller } 230376b8519SHelge Deller } 231376b8519SHelge Deller } 232376b8519SHelge Deller } 233376b8519SHelge Deller 23446f2594cSMark Cave-Ayland DeviceState *lasi_initfn(MemoryRegion *address_space) 235376b8519SHelge Deller { 236376b8519SHelge Deller DeviceState *dev; 237376b8519SHelge Deller LasiState *s; 238376b8519SHelge Deller 2393e80f690SMarkus Armbruster dev = qdev_new(TYPE_LASI_CHIP); 240376b8519SHelge Deller s = LASI_CHIP(dev); 2413c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 242376b8519SHelge Deller 243376b8519SHelge Deller /* LAN */ 244376b8519SHelge Deller if (enable_lasi_lan()) { 245376b8519SHelge Deller qemu_irq lan_irq = qemu_allocate_irq(lasi_set_irq, s, 2460f04d577SMark Cave-Ayland LASI_IRQ_LAN_HPA); 247376b8519SHelge Deller lasi_82596_init(address_space, LASI_LAN_HPA, lan_irq); 248376b8519SHelge Deller } 249376b8519SHelge Deller 250376b8519SHelge Deller /* Parallel port */ 251376b8519SHelge Deller qemu_irq lpt_irq = qemu_allocate_irq(lasi_set_irq, s, 2520f04d577SMark Cave-Ayland LASI_IRQ_LPT_HPA); 253376b8519SHelge Deller parallel_mm_init(address_space, LASI_LPT_HPA + 0x800, 0, 254376b8519SHelge Deller lpt_irq, parallel_hds[0]); 255376b8519SHelge Deller 256376b8519SHelge Deller if (serial_hd(1)) { 257376b8519SHelge Deller /* Serial port */ 258376b8519SHelge Deller qemu_irq serial_irq = qemu_allocate_irq(lasi_set_irq, s, 2590f04d577SMark Cave-Ayland LASI_IRQ_UART_HPA); 260376b8519SHelge Deller serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0, 261376b8519SHelge Deller serial_irq, 8000000 / 16, 2622a6505b0SSven Schnelle serial_hd(0), DEVICE_NATIVE_ENDIAN); 263376b8519SHelge Deller } 2642a6505b0SSven Schnelle 2652a6505b0SSven Schnelle /* PS/2 Keyboard/Mouse */ 2662a6505b0SSven Schnelle qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s, 2670f04d577SMark Cave-Ayland LASI_IRQ_PS2KBD_HPA); 2682a6505b0SSven Schnelle lasips2_init(address_space, LASI_PS2KBD_HPA, ps2kbd_irq); 2692a6505b0SSven Schnelle 270376b8519SHelge Deller return dev; 271376b8519SHelge Deller } 272376b8519SHelge Deller 273b3cdb7e4SMark Cave-Ayland static void lasi_reset(DeviceState *dev) 274b3cdb7e4SMark Cave-Ayland { 275b3cdb7e4SMark Cave-Ayland LasiState *s = LASI_CHIP(dev); 276b3cdb7e4SMark Cave-Ayland 277b3cdb7e4SMark Cave-Ayland s->iar = CPU_HPA + 3; 278b3cdb7e4SMark Cave-Ayland 279b3cdb7e4SMark Cave-Ayland /* Real time clock (RTC), it's only one 32-bit counter @9000 */ 280b3cdb7e4SMark Cave-Ayland s->rtc = time(NULL); 281b3cdb7e4SMark Cave-Ayland s->rtc_ref = 0; 282b3cdb7e4SMark Cave-Ayland } 283b3cdb7e4SMark Cave-Ayland 28446f2594cSMark Cave-Ayland static void lasi_init(Object *obj) 28546f2594cSMark Cave-Ayland { 28646f2594cSMark Cave-Ayland LasiState *s = LASI_CHIP(obj); 2872683758cSMark Cave-Ayland SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 28846f2594cSMark Cave-Ayland 28946f2594cSMark Cave-Ayland memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops, 29046f2594cSMark Cave-Ayland s, "lasi", 0x100000); 2912683758cSMark Cave-Ayland 2922683758cSMark Cave-Ayland sysbus_init_mmio(sbd, &s->this_mem); 293*cb9f6c4bSMark Cave-Ayland 294*cb9f6c4bSMark Cave-Ayland qdev_init_gpio_in(DEVICE(obj), lasi_set_irq, LASI_IRQS); 29546f2594cSMark Cave-Ayland } 29646f2594cSMark Cave-Ayland 297376b8519SHelge Deller static void lasi_class_init(ObjectClass *klass, void *data) 298376b8519SHelge Deller { 299376b8519SHelge Deller DeviceClass *dc = DEVICE_CLASS(klass); 300376b8519SHelge Deller 301b3cdb7e4SMark Cave-Ayland dc->reset = lasi_reset; 302376b8519SHelge Deller dc->vmsd = &vmstate_lasi; 303376b8519SHelge Deller } 304376b8519SHelge Deller 305376b8519SHelge Deller static const TypeInfo lasi_pcihost_info = { 306376b8519SHelge Deller .name = TYPE_LASI_CHIP, 307376b8519SHelge Deller .parent = TYPE_SYS_BUS_DEVICE, 30846f2594cSMark Cave-Ayland .instance_init = lasi_init, 309376b8519SHelge Deller .instance_size = sizeof(LasiState), 310376b8519SHelge Deller .class_init = lasi_class_init, 311376b8519SHelge Deller }; 312376b8519SHelge Deller 313376b8519SHelge Deller static void lasi_register_types(void) 314376b8519SHelge Deller { 315376b8519SHelge Deller type_register_static(&lasi_pcihost_info); 316376b8519SHelge Deller } 317376b8519SHelge Deller 318376b8519SHelge Deller type_init(lasi_register_types) 319