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 "system/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 const Property swim_drive_properties[] = { 170 DEFINE_PROP_INT32("unit", SWIMDrive, unit, -1), 171 DEFINE_BLOCK_PROPERTIES(SWIMDrive, conf), 172 }; 173 174 static void swim_drive_realize(DeviceState *qdev, Error **errp) 175 { 176 SWIMDrive *dev = SWIM_DRIVE(qdev); 177 SWIMBus *bus = SWIM_BUS(qdev->parent_bus); 178 FDrive *drive; 179 int ret; 180 181 if (dev->unit == -1) { 182 for (dev->unit = 0; dev->unit < SWIM_MAX_FD; dev->unit++) { 183 drive = &bus->ctrl->drives[dev->unit]; 184 if (!drive->blk) { 185 break; 186 } 187 } 188 } 189 190 if (dev->unit >= SWIM_MAX_FD) { 191 error_setg(errp, "Can't create floppy unit %d, bus supports " 192 "only %d units", dev->unit, SWIM_MAX_FD); 193 return; 194 } 195 196 drive = &bus->ctrl->drives[dev->unit]; 197 if (drive->blk) { 198 error_setg(errp, "Floppy unit %d is in use", dev->unit); 199 return; 200 } 201 202 if (!dev->conf.blk) { 203 /* Anonymous BlockBackend for an empty drive */ 204 dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 205 ret = blk_attach_dev(dev->conf.blk, qdev); 206 assert(ret == 0); 207 } 208 209 if (!blkconf_blocksizes(&dev->conf, errp)) { 210 return; 211 } 212 213 if (dev->conf.logical_block_size != 512 || 214 dev->conf.physical_block_size != 512) 215 { 216 error_setg(errp, "Physical and logical block size must " 217 "be 512 for floppy"); 218 return; 219 } 220 221 /* 222 * rerror/werror aren't supported by fdc and therefore not even registered 223 * with qdev. So set the defaults manually before they are used in 224 * blkconf_apply_backend_options(). 225 */ 226 dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO; 227 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO; 228 229 if (!blkconf_apply_backend_options(&dev->conf, 230 !blk_supports_write_perm(dev->conf.blk), 231 false, errp)) { 232 return; 233 } 234 235 /* 236 * 'enospc' is the default for -drive, 'report' is what blk_new() gives us 237 * for empty drives. 238 */ 239 if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC && 240 blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) { 241 error_setg(errp, "fdc doesn't support drive option werror"); 242 return; 243 } 244 if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) { 245 error_setg(errp, "fdc doesn't support drive option rerror"); 246 return; 247 } 248 249 drive->conf = &dev->conf; 250 drive->blk = dev->conf.blk; 251 drive->swimctrl = bus->ctrl; 252 253 blk_set_dev_ops(drive->blk, &swim_block_ops, drive); 254 } 255 256 static void swim_drive_class_init(ObjectClass *klass, void *data) 257 { 258 DeviceClass *k = DEVICE_CLASS(klass); 259 k->realize = swim_drive_realize; 260 set_bit(DEVICE_CATEGORY_STORAGE, k->categories); 261 k->bus_type = TYPE_SWIM_BUS; 262 device_class_set_props(k, swim_drive_properties); 263 k->desc = "virtual SWIM drive"; 264 } 265 266 static const TypeInfo swim_drive_info = { 267 .name = TYPE_SWIM_DRIVE, 268 .parent = TYPE_DEVICE, 269 .instance_size = sizeof(SWIMDrive), 270 .class_init = swim_drive_class_init, 271 }; 272 273 static const TypeInfo swim_bus_info = { 274 .name = TYPE_SWIM_BUS, 275 .parent = TYPE_BUS, 276 .instance_size = sizeof(SWIMBus), 277 }; 278 279 static void iwmctrl_write(void *opaque, hwaddr addr, uint64_t value, 280 unsigned size) 281 { 282 SWIMCtrl *swimctrl = opaque; 283 uint8_t latch, reg, ism_bit; 284 285 addr >>= REG_SHIFT; 286 287 /* A3-A1 select a latch, A0 specifies the value */ 288 latch = (addr >> 1) & 7; 289 if (addr & 1) { 290 swimctrl->iwm_latches |= (1 << latch); 291 } else { 292 swimctrl->iwm_latches &= ~(1 << latch); 293 } 294 295 reg = (swimctrl->iwm_latches & 0xc0) >> 5 | 296 (swimctrl->iwm_latches & 0x10) >> 4; 297 298 swimctrl->iwmregs[reg] = value; 299 trace_swim_iwmctrl_write(reg, iwm_reg_names[reg], size, value); 300 301 switch (reg) { 302 case IWM_WRITESETMODE: 303 /* detect sequence to switch from IWM mode to SWIM mode */ 304 ism_bit = (value & (1 << SWIM_MODE_STATUS_BIT)); 305 306 switch (swimctrl->iwm_switch) { 307 case 0: 308 if (ism_bit) { /* 1 */ 309 swimctrl->iwm_switch++; 310 } 311 break; 312 case 1: 313 if (!ism_bit) { /* 0 */ 314 swimctrl->iwm_switch++; 315 } 316 break; 317 case 2: 318 if (ism_bit) { /* 1 */ 319 swimctrl->iwm_switch++; 320 } 321 break; 322 case 3: 323 if (ism_bit) { /* 1 */ 324 swimctrl->iwm_switch++; 325 326 swimctrl->mode = SWIM_MODE_ISM; 327 swimctrl->swim_mode |= (1 << SWIM_MODE_STATUS_BIT); 328 swimctrl->iwm_switch = 0; 329 trace_swim_switch_to_ism(); 330 331 /* Switch to ISM registers */ 332 memory_region_del_subregion(&swimctrl->swim, &swimctrl->iwm); 333 memory_region_add_subregion(&swimctrl->swim, 0x0, 334 &swimctrl->ism); 335 } 336 break; 337 } 338 break; 339 default: 340 break; 341 } 342 } 343 344 static uint64_t iwmctrl_read(void *opaque, hwaddr addr, unsigned size) 345 { 346 SWIMCtrl *swimctrl = opaque; 347 uint8_t latch, reg, value; 348 349 addr >>= REG_SHIFT; 350 351 /* A3-A1 select a latch, A0 specifies the value */ 352 latch = (addr >> 1) & 7; 353 if (addr & 1) { 354 swimctrl->iwm_latches |= (1 << latch); 355 } else { 356 swimctrl->iwm_latches &= ~(1 << latch); 357 } 358 359 reg = (swimctrl->iwm_latches & 0xc0) >> 5 | 360 (swimctrl->iwm_latches & 0x10) >> 4; 361 362 switch (reg) { 363 case IWM_READALLONES: 364 value = 0xff; 365 break; 366 default: 367 value = 0; 368 break; 369 } 370 371 trace_swim_iwmctrl_read(reg, iwm_reg_names[reg], size, value); 372 return value; 373 } 374 375 static const MemoryRegionOps swimctrl_iwm_ops = { 376 .write = iwmctrl_write, 377 .read = iwmctrl_read, 378 .endianness = DEVICE_BIG_ENDIAN, 379 }; 380 381 static void ismctrl_write(void *opaque, hwaddr reg, uint64_t value, 382 unsigned size) 383 { 384 SWIMCtrl *swimctrl = opaque; 385 386 reg >>= REG_SHIFT; 387 388 trace_swim_ismctrl_write(reg, ism_reg_names[reg], size, value); 389 390 switch (reg) { 391 case SWIM_WRITE_PHASE: 392 swimctrl->swim_phase = value; 393 break; 394 case SWIM_WRITE_MODE0: 395 swimctrl->swim_mode &= ~value; 396 /* Any access to MODE0 register resets PRAM index */ 397 swimctrl->pram_idx = 0; 398 399 if (!(swimctrl->swim_mode & (1 << SWIM_MODE_STATUS_BIT))) { 400 /* Clearing the mode bit switches to IWM mode */ 401 swimctrl->mode = SWIM_MODE_IWM; 402 swimctrl->iwm_latches = 0; 403 trace_swim_switch_to_iwm(); 404 405 /* Switch to IWM registers */ 406 memory_region_del_subregion(&swimctrl->swim, &swimctrl->ism); 407 memory_region_add_subregion(&swimctrl->swim, 0x0, 408 &swimctrl->iwm); 409 } 410 break; 411 case SWIM_WRITE_MODE1: 412 swimctrl->swim_mode |= value; 413 break; 414 case SWIM_WRITE_PARAMETER: 415 swimctrl->pram[swimctrl->pram_idx++] = value; 416 swimctrl->pram_idx &= 0xf; 417 break; 418 case SWIM_WRITE_DATA: 419 case SWIM_WRITE_MARK: 420 case SWIM_WRITE_CRC: 421 case SWIM_WRITE_SETUP: 422 break; 423 } 424 } 425 426 static uint64_t ismctrl_read(void *opaque, hwaddr reg, unsigned size) 427 { 428 SWIMCtrl *swimctrl = opaque; 429 uint32_t value = 0; 430 431 reg >>= REG_SHIFT; 432 433 switch (reg) { 434 case SWIM_READ_PHASE: 435 value = swimctrl->swim_phase; 436 break; 437 case SWIM_READ_HANDSHAKE: 438 if (swimctrl->swim_phase == SWIM_DRIVE_PRESENT) { 439 /* always answer "no drive present" */ 440 value = SWIM_SENSE; 441 } 442 break; 443 case SWIM_READ_PARAMETER: 444 value = swimctrl->pram[swimctrl->pram_idx++]; 445 swimctrl->pram_idx &= 0xf; 446 break; 447 case SWIM_READ_STATUS: 448 value = swimctrl->swim_status & ~(1 << SWIM_MODE_STATUS_BIT); 449 if (swimctrl->swim_mode == SWIM_MODE_ISM) { 450 value |= (1 << SWIM_MODE_STATUS_BIT); 451 } 452 break; 453 case SWIM_READ_DATA: 454 case SWIM_READ_MARK: 455 case SWIM_READ_ERROR: 456 case SWIM_READ_SETUP: 457 break; 458 } 459 460 trace_swim_ismctrl_read(reg, ism_reg_names[reg], size, value); 461 return value; 462 } 463 464 static const MemoryRegionOps swimctrl_ism_ops = { 465 .write = ismctrl_write, 466 .read = ismctrl_read, 467 .endianness = DEVICE_BIG_ENDIAN, 468 }; 469 470 static void sysbus_swim_reset(DeviceState *d) 471 { 472 Swim *sys = SWIM(d); 473 SWIMCtrl *ctrl = &sys->ctrl; 474 int i; 475 476 ctrl->mode = 0; 477 ctrl->iwm_switch = 0; 478 memset(ctrl->iwmregs, 0, sizeof(ctrl->iwmregs)); 479 480 ctrl->swim_phase = 0; 481 ctrl->swim_mode = 0; 482 memset(ctrl->ismregs, 0, sizeof(ctrl->ismregs)); 483 for (i = 0; i < SWIM_MAX_FD; i++) { 484 fd_recalibrate(&ctrl->drives[i]); 485 } 486 } 487 488 static void sysbus_swim_init(Object *obj) 489 { 490 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 491 Swim *sbs = SWIM(obj); 492 SWIMCtrl *swimctrl = &sbs->ctrl; 493 494 memory_region_init(&swimctrl->swim, obj, "swim", 0x2000); 495 memory_region_init_io(&swimctrl->iwm, obj, &swimctrl_iwm_ops, swimctrl, 496 "iwm", 0x2000); 497 memory_region_init_io(&swimctrl->ism, obj, &swimctrl_ism_ops, swimctrl, 498 "ism", 0x2000); 499 sysbus_init_mmio(sbd, &swimctrl->swim); 500 } 501 502 static void sysbus_swim_realize(DeviceState *dev, Error **errp) 503 { 504 Swim *sys = SWIM(dev); 505 SWIMCtrl *swimctrl = &sys->ctrl; 506 507 qbus_init(&swimctrl->bus, sizeof(SWIMBus), TYPE_SWIM_BUS, dev, NULL); 508 swimctrl->bus.ctrl = swimctrl; 509 510 /* Default register set is IWM */ 511 memory_region_add_subregion(&swimctrl->swim, 0x0, &swimctrl->iwm); 512 } 513 514 static const VMStateDescription vmstate_fdrive = { 515 .name = "fdrive", 516 .version_id = 1, 517 .minimum_version_id = 1, 518 .fields = (const VMStateField[]) { 519 VMSTATE_END_OF_LIST() 520 }, 521 }; 522 523 static const VMStateDescription vmstate_swim = { 524 .name = "swim", 525 .version_id = 1, 526 .minimum_version_id = 1, 527 .fields = (const VMStateField[]) { 528 VMSTATE_INT32(mode, SWIMCtrl), 529 /* IWM mode */ 530 VMSTATE_INT32(iwm_switch, SWIMCtrl), 531 VMSTATE_UINT8(iwm_latches, SWIMCtrl), 532 VMSTATE_UINT8_ARRAY(iwmregs, SWIMCtrl, 8), 533 /* SWIM mode */ 534 VMSTATE_UINT8_ARRAY(ismregs, SWIMCtrl, 16), 535 VMSTATE_UINT8(swim_phase, SWIMCtrl), 536 VMSTATE_UINT8(swim_mode, SWIMCtrl), 537 /* Drives */ 538 VMSTATE_STRUCT_ARRAY(drives, SWIMCtrl, SWIM_MAX_FD, 1, 539 vmstate_fdrive, FDrive), 540 VMSTATE_END_OF_LIST() 541 }, 542 }; 543 544 static const VMStateDescription vmstate_sysbus_swim = { 545 .name = "SWIM", 546 .version_id = 1, 547 .fields = (const VMStateField[]) { 548 VMSTATE_STRUCT(ctrl, Swim, 0, vmstate_swim, SWIMCtrl), 549 VMSTATE_END_OF_LIST() 550 } 551 }; 552 553 static void sysbus_swim_class_init(ObjectClass *oc, void *data) 554 { 555 DeviceClass *dc = DEVICE_CLASS(oc); 556 557 dc->realize = sysbus_swim_realize; 558 device_class_set_legacy_reset(dc, sysbus_swim_reset); 559 dc->vmsd = &vmstate_sysbus_swim; 560 } 561 562 static const TypeInfo sysbus_swim_info = { 563 .name = TYPE_SWIM, 564 .parent = TYPE_SYS_BUS_DEVICE, 565 .instance_size = sizeof(Swim), 566 .instance_init = sysbus_swim_init, 567 .class_init = sysbus_swim_class_init, 568 }; 569 570 static void swim_register_types(void) 571 { 572 type_register_static(&sysbus_swim_info); 573 type_register_static(&swim_bus_info); 574 type_register_static(&swim_drive_info); 575 } 576 577 type_init(swim_register_types) 578