1 /* 2 * QEMU Macintosh floppy disk controller emulator (SWIM) 3 * 4 * Copyright (c) 2014-2018 Laurent Vivier <laurent@vivier.eu> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2. See 7 * the COPYING file in the top-level directory. 8 * 9 * Only the basic support: it allows to switch from IWM (Integrated WOZ 10 * Machine) mode to the SWIM mode and makes the linux driver happy. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qemu/main-loop.h" 15 #include "qapi/error.h" 16 #include "sysemu/block-backend.h" 17 #include "hw/sysbus.h" 18 #include "migration/vmstate.h" 19 #include "hw/block/block.h" 20 #include "hw/block/swim.h" 21 #include "hw/qdev-properties.h" 22 #include "trace.h" 23 24 25 /* IWM latch bits */ 26 27 #define IWMLB_PHASE0 0 28 #define IWMLB_PHASE1 1 29 #define IWMLB_PHASE2 2 30 #define IWMLB_PHASE3 3 31 #define IWMLB_MOTORON 4 32 #define IWMLB_DRIVESEL 5 33 #define IWMLB_L6 6 34 #define IWMLB_L7 7 35 36 /* IWM registers */ 37 38 #define IWM_READALLONES 0 39 #define IWM_READDATA 1 40 #define IWM_READSTATUS0 2 41 #define IWM_READSTATUS1 3 42 #define IWM_READWHANDSHAKE0 4 43 #define IWM_READWHANDSHAKE1 5 44 #define IWM_WRITESETMODE 6 45 #define IWM_WRITEDATA 7 46 47 /* SWIM registers */ 48 49 #define SWIM_WRITE_DATA 0 50 #define SWIM_WRITE_MARK 1 51 #define SWIM_WRITE_CRC 2 52 #define SWIM_WRITE_PARAMETER 3 53 #define SWIM_WRITE_PHASE 4 54 #define SWIM_WRITE_SETUP 5 55 #define SWIM_WRITE_MODE0 6 56 #define SWIM_WRITE_MODE1 7 57 58 #define SWIM_READ_DATA 8 59 #define SWIM_READ_MARK 9 60 #define SWIM_READ_ERROR 10 61 #define SWIM_READ_PARAMETER 11 62 #define SWIM_READ_PHASE 12 63 #define SWIM_READ_SETUP 13 64 #define SWIM_READ_STATUS 14 65 #define SWIM_READ_HANDSHAKE 15 66 67 #define REG_SHIFT 9 68 69 #define SWIM_MODE_STATUS_BIT 6 70 #define SWIM_MODE_IWM 0 71 #define SWIM_MODE_ISM 1 72 73 /* bits in phase register */ 74 75 #define SWIM_SEEK_NEGATIVE 0x074 76 #define SWIM_STEP 0x071 77 #define SWIM_MOTOR_ON 0x072 78 #define SWIM_MOTOR_OFF 0x076 79 #define SWIM_INDEX 0x073 80 #define SWIM_EJECT 0x077 81 #define SWIM_SETMFM 0x171 82 #define SWIM_SETGCR 0x175 83 #define SWIM_RELAX 0x033 84 #define SWIM_LSTRB 0x008 85 #define SWIM_CA_MASK 0x077 86 87 /* Select values for swim_select and swim_readbit */ 88 89 #define SWIM_READ_DATA_0 0x074 90 #define SWIM_TWOMEG_DRIVE 0x075 91 #define SWIM_SINGLE_SIDED 0x076 92 #define SWIM_DRIVE_PRESENT 0x077 93 #define SWIM_DISK_IN 0x170 94 #define SWIM_WRITE_PROT 0x171 95 #define SWIM_TRACK_ZERO 0x172 96 #define SWIM_TACHO 0x173 97 #define SWIM_READ_DATA_1 0x174 98 #define SWIM_MFM_MODE 0x175 99 #define SWIM_SEEK_COMPLETE 0x176 100 #define SWIM_ONEMEG_MEDIA 0x177 101 102 /* Bits in handshake register */ 103 104 #define SWIM_MARK_BYTE 0x01 105 #define SWIM_CRC_ZERO 0x02 106 #define SWIM_RDDATA 0x04 107 #define SWIM_SENSE 0x08 108 #define SWIM_MOTEN 0x10 109 #define SWIM_ERROR 0x20 110 #define SWIM_DAT2BYTE 0x40 111 #define SWIM_DAT1BYTE 0x80 112 113 /* bits in setup register */ 114 115 #define SWIM_S_INV_WDATA 0x01 116 #define SWIM_S_3_5_SELECT 0x02 117 #define SWIM_S_GCR 0x04 118 #define SWIM_S_FCLK_DIV2 0x08 119 #define SWIM_S_ERROR_CORR 0x10 120 #define SWIM_S_IBM_DRIVE 0x20 121 #define SWIM_S_GCR_WRITE 0x40 122 #define SWIM_S_TIMEOUT 0x80 123 124 /* bits in mode register */ 125 126 #define SWIM_CLFIFO 0x01 127 #define SWIM_ENBL1 0x02 128 #define SWIM_ENBL2 0x04 129 #define SWIM_ACTION 0x08 130 #define SWIM_WRITE_MODE 0x10 131 #define SWIM_HEDSEL 0x20 132 #define SWIM_MOTON 0x80 133 134 static const char *iwm_reg_names[] = { 135 "READALLONES", "READDATA", "READSTATUS0", "READSTATUS1", 136 "READWHANDSHAKE0", "READWHANDSHAKE1", "WRITESETMODE", "WRITEDATA" 137 }; 138 139 static const char *ism_reg_names[] = { 140 "WRITE_DATA", "WRITE_MARK", "WRITE_CRC", "WRITE_PARAMETER", 141 "WRITE_PHASE", "WRITE_SETUP", "WRITE_MODE0", "WRITE_MODE1", 142 "READ_DATA", "READ_MARK", "READ_ERROR", "READ_PARAMETER", 143 "READ_PHASE", "READ_SETUP", "READ_STATUS", "READ_HANDSHAKE" 144 }; 145 146 static void fd_recalibrate(FDrive *drive) 147 { 148 } 149 150 static void swim_change_cb(void *opaque, bool load, Error **errp) 151 { 152 FDrive *drive = opaque; 153 154 if (!load) { 155 blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort); 156 } else { 157 if (!blkconf_apply_backend_options(drive->conf, 158 !blk_supports_write_perm(drive->blk), 159 false, errp)) { 160 return; 161 } 162 } 163 } 164 165 static const BlockDevOps swim_block_ops = { 166 .change_media_cb = swim_change_cb, 167 }; 168 169 static Property swim_drive_properties[] = { 170 DEFINE_PROP_INT32("unit", SWIMDrive, unit, -1), 171 DEFINE_BLOCK_PROPERTIES(SWIMDrive, conf), 172 DEFINE_PROP_END_OF_LIST(), 173 }; 174 175 static void swim_drive_realize(DeviceState *qdev, Error **errp) 176 { 177 SWIMDrive *dev = SWIM_DRIVE(qdev); 178 SWIMBus *bus = SWIM_BUS(qdev->parent_bus); 179 FDrive *drive; 180 int ret; 181 182 if (dev->unit == -1) { 183 for (dev->unit = 0; dev->unit < SWIM_MAX_FD; dev->unit++) { 184 drive = &bus->ctrl->drives[dev->unit]; 185 if (!drive->blk) { 186 break; 187 } 188 } 189 } 190 191 if (dev->unit >= SWIM_MAX_FD) { 192 error_setg(errp, "Can't create floppy unit %d, bus supports " 193 "only %d units", dev->unit, SWIM_MAX_FD); 194 return; 195 } 196 197 drive = &bus->ctrl->drives[dev->unit]; 198 if (drive->blk) { 199 error_setg(errp, "Floppy unit %d is in use", dev->unit); 200 return; 201 } 202 203 if (!dev->conf.blk) { 204 /* Anonymous BlockBackend for an empty drive */ 205 dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 206 ret = blk_attach_dev(dev->conf.blk, qdev); 207 assert(ret == 0); 208 } 209 210 if (!blkconf_blocksizes(&dev->conf, errp)) { 211 return; 212 } 213 214 if (dev->conf.logical_block_size != 512 || 215 dev->conf.physical_block_size != 512) 216 { 217 error_setg(errp, "Physical and logical block size must " 218 "be 512 for floppy"); 219 return; 220 } 221 222 /* 223 * rerror/werror aren't supported by fdc and therefore not even registered 224 * with qdev. So set the defaults manually before they are used in 225 * blkconf_apply_backend_options(). 226 */ 227 dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO; 228 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO; 229 230 if (!blkconf_apply_backend_options(&dev->conf, 231 !blk_supports_write_perm(dev->conf.blk), 232 false, errp)) { 233 return; 234 } 235 236 /* 237 * 'enospc' is the default for -drive, 'report' is what blk_new() gives us 238 * for empty drives. 239 */ 240 if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC && 241 blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) { 242 error_setg(errp, "fdc doesn't support drive option werror"); 243 return; 244 } 245 if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) { 246 error_setg(errp, "fdc doesn't support drive option rerror"); 247 return; 248 } 249 250 drive->conf = &dev->conf; 251 drive->blk = dev->conf.blk; 252 drive->swimctrl = bus->ctrl; 253 254 blk_set_dev_ops(drive->blk, &swim_block_ops, drive); 255 } 256 257 static void swim_drive_class_init(ObjectClass *klass, void *data) 258 { 259 DeviceClass *k = DEVICE_CLASS(klass); 260 k->realize = swim_drive_realize; 261 set_bit(DEVICE_CATEGORY_STORAGE, k->categories); 262 k->bus_type = TYPE_SWIM_BUS; 263 device_class_set_props(k, swim_drive_properties); 264 k->desc = "virtual SWIM drive"; 265 } 266 267 static const TypeInfo swim_drive_info = { 268 .name = TYPE_SWIM_DRIVE, 269 .parent = TYPE_DEVICE, 270 .instance_size = sizeof(SWIMDrive), 271 .class_init = swim_drive_class_init, 272 }; 273 274 static const TypeInfo swim_bus_info = { 275 .name = TYPE_SWIM_BUS, 276 .parent = TYPE_BUS, 277 .instance_size = sizeof(SWIMBus), 278 }; 279 280 static void iwmctrl_write(void *opaque, hwaddr addr, uint64_t value, 281 unsigned size) 282 { 283 SWIMCtrl *swimctrl = opaque; 284 uint8_t latch, reg, ism_bit; 285 286 addr >>= REG_SHIFT; 287 288 /* A3-A1 select a latch, A0 specifies the value */ 289 latch = (addr >> 1) & 7; 290 if (addr & 1) { 291 swimctrl->iwm_latches |= (1 << latch); 292 } else { 293 swimctrl->iwm_latches &= ~(1 << latch); 294 } 295 296 reg = (swimctrl->iwm_latches & 0xc0) >> 5 | 297 (swimctrl->iwm_latches & 0x10) >> 4; 298 299 swimctrl->iwmregs[reg] = value; 300 trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value); 301 302 switch (reg) { 303 case IWM_WRITESETMODE: 304 /* detect sequence to switch from IWM mode to SWIM mode */ 305 ism_bit = (value & (1 << SWIM_MODE_STATUS_BIT)); 306 307 switch (swimctrl->iwm_switch) { 308 case 0: 309 if (ism_bit) { /* 1 */ 310 swimctrl->iwm_switch++; 311 } 312 break; 313 case 1: 314 if (!ism_bit) { /* 0 */ 315 swimctrl->iwm_switch++; 316 } 317 break; 318 case 2: 319 if (ism_bit) { /* 1 */ 320 swimctrl->iwm_switch++; 321 } 322 break; 323 case 3: 324 if (ism_bit) { /* 1 */ 325 swimctrl->iwm_switch++; 326 327 swimctrl->mode = SWIM_MODE_ISM; 328 swimctrl->swim_mode |= (1 << SWIM_MODE_STATUS_BIT); 329 swimctrl->iwm_switch = 0; 330 trace_swim_switch_to_ism(); 331 332 /* Switch to ISM registers */ 333 memory_region_del_subregion(&swimctrl->swim, &swimctrl->iwm); 334 memory_region_add_subregion(&swimctrl->swim, 0x0, 335 &swimctrl->ism); 336 } 337 break; 338 } 339 break; 340 default: 341 break; 342 } 343 } 344 345 static uint64_t iwmctrl_read(void *opaque, hwaddr addr, unsigned size) 346 { 347 SWIMCtrl *swimctrl = opaque; 348 uint8_t latch, reg, value; 349 350 addr >>= REG_SHIFT; 351 352 /* A3-A1 select a latch, A0 specifies the value */ 353 latch = (addr >> 1) & 7; 354 if (addr & 1) { 355 swimctrl->iwm_latches |= (1 << latch); 356 } else { 357 swimctrl->iwm_latches &= ~(1 << latch); 358 } 359 360 reg = (swimctrl->iwm_latches & 0xc0) >> 5 | 361 (swimctrl->iwm_latches & 0x10) >> 4; 362 363 switch (reg) { 364 case IWM_READALLONES: 365 value = 0xff; 366 break; 367 default: 368 value = 0; 369 break; 370 } 371 372 trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); 373 return value; 374 } 375 376 static const MemoryRegionOps swimctrl_iwm_ops = { 377 .write = iwmctrl_write, 378 .read = iwmctrl_read, 379 .endianness = DEVICE_BIG_ENDIAN, 380 }; 381 382 static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value, 383 unsigned size) 384 { 385 SWIMCtrl *swimctrl = opaque; 386 387 reg >>= REG_SHIFT; 388 389 trace_swim_ismctrl_write(reg, ism_reg_names[reg], size, value); 390 391 switch (reg) { 392 case SWIM_WRITE_PHASE: 393 swimctrl->swim_phase = value; 394 break; 395 case SWIM_WRITE_MODE0: 396 swimctrl->swim_mode &= ~value; 397 /* Any access to MODE0 register resets PRAM index */ 398 swimctrl->pram_idx = 0; 399 400 if (!(swimctrl->swim_mode & (1 << SWIM_MODE_STATUS_BIT))) { 401 /* Clearing the mode bit switches to IWM mode */ 402 swimctrl->mode = SWIM_MODE_IWM; 403 swimctrl->iwm_latches = 0; 404 trace_swim_switch_to_iwm(); 405 406 /* Switch to IWM registers */ 407 memory_region_del_subregion(&swimctrl->swim, &swimctrl->ism); 408 memory_region_add_subregion(&swimctrl->swim, 0x0, 409 &swimctrl->iwm); 410 } 411 break; 412 case SWIM_WRITE_MODE1: 413 swimctrl->swim_mode |= value; 414 break; 415 case SWIM_WRITE_PARAMETER: 416 swimctrl->pram[swimctrl->pram_idx++] = value; 417 swimctrl->pram_idx &= 0xf; 418 break; 419 case SWIM_WRITE_DATA: 420 case SWIM_WRITE_MARK: 421 case SWIM_WRITE_CRC: 422 case SWIM_WRITE_SETUP: 423 break; 424 } 425 } 426 427 static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size) 428 { 429 SWIMCtrl *swimctrl = opaque; 430 uint32_t value = 0; 431 432 reg >>= REG_SHIFT; 433 434 switch (reg) { 435 case SWIM_READ_PHASE: 436 value = swimctrl->swim_phase; 437 break; 438 case SWIM_READ_HANDSHAKE: 439 if (swimctrl->swim_phase == SWIM_DRIVE_PRESENT) { 440 /* always answer "no drive present" */ 441 value = SWIM_SENSE; 442 } 443 break; 444 case SWIM_READ_PARAMETER: 445 value = swimctrl->pram[swimctrl->pram_idx++]; 446 swimctrl->pram_idx &= 0xf; 447 break; 448 case SWIM_READ_STATUS: 449 value = swimctrl->swim_status & ~(1 << SWIM_MODE_STATUS_BIT); 450 if (swimctrl->swim_mode == SWIM_MODE_ISM) { 451 value |= (1 << SWIM_MODE_STATUS_BIT); 452 } 453 break; 454 case SWIM_READ_DATA: 455 case SWIM_READ_MARK: 456 case SWIM_READ_ERROR: 457 case SWIM_READ_SETUP: 458 break; 459 } 460 461 trace_swim_ismctrl_read(reg, ism_reg_names[reg], size, value); 462 return value; 463 } 464 465 static const MemoryRegionOps swimctrl_ism_ops = { 466 .write = ismctrl_write, 467 .read = ismctrl_read, 468 .endianness = DEVICE_BIG_ENDIAN, 469 }; 470 471 static void sysbus_swim_reset(DeviceState *d) 472 { 473 Swim *sys = SWIM(d); 474 SWIMCtrl *ctrl = &sys->ctrl; 475 int i; 476 477 ctrl->mode = 0; 478 ctrl->iwm_switch = 0; 479 memset(ctrl->iwmregs, 0, sizeof(ctrl->iwmregs)); 480 481 ctrl->swim_phase = 0; 482 ctrl->swim_mode = 0; 483 memset(ctrl->ismregs, 0, sizeof(ctrl->ismregs)); 484 for (i = 0; i < SWIM_MAX_FD; i++) { 485 fd_recalibrate(&ctrl->drives[i]); 486 } 487 } 488 489 static void sysbus_swim_init(Object *obj) 490 { 491 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 492 Swim *sbs = SWIM(obj); 493 SWIMCtrl *swimctrl = &sbs->ctrl; 494 495 memory_region_init(&swimctrl->swim, obj, "swim", 0x2000); 496 memory_region_init_io(&swimctrl->iwm, obj, &swimctrl_iwm_ops, swimctrl, 497 "iwm", 0x2000); 498 memory_region_init_io(&swimctrl->ism, obj, &swimctrl_ism_ops, swimctrl, 499 "ism", 0x2000); 500 sysbus_init_mmio(sbd, &swimctrl->swim); 501 } 502 503 static void sysbus_swim_realize(DeviceState *dev, Error **errp) 504 { 505 Swim *sys = SWIM(dev); 506 SWIMCtrl *swimctrl = &sys->ctrl; 507 508 qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL); 509 swimctrl->bus.ctrl = swimctrl; 510 511 /* Default register set is IWM */ 512 memory_region_add_subregion(&swimctrl->swim, 0x0, &swimctrl->iwm); 513 } 514 515 static const VMStateDescription vmstate_fdrive = { 516 .name = "fdrive", 517 .version_id = 1, 518 .minimum_version_id = 1, 519 .fields = (VMStateField[]) { 520 VMSTATE_END_OF_LIST() 521 }, 522 }; 523 524 static const VMStateDescription vmstate_swim = { 525 .name = "swim", 526 .version_id = 1, 527 .minimum_version_id = 1, 528 .fields = (VMStateField[]) { 529 VMSTATE_INT32(mode, SWIMCtrl), 530 /* IWM mode */ 531 VMSTATE_INT32(iwm_switch, SWIMCtrl), 532 VMSTATE_UINT8(iwm_latches, SWIMCtrl), 533 VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 8), 534 /* SWIM mode */ 535 VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16), 536 VMSTATE_UINT8(swim_phase, SWIMCtrl), 537 VMSTATE_UINT8(swim_mode, SWIMCtrl), 538 /* Drives */ 539 VMSTATE_STRUCT_ARRAY(drives, SWIMCtrl, SWIM_MAX_FD, 1, 540 vmstate_fdrive, FDrive), 541 VMSTATE_END_OF_LIST() 542 }, 543 }; 544 545 static const VMStateDescription vmstate_sysbus_swim = { 546 .name = "SWIM", 547 .version_id = 1, 548 .fields = (VMStateField[]) { 549 VMSTATE_STRUCT(ctrl, Swim, 0, vmstate_swim, SWIMCtrl), 550 VMSTATE_END_OF_LIST() 551 } 552 }; 553 554 static void sysbus_swim_class_init(ObjectClass *oc, void *data) 555 { 556 DeviceClass *dc = DEVICE_CLASS(oc); 557 558 dc->realize = sysbus_swim_realize; 559 dc->reset = sysbus_swim_reset; 560 dc->vmsd = &vmstate_sysbus_swim; 561 } 562 563 static const TypeInfo sysbus_swim_info = { 564 .name = TYPE_SWIM, 565 .parent = TYPE_SYS_BUS_DEVICE, 566 .instance_size = sizeof(Swim), 567 .instance_init = sysbus_swim_init, 568 .class_init = sysbus_swim_class_init, 569 }; 570 571 static void swim_register_types(void) 572 { 573 type_register_static(&sysbus_swim_info); 574 type_register_static(&swim_bus_info); 575 type_register_static(&swim_drive_info); 576 } 577 578 type_init(swim_register_types) 579