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