1 /* 2 * QEMU Floppy disk emulator (Intel 82078) 3 * 4 * Copyright (c) 2003, 2007 Jocelyn Mayer 5 * Copyright (c) 2008 Hervé Poussineau 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy 8 * of this software and associated documentation files (the "Software"), to deal 9 * in the Software without restriction, including without limitation the rights 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 * copies of the Software, and to permit persons to whom the Software is 12 * furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 * THE SOFTWARE. 24 */ 25 /* 26 * The controller is used in Sun4m systems in a slightly different 27 * way. There are changes in DOR register and DMA is not available. 28 */ 29 30 #include "qemu/osdep.h" 31 #include "hw/block/fdc.h" 32 #include "qapi/error.h" 33 #include "qemu/error-report.h" 34 #include "qemu/timer.h" 35 #include "hw/irq.h" 36 #include "hw/isa/isa.h" 37 #include "hw/qdev-properties.h" 38 #include "hw/qdev-properties-system.h" 39 #include "hw/sysbus.h" 40 #include "migration/vmstate.h" 41 #include "hw/block/block.h" 42 #include "sysemu/block-backend.h" 43 #include "sysemu/blockdev.h" 44 #include "sysemu/sysemu.h" 45 #include "qemu/log.h" 46 #include "qemu/main-loop.h" 47 #include "qemu/module.h" 48 #include "trace.h" 49 #include "qom/object.h" 50 #include "fdc-internal.h" 51 52 /********************************************************/ 53 /* debug Floppy devices */ 54 55 #define DEBUG_FLOPPY 0 56 57 #define FLOPPY_DPRINTF(fmt, ...) \ 58 do { \ 59 if (DEBUG_FLOPPY) { \ 60 fprintf(stderr, "FLOPPY: " fmt , ## __VA_ARGS__); \ 61 } \ 62 } while (0) 63 64 65 /********************************************************/ 66 /* qdev floppy bus */ 67 68 #define TYPE_FLOPPY_BUS "floppy-bus" 69 OBJECT_DECLARE_SIMPLE_TYPE(FloppyBus, FLOPPY_BUS) 70 71 static FDrive *get_drv(FDCtrl *fdctrl, int unit); 72 73 static const TypeInfo floppy_bus_info = { 74 .name = TYPE_FLOPPY_BUS, 75 .parent = TYPE_BUS, 76 .instance_size = sizeof(FloppyBus), 77 }; 78 79 static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev) 80 { 81 qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL); 82 bus->fdc = fdc; 83 } 84 85 86 /********************************************************/ 87 /* Floppy drive emulation */ 88 89 /* In many cases, the total sector size of a format is enough to uniquely 90 * identify it. However, there are some total sector collisions between 91 * formats of different physical size, and these are noted below by 92 * highlighting the total sector size for entries with collisions. */ 93 const FDFormat fd_formats[] = { 94 /* First entry is default format */ 95 /* 1.44 MB 3"1/2 floppy disks */ 96 { FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */ 97 { FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */ 98 { FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, }, 99 { FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, }, 100 { FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, }, 101 { FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, }, 102 { FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, }, 103 { FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, }, 104 /* 2.88 MB 3"1/2 floppy disks */ 105 { FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, }, 106 { FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, }, 107 { FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, }, 108 { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, }, 109 { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, }, 110 /* 720 kB 3"1/2 floppy disks */ 111 { FLOPPY_DRIVE_TYPE_144, 9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */ 112 { FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, }, 113 { FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, }, 114 { FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, }, 115 { FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, }, 116 { FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, }, 117 /* 1.2 MB 5"1/4 floppy disks */ 118 { FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, }, 119 { FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */ 120 { FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, }, 121 { FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, }, 122 { FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */ 123 /* 720 kB 5"1/4 floppy disks */ 124 { FLOPPY_DRIVE_TYPE_120, 9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */ 125 { FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, }, 126 /* 360 kB 5"1/4 floppy disks */ 127 { FLOPPY_DRIVE_TYPE_120, 9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */ 128 { FLOPPY_DRIVE_TYPE_120, 9, 40, 0, FDRIVE_RATE_300K, }, 129 { FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, }, 130 { FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, }, 131 /* 320 kB 5"1/4 floppy disks */ 132 { FLOPPY_DRIVE_TYPE_120, 8, 40, 1, FDRIVE_RATE_250K, }, 133 { FLOPPY_DRIVE_TYPE_120, 8, 40, 0, FDRIVE_RATE_250K, }, 134 /* 360 kB must match 5"1/4 better than 3"1/2... */ 135 { FLOPPY_DRIVE_TYPE_144, 9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */ 136 /* end */ 137 { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, }, 138 }; 139 140 static FDriveSize drive_size(FloppyDriveType drive) 141 { 142 switch (drive) { 143 case FLOPPY_DRIVE_TYPE_120: 144 return FDRIVE_SIZE_525; 145 case FLOPPY_DRIVE_TYPE_144: 146 case FLOPPY_DRIVE_TYPE_288: 147 return FDRIVE_SIZE_350; 148 default: 149 return FDRIVE_SIZE_UNKNOWN; 150 } 151 } 152 153 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv) 154 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive)) 155 156 /* Will always be a fixed parameter for us */ 157 #define FD_SECTOR_LEN 512 158 #define FD_SECTOR_SC 2 /* Sector size code */ 159 #define FD_RESET_SENSEI_COUNT 4 /* Number of sense interrupts on RESET */ 160 161 162 static FloppyDriveType get_fallback_drive_type(FDrive *drv); 163 164 /* Hack: FD_SEEK is expected to work on empty drives. However, QEMU 165 * currently goes through some pains to keep seeks within the bounds 166 * established by last_sect and max_track. Correcting this is difficult, 167 * as refactoring FDC code tends to expose nasty bugs in the Linux kernel. 168 * 169 * For now: allow empty drives to have large bounds so we can seek around, 170 * with the understanding that when a diskette is inserted, the bounds will 171 * properly tighten to match the geometry of that inserted medium. 172 */ 173 static void fd_empty_seek_hack(FDrive *drv) 174 { 175 drv->last_sect = 0xFF; 176 drv->max_track = 0xFF; 177 } 178 179 static void fd_init(FDrive *drv) 180 { 181 /* Drive */ 182 drv->perpendicular = 0; 183 /* Disk */ 184 drv->disk = FLOPPY_DRIVE_TYPE_NONE; 185 drv->last_sect = 0; 186 drv->max_track = 0; 187 drv->ro = true; 188 drv->media_changed = 1; 189 } 190 191 #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1) 192 193 static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect, 194 uint8_t last_sect, uint8_t num_sides) 195 { 196 return (((track * num_sides) + head) * last_sect) + sect - 1; 197 } 198 199 /* Returns current position, in sectors, for given drive */ 200 static int fd_sector(FDrive *drv) 201 { 202 return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect, 203 NUM_SIDES(drv)); 204 } 205 206 /* Returns current position, in bytes, for given drive */ 207 static int fd_offset(FDrive *drv) 208 { 209 g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS); 210 return fd_sector(drv) << BDRV_SECTOR_BITS; 211 } 212 213 /* Seek to a new position: 214 * returns 0 if already on right track 215 * returns 1 if track changed 216 * returns 2 if track is invalid 217 * returns 3 if sector is invalid 218 * returns 4 if seek is disabled 219 */ 220 static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect, 221 int enable_seek) 222 { 223 uint32_t sector; 224 int ret; 225 226 if (track > drv->max_track || 227 (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) { 228 FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n", 229 head, track, sect, 1, 230 (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1, 231 drv->max_track, drv->last_sect); 232 return 2; 233 } 234 if (sect > drv->last_sect) { 235 FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n", 236 head, track, sect, 1, 237 (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1, 238 drv->max_track, drv->last_sect); 239 return 3; 240 } 241 sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv)); 242 ret = 0; 243 if (sector != fd_sector(drv)) { 244 #if 0 245 if (!enable_seek) { 246 FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x" 247 " (max=%d %02x %02x)\n", 248 head, track, sect, 1, drv->max_track, 249 drv->last_sect); 250 return 4; 251 } 252 #endif 253 drv->head = head; 254 if (drv->track != track) { 255 if (drv->blk != NULL && blk_is_inserted(drv->blk)) { 256 drv->media_changed = 0; 257 } 258 ret = 1; 259 } 260 drv->track = track; 261 drv->sect = sect; 262 } 263 264 if (drv->blk == NULL || !blk_is_inserted(drv->blk)) { 265 ret = 2; 266 } 267 268 return ret; 269 } 270 271 /* Set drive back to track 0 */ 272 static void fd_recalibrate(FDrive *drv) 273 { 274 FLOPPY_DPRINTF("recalibrate\n"); 275 fd_seek(drv, 0, 0, 1, 1); 276 } 277 278 /** 279 * Determine geometry based on inserted diskette. 280 * Will not operate on an empty drive. 281 * 282 * @return: 0 on success, -1 if the drive is empty. 283 */ 284 static int pick_geometry(FDrive *drv) 285 { 286 BlockBackend *blk = drv->blk; 287 const FDFormat *parse; 288 uint64_t nb_sectors, size; 289 int i; 290 int match, size_match, type_match; 291 bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO; 292 293 /* We can only pick a geometry if we have a diskette. */ 294 if (!drv->blk || !blk_is_inserted(drv->blk) || 295 drv->drive == FLOPPY_DRIVE_TYPE_NONE) 296 { 297 return -1; 298 } 299 300 /* We need to determine the likely geometry of the inserted medium. 301 * In order of preference, we look for: 302 * (1) The same drive type and number of sectors, 303 * (2) The same diskette size and number of sectors, 304 * (3) The same drive type. 305 * 306 * In all cases, matches that occur higher in the drive table will take 307 * precedence over matches that occur later in the table. 308 */ 309 blk_get_geometry(blk, &nb_sectors); 310 match = size_match = type_match = -1; 311 for (i = 0; ; i++) { 312 parse = &fd_formats[i]; 313 if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) { 314 break; 315 } 316 size = (parse->max_head + 1) * parse->max_track * parse->last_sect; 317 if (nb_sectors == size) { 318 if (magic || parse->drive == drv->drive) { 319 /* (1) perfect match -- nb_sectors and drive type */ 320 goto out; 321 } else if (drive_size(parse->drive) == drive_size(drv->drive)) { 322 /* (2) size match -- nb_sectors and physical medium size */ 323 match = (match == -1) ? i : match; 324 } else { 325 /* This is suspicious -- Did the user misconfigure? */ 326 size_match = (size_match == -1) ? i : size_match; 327 } 328 } else if (type_match == -1) { 329 if ((parse->drive == drv->drive) || 330 (magic && (parse->drive == get_fallback_drive_type(drv)))) { 331 /* (3) type match -- nb_sectors mismatch, but matches the type 332 * specified explicitly by the user, or matches the fallback 333 * default type when using the drive autodetect mechanism */ 334 type_match = i; 335 } 336 } 337 } 338 339 /* No exact match found */ 340 if (match == -1) { 341 if (size_match != -1) { 342 parse = &fd_formats[size_match]; 343 FLOPPY_DPRINTF("User requested floppy drive type '%s', " 344 "but inserted medium appears to be a " 345 "%"PRId64" sector '%s' type\n", 346 FloppyDriveType_str(drv->drive), 347 nb_sectors, 348 FloppyDriveType_str(parse->drive)); 349 } 350 assert(type_match != -1 && "misconfigured fd_format"); 351 match = type_match; 352 } 353 parse = &(fd_formats[match]); 354 355 out: 356 if (parse->max_head == 0) { 357 drv->flags &= ~FDISK_DBL_SIDES; 358 } else { 359 drv->flags |= FDISK_DBL_SIDES; 360 } 361 drv->max_track = parse->max_track; 362 drv->last_sect = parse->last_sect; 363 drv->disk = parse->drive; 364 drv->media_rate = parse->rate; 365 return 0; 366 } 367 368 static void pick_drive_type(FDrive *drv) 369 { 370 if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) { 371 return; 372 } 373 374 if (pick_geometry(drv) == 0) { 375 drv->drive = drv->disk; 376 } else { 377 drv->drive = get_fallback_drive_type(drv); 378 } 379 380 g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO); 381 } 382 383 /* Revalidate a disk drive after a disk change */ 384 static void fd_revalidate(FDrive *drv) 385 { 386 int rc; 387 388 FLOPPY_DPRINTF("revalidate\n"); 389 if (drv->blk != NULL) { 390 drv->ro = !blk_is_writable(drv->blk); 391 if (!blk_is_inserted(drv->blk)) { 392 FLOPPY_DPRINTF("No disk in drive\n"); 393 drv->disk = FLOPPY_DRIVE_TYPE_NONE; 394 fd_empty_seek_hack(drv); 395 } else if (!drv->media_validated) { 396 rc = pick_geometry(drv); 397 if (rc) { 398 FLOPPY_DPRINTF("Could not validate floppy drive media"); 399 } else { 400 drv->media_validated = true; 401 FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", 402 (drv->flags & FDISK_DBL_SIDES) ? 2 : 1, 403 drv->max_track, drv->last_sect, 404 drv->ro ? "ro" : "rw"); 405 } 406 } 407 } else { 408 FLOPPY_DPRINTF("No drive connected\n"); 409 drv->last_sect = 0; 410 drv->max_track = 0; 411 drv->flags &= ~FDISK_DBL_SIDES; 412 drv->drive = FLOPPY_DRIVE_TYPE_NONE; 413 drv->disk = FLOPPY_DRIVE_TYPE_NONE; 414 } 415 } 416 417 static void fd_change_cb(void *opaque, bool load, Error **errp) 418 { 419 FDrive *drive = opaque; 420 421 if (!load) { 422 blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort); 423 } else { 424 if (!blkconf_apply_backend_options(drive->conf, 425 !blk_supports_write_perm(drive->blk), 426 false, errp)) { 427 return; 428 } 429 } 430 431 drive->media_changed = 1; 432 drive->media_validated = false; 433 fd_revalidate(drive); 434 } 435 436 static const BlockDevOps fd_block_ops = { 437 .change_media_cb = fd_change_cb, 438 }; 439 440 441 #define TYPE_FLOPPY_DRIVE "floppy" 442 OBJECT_DECLARE_SIMPLE_TYPE(FloppyDrive, FLOPPY_DRIVE) 443 444 struct FloppyDrive { 445 DeviceState qdev; 446 uint32_t unit; 447 BlockConf conf; 448 FloppyDriveType type; 449 }; 450 451 static Property floppy_drive_properties[] = { 452 DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1), 453 DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf), 454 DEFINE_PROP_SIGNED("drive-type", FloppyDrive, type, 455 FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, 456 FloppyDriveType), 457 DEFINE_PROP_END_OF_LIST(), 458 }; 459 460 static void floppy_drive_realize(DeviceState *qdev, Error **errp) 461 { 462 FloppyDrive *dev = FLOPPY_DRIVE(qdev); 463 FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus); 464 FDrive *drive; 465 bool read_only; 466 int ret; 467 468 if (dev->unit == -1) { 469 for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) { 470 drive = get_drv(bus->fdc, dev->unit); 471 if (!drive->blk) { 472 break; 473 } 474 } 475 } 476 477 if (dev->unit >= MAX_FD) { 478 error_setg(errp, "Can't create floppy unit %d, bus supports " 479 "only %d units", dev->unit, MAX_FD); 480 return; 481 } 482 483 drive = get_drv(bus->fdc, dev->unit); 484 if (drive->blk) { 485 error_setg(errp, "Floppy unit %d is in use", dev->unit); 486 return; 487 } 488 489 if (!dev->conf.blk) { 490 /* Anonymous BlockBackend for an empty drive */ 491 dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 492 ret = blk_attach_dev(dev->conf.blk, qdev); 493 assert(ret == 0); 494 495 /* Don't take write permissions on an empty drive to allow attaching a 496 * read-only node later */ 497 read_only = true; 498 } else { 499 read_only = !blk_bs(dev->conf.blk) || 500 !blk_supports_write_perm(dev->conf.blk); 501 } 502 503 if (!blkconf_blocksizes(&dev->conf, errp)) { 504 return; 505 } 506 507 if (dev->conf.logical_block_size != 512 || 508 dev->conf.physical_block_size != 512) 509 { 510 error_setg(errp, "Physical and logical block size must " 511 "be 512 for floppy"); 512 return; 513 } 514 515 /* rerror/werror aren't supported by fdc and therefore not even registered 516 * with qdev. So set the defaults manually before they are used in 517 * blkconf_apply_backend_options(). */ 518 dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO; 519 dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO; 520 521 if (!blkconf_apply_backend_options(&dev->conf, read_only, false, errp)) { 522 return; 523 } 524 525 /* 'enospc' is the default for -drive, 'report' is what blk_new() gives us 526 * for empty drives. */ 527 if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC && 528 blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) { 529 error_setg(errp, "fdc doesn't support drive option werror"); 530 return; 531 } 532 if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) { 533 error_setg(errp, "fdc doesn't support drive option rerror"); 534 return; 535 } 536 537 drive->conf = &dev->conf; 538 drive->blk = dev->conf.blk; 539 drive->fdctrl = bus->fdc; 540 541 fd_init(drive); 542 blk_set_dev_ops(drive->blk, &fd_block_ops, drive); 543 544 /* Keep 'type' qdev property and FDrive->drive in sync */ 545 drive->drive = dev->type; 546 pick_drive_type(drive); 547 dev->type = drive->drive; 548 549 fd_revalidate(drive); 550 } 551 552 static void floppy_drive_class_init(ObjectClass *klass, void *data) 553 { 554 DeviceClass *k = DEVICE_CLASS(klass); 555 k->realize = floppy_drive_realize; 556 set_bit(DEVICE_CATEGORY_STORAGE, k->categories); 557 k->bus_type = TYPE_FLOPPY_BUS; 558 device_class_set_props(k, floppy_drive_properties); 559 k->desc = "virtual floppy drive"; 560 } 561 562 static const TypeInfo floppy_drive_info = { 563 .name = TYPE_FLOPPY_DRIVE, 564 .parent = TYPE_DEVICE, 565 .instance_size = sizeof(FloppyDrive), 566 .class_init = floppy_drive_class_init, 567 }; 568 569 /********************************************************/ 570 /* Intel 82078 floppy disk controller emulation */ 571 572 static void fdctrl_to_command_phase(FDCtrl *fdctrl); 573 static void fdctrl_raise_irq(FDCtrl *fdctrl); 574 static FDrive *get_cur_drv(FDCtrl *fdctrl); 575 576 static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl); 577 static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl); 578 static uint32_t fdctrl_read_dor(FDCtrl *fdctrl); 579 static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value); 580 static uint32_t fdctrl_read_tape(FDCtrl *fdctrl); 581 static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value); 582 static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl); 583 static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value); 584 static uint32_t fdctrl_read_data(FDCtrl *fdctrl); 585 static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value); 586 static uint32_t fdctrl_read_dir(FDCtrl *fdctrl); 587 static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value); 588 589 enum { 590 FD_DIR_WRITE = 0, 591 FD_DIR_READ = 1, 592 FD_DIR_SCANE = 2, 593 FD_DIR_SCANL = 3, 594 FD_DIR_SCANH = 4, 595 FD_DIR_VERIFY = 5, 596 }; 597 598 enum { 599 FD_STATE_MULTI = 0x01, /* multi track flag */ 600 FD_STATE_FORMAT = 0x02, /* format flag */ 601 }; 602 603 enum { 604 FD_REG_SRA = 0x00, 605 FD_REG_SRB = 0x01, 606 FD_REG_DOR = 0x02, 607 FD_REG_TDR = 0x03, 608 FD_REG_MSR = 0x04, 609 FD_REG_DSR = 0x04, 610 FD_REG_FIFO = 0x05, 611 FD_REG_DIR = 0x07, 612 FD_REG_CCR = 0x07, 613 }; 614 615 enum { 616 FD_CMD_READ_TRACK = 0x02, 617 FD_CMD_SPECIFY = 0x03, 618 FD_CMD_SENSE_DRIVE_STATUS = 0x04, 619 FD_CMD_WRITE = 0x05, 620 FD_CMD_READ = 0x06, 621 FD_CMD_RECALIBRATE = 0x07, 622 FD_CMD_SENSE_INTERRUPT_STATUS = 0x08, 623 FD_CMD_WRITE_DELETED = 0x09, 624 FD_CMD_READ_ID = 0x0a, 625 FD_CMD_READ_DELETED = 0x0c, 626 FD_CMD_FORMAT_TRACK = 0x0d, 627 FD_CMD_DUMPREG = 0x0e, 628 FD_CMD_SEEK = 0x0f, 629 FD_CMD_VERSION = 0x10, 630 FD_CMD_SCAN_EQUAL = 0x11, 631 FD_CMD_PERPENDICULAR_MODE = 0x12, 632 FD_CMD_CONFIGURE = 0x13, 633 FD_CMD_LOCK = 0x14, 634 FD_CMD_VERIFY = 0x16, 635 FD_CMD_POWERDOWN_MODE = 0x17, 636 FD_CMD_PART_ID = 0x18, 637 FD_CMD_SCAN_LOW_OR_EQUAL = 0x19, 638 FD_CMD_SCAN_HIGH_OR_EQUAL = 0x1d, 639 FD_CMD_SAVE = 0x2e, 640 FD_CMD_OPTION = 0x33, 641 FD_CMD_RESTORE = 0x4e, 642 FD_CMD_DRIVE_SPECIFICATION_COMMAND = 0x8e, 643 FD_CMD_RELATIVE_SEEK_OUT = 0x8f, 644 FD_CMD_FORMAT_AND_WRITE = 0xcd, 645 FD_CMD_RELATIVE_SEEK_IN = 0xcf, 646 }; 647 648 enum { 649 FD_CONFIG_PRETRK = 0xff, /* Pre-compensation set to track 0 */ 650 FD_CONFIG_FIFOTHR = 0x0f, /* FIFO threshold set to 1 byte */ 651 FD_CONFIG_POLL = 0x10, /* Poll enabled */ 652 FD_CONFIG_EFIFO = 0x20, /* FIFO disabled */ 653 FD_CONFIG_EIS = 0x40, /* No implied seeks */ 654 }; 655 656 enum { 657 FD_SR0_DS0 = 0x01, 658 FD_SR0_DS1 = 0x02, 659 FD_SR0_HEAD = 0x04, 660 FD_SR0_EQPMT = 0x10, 661 FD_SR0_SEEK = 0x20, 662 FD_SR0_ABNTERM = 0x40, 663 FD_SR0_INVCMD = 0x80, 664 FD_SR0_RDYCHG = 0xc0, 665 }; 666 667 enum { 668 FD_SR1_MA = 0x01, /* Missing address mark */ 669 FD_SR1_NW = 0x02, /* Not writable */ 670 FD_SR1_EC = 0x80, /* End of cylinder */ 671 }; 672 673 enum { 674 FD_SR2_SNS = 0x04, /* Scan not satisfied */ 675 FD_SR2_SEH = 0x08, /* Scan equal hit */ 676 }; 677 678 enum { 679 FD_SRA_DIR = 0x01, 680 FD_SRA_nWP = 0x02, 681 FD_SRA_nINDX = 0x04, 682 FD_SRA_HDSEL = 0x08, 683 FD_SRA_nTRK0 = 0x10, 684 FD_SRA_STEP = 0x20, 685 FD_SRA_nDRV2 = 0x40, 686 FD_SRA_INTPEND = 0x80, 687 }; 688 689 enum { 690 FD_SRB_MTR0 = 0x01, 691 FD_SRB_MTR1 = 0x02, 692 FD_SRB_WGATE = 0x04, 693 FD_SRB_RDATA = 0x08, 694 FD_SRB_WDATA = 0x10, 695 FD_SRB_DR0 = 0x20, 696 }; 697 698 enum { 699 #if MAX_FD == 4 700 FD_DOR_SELMASK = 0x03, 701 #else 702 FD_DOR_SELMASK = 0x01, 703 #endif 704 FD_DOR_nRESET = 0x04, 705 FD_DOR_DMAEN = 0x08, 706 FD_DOR_MOTEN0 = 0x10, 707 FD_DOR_MOTEN1 = 0x20, 708 FD_DOR_MOTEN2 = 0x40, 709 FD_DOR_MOTEN3 = 0x80, 710 }; 711 712 enum { 713 #if MAX_FD == 4 714 FD_TDR_BOOTSEL = 0x0c, 715 #else 716 FD_TDR_BOOTSEL = 0x04, 717 #endif 718 }; 719 720 enum { 721 FD_DSR_DRATEMASK= 0x03, 722 FD_DSR_PWRDOWN = 0x40, 723 FD_DSR_SWRESET = 0x80, 724 }; 725 726 enum { 727 FD_MSR_DRV0BUSY = 0x01, 728 FD_MSR_DRV1BUSY = 0x02, 729 FD_MSR_DRV2BUSY = 0x04, 730 FD_MSR_DRV3BUSY = 0x08, 731 FD_MSR_CMDBUSY = 0x10, 732 FD_MSR_NONDMA = 0x20, 733 FD_MSR_DIO = 0x40, 734 FD_MSR_RQM = 0x80, 735 }; 736 737 enum { 738 FD_DIR_DSKCHG = 0x80, 739 }; 740 741 /* 742 * See chapter 5.0 "Controller phases" of the spec: 743 * 744 * Command phase: 745 * The host writes a command and its parameters into the FIFO. The command 746 * phase is completed when all parameters for the command have been supplied, 747 * and execution phase is entered. 748 * 749 * Execution phase: 750 * Data transfers, either DMA or non-DMA. For non-DMA transfers, the FIFO 751 * contains the payload now, otherwise it's unused. When all bytes of the 752 * required data have been transferred, the state is switched to either result 753 * phase (if the command produces status bytes) or directly back into the 754 * command phase for the next command. 755 * 756 * Result phase: 757 * The host reads out the FIFO, which contains one or more result bytes now. 758 */ 759 enum { 760 /* Only for migration: reconstruct phase from registers like qemu 2.3 */ 761 FD_PHASE_RECONSTRUCT = 0, 762 763 FD_PHASE_COMMAND = 1, 764 FD_PHASE_EXECUTION = 2, 765 FD_PHASE_RESULT = 3, 766 }; 767 768 #define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI) 769 #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT) 770 771 static FloppyDriveType get_fallback_drive_type(FDrive *drv) 772 { 773 return drv->fdctrl->fallback; 774 } 775 776 #define TYPE_SYSBUS_FDC "base-sysbus-fdc" 777 OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlSysBus, SYSBUS_FDC) 778 779 struct FDCtrlSysBus { 780 /*< private >*/ 781 SysBusDevice parent_obj; 782 /*< public >*/ 783 784 struct FDCtrl state; 785 }; 786 787 uint32_t fdctrl_read(void *opaque, uint32_t reg) 788 { 789 FDCtrl *fdctrl = opaque; 790 uint32_t retval; 791 792 reg &= 7; 793 switch (reg) { 794 case FD_REG_SRA: 795 retval = fdctrl_read_statusA(fdctrl); 796 break; 797 case FD_REG_SRB: 798 retval = fdctrl_read_statusB(fdctrl); 799 break; 800 case FD_REG_DOR: 801 retval = fdctrl_read_dor(fdctrl); 802 break; 803 case FD_REG_TDR: 804 retval = fdctrl_read_tape(fdctrl); 805 break; 806 case FD_REG_MSR: 807 retval = fdctrl_read_main_status(fdctrl); 808 break; 809 case FD_REG_FIFO: 810 retval = fdctrl_read_data(fdctrl); 811 break; 812 case FD_REG_DIR: 813 retval = fdctrl_read_dir(fdctrl); 814 break; 815 default: 816 retval = (uint32_t)(-1); 817 break; 818 } 819 trace_fdc_ioport_read(reg, retval); 820 821 return retval; 822 } 823 824 void fdctrl_write(void *opaque, uint32_t reg, uint32_t value) 825 { 826 FDCtrl *fdctrl = opaque; 827 828 reg &= 7; 829 trace_fdc_ioport_write(reg, value); 830 switch (reg) { 831 case FD_REG_DOR: 832 fdctrl_write_dor(fdctrl, value); 833 break; 834 case FD_REG_TDR: 835 fdctrl_write_tape(fdctrl, value); 836 break; 837 case FD_REG_DSR: 838 fdctrl_write_rate(fdctrl, value); 839 break; 840 case FD_REG_FIFO: 841 fdctrl_write_data(fdctrl, value); 842 break; 843 case FD_REG_CCR: 844 fdctrl_write_ccr(fdctrl, value); 845 break; 846 default: 847 break; 848 } 849 } 850 851 static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg, 852 unsigned ize) 853 { 854 return fdctrl_read(opaque, (uint32_t)reg); 855 } 856 857 static void fdctrl_write_mem (void *opaque, hwaddr reg, 858 uint64_t value, unsigned size) 859 { 860 fdctrl_write(opaque, (uint32_t)reg, value); 861 } 862 863 static const MemoryRegionOps fdctrl_mem_ops = { 864 .read = fdctrl_read_mem, 865 .write = fdctrl_write_mem, 866 .endianness = DEVICE_NATIVE_ENDIAN, 867 }; 868 869 static const MemoryRegionOps fdctrl_mem_strict_ops = { 870 .read = fdctrl_read_mem, 871 .write = fdctrl_write_mem, 872 .endianness = DEVICE_NATIVE_ENDIAN, 873 .valid = { 874 .min_access_size = 1, 875 .max_access_size = 1, 876 }, 877 }; 878 879 static bool fdrive_media_changed_needed(void *opaque) 880 { 881 FDrive *drive = opaque; 882 883 return (drive->blk != NULL && drive->media_changed != 1); 884 } 885 886 static const VMStateDescription vmstate_fdrive_media_changed = { 887 .name = "fdrive/media_changed", 888 .version_id = 1, 889 .minimum_version_id = 1, 890 .needed = fdrive_media_changed_needed, 891 .fields = (VMStateField[]) { 892 VMSTATE_UINT8(media_changed, FDrive), 893 VMSTATE_END_OF_LIST() 894 } 895 }; 896 897 static const VMStateDescription vmstate_fdrive_media_rate = { 898 .name = "fdrive/media_rate", 899 .version_id = 1, 900 .minimum_version_id = 1, 901 .fields = (VMStateField[]) { 902 VMSTATE_UINT8(media_rate, FDrive), 903 VMSTATE_END_OF_LIST() 904 } 905 }; 906 907 static bool fdrive_perpendicular_needed(void *opaque) 908 { 909 FDrive *drive = opaque; 910 911 return drive->perpendicular != 0; 912 } 913 914 static const VMStateDescription vmstate_fdrive_perpendicular = { 915 .name = "fdrive/perpendicular", 916 .version_id = 1, 917 .minimum_version_id = 1, 918 .needed = fdrive_perpendicular_needed, 919 .fields = (VMStateField[]) { 920 VMSTATE_UINT8(perpendicular, FDrive), 921 VMSTATE_END_OF_LIST() 922 } 923 }; 924 925 static int fdrive_post_load(void *opaque, int version_id) 926 { 927 fd_revalidate(opaque); 928 return 0; 929 } 930 931 static const VMStateDescription vmstate_fdrive = { 932 .name = "fdrive", 933 .version_id = 1, 934 .minimum_version_id = 1, 935 .post_load = fdrive_post_load, 936 .fields = (VMStateField[]) { 937 VMSTATE_UINT8(head, FDrive), 938 VMSTATE_UINT8(track, FDrive), 939 VMSTATE_UINT8(sect, FDrive), 940 VMSTATE_END_OF_LIST() 941 }, 942 .subsections = (const VMStateDescription*[]) { 943 &vmstate_fdrive_media_changed, 944 &vmstate_fdrive_media_rate, 945 &vmstate_fdrive_perpendicular, 946 NULL 947 } 948 }; 949 950 /* 951 * Reconstructs the phase from register values according to the logic that was 952 * implemented in qemu 2.3. This is the default value that is used if the phase 953 * subsection is not present on migration. 954 * 955 * Don't change this function to reflect newer qemu versions, it is part of 956 * the migration ABI. 957 */ 958 static int reconstruct_phase(FDCtrl *fdctrl) 959 { 960 if (fdctrl->msr & FD_MSR_NONDMA) { 961 return FD_PHASE_EXECUTION; 962 } else if ((fdctrl->msr & FD_MSR_RQM) == 0) { 963 /* qemu 2.3 disabled RQM only during DMA transfers */ 964 return FD_PHASE_EXECUTION; 965 } else if (fdctrl->msr & FD_MSR_DIO) { 966 return FD_PHASE_RESULT; 967 } else { 968 return FD_PHASE_COMMAND; 969 } 970 } 971 972 static int fdc_pre_save(void *opaque) 973 { 974 FDCtrl *s = opaque; 975 976 s->dor_vmstate = s->dor | GET_CUR_DRV(s); 977 978 return 0; 979 } 980 981 static int fdc_pre_load(void *opaque) 982 { 983 FDCtrl *s = opaque; 984 s->phase = FD_PHASE_RECONSTRUCT; 985 return 0; 986 } 987 988 static int fdc_post_load(void *opaque, int version_id) 989 { 990 FDCtrl *s = opaque; 991 992 SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK); 993 s->dor = s->dor_vmstate & ~FD_DOR_SELMASK; 994 995 if (s->phase == FD_PHASE_RECONSTRUCT) { 996 s->phase = reconstruct_phase(s); 997 } 998 999 return 0; 1000 } 1001 1002 static bool fdc_reset_sensei_needed(void *opaque) 1003 { 1004 FDCtrl *s = opaque; 1005 1006 return s->reset_sensei != 0; 1007 } 1008 1009 static const VMStateDescription vmstate_fdc_reset_sensei = { 1010 .name = "fdc/reset_sensei", 1011 .version_id = 1, 1012 .minimum_version_id = 1, 1013 .needed = fdc_reset_sensei_needed, 1014 .fields = (VMStateField[]) { 1015 VMSTATE_INT32(reset_sensei, FDCtrl), 1016 VMSTATE_END_OF_LIST() 1017 } 1018 }; 1019 1020 static bool fdc_result_timer_needed(void *opaque) 1021 { 1022 FDCtrl *s = opaque; 1023 1024 return timer_pending(s->result_timer); 1025 } 1026 1027 static const VMStateDescription vmstate_fdc_result_timer = { 1028 .name = "fdc/result_timer", 1029 .version_id = 1, 1030 .minimum_version_id = 1, 1031 .needed = fdc_result_timer_needed, 1032 .fields = (VMStateField[]) { 1033 VMSTATE_TIMER_PTR(result_timer, FDCtrl), 1034 VMSTATE_END_OF_LIST() 1035 } 1036 }; 1037 1038 static bool fdc_phase_needed(void *opaque) 1039 { 1040 FDCtrl *fdctrl = opaque; 1041 1042 return reconstruct_phase(fdctrl) != fdctrl->phase; 1043 } 1044 1045 static const VMStateDescription vmstate_fdc_phase = { 1046 .name = "fdc/phase", 1047 .version_id = 1, 1048 .minimum_version_id = 1, 1049 .needed = fdc_phase_needed, 1050 .fields = (VMStateField[]) { 1051 VMSTATE_UINT8(phase, FDCtrl), 1052 VMSTATE_END_OF_LIST() 1053 } 1054 }; 1055 1056 const VMStateDescription vmstate_fdc = { 1057 .name = "fdc", 1058 .version_id = 2, 1059 .minimum_version_id = 2, 1060 .pre_save = fdc_pre_save, 1061 .pre_load = fdc_pre_load, 1062 .post_load = fdc_post_load, 1063 .fields = (VMStateField[]) { 1064 /* Controller State */ 1065 VMSTATE_UINT8(sra, FDCtrl), 1066 VMSTATE_UINT8(srb, FDCtrl), 1067 VMSTATE_UINT8(dor_vmstate, FDCtrl), 1068 VMSTATE_UINT8(tdr, FDCtrl), 1069 VMSTATE_UINT8(dsr, FDCtrl), 1070 VMSTATE_UINT8(msr, FDCtrl), 1071 VMSTATE_UINT8(status0, FDCtrl), 1072 VMSTATE_UINT8(status1, FDCtrl), 1073 VMSTATE_UINT8(status2, FDCtrl), 1074 /* Command FIFO */ 1075 VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8, 1076 uint8_t), 1077 VMSTATE_UINT32(data_pos, FDCtrl), 1078 VMSTATE_UINT32(data_len, FDCtrl), 1079 VMSTATE_UINT8(data_state, FDCtrl), 1080 VMSTATE_UINT8(data_dir, FDCtrl), 1081 VMSTATE_UINT8(eot, FDCtrl), 1082 /* States kept only to be returned back */ 1083 VMSTATE_UINT8(timer0, FDCtrl), 1084 VMSTATE_UINT8(timer1, FDCtrl), 1085 VMSTATE_UINT8(precomp_trk, FDCtrl), 1086 VMSTATE_UINT8(config, FDCtrl), 1087 VMSTATE_UINT8(lock, FDCtrl), 1088 VMSTATE_UINT8(pwrd, FDCtrl), 1089 VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl, NULL), 1090 VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1, 1091 vmstate_fdrive, FDrive), 1092 VMSTATE_END_OF_LIST() 1093 }, 1094 .subsections = (const VMStateDescription*[]) { 1095 &vmstate_fdc_reset_sensei, 1096 &vmstate_fdc_result_timer, 1097 &vmstate_fdc_phase, 1098 NULL 1099 } 1100 }; 1101 1102 static void fdctrl_external_reset_sysbus(DeviceState *d) 1103 { 1104 FDCtrlSysBus *sys = SYSBUS_FDC(d); 1105 FDCtrl *s = &sys->state; 1106 1107 fdctrl_reset(s, 0); 1108 } 1109 1110 static void fdctrl_handle_tc(void *opaque, int irq, int level) 1111 { 1112 trace_fdctrl_tc_pulse(level); 1113 } 1114 1115 /* Change IRQ state */ 1116 static void fdctrl_reset_irq(FDCtrl *fdctrl) 1117 { 1118 fdctrl->status0 = 0; 1119 if (!(fdctrl->sra & FD_SRA_INTPEND)) 1120 return; 1121 FLOPPY_DPRINTF("Reset interrupt\n"); 1122 qemu_set_irq(fdctrl->irq, 0); 1123 fdctrl->sra &= ~FD_SRA_INTPEND; 1124 } 1125 1126 static void fdctrl_raise_irq(FDCtrl *fdctrl) 1127 { 1128 if (!(fdctrl->sra & FD_SRA_INTPEND)) { 1129 qemu_set_irq(fdctrl->irq, 1); 1130 fdctrl->sra |= FD_SRA_INTPEND; 1131 } 1132 1133 fdctrl->reset_sensei = 0; 1134 FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0); 1135 } 1136 1137 /* Reset controller */ 1138 void fdctrl_reset(FDCtrl *fdctrl, int do_irq) 1139 { 1140 int i; 1141 1142 FLOPPY_DPRINTF("reset controller\n"); 1143 fdctrl_reset_irq(fdctrl); 1144 /* Initialise controller */ 1145 fdctrl->sra = 0; 1146 fdctrl->srb = 0xc0; 1147 if (!fdctrl->drives[1].blk) { 1148 fdctrl->sra |= FD_SRA_nDRV2; 1149 } 1150 fdctrl->cur_drv = 0; 1151 fdctrl->dor = FD_DOR_nRESET; 1152 fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0; 1153 fdctrl->msr = FD_MSR_RQM; 1154 fdctrl->reset_sensei = 0; 1155 timer_del(fdctrl->result_timer); 1156 /* FIFO state */ 1157 fdctrl->data_pos = 0; 1158 fdctrl->data_len = 0; 1159 fdctrl->data_state = 0; 1160 fdctrl->data_dir = FD_DIR_WRITE; 1161 for (i = 0; i < MAX_FD; i++) 1162 fd_recalibrate(&fdctrl->drives[i]); 1163 fdctrl_to_command_phase(fdctrl); 1164 if (do_irq) { 1165 fdctrl->status0 |= FD_SR0_RDYCHG; 1166 fdctrl_raise_irq(fdctrl); 1167 fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT; 1168 } 1169 } 1170 1171 static inline FDrive *drv0(FDCtrl *fdctrl) 1172 { 1173 return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2]; 1174 } 1175 1176 static inline FDrive *drv1(FDCtrl *fdctrl) 1177 { 1178 if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2)) 1179 return &fdctrl->drives[1]; 1180 else 1181 return &fdctrl->drives[0]; 1182 } 1183 1184 #if MAX_FD == 4 1185 static inline FDrive *drv2(FDCtrl *fdctrl) 1186 { 1187 if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2)) 1188 return &fdctrl->drives[2]; 1189 else 1190 return &fdctrl->drives[1]; 1191 } 1192 1193 static inline FDrive *drv3(FDCtrl *fdctrl) 1194 { 1195 if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2)) 1196 return &fdctrl->drives[3]; 1197 else 1198 return &fdctrl->drives[2]; 1199 } 1200 #endif 1201 1202 static FDrive *get_drv(FDCtrl *fdctrl, int unit) 1203 { 1204 switch (unit) { 1205 case 0: return drv0(fdctrl); 1206 case 1: return drv1(fdctrl); 1207 #if MAX_FD == 4 1208 case 2: return drv2(fdctrl); 1209 case 3: return drv3(fdctrl); 1210 #endif 1211 default: return NULL; 1212 } 1213 } 1214 1215 static FDrive *get_cur_drv(FDCtrl *fdctrl) 1216 { 1217 return get_drv(fdctrl, fdctrl->cur_drv); 1218 } 1219 1220 /* Status A register : 0x00 (read-only) */ 1221 static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl) 1222 { 1223 uint32_t retval = fdctrl->sra; 1224 1225 FLOPPY_DPRINTF("status register A: 0x%02x\n", retval); 1226 1227 return retval; 1228 } 1229 1230 /* Status B register : 0x01 (read-only) */ 1231 static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl) 1232 { 1233 uint32_t retval = fdctrl->srb; 1234 1235 FLOPPY_DPRINTF("status register B: 0x%02x\n", retval); 1236 1237 return retval; 1238 } 1239 1240 /* Digital output register : 0x02 */ 1241 static uint32_t fdctrl_read_dor(FDCtrl *fdctrl) 1242 { 1243 uint32_t retval = fdctrl->dor; 1244 1245 /* Selected drive */ 1246 retval |= fdctrl->cur_drv; 1247 FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval); 1248 1249 return retval; 1250 } 1251 1252 static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value) 1253 { 1254 FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value); 1255 1256 /* Motors */ 1257 if (value & FD_DOR_MOTEN0) 1258 fdctrl->srb |= FD_SRB_MTR0; 1259 else 1260 fdctrl->srb &= ~FD_SRB_MTR0; 1261 if (value & FD_DOR_MOTEN1) 1262 fdctrl->srb |= FD_SRB_MTR1; 1263 else 1264 fdctrl->srb &= ~FD_SRB_MTR1; 1265 1266 /* Drive */ 1267 if (value & 1) 1268 fdctrl->srb |= FD_SRB_DR0; 1269 else 1270 fdctrl->srb &= ~FD_SRB_DR0; 1271 1272 /* Reset */ 1273 if (!(value & FD_DOR_nRESET)) { 1274 if (fdctrl->dor & FD_DOR_nRESET) { 1275 FLOPPY_DPRINTF("controller enter RESET state\n"); 1276 } 1277 } else { 1278 if (!(fdctrl->dor & FD_DOR_nRESET)) { 1279 FLOPPY_DPRINTF("controller out of RESET state\n"); 1280 fdctrl_reset(fdctrl, 1); 1281 fdctrl->dsr &= ~FD_DSR_PWRDOWN; 1282 } 1283 } 1284 /* Selected drive */ 1285 fdctrl->cur_drv = value & FD_DOR_SELMASK; 1286 1287 fdctrl->dor = value; 1288 } 1289 1290 /* Tape drive register : 0x03 */ 1291 static uint32_t fdctrl_read_tape(FDCtrl *fdctrl) 1292 { 1293 uint32_t retval = fdctrl->tdr; 1294 1295 FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval); 1296 1297 return retval; 1298 } 1299 1300 static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value) 1301 { 1302 /* Reset mode */ 1303 if (!(fdctrl->dor & FD_DOR_nRESET)) { 1304 FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); 1305 return; 1306 } 1307 FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value); 1308 /* Disk boot selection indicator */ 1309 fdctrl->tdr = value & FD_TDR_BOOTSEL; 1310 /* Tape indicators: never allow */ 1311 } 1312 1313 /* Main status register : 0x04 (read) */ 1314 static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl) 1315 { 1316 uint32_t retval = fdctrl->msr; 1317 1318 fdctrl->dsr &= ~FD_DSR_PWRDOWN; 1319 fdctrl->dor |= FD_DOR_nRESET; 1320 1321 FLOPPY_DPRINTF("main status register: 0x%02x\n", retval); 1322 1323 return retval; 1324 } 1325 1326 /* Data select rate register : 0x04 (write) */ 1327 static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value) 1328 { 1329 /* Reset mode */ 1330 if (!(fdctrl->dor & FD_DOR_nRESET)) { 1331 FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); 1332 return; 1333 } 1334 FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value); 1335 /* Reset: autoclear */ 1336 if (value & FD_DSR_SWRESET) { 1337 fdctrl->dor &= ~FD_DOR_nRESET; 1338 fdctrl_reset(fdctrl, 1); 1339 fdctrl->dor |= FD_DOR_nRESET; 1340 } 1341 if (value & FD_DSR_PWRDOWN) { 1342 fdctrl_reset(fdctrl, 1); 1343 } 1344 fdctrl->dsr = value; 1345 } 1346 1347 /* Configuration control register: 0x07 (write) */ 1348 static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value) 1349 { 1350 /* Reset mode */ 1351 if (!(fdctrl->dor & FD_DOR_nRESET)) { 1352 FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); 1353 return; 1354 } 1355 FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value); 1356 1357 /* Only the rate selection bits used in AT mode, and we 1358 * store those in the DSR. 1359 */ 1360 fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) | 1361 (value & FD_DSR_DRATEMASK); 1362 } 1363 1364 static int fdctrl_media_changed(FDrive *drv) 1365 { 1366 return drv->media_changed; 1367 } 1368 1369 /* Digital input register : 0x07 (read-only) */ 1370 static uint32_t fdctrl_read_dir(FDCtrl *fdctrl) 1371 { 1372 uint32_t retval = 0; 1373 1374 if (fdctrl_media_changed(get_cur_drv(fdctrl))) { 1375 retval |= FD_DIR_DSKCHG; 1376 } 1377 if (retval != 0) { 1378 FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval); 1379 } 1380 1381 return retval; 1382 } 1383 1384 /* Clear the FIFO and update the state for receiving the next command */ 1385 static void fdctrl_to_command_phase(FDCtrl *fdctrl) 1386 { 1387 fdctrl->phase = FD_PHASE_COMMAND; 1388 fdctrl->data_dir = FD_DIR_WRITE; 1389 fdctrl->data_pos = 0; 1390 fdctrl->data_len = 1; /* Accept command byte, adjust for params later */ 1391 fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO); 1392 fdctrl->msr |= FD_MSR_RQM; 1393 } 1394 1395 /* Update the state to allow the guest to read out the command status. 1396 * @fifo_len is the number of result bytes to be read out. */ 1397 static void fdctrl_to_result_phase(FDCtrl *fdctrl, int fifo_len) 1398 { 1399 fdctrl->phase = FD_PHASE_RESULT; 1400 fdctrl->data_dir = FD_DIR_READ; 1401 fdctrl->data_len = fifo_len; 1402 fdctrl->data_pos = 0; 1403 fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO; 1404 } 1405 1406 /* Set an error: unimplemented/unknown command */ 1407 static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction) 1408 { 1409 qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n", 1410 fdctrl->fifo[0]); 1411 fdctrl->fifo[0] = FD_SR0_INVCMD; 1412 fdctrl_to_result_phase(fdctrl, 1); 1413 } 1414 1415 /* Seek to next sector 1416 * returns 0 when end of track reached (for DBL_SIDES on head 1) 1417 * otherwise returns 1 1418 */ 1419 static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv) 1420 { 1421 FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n", 1422 cur_drv->head, cur_drv->track, cur_drv->sect, 1423 fd_sector(cur_drv)); 1424 /* XXX: cur_drv->sect >= cur_drv->last_sect should be an 1425 error in fact */ 1426 uint8_t new_head = cur_drv->head; 1427 uint8_t new_track = cur_drv->track; 1428 uint8_t new_sect = cur_drv->sect; 1429 1430 int ret = 1; 1431 1432 if (new_sect >= cur_drv->last_sect || 1433 new_sect == fdctrl->eot) { 1434 new_sect = 1; 1435 if (FD_MULTI_TRACK(fdctrl->data_state)) { 1436 if (new_head == 0 && 1437 (cur_drv->flags & FDISK_DBL_SIDES) != 0) { 1438 new_head = 1; 1439 } else { 1440 new_head = 0; 1441 new_track++; 1442 fdctrl->status0 |= FD_SR0_SEEK; 1443 if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) { 1444 ret = 0; 1445 } 1446 } 1447 } else { 1448 fdctrl->status0 |= FD_SR0_SEEK; 1449 new_track++; 1450 ret = 0; 1451 } 1452 if (ret == 1) { 1453 FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n", 1454 new_head, new_track, new_sect, fd_sector(cur_drv)); 1455 } 1456 } else { 1457 new_sect++; 1458 } 1459 fd_seek(cur_drv, new_head, new_track, new_sect, 1); 1460 return ret; 1461 } 1462 1463 /* Callback for transfer end (stop or abort) */ 1464 static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0, 1465 uint8_t status1, uint8_t status2) 1466 { 1467 FDrive *cur_drv; 1468 cur_drv = get_cur_drv(fdctrl); 1469 1470 fdctrl->status0 &= ~(FD_SR0_DS0 | FD_SR0_DS1 | FD_SR0_HEAD); 1471 fdctrl->status0 |= GET_CUR_DRV(fdctrl); 1472 if (cur_drv->head) { 1473 fdctrl->status0 |= FD_SR0_HEAD; 1474 } 1475 fdctrl->status0 |= status0; 1476 1477 FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n", 1478 status0, status1, status2, fdctrl->status0); 1479 fdctrl->fifo[0] = fdctrl->status0; 1480 fdctrl->fifo[1] = status1; 1481 fdctrl->fifo[2] = status2; 1482 fdctrl->fifo[3] = cur_drv->track; 1483 fdctrl->fifo[4] = cur_drv->head; 1484 fdctrl->fifo[5] = cur_drv->sect; 1485 fdctrl->fifo[6] = FD_SECTOR_SC; 1486 fdctrl->data_dir = FD_DIR_READ; 1487 if (fdctrl->dma_chann != -1 && !(fdctrl->msr & FD_MSR_NONDMA)) { 1488 IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma); 1489 k->release_DREQ(fdctrl->dma, fdctrl->dma_chann); 1490 } 1491 fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO; 1492 fdctrl->msr &= ~FD_MSR_NONDMA; 1493 1494 fdctrl_to_result_phase(fdctrl, 7); 1495 fdctrl_raise_irq(fdctrl); 1496 } 1497 1498 /* Prepare a data transfer (either DMA or FIFO) */ 1499 static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction) 1500 { 1501 FDrive *cur_drv; 1502 uint8_t kh, kt, ks; 1503 1504 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 1505 cur_drv = get_cur_drv(fdctrl); 1506 kt = fdctrl->fifo[2]; 1507 kh = fdctrl->fifo[3]; 1508 ks = fdctrl->fifo[4]; 1509 FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n", 1510 GET_CUR_DRV(fdctrl), kh, kt, ks, 1511 fd_sector_calc(kh, kt, ks, cur_drv->last_sect, 1512 NUM_SIDES(cur_drv))); 1513 switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) { 1514 case 2: 1515 /* sect too big */ 1516 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1517 fdctrl->fifo[3] = kt; 1518 fdctrl->fifo[4] = kh; 1519 fdctrl->fifo[5] = ks; 1520 return; 1521 case 3: 1522 /* track too big */ 1523 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00); 1524 fdctrl->fifo[3] = kt; 1525 fdctrl->fifo[4] = kh; 1526 fdctrl->fifo[5] = ks; 1527 return; 1528 case 4: 1529 /* No seek enabled */ 1530 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1531 fdctrl->fifo[3] = kt; 1532 fdctrl->fifo[4] = kh; 1533 fdctrl->fifo[5] = ks; 1534 return; 1535 case 1: 1536 fdctrl->status0 |= FD_SR0_SEEK; 1537 break; 1538 default: 1539 break; 1540 } 1541 1542 /* Check the data rate. If the programmed data rate does not match 1543 * the currently inserted medium, the operation has to fail. */ 1544 if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) { 1545 FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n", 1546 fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate); 1547 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00); 1548 fdctrl->fifo[3] = kt; 1549 fdctrl->fifo[4] = kh; 1550 fdctrl->fifo[5] = ks; 1551 return; 1552 } 1553 1554 /* Set the FIFO state */ 1555 fdctrl->data_dir = direction; 1556 fdctrl->data_pos = 0; 1557 assert(fdctrl->msr & FD_MSR_CMDBUSY); 1558 if (fdctrl->fifo[0] & 0x80) 1559 fdctrl->data_state |= FD_STATE_MULTI; 1560 else 1561 fdctrl->data_state &= ~FD_STATE_MULTI; 1562 if (fdctrl->fifo[5] == 0) { 1563 fdctrl->data_len = fdctrl->fifo[8]; 1564 } else { 1565 int tmp; 1566 fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]); 1567 tmp = (fdctrl->fifo[6] - ks + 1); 1568 if (fdctrl->fifo[0] & 0x80) 1569 tmp += fdctrl->fifo[6]; 1570 fdctrl->data_len *= tmp; 1571 } 1572 fdctrl->eot = fdctrl->fifo[6]; 1573 if (fdctrl->dor & FD_DOR_DMAEN) { 1574 /* DMA transfer is enabled. */ 1575 IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma); 1576 1577 FLOPPY_DPRINTF("direction=%d (%d - %d)\n", 1578 direction, (128 << fdctrl->fifo[5]) * 1579 (cur_drv->last_sect - ks + 1), fdctrl->data_len); 1580 1581 /* No access is allowed until DMA transfer has completed */ 1582 fdctrl->msr &= ~FD_MSR_RQM; 1583 if (direction != FD_DIR_VERIFY) { 1584 /* 1585 * Now, we just have to wait for the DMA controller to 1586 * recall us... 1587 */ 1588 k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann); 1589 k->schedule(fdctrl->dma); 1590 } else { 1591 /* Start transfer */ 1592 fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0, 1593 fdctrl->data_len); 1594 } 1595 return; 1596 } 1597 FLOPPY_DPRINTF("start non-DMA transfer\n"); 1598 fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM; 1599 if (direction != FD_DIR_WRITE) 1600 fdctrl->msr |= FD_MSR_DIO; 1601 /* IO based transfer: calculate len */ 1602 fdctrl_raise_irq(fdctrl); 1603 } 1604 1605 /* Prepare a transfer of deleted data */ 1606 static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction) 1607 { 1608 qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n"); 1609 1610 /* We don't handle deleted data, 1611 * so we don't return *ANYTHING* 1612 */ 1613 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); 1614 } 1615 1616 /* handlers for DMA transfers */ 1617 int fdctrl_transfer_handler(void *opaque, int nchan, int dma_pos, int dma_len) 1618 { 1619 FDCtrl *fdctrl; 1620 FDrive *cur_drv; 1621 int len, start_pos, rel_pos; 1622 uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00; 1623 IsaDmaClass *k; 1624 1625 fdctrl = opaque; 1626 if (fdctrl->msr & FD_MSR_RQM) { 1627 FLOPPY_DPRINTF("Not in DMA transfer mode !\n"); 1628 return 0; 1629 } 1630 k = ISADMA_GET_CLASS(fdctrl->dma); 1631 cur_drv = get_cur_drv(fdctrl); 1632 if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL || 1633 fdctrl->data_dir == FD_DIR_SCANH) 1634 status2 = FD_SR2_SNS; 1635 if (dma_len > fdctrl->data_len) 1636 dma_len = fdctrl->data_len; 1637 if (cur_drv->blk == NULL) { 1638 if (fdctrl->data_dir == FD_DIR_WRITE) 1639 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); 1640 else 1641 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1642 len = 0; 1643 goto transfer_error; 1644 } 1645 rel_pos = fdctrl->data_pos % FD_SECTOR_LEN; 1646 for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) { 1647 len = dma_len - fdctrl->data_pos; 1648 if (len + rel_pos > FD_SECTOR_LEN) 1649 len = FD_SECTOR_LEN - rel_pos; 1650 FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x " 1651 "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos, 1652 fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head, 1653 cur_drv->track, cur_drv->sect, fd_sector(cur_drv), 1654 fd_sector(cur_drv) * FD_SECTOR_LEN); 1655 if (fdctrl->data_dir != FD_DIR_WRITE || 1656 len < FD_SECTOR_LEN || rel_pos != 0) { 1657 /* READ & SCAN commands and realign to a sector for WRITE */ 1658 if (blk_pread(cur_drv->blk, fd_offset(cur_drv), 1659 fdctrl->fifo, BDRV_SECTOR_SIZE) < 0) { 1660 FLOPPY_DPRINTF("Floppy: error getting sector %d\n", 1661 fd_sector(cur_drv)); 1662 /* Sure, image size is too small... */ 1663 memset(fdctrl->fifo, 0, FD_SECTOR_LEN); 1664 } 1665 } 1666 switch (fdctrl->data_dir) { 1667 case FD_DIR_READ: 1668 /* READ commands */ 1669 k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos, 1670 fdctrl->data_pos, len); 1671 break; 1672 case FD_DIR_WRITE: 1673 /* WRITE commands */ 1674 if (cur_drv->ro) { 1675 /* Handle readonly medium early, no need to do DMA, touch the 1676 * LED or attempt any writes. A real floppy doesn't attempt 1677 * to write to readonly media either. */ 1678 fdctrl_stop_transfer(fdctrl, 1679 FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW, 1680 0x00); 1681 goto transfer_error; 1682 } 1683 1684 k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos, 1685 fdctrl->data_pos, len); 1686 if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), 1687 fdctrl->fifo, BDRV_SECTOR_SIZE, 0) < 0) { 1688 FLOPPY_DPRINTF("error writing sector %d\n", 1689 fd_sector(cur_drv)); 1690 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); 1691 goto transfer_error; 1692 } 1693 break; 1694 case FD_DIR_VERIFY: 1695 /* VERIFY commands */ 1696 break; 1697 default: 1698 /* SCAN commands */ 1699 { 1700 uint8_t tmpbuf[FD_SECTOR_LEN]; 1701 int ret; 1702 k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos, 1703 len); 1704 ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len); 1705 if (ret == 0) { 1706 status2 = FD_SR2_SEH; 1707 goto end_transfer; 1708 } 1709 if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) || 1710 (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) { 1711 status2 = 0x00; 1712 goto end_transfer; 1713 } 1714 } 1715 break; 1716 } 1717 fdctrl->data_pos += len; 1718 rel_pos = fdctrl->data_pos % FD_SECTOR_LEN; 1719 if (rel_pos == 0) { 1720 /* Seek to next sector */ 1721 if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) 1722 break; 1723 } 1724 } 1725 end_transfer: 1726 len = fdctrl->data_pos - start_pos; 1727 FLOPPY_DPRINTF("end transfer %d %d %d\n", 1728 fdctrl->data_pos, len, fdctrl->data_len); 1729 if (fdctrl->data_dir == FD_DIR_SCANE || 1730 fdctrl->data_dir == FD_DIR_SCANL || 1731 fdctrl->data_dir == FD_DIR_SCANH) 1732 status2 = FD_SR2_SEH; 1733 fdctrl->data_len -= len; 1734 fdctrl_stop_transfer(fdctrl, status0, status1, status2); 1735 transfer_error: 1736 1737 return len; 1738 } 1739 1740 /* Data register : 0x05 */ 1741 static uint32_t fdctrl_read_data(FDCtrl *fdctrl) 1742 { 1743 FDrive *cur_drv; 1744 uint32_t retval = 0; 1745 uint32_t pos; 1746 1747 cur_drv = get_cur_drv(fdctrl); 1748 fdctrl->dsr &= ~FD_DSR_PWRDOWN; 1749 if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) { 1750 FLOPPY_DPRINTF("error: controller not ready for reading\n"); 1751 return 0; 1752 } 1753 1754 /* If data_len spans multiple sectors, the current position in the FIFO 1755 * wraps around while fdctrl->data_pos is the real position in the whole 1756 * request. */ 1757 pos = fdctrl->data_pos; 1758 pos %= FD_SECTOR_LEN; 1759 1760 switch (fdctrl->phase) { 1761 case FD_PHASE_EXECUTION: 1762 assert(fdctrl->msr & FD_MSR_NONDMA); 1763 if (pos == 0) { 1764 if (fdctrl->data_pos != 0) 1765 if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { 1766 FLOPPY_DPRINTF("error seeking to next sector %d\n", 1767 fd_sector(cur_drv)); 1768 return 0; 1769 } 1770 if (blk_pread(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, 1771 BDRV_SECTOR_SIZE) 1772 < 0) { 1773 FLOPPY_DPRINTF("error getting sector %d\n", 1774 fd_sector(cur_drv)); 1775 /* Sure, image size is too small... */ 1776 memset(fdctrl->fifo, 0, FD_SECTOR_LEN); 1777 } 1778 } 1779 1780 if (++fdctrl->data_pos == fdctrl->data_len) { 1781 fdctrl->msr &= ~FD_MSR_RQM; 1782 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 1783 } 1784 break; 1785 1786 case FD_PHASE_RESULT: 1787 assert(!(fdctrl->msr & FD_MSR_NONDMA)); 1788 if (++fdctrl->data_pos == fdctrl->data_len) { 1789 fdctrl->msr &= ~FD_MSR_RQM; 1790 fdctrl_to_command_phase(fdctrl); 1791 fdctrl_reset_irq(fdctrl); 1792 } 1793 break; 1794 1795 case FD_PHASE_COMMAND: 1796 default: 1797 abort(); 1798 } 1799 1800 retval = fdctrl->fifo[pos]; 1801 FLOPPY_DPRINTF("data register: 0x%02x\n", retval); 1802 1803 return retval; 1804 } 1805 1806 static void fdctrl_format_sector(FDCtrl *fdctrl) 1807 { 1808 FDrive *cur_drv; 1809 uint8_t kh, kt, ks; 1810 1811 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 1812 cur_drv = get_cur_drv(fdctrl); 1813 kt = fdctrl->fifo[6]; 1814 kh = fdctrl->fifo[7]; 1815 ks = fdctrl->fifo[8]; 1816 FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n", 1817 GET_CUR_DRV(fdctrl), kh, kt, ks, 1818 fd_sector_calc(kh, kt, ks, cur_drv->last_sect, 1819 NUM_SIDES(cur_drv))); 1820 switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) { 1821 case 2: 1822 /* sect too big */ 1823 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1824 fdctrl->fifo[3] = kt; 1825 fdctrl->fifo[4] = kh; 1826 fdctrl->fifo[5] = ks; 1827 return; 1828 case 3: 1829 /* track too big */ 1830 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00); 1831 fdctrl->fifo[3] = kt; 1832 fdctrl->fifo[4] = kh; 1833 fdctrl->fifo[5] = ks; 1834 return; 1835 case 4: 1836 /* No seek enabled */ 1837 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00); 1838 fdctrl->fifo[3] = kt; 1839 fdctrl->fifo[4] = kh; 1840 fdctrl->fifo[5] = ks; 1841 return; 1842 case 1: 1843 fdctrl->status0 |= FD_SR0_SEEK; 1844 break; 1845 default: 1846 break; 1847 } 1848 memset(fdctrl->fifo, 0, FD_SECTOR_LEN); 1849 if (cur_drv->blk == NULL || 1850 blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, 1851 BDRV_SECTOR_SIZE, 0) < 0) { 1852 FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv)); 1853 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00); 1854 } else { 1855 if (cur_drv->sect == cur_drv->last_sect) { 1856 fdctrl->data_state &= ~FD_STATE_FORMAT; 1857 /* Last sector done */ 1858 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 1859 } else { 1860 /* More to do */ 1861 fdctrl->data_pos = 0; 1862 fdctrl->data_len = 4; 1863 } 1864 } 1865 } 1866 1867 static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction) 1868 { 1869 fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0; 1870 fdctrl->fifo[0] = fdctrl->lock << 4; 1871 fdctrl_to_result_phase(fdctrl, 1); 1872 } 1873 1874 static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction) 1875 { 1876 FDrive *cur_drv = get_cur_drv(fdctrl); 1877 1878 /* Drives position */ 1879 fdctrl->fifo[0] = drv0(fdctrl)->track; 1880 fdctrl->fifo[1] = drv1(fdctrl)->track; 1881 #if MAX_FD == 4 1882 fdctrl->fifo[2] = drv2(fdctrl)->track; 1883 fdctrl->fifo[3] = drv3(fdctrl)->track; 1884 #else 1885 fdctrl->fifo[2] = 0; 1886 fdctrl->fifo[3] = 0; 1887 #endif 1888 /* timers */ 1889 fdctrl->fifo[4] = fdctrl->timer0; 1890 fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0); 1891 fdctrl->fifo[6] = cur_drv->last_sect; 1892 fdctrl->fifo[7] = (fdctrl->lock << 7) | 1893 (cur_drv->perpendicular << 2); 1894 fdctrl->fifo[8] = fdctrl->config; 1895 fdctrl->fifo[9] = fdctrl->precomp_trk; 1896 fdctrl_to_result_phase(fdctrl, 10); 1897 } 1898 1899 static void fdctrl_handle_version(FDCtrl *fdctrl, int direction) 1900 { 1901 /* Controller's version */ 1902 fdctrl->fifo[0] = fdctrl->version; 1903 fdctrl_to_result_phase(fdctrl, 1); 1904 } 1905 1906 static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction) 1907 { 1908 fdctrl->fifo[0] = 0x41; /* Stepping 1 */ 1909 fdctrl_to_result_phase(fdctrl, 1); 1910 } 1911 1912 static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction) 1913 { 1914 FDrive *cur_drv = get_cur_drv(fdctrl); 1915 1916 /* Drives position */ 1917 drv0(fdctrl)->track = fdctrl->fifo[3]; 1918 drv1(fdctrl)->track = fdctrl->fifo[4]; 1919 #if MAX_FD == 4 1920 drv2(fdctrl)->track = fdctrl->fifo[5]; 1921 drv3(fdctrl)->track = fdctrl->fifo[6]; 1922 #endif 1923 /* timers */ 1924 fdctrl->timer0 = fdctrl->fifo[7]; 1925 fdctrl->timer1 = fdctrl->fifo[8]; 1926 cur_drv->last_sect = fdctrl->fifo[9]; 1927 fdctrl->lock = fdctrl->fifo[10] >> 7; 1928 cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF; 1929 fdctrl->config = fdctrl->fifo[11]; 1930 fdctrl->precomp_trk = fdctrl->fifo[12]; 1931 fdctrl->pwrd = fdctrl->fifo[13]; 1932 fdctrl_to_command_phase(fdctrl); 1933 } 1934 1935 static void fdctrl_handle_save(FDCtrl *fdctrl, int direction) 1936 { 1937 FDrive *cur_drv = get_cur_drv(fdctrl); 1938 1939 fdctrl->fifo[0] = 0; 1940 fdctrl->fifo[1] = 0; 1941 /* Drives position */ 1942 fdctrl->fifo[2] = drv0(fdctrl)->track; 1943 fdctrl->fifo[3] = drv1(fdctrl)->track; 1944 #if MAX_FD == 4 1945 fdctrl->fifo[4] = drv2(fdctrl)->track; 1946 fdctrl->fifo[5] = drv3(fdctrl)->track; 1947 #else 1948 fdctrl->fifo[4] = 0; 1949 fdctrl->fifo[5] = 0; 1950 #endif 1951 /* timers */ 1952 fdctrl->fifo[6] = fdctrl->timer0; 1953 fdctrl->fifo[7] = fdctrl->timer1; 1954 fdctrl->fifo[8] = cur_drv->last_sect; 1955 fdctrl->fifo[9] = (fdctrl->lock << 7) | 1956 (cur_drv->perpendicular << 2); 1957 fdctrl->fifo[10] = fdctrl->config; 1958 fdctrl->fifo[11] = fdctrl->precomp_trk; 1959 fdctrl->fifo[12] = fdctrl->pwrd; 1960 fdctrl->fifo[13] = 0; 1961 fdctrl->fifo[14] = 0; 1962 fdctrl_to_result_phase(fdctrl, 15); 1963 } 1964 1965 static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction) 1966 { 1967 FDrive *cur_drv = get_cur_drv(fdctrl); 1968 1969 cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; 1970 timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1971 (NANOSECONDS_PER_SECOND / 50)); 1972 } 1973 1974 static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction) 1975 { 1976 FDrive *cur_drv; 1977 1978 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 1979 cur_drv = get_cur_drv(fdctrl); 1980 fdctrl->data_state |= FD_STATE_FORMAT; 1981 if (fdctrl->fifo[0] & 0x80) 1982 fdctrl->data_state |= FD_STATE_MULTI; 1983 else 1984 fdctrl->data_state &= ~FD_STATE_MULTI; 1985 cur_drv->bps = 1986 fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2]; 1987 #if 0 1988 cur_drv->last_sect = 1989 cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] : 1990 fdctrl->fifo[3] / 2; 1991 #else 1992 cur_drv->last_sect = fdctrl->fifo[3]; 1993 #endif 1994 /* TODO: implement format using DMA expected by the Bochs BIOS 1995 * and Linux fdformat (read 3 bytes per sector via DMA and fill 1996 * the sector with the specified fill byte 1997 */ 1998 fdctrl->data_state &= ~FD_STATE_FORMAT; 1999 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 2000 } 2001 2002 static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction) 2003 { 2004 fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF; 2005 fdctrl->timer1 = fdctrl->fifo[2] >> 1; 2006 if (fdctrl->fifo[2] & 1) 2007 fdctrl->dor &= ~FD_DOR_DMAEN; 2008 else 2009 fdctrl->dor |= FD_DOR_DMAEN; 2010 /* No result back */ 2011 fdctrl_to_command_phase(fdctrl); 2012 } 2013 2014 static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction) 2015 { 2016 FDrive *cur_drv; 2017 2018 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 2019 cur_drv = get_cur_drv(fdctrl); 2020 cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; 2021 /* 1 Byte status back */ 2022 fdctrl->fifo[0] = (cur_drv->ro << 6) | 2023 (cur_drv->track == 0 ? 0x10 : 0x00) | 2024 (cur_drv->head << 2) | 2025 GET_CUR_DRV(fdctrl) | 2026 0x28; 2027 fdctrl_to_result_phase(fdctrl, 1); 2028 } 2029 2030 static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction) 2031 { 2032 FDrive *cur_drv; 2033 2034 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 2035 cur_drv = get_cur_drv(fdctrl); 2036 fd_recalibrate(cur_drv); 2037 fdctrl_to_command_phase(fdctrl); 2038 /* Raise Interrupt */ 2039 fdctrl->status0 |= FD_SR0_SEEK; 2040 fdctrl_raise_irq(fdctrl); 2041 } 2042 2043 static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction) 2044 { 2045 FDrive *cur_drv = get_cur_drv(fdctrl); 2046 2047 if (fdctrl->reset_sensei > 0) { 2048 fdctrl->fifo[0] = 2049 FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei; 2050 fdctrl->reset_sensei--; 2051 } else if (!(fdctrl->sra & FD_SRA_INTPEND)) { 2052 fdctrl->fifo[0] = FD_SR0_INVCMD; 2053 fdctrl_to_result_phase(fdctrl, 1); 2054 return; 2055 } else { 2056 fdctrl->fifo[0] = 2057 (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0)) 2058 | GET_CUR_DRV(fdctrl); 2059 } 2060 2061 fdctrl->fifo[1] = cur_drv->track; 2062 fdctrl_to_result_phase(fdctrl, 2); 2063 fdctrl_reset_irq(fdctrl); 2064 fdctrl->status0 = FD_SR0_RDYCHG; 2065 } 2066 2067 static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction) 2068 { 2069 FDrive *cur_drv; 2070 2071 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 2072 cur_drv = get_cur_drv(fdctrl); 2073 fdctrl_to_command_phase(fdctrl); 2074 /* The seek command just sends step pulses to the drive and doesn't care if 2075 * there is a medium inserted of if it's banging the head against the drive. 2076 */ 2077 fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1); 2078 /* Raise Interrupt */ 2079 fdctrl->status0 |= FD_SR0_SEEK; 2080 fdctrl_raise_irq(fdctrl); 2081 } 2082 2083 static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction) 2084 { 2085 FDrive *cur_drv = get_cur_drv(fdctrl); 2086 2087 if (fdctrl->fifo[1] & 0x80) 2088 cur_drv->perpendicular = fdctrl->fifo[1] & 0x7; 2089 /* No result back */ 2090 fdctrl_to_command_phase(fdctrl); 2091 } 2092 2093 static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction) 2094 { 2095 fdctrl->config = fdctrl->fifo[2]; 2096 fdctrl->precomp_trk = fdctrl->fifo[3]; 2097 /* No result back */ 2098 fdctrl_to_command_phase(fdctrl); 2099 } 2100 2101 static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction) 2102 { 2103 fdctrl->pwrd = fdctrl->fifo[1]; 2104 fdctrl->fifo[0] = fdctrl->fifo[1]; 2105 fdctrl_to_result_phase(fdctrl, 1); 2106 } 2107 2108 static void fdctrl_handle_option(FDCtrl *fdctrl, int direction) 2109 { 2110 /* No result back */ 2111 fdctrl_to_command_phase(fdctrl); 2112 } 2113 2114 static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction) 2115 { 2116 FDrive *cur_drv = get_cur_drv(fdctrl); 2117 uint32_t pos; 2118 2119 pos = fdctrl->data_pos - 1; 2120 pos %= FD_SECTOR_LEN; 2121 if (fdctrl->fifo[pos] & 0x80) { 2122 /* Command parameters done */ 2123 if (fdctrl->fifo[pos] & 0x40) { 2124 fdctrl->fifo[0] = fdctrl->fifo[1]; 2125 fdctrl->fifo[2] = 0; 2126 fdctrl->fifo[3] = 0; 2127 fdctrl_to_result_phase(fdctrl, 4); 2128 } else { 2129 fdctrl_to_command_phase(fdctrl); 2130 } 2131 } else if (fdctrl->data_len > 7) { 2132 /* ERROR */ 2133 fdctrl->fifo[0] = 0x80 | 2134 (cur_drv->head << 2) | GET_CUR_DRV(fdctrl); 2135 fdctrl_to_result_phase(fdctrl, 1); 2136 } 2137 } 2138 2139 static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction) 2140 { 2141 FDrive *cur_drv; 2142 2143 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 2144 cur_drv = get_cur_drv(fdctrl); 2145 if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) { 2146 fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1, 2147 cur_drv->sect, 1); 2148 } else { 2149 fd_seek(cur_drv, cur_drv->head, 2150 cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1); 2151 } 2152 fdctrl_to_command_phase(fdctrl); 2153 /* Raise Interrupt */ 2154 fdctrl->status0 |= FD_SR0_SEEK; 2155 fdctrl_raise_irq(fdctrl); 2156 } 2157 2158 static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction) 2159 { 2160 FDrive *cur_drv; 2161 2162 SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); 2163 cur_drv = get_cur_drv(fdctrl); 2164 if (fdctrl->fifo[2] > cur_drv->track) { 2165 fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1); 2166 } else { 2167 fd_seek(cur_drv, cur_drv->head, 2168 cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1); 2169 } 2170 fdctrl_to_command_phase(fdctrl); 2171 /* Raise Interrupt */ 2172 fdctrl->status0 |= FD_SR0_SEEK; 2173 fdctrl_raise_irq(fdctrl); 2174 } 2175 2176 /* 2177 * Handlers for the execution phase of each command 2178 */ 2179 typedef struct FDCtrlCommand { 2180 uint8_t value; 2181 uint8_t mask; 2182 const char* name; 2183 int parameters; 2184 void (*handler)(FDCtrl *fdctrl, int direction); 2185 int direction; 2186 } FDCtrlCommand; 2187 2188 static const FDCtrlCommand handlers[] = { 2189 { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ }, 2190 { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE }, 2191 { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek }, 2192 { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status }, 2193 { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate }, 2194 { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track }, 2195 { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ }, 2196 { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */ 2197 { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */ 2198 { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ }, 2199 { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE }, 2200 { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_start_transfer, FD_DIR_VERIFY }, 2201 { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL }, 2202 { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH }, 2203 { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE }, 2204 { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid }, 2205 { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify }, 2206 { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status }, 2207 { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode }, 2208 { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure }, 2209 { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode }, 2210 { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option }, 2211 { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command }, 2212 { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out }, 2213 { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented }, 2214 { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in }, 2215 { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock }, 2216 { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg }, 2217 { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version }, 2218 { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid }, 2219 { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */ 2220 { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */ 2221 }; 2222 /* Associate command to an index in the 'handlers' array */ 2223 static uint8_t command_to_handler[256]; 2224 2225 static const FDCtrlCommand *get_command(uint8_t cmd) 2226 { 2227 int idx; 2228 2229 idx = command_to_handler[cmd]; 2230 FLOPPY_DPRINTF("%s command\n", handlers[idx].name); 2231 return &handlers[idx]; 2232 } 2233 2234 static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) 2235 { 2236 FDrive *cur_drv; 2237 const FDCtrlCommand *cmd; 2238 uint32_t pos; 2239 2240 /* Reset mode */ 2241 if (!(fdctrl->dor & FD_DOR_nRESET)) { 2242 FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); 2243 return; 2244 } 2245 if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) { 2246 FLOPPY_DPRINTF("error: controller not ready for writing\n"); 2247 return; 2248 } 2249 fdctrl->dsr &= ~FD_DSR_PWRDOWN; 2250 2251 FLOPPY_DPRINTF("%s: %02x\n", __func__, value); 2252 2253 /* If data_len spans multiple sectors, the current position in the FIFO 2254 * wraps around while fdctrl->data_pos is the real position in the whole 2255 * request. */ 2256 pos = fdctrl->data_pos++; 2257 pos %= FD_SECTOR_LEN; 2258 fdctrl->fifo[pos] = value; 2259 2260 if (fdctrl->data_pos == fdctrl->data_len) { 2261 fdctrl->msr &= ~FD_MSR_RQM; 2262 } 2263 2264 switch (fdctrl->phase) { 2265 case FD_PHASE_EXECUTION: 2266 /* For DMA requests, RQM should be cleared during execution phase, so 2267 * we would have errored out above. */ 2268 assert(fdctrl->msr & FD_MSR_NONDMA); 2269 2270 /* FIFO data write */ 2271 if (pos == FD_SECTOR_LEN - 1 || 2272 fdctrl->data_pos == fdctrl->data_len) { 2273 cur_drv = get_cur_drv(fdctrl); 2274 if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo, 2275 BDRV_SECTOR_SIZE, 0) < 0) { 2276 FLOPPY_DPRINTF("error writing sector %d\n", 2277 fd_sector(cur_drv)); 2278 break; 2279 } 2280 if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { 2281 FLOPPY_DPRINTF("error seeking to next sector %d\n", 2282 fd_sector(cur_drv)); 2283 break; 2284 } 2285 } 2286 2287 /* Switch to result phase when done with the transfer */ 2288 if (fdctrl->data_pos == fdctrl->data_len) { 2289 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 2290 } 2291 break; 2292 2293 case FD_PHASE_COMMAND: 2294 assert(!(fdctrl->msr & FD_MSR_NONDMA)); 2295 assert(fdctrl->data_pos < FD_SECTOR_LEN); 2296 2297 if (pos == 0) { 2298 /* The first byte specifies the command. Now we start reading 2299 * as many parameters as this command requires. */ 2300 cmd = get_command(value); 2301 fdctrl->data_len = cmd->parameters + 1; 2302 if (cmd->parameters) { 2303 fdctrl->msr |= FD_MSR_RQM; 2304 } 2305 fdctrl->msr |= FD_MSR_CMDBUSY; 2306 } 2307 2308 if (fdctrl->data_pos == fdctrl->data_len) { 2309 /* We have all parameters now, execute the command */ 2310 fdctrl->phase = FD_PHASE_EXECUTION; 2311 2312 if (fdctrl->data_state & FD_STATE_FORMAT) { 2313 fdctrl_format_sector(fdctrl); 2314 break; 2315 } 2316 2317 cmd = get_command(fdctrl->fifo[0]); 2318 FLOPPY_DPRINTF("Calling handler for '%s'\n", cmd->name); 2319 cmd->handler(fdctrl, cmd->direction); 2320 } 2321 break; 2322 2323 case FD_PHASE_RESULT: 2324 default: 2325 abort(); 2326 } 2327 } 2328 2329 static void fdctrl_result_timer(void *opaque) 2330 { 2331 FDCtrl *fdctrl = opaque; 2332 FDrive *cur_drv = get_cur_drv(fdctrl); 2333 2334 /* Pretend we are spinning. 2335 * This is needed for Coherent, which uses READ ID to check for 2336 * sector interleaving. 2337 */ 2338 if (cur_drv->last_sect != 0) { 2339 cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1; 2340 } 2341 /* READ_ID can't automatically succeed! */ 2342 if ((fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) { 2343 FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n", 2344 fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate); 2345 fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00); 2346 } else { 2347 fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00); 2348 } 2349 } 2350 2351 /* Init functions */ 2352 2353 void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds) 2354 { 2355 DeviceState *dev; 2356 int i; 2357 2358 for (i = 0; i < MAX_FD; i++) { 2359 if (fds[i]) { 2360 dev = qdev_new("floppy"); 2361 qdev_prop_set_uint32(dev, "unit", i); 2362 qdev_prop_set_enum(dev, "drive-type", FLOPPY_DRIVE_TYPE_AUTO); 2363 qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(fds[i]), 2364 &error_fatal); 2365 qdev_realize_and_unref(dev, &bus->bus, &error_fatal); 2366 } 2367 } 2368 } 2369 2370 void fdctrl_init_sysbus(qemu_irq irq, int dma_chann, 2371 hwaddr mmio_base, DriveInfo **fds) 2372 { 2373 FDCtrl *fdctrl; 2374 DeviceState *dev; 2375 SysBusDevice *sbd; 2376 FDCtrlSysBus *sys; 2377 2378 dev = qdev_new("sysbus-fdc"); 2379 sys = SYSBUS_FDC(dev); 2380 fdctrl = &sys->state; 2381 fdctrl->dma_chann = dma_chann; /* FIXME */ 2382 sbd = SYS_BUS_DEVICE(dev); 2383 sysbus_realize_and_unref(sbd, &error_fatal); 2384 sysbus_connect_irq(sbd, 0, irq); 2385 sysbus_mmio_map(sbd, 0, mmio_base); 2386 2387 fdctrl_init_drives(&sys->state.bus, fds); 2388 } 2389 2390 void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base, 2391 DriveInfo **fds, qemu_irq *fdc_tc) 2392 { 2393 DeviceState *dev; 2394 FDCtrlSysBus *sys; 2395 2396 dev = qdev_new("sun-fdtwo"); 2397 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 2398 sys = SYSBUS_FDC(dev); 2399 sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq); 2400 sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base); 2401 *fdc_tc = qdev_get_gpio_in(dev, 0); 2402 2403 fdctrl_init_drives(&sys->state.bus, fds); 2404 } 2405 2406 void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl, Error **errp) 2407 { 2408 int i, j; 2409 FDrive *drive; 2410 static int command_tables_inited = 0; 2411 2412 if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) { 2413 error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'"); 2414 return; 2415 } 2416 2417 /* Fill 'command_to_handler' lookup table */ 2418 if (!command_tables_inited) { 2419 command_tables_inited = 1; 2420 for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) { 2421 for (j = 0; j < sizeof(command_to_handler); j++) { 2422 if ((j & handlers[i].mask) == handlers[i].value) { 2423 command_to_handler[j] = i; 2424 } 2425 } 2426 } 2427 } 2428 2429 FLOPPY_DPRINTF("init controller\n"); 2430 fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); 2431 memset(fdctrl->fifo, 0, FD_SECTOR_LEN); 2432 fdctrl->fifo_size = 512; 2433 fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 2434 fdctrl_result_timer, fdctrl); 2435 2436 fdctrl->version = 0x90; /* Intel 82078 controller */ 2437 fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ 2438 fdctrl->num_floppies = MAX_FD; 2439 2440 floppy_bus_create(fdctrl, &fdctrl->bus, dev); 2441 2442 for (i = 0; i < MAX_FD; i++) { 2443 drive = &fdctrl->drives[i]; 2444 drive->fdctrl = fdctrl; 2445 fd_init(drive); 2446 fd_revalidate(drive); 2447 } 2448 } 2449 2450 static void sysbus_fdc_initfn(Object *obj) 2451 { 2452 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 2453 FDCtrlSysBus *sys = SYSBUS_FDC(obj); 2454 FDCtrl *fdctrl = &sys->state; 2455 2456 fdctrl->dma_chann = -1; 2457 2458 memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl, 2459 "fdc", 0x08); 2460 sysbus_init_mmio(sbd, &fdctrl->iomem); 2461 } 2462 2463 static void sun4m_fdc_initfn(Object *obj) 2464 { 2465 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 2466 FDCtrlSysBus *sys = SYSBUS_FDC(obj); 2467 FDCtrl *fdctrl = &sys->state; 2468 2469 fdctrl->dma_chann = -1; 2470 2471 memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops, 2472 fdctrl, "fdctrl", 0x08); 2473 sysbus_init_mmio(sbd, &fdctrl->iomem); 2474 } 2475 2476 static void sysbus_fdc_common_initfn(Object *obj) 2477 { 2478 DeviceState *dev = DEVICE(obj); 2479 SysBusDevice *sbd = SYS_BUS_DEVICE(dev); 2480 FDCtrlSysBus *sys = SYSBUS_FDC(obj); 2481 FDCtrl *fdctrl = &sys->state; 2482 2483 qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */ 2484 2485 sysbus_init_irq(sbd, &fdctrl->irq); 2486 qdev_init_gpio_in(dev, fdctrl_handle_tc, 1); 2487 } 2488 2489 static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp) 2490 { 2491 FDCtrlSysBus *sys = SYSBUS_FDC(dev); 2492 FDCtrl *fdctrl = &sys->state; 2493 2494 fdctrl_realize_common(dev, fdctrl, errp); 2495 } 2496 2497 static const VMStateDescription vmstate_sysbus_fdc ={ 2498 .name = "fdc", 2499 .version_id = 2, 2500 .minimum_version_id = 2, 2501 .fields = (VMStateField[]) { 2502 VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl), 2503 VMSTATE_END_OF_LIST() 2504 } 2505 }; 2506 2507 static Property sysbus_fdc_properties[] = { 2508 DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type, 2509 FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, 2510 FloppyDriveType), 2511 DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type, 2512 FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, 2513 FloppyDriveType), 2514 DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback, 2515 FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type, 2516 FloppyDriveType), 2517 DEFINE_PROP_END_OF_LIST(), 2518 }; 2519 2520 static void sysbus_fdc_class_init(ObjectClass *klass, void *data) 2521 { 2522 DeviceClass *dc = DEVICE_CLASS(klass); 2523 2524 device_class_set_props(dc, sysbus_fdc_properties); 2525 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 2526 } 2527 2528 static const TypeInfo sysbus_fdc_info = { 2529 .name = "sysbus-fdc", 2530 .parent = TYPE_SYSBUS_FDC, 2531 .instance_init = sysbus_fdc_initfn, 2532 .class_init = sysbus_fdc_class_init, 2533 }; 2534 2535 static Property sun4m_fdc_properties[] = { 2536 DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type, 2537 FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type, 2538 FloppyDriveType), 2539 DEFINE_PROP_SIGNED("fallback", FDCtrlSysBus, state.fallback, 2540 FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type, 2541 FloppyDriveType), 2542 DEFINE_PROP_END_OF_LIST(), 2543 }; 2544 2545 static void sun4m_fdc_class_init(ObjectClass *klass, void *data) 2546 { 2547 DeviceClass *dc = DEVICE_CLASS(klass); 2548 2549 device_class_set_props(dc, sun4m_fdc_properties); 2550 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 2551 } 2552 2553 static const TypeInfo sun4m_fdc_info = { 2554 .name = "sun-fdtwo", 2555 .parent = TYPE_SYSBUS_FDC, 2556 .instance_init = sun4m_fdc_initfn, 2557 .class_init = sun4m_fdc_class_init, 2558 }; 2559 2560 static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data) 2561 { 2562 DeviceClass *dc = DEVICE_CLASS(klass); 2563 2564 dc->realize = sysbus_fdc_common_realize; 2565 dc->reset = fdctrl_external_reset_sysbus; 2566 dc->vmsd = &vmstate_sysbus_fdc; 2567 } 2568 2569 static const TypeInfo sysbus_fdc_type_info = { 2570 .name = TYPE_SYSBUS_FDC, 2571 .parent = TYPE_SYS_BUS_DEVICE, 2572 .instance_size = sizeof(FDCtrlSysBus), 2573 .instance_init = sysbus_fdc_common_initfn, 2574 .abstract = true, 2575 .class_init = sysbus_fdc_common_class_init, 2576 }; 2577 2578 static void fdc_register_types(void) 2579 { 2580 type_register_static(&sysbus_fdc_type_info); 2581 type_register_static(&sysbus_fdc_info); 2582 type_register_static(&sun4m_fdc_info); 2583 type_register_static(&floppy_bus_info); 2584 type_register_static(&floppy_drive_info); 2585 } 2586 2587 type_init(fdc_register_types) 2588