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" 14376b8519SHelge Deller #include "qapi/error.h" 15376b8519SHelge Deller #include "cpu.h" 16376b8519SHelge Deller #include "trace.h" 17376b8519SHelge Deller #include "hw/hw.h" 18376b8519SHelge Deller #include "hw/irq.h" 19376b8519SHelge Deller #include "sysemu/sysemu.h" 20376b8519SHelge Deller #include "sysemu/runstate.h" 21376b8519SHelge Deller #include "hppa_sys.h" 22376b8519SHelge Deller #include "hw/net/lasi_82596.h" 23376b8519SHelge Deller #include "hw/char/parallel.h" 24376b8519SHelge Deller #include "hw/char/serial.h" 252a6505b0SSven Schnelle #include "hw/input/lasips2.h" 26376b8519SHelge Deller #include "exec/address-spaces.h" 27376b8519SHelge Deller #include "migration/vmstate.h" 28376b8519SHelge Deller 29376b8519SHelge Deller #define TYPE_LASI_CHIP "lasi-chip" 30376b8519SHelge Deller 31376b8519SHelge Deller #define LASI_IRR 0x00 /* RO */ 32376b8519SHelge Deller #define LASI_IMR 0x04 33376b8519SHelge Deller #define LASI_IPR 0x08 34376b8519SHelge Deller #define LASI_ICR 0x0c 35376b8519SHelge Deller #define LASI_IAR 0x10 36376b8519SHelge Deller 37376b8519SHelge Deller #define LASI_PCR 0x0C000 /* LASI Power Control register */ 38376b8519SHelge Deller #define LASI_ERRLOG 0x0C004 /* LASI Error Logging register */ 39376b8519SHelge Deller #define LASI_VER 0x0C008 /* LASI Version Control register */ 40376b8519SHelge Deller #define LASI_IORESET 0x0C00C /* LASI I/O Reset register */ 41376b8519SHelge Deller #define LASI_AMR 0x0C010 /* LASI Arbitration Mask register */ 42376b8519SHelge Deller #define LASI_IO_CONF 0x7FFFE /* LASI primary configuration register */ 43376b8519SHelge Deller #define LASI_IO_CONF2 0x7FFFF /* LASI secondary configuration register */ 44376b8519SHelge Deller 45376b8519SHelge Deller #define LASI_BIT(x) (1ul << (x)) 46376b8519SHelge Deller #define LASI_IRQ_BITS (LASI_BIT(5) | LASI_BIT(7) | LASI_BIT(8) | LASI_BIT(9) \ 47376b8519SHelge Deller | LASI_BIT(13) | LASI_BIT(14) | LASI_BIT(16) | LASI_BIT(17) \ 48376b8519SHelge Deller | LASI_BIT(18) | LASI_BIT(19) | LASI_BIT(20) | LASI_BIT(21) \ 49376b8519SHelge Deller | LASI_BIT(26)) 50376b8519SHelge Deller 51376b8519SHelge Deller #define ICR_BUS_ERROR_BIT LASI_BIT(8) /* bit 8 in ICR */ 52376b8519SHelge Deller #define ICR_TOC_BIT LASI_BIT(1) /* bit 1 in ICR */ 53376b8519SHelge Deller 54376b8519SHelge Deller #define LASI_CHIP(obj) \ 55376b8519SHelge Deller OBJECT_CHECK(LasiState, (obj), TYPE_LASI_CHIP) 56376b8519SHelge Deller 57376b8519SHelge Deller #define LASI_RTC_HPA (LASI_HPA + 0x9000) 58376b8519SHelge Deller 59376b8519SHelge Deller typedef struct LasiState { 60376b8519SHelge Deller PCIHostState parent_obj; 61376b8519SHelge Deller 62376b8519SHelge Deller uint32_t irr; 63376b8519SHelge Deller uint32_t imr; 64376b8519SHelge Deller uint32_t ipr; 65376b8519SHelge Deller uint32_t icr; 66376b8519SHelge Deller uint32_t iar; 67376b8519SHelge Deller 68376b8519SHelge Deller uint32_t errlog; 69376b8519SHelge Deller uint32_t amr; 70376b8519SHelge Deller uint32_t rtc; 71376b8519SHelge Deller time_t rtc_ref; 72376b8519SHelge Deller 73376b8519SHelge Deller MemoryRegion this_mem; 74376b8519SHelge Deller } LasiState; 75376b8519SHelge Deller 76376b8519SHelge Deller static bool lasi_chip_mem_valid(void *opaque, hwaddr addr, 77376b8519SHelge Deller unsigned size, bool is_write, 78376b8519SHelge Deller MemTxAttrs attrs) 79376b8519SHelge Deller { 80376b8519SHelge Deller bool ret = false; 81376b8519SHelge Deller 82376b8519SHelge Deller switch (addr) { 83376b8519SHelge Deller case LASI_IRR: 84376b8519SHelge Deller case LASI_IMR: 85376b8519SHelge Deller case LASI_IPR: 86376b8519SHelge Deller case LASI_ICR: 87376b8519SHelge Deller case LASI_IAR: 88376b8519SHelge Deller 89376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 90376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 91376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 92376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 93376b8519SHelge Deller 94376b8519SHelge Deller case LASI_PCR ... LASI_AMR: 95376b8519SHelge Deller ret = true; 96376b8519SHelge Deller } 97376b8519SHelge Deller 98376b8519SHelge Deller trace_lasi_chip_mem_valid(addr, ret); 99376b8519SHelge Deller return ret; 100376b8519SHelge Deller } 101376b8519SHelge Deller 102376b8519SHelge Deller static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr, 103376b8519SHelge Deller uint64_t *data, unsigned size, 104376b8519SHelge Deller MemTxAttrs attrs) 105376b8519SHelge Deller { 106376b8519SHelge Deller LasiState *s = opaque; 107376b8519SHelge Deller MemTxResult ret = MEMTX_OK; 108376b8519SHelge Deller uint32_t val; 109376b8519SHelge Deller 110376b8519SHelge Deller switch (addr) { 111376b8519SHelge Deller case LASI_IRR: 112376b8519SHelge Deller val = s->irr; 113376b8519SHelge Deller break; 114376b8519SHelge Deller case LASI_IMR: 115376b8519SHelge Deller val = s->imr; 116376b8519SHelge Deller break; 117376b8519SHelge Deller case LASI_IPR: 118376b8519SHelge Deller val = s->ipr; 119376b8519SHelge Deller /* Any read to IPR clears the register. */ 120376b8519SHelge Deller s->ipr = 0; 121376b8519SHelge Deller break; 122376b8519SHelge Deller case LASI_ICR: 123376b8519SHelge Deller val = s->icr & ICR_BUS_ERROR_BIT; /* bus_error */ 124376b8519SHelge Deller break; 125376b8519SHelge Deller case LASI_IAR: 126376b8519SHelge Deller val = s->iar; 127376b8519SHelge Deller break; 128376b8519SHelge Deller 129376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 130376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 131376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 132376b8519SHelge Deller val = 0; 133376b8519SHelge Deller break; 134376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 135376b8519SHelge Deller val = time(NULL); 136376b8519SHelge Deller val += s->rtc_ref; 137376b8519SHelge Deller break; 138376b8519SHelge Deller 139376b8519SHelge Deller case LASI_PCR: 140376b8519SHelge Deller case LASI_VER: /* only version 0 existed. */ 141376b8519SHelge Deller case LASI_IORESET: 142376b8519SHelge Deller val = 0; 143376b8519SHelge Deller break; 144376b8519SHelge Deller case LASI_ERRLOG: 145376b8519SHelge Deller val = s->errlog; 146376b8519SHelge Deller break; 147376b8519SHelge Deller case LASI_AMR: 148376b8519SHelge Deller val = s->amr; 149376b8519SHelge Deller break; 150376b8519SHelge Deller 151376b8519SHelge Deller default: 152376b8519SHelge Deller /* Controlled by lasi_chip_mem_valid above. */ 153376b8519SHelge Deller g_assert_not_reached(); 154376b8519SHelge Deller } 155376b8519SHelge Deller 156376b8519SHelge Deller trace_lasi_chip_read(addr, val); 157376b8519SHelge Deller 158376b8519SHelge Deller *data = val; 159376b8519SHelge Deller return ret; 160376b8519SHelge Deller } 161376b8519SHelge Deller 162376b8519SHelge Deller static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr, 163376b8519SHelge Deller uint64_t val, unsigned size, 164376b8519SHelge Deller MemTxAttrs attrs) 165376b8519SHelge Deller { 166376b8519SHelge Deller LasiState *s = opaque; 167376b8519SHelge Deller 168376b8519SHelge Deller trace_lasi_chip_write(addr, val); 169376b8519SHelge Deller 170376b8519SHelge Deller switch (addr) { 171376b8519SHelge Deller case LASI_IRR: 172376b8519SHelge Deller /* read-only. */ 173376b8519SHelge Deller break; 174376b8519SHelge Deller case LASI_IMR: 175376b8519SHelge Deller s->imr = val; /* 0x20 ?? */ 176376b8519SHelge Deller assert((val & LASI_IRQ_BITS) == val); 177376b8519SHelge Deller break; 178376b8519SHelge Deller case LASI_IPR: 179376b8519SHelge Deller /* Any write to IPR clears the register. */ 180376b8519SHelge Deller s->ipr = 0; 181376b8519SHelge Deller break; 182376b8519SHelge Deller case LASI_ICR: 183376b8519SHelge Deller s->icr = val; 184376b8519SHelge Deller /* if (val & ICR_TOC_BIT) issue_toc(); */ 185376b8519SHelge Deller break; 186376b8519SHelge Deller case LASI_IAR: 187376b8519SHelge Deller s->iar = val; 188376b8519SHelge Deller break; 189376b8519SHelge Deller 190376b8519SHelge Deller case (LASI_LAN_HPA - LASI_HPA): 191376b8519SHelge Deller /* XXX: reset LAN card */ 192376b8519SHelge Deller break; 193376b8519SHelge Deller case (LASI_LPT_HPA - LASI_HPA): 194376b8519SHelge Deller /* XXX: reset parallel port */ 195376b8519SHelge Deller break; 196376b8519SHelge Deller case (LASI_UART_HPA - LASI_HPA): 197376b8519SHelge Deller /* XXX: reset serial port */ 198376b8519SHelge Deller break; 199376b8519SHelge Deller case (LASI_RTC_HPA - LASI_HPA): 200376b8519SHelge Deller s->rtc_ref = val - time(NULL); 201376b8519SHelge Deller break; 202376b8519SHelge Deller 203376b8519SHelge Deller case LASI_PCR: 204376b8519SHelge Deller if (val == 0x02) /* immediately power off */ 205376b8519SHelge Deller qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); 206376b8519SHelge Deller break; 207376b8519SHelge Deller case LASI_ERRLOG: 208376b8519SHelge Deller s->errlog = val; 209376b8519SHelge Deller break; 210376b8519SHelge Deller case LASI_VER: 211376b8519SHelge Deller /* read-only. */ 212376b8519SHelge Deller break; 213376b8519SHelge Deller case LASI_IORESET: 214376b8519SHelge Deller break; /* XXX: TODO: Reset various devices. */ 215376b8519SHelge Deller case LASI_AMR: 216376b8519SHelge Deller s->amr = val; 217376b8519SHelge Deller break; 218376b8519SHelge Deller 219376b8519SHelge Deller default: 220376b8519SHelge Deller /* Controlled by lasi_chip_mem_valid above. */ 221376b8519SHelge Deller g_assert_not_reached(); 222376b8519SHelge Deller } 223376b8519SHelge Deller return MEMTX_OK; 224376b8519SHelge Deller } 225376b8519SHelge Deller 226376b8519SHelge Deller static const MemoryRegionOps lasi_chip_ops = { 227376b8519SHelge Deller .read_with_attrs = lasi_chip_read_with_attrs, 228376b8519SHelge Deller .write_with_attrs = lasi_chip_write_with_attrs, 229376b8519SHelge Deller .endianness = DEVICE_BIG_ENDIAN, 230376b8519SHelge Deller .valid = { 231376b8519SHelge Deller .min_access_size = 1, 232376b8519SHelge Deller .max_access_size = 4, 233376b8519SHelge Deller .accepts = lasi_chip_mem_valid, 234376b8519SHelge Deller }, 235376b8519SHelge Deller .impl = { 236376b8519SHelge Deller .min_access_size = 1, 237376b8519SHelge Deller .max_access_size = 4, 238376b8519SHelge Deller }, 239376b8519SHelge Deller }; 240376b8519SHelge Deller 241376b8519SHelge Deller static const VMStateDescription vmstate_lasi = { 242376b8519SHelge Deller .name = "Lasi", 243376b8519SHelge Deller .version_id = 1, 244376b8519SHelge Deller .minimum_version_id = 1, 245376b8519SHelge Deller .fields = (VMStateField[]) { 246376b8519SHelge Deller VMSTATE_UINT32(irr, LasiState), 247376b8519SHelge Deller VMSTATE_UINT32(imr, LasiState), 248376b8519SHelge Deller VMSTATE_UINT32(ipr, LasiState), 249376b8519SHelge Deller VMSTATE_UINT32(icr, LasiState), 250376b8519SHelge Deller VMSTATE_UINT32(iar, LasiState), 251376b8519SHelge Deller VMSTATE_UINT32(errlog, LasiState), 252376b8519SHelge Deller VMSTATE_UINT32(amr, LasiState), 253376b8519SHelge Deller VMSTATE_END_OF_LIST() 254376b8519SHelge Deller } 255376b8519SHelge Deller }; 256376b8519SHelge Deller 257376b8519SHelge Deller 258376b8519SHelge Deller static void lasi_set_irq(void *opaque, int irq, int level) 259376b8519SHelge Deller { 260376b8519SHelge Deller LasiState *s = opaque; 261376b8519SHelge Deller uint32_t bit = 1u << irq; 262376b8519SHelge Deller 263376b8519SHelge Deller if (level) { 264376b8519SHelge Deller s->ipr |= bit; 265376b8519SHelge Deller if (bit & s->imr) { 266376b8519SHelge Deller uint32_t iar = s->iar; 267376b8519SHelge Deller s->irr |= bit; 268376b8519SHelge Deller if ((s->icr & ICR_BUS_ERROR_BIT) == 0) { 269376b8519SHelge Deller stl_be_phys(&address_space_memory, iar & -32, iar & 31); 270376b8519SHelge Deller } 271376b8519SHelge Deller } 272376b8519SHelge Deller } 273376b8519SHelge Deller } 274376b8519SHelge Deller 275376b8519SHelge Deller static int lasi_get_irq(unsigned long hpa) 276376b8519SHelge Deller { 277376b8519SHelge Deller switch (hpa) { 278376b8519SHelge Deller case LASI_HPA: 279376b8519SHelge Deller return 14; 280376b8519SHelge Deller case LASI_UART_HPA: 281376b8519SHelge Deller return 5; 282376b8519SHelge Deller case LASI_LPT_HPA: 283376b8519SHelge Deller return 7; 284376b8519SHelge Deller case LASI_LAN_HPA: 285376b8519SHelge Deller return 8; 286376b8519SHelge Deller case LASI_SCSI_HPA: 287376b8519SHelge Deller return 9; 288376b8519SHelge Deller case LASI_AUDIO_HPA: 289376b8519SHelge Deller return 13; 290376b8519SHelge Deller case LASI_PS2KBD_HPA: 291376b8519SHelge Deller case LASI_PS2MOU_HPA: 292376b8519SHelge Deller return 26; 293376b8519SHelge Deller default: 294376b8519SHelge Deller g_assert_not_reached(); 295376b8519SHelge Deller } 296376b8519SHelge Deller } 297376b8519SHelge Deller 298376b8519SHelge Deller DeviceState *lasi_init(MemoryRegion *address_space) 299376b8519SHelge Deller { 300376b8519SHelge Deller DeviceState *dev; 301376b8519SHelge Deller LasiState *s; 302376b8519SHelge Deller 3033e80f690SMarkus Armbruster dev = qdev_new(TYPE_LASI_CHIP); 304376b8519SHelge Deller s = LASI_CHIP(dev); 305376b8519SHelge Deller s->iar = CPU_HPA + 3; 306376b8519SHelge Deller 307376b8519SHelge Deller /* Lasi access from main memory. */ 308376b8519SHelge Deller memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops, 309376b8519SHelge Deller s, "lasi", 0x100000); 310376b8519SHelge Deller memory_region_add_subregion(address_space, LASI_HPA, &s->this_mem); 311376b8519SHelge Deller 3123c6ef471SMarkus Armbruster sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 313376b8519SHelge Deller 314376b8519SHelge Deller /* LAN */ 315376b8519SHelge Deller if (enable_lasi_lan()) { 316376b8519SHelge Deller qemu_irq lan_irq = qemu_allocate_irq(lasi_set_irq, s, 317376b8519SHelge Deller lasi_get_irq(LASI_LAN_HPA)); 318376b8519SHelge Deller lasi_82596_init(address_space, LASI_LAN_HPA, lan_irq); 319376b8519SHelge Deller } 320376b8519SHelge Deller 321376b8519SHelge Deller /* Parallel port */ 322376b8519SHelge Deller qemu_irq lpt_irq = qemu_allocate_irq(lasi_set_irq, s, 323376b8519SHelge Deller lasi_get_irq(LASI_LPT_HPA)); 324376b8519SHelge Deller parallel_mm_init(address_space, LASI_LPT_HPA + 0x800, 0, 325376b8519SHelge Deller lpt_irq, parallel_hds[0]); 326376b8519SHelge Deller 327376b8519SHelge Deller /* Real time clock (RTC), it's only one 32-bit counter @9000 */ 3282a6505b0SSven Schnelle 329376b8519SHelge Deller s->rtc = time(NULL); 330376b8519SHelge Deller s->rtc_ref = 0; 331376b8519SHelge Deller 332376b8519SHelge Deller if (serial_hd(1)) { 333376b8519SHelge Deller /* Serial port */ 334376b8519SHelge Deller qemu_irq serial_irq = qemu_allocate_irq(lasi_set_irq, s, 335376b8519SHelge Deller lasi_get_irq(LASI_UART_HPA)); 336376b8519SHelge Deller serial_mm_init(address_space, LASI_UART_HPA + 0x800, 0, 337376b8519SHelge Deller serial_irq, 8000000 / 16, 3382a6505b0SSven Schnelle serial_hd(0), DEVICE_NATIVE_ENDIAN); 339376b8519SHelge Deller } 3402a6505b0SSven Schnelle 3412a6505b0SSven Schnelle /* PS/2 Keyboard/Mouse */ 3422a6505b0SSven Schnelle qemu_irq ps2kbd_irq = qemu_allocate_irq(lasi_set_irq, s, 3432a6505b0SSven Schnelle lasi_get_irq(LASI_PS2KBD_HPA)); 3442a6505b0SSven Schnelle lasips2_init(address_space, LASI_PS2KBD_HPA, ps2kbd_irq); 3452a6505b0SSven Schnelle 346376b8519SHelge Deller return dev; 347376b8519SHelge Deller } 348376b8519SHelge Deller 349376b8519SHelge Deller static void lasi_class_init(ObjectClass *klass, void *data) 350376b8519SHelge Deller { 351376b8519SHelge Deller DeviceClass *dc = DEVICE_CLASS(klass); 352376b8519SHelge Deller 353376b8519SHelge Deller dc->vmsd = &vmstate_lasi; 354376b8519SHelge Deller } 355376b8519SHelge Deller 356376b8519SHelge Deller static const TypeInfo lasi_pcihost_info = { 357376b8519SHelge Deller .name = TYPE_LASI_CHIP, 358376b8519SHelge Deller .parent = TYPE_SYS_BUS_DEVICE, 359376b8519SHelge Deller .instance_size = sizeof(LasiState), 360376b8519SHelge Deller .class_init = lasi_class_init, 361376b8519SHelge Deller }; 362376b8519SHelge Deller 363376b8519SHelge Deller static void lasi_register_types(void) 364376b8519SHelge Deller { 365376b8519SHelge Deller type_register_static(&lasi_pcihost_info); 366376b8519SHelge Deller } 367376b8519SHelge Deller 368376b8519SHelge Deller type_init(lasi_register_types) 369