xref: /openbmc/qemu/hw/block/fdc.c (revision a00cfed0ed9c366a383fe39c2d283362ebaaefd3)
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"
69  OBJECT_DECLARE_SIMPLE_TYPE(FloppyBus, FLOPPY_BUS)
70  
71  typedef struct FDCtrl FDCtrl;
72  typedef struct FDrive FDrive;
73  static FDrive *get_drv(FDCtrl *fdctrl, int unit);
74  
75  struct FloppyBus {
76      BusState bus;
77      FDCtrl *fdc;
78  };
79  
80  static const TypeInfo floppy_bus_info = {
81      .name = TYPE_FLOPPY_BUS,
82      .parent = TYPE_BUS,
83      .instance_size = sizeof(FloppyBus),
84  };
85  
86  static 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  
96  typedef 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  
103  typedef enum FDriveSize {
104      FDRIVE_SIZE_UNKNOWN,
105      FDRIVE_SIZE_350,
106      FDRIVE_SIZE_525,
107  } FDriveSize;
108  
109  typedef 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. */
121  static 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  
168  static 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 */
190  typedef enum FDiskFlags {
191      FDISK_DBL_SIDES  = 0x01,
192  } FDiskFlags;
193  
194  struct 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  
219  static 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   */
230  static void fd_empty_seek_hack(FDrive *drv)
231  {
232      drv->last_sect = 0xFF;
233      drv->max_track = 0xFF;
234  }
235  
236  static 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  
250  static 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 */
257  static 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 */
264  static 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   */
277  static 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 */
329  static 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   */
341  static 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  
425  static 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 */
441  static 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  
474  static 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  
493  static const BlockDevOps fd_block_ops = {
494      .change_media_cb = fd_change_cb,
495  };
496  
497  
498  #define TYPE_FLOPPY_DRIVE "floppy"
499  OBJECT_DECLARE_SIMPLE_TYPE(FloppyDrive, FLOPPY_DRIVE)
500  
501  struct FloppyDrive {
502      DeviceState     qdev;
503      uint32_t        unit;
504      BlockConf       conf;
505      FloppyDriveType type;
506  };
507  
508  static 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  
517  static 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  
609  static 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  
619  static 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  
629  static void fdctrl_reset(FDCtrl *fdctrl, int do_irq);
630  static void fdctrl_to_command_phase(FDCtrl *fdctrl);
631  static int fdctrl_transfer_handler (void *opaque, int nchan,
632                                      int dma_pos, int dma_len);
633  static void fdctrl_raise_irq(FDCtrl *fdctrl);
634  static FDrive *get_cur_drv(FDCtrl *fdctrl);
635  
636  static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl);
637  static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl);
638  static uint32_t fdctrl_read_dor(FDCtrl *fdctrl);
639  static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value);
640  static uint32_t fdctrl_read_tape(FDCtrl *fdctrl);
641  static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value);
642  static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl);
643  static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value);
644  static uint32_t fdctrl_read_data(FDCtrl *fdctrl);
645  static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value);
646  static uint32_t fdctrl_read_dir(FDCtrl *fdctrl);
647  static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value);
648  
649  enum {
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  
658  enum {
659      FD_STATE_MULTI  = 0x01,	/* multi track flag */
660      FD_STATE_FORMAT = 0x02,	/* format flag */
661  };
662  
663  enum {
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  
675  enum {
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  
708  enum {
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  
716  enum {
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  
727  enum {
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  
733  enum {
734      FD_SR2_SNS      = 0x04, /* Scan not satisfied */
735      FD_SR2_SEH      = 0x08, /* Scan equal hit */
736  };
737  
738  enum {
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  
749  enum {
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  
758  enum {
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  
772  enum {
773  #if MAX_FD == 4
774      FD_TDR_BOOTSEL  = 0x0c,
775  #else
776      FD_TDR_BOOTSEL  = 0x04,
777  #endif
778  };
779  
780  enum {
781      FD_DSR_DRATEMASK= 0x03,
782      FD_DSR_PWRDOWN  = 0x40,
783      FD_DSR_SWRESET  = 0x80,
784  };
785  
786  enum {
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  
797  enum {
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   */
819  enum {
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  
831  struct 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          BlockBackend *blk;
874          FloppyDriveType type;
875      } qdev_for_drives[MAX_FD];
876      int reset_sensei;
877      uint32_t check_media_rate;
878      FloppyDriveType fallback; /* type=auto failure fallback */
879      /* Timers state */
880      uint8_t timer0;
881      uint8_t timer1;
882      PortioList portio_list;
883  };
884  
885  static FloppyDriveType get_fallback_drive_type(FDrive *drv)
886  {
887      return drv->fdctrl->fallback;
888  }
889  
890  #define TYPE_SYSBUS_FDC "base-sysbus-fdc"
891  OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlSysBus, SYSBUS_FDC)
892  
893  struct FDCtrlSysBus {
894      /*< private >*/
895      SysBusDevice parent_obj;
896      /*< public >*/
897  
898      struct FDCtrl state;
899  };
900  
901  OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlISABus, ISA_FDC)
902  
903  struct FDCtrlISABus {
904      ISADevice parent_obj;
905  
906      uint32_t iobase;
907      uint32_t irq;
908      uint32_t dma;
909      struct FDCtrl state;
910      int32_t bootindexA;
911      int32_t bootindexB;
912  };
913  
914  static uint32_t fdctrl_read (void *opaque, uint32_t reg)
915  {
916      FDCtrl *fdctrl = opaque;
917      uint32_t retval;
918  
919      reg &= 7;
920      switch (reg) {
921      case FD_REG_SRA:
922          retval = fdctrl_read_statusA(fdctrl);
923          break;
924      case FD_REG_SRB:
925          retval = fdctrl_read_statusB(fdctrl);
926          break;
927      case FD_REG_DOR:
928          retval = fdctrl_read_dor(fdctrl);
929          break;
930      case FD_REG_TDR:
931          retval = fdctrl_read_tape(fdctrl);
932          break;
933      case FD_REG_MSR:
934          retval = fdctrl_read_main_status(fdctrl);
935          break;
936      case FD_REG_FIFO:
937          retval = fdctrl_read_data(fdctrl);
938          break;
939      case FD_REG_DIR:
940          retval = fdctrl_read_dir(fdctrl);
941          break;
942      default:
943          retval = (uint32_t)(-1);
944          break;
945      }
946      trace_fdc_ioport_read(reg, retval);
947  
948      return retval;
949  }
950  
951  static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
952  {
953      FDCtrl *fdctrl = opaque;
954  
955      reg &= 7;
956      trace_fdc_ioport_write(reg, value);
957      switch (reg) {
958      case FD_REG_DOR:
959          fdctrl_write_dor(fdctrl, value);
960          break;
961      case FD_REG_TDR:
962          fdctrl_write_tape(fdctrl, value);
963          break;
964      case FD_REG_DSR:
965          fdctrl_write_rate(fdctrl, value);
966          break;
967      case FD_REG_FIFO:
968          fdctrl_write_data(fdctrl, value);
969          break;
970      case FD_REG_CCR:
971          fdctrl_write_ccr(fdctrl, value);
972          break;
973      default:
974          break;
975      }
976  }
977  
978  static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg,
979                                   unsigned ize)
980  {
981      return fdctrl_read(opaque, (uint32_t)reg);
982  }
983  
984  static void fdctrl_write_mem (void *opaque, hwaddr reg,
985                                uint64_t value, unsigned size)
986  {
987      fdctrl_write(opaque, (uint32_t)reg, value);
988  }
989  
990  static const MemoryRegionOps fdctrl_mem_ops = {
991      .read = fdctrl_read_mem,
992      .write = fdctrl_write_mem,
993      .endianness = DEVICE_NATIVE_ENDIAN,
994  };
995  
996  static const MemoryRegionOps fdctrl_mem_strict_ops = {
997      .read = fdctrl_read_mem,
998      .write = fdctrl_write_mem,
999      .endianness = DEVICE_NATIVE_ENDIAN,
1000      .valid = {
1001          .min_access_size = 1,
1002          .max_access_size = 1,
1003      },
1004  };
1005  
1006  static bool fdrive_media_changed_needed(void *opaque)
1007  {
1008      FDrive *drive = opaque;
1009  
1010      return (drive->blk != NULL && drive->media_changed != 1);
1011  }
1012  
1013  static const VMStateDescription vmstate_fdrive_media_changed = {
1014      .name = "fdrive/media_changed",
1015      .version_id = 1,
1016      .minimum_version_id = 1,
1017      .needed = fdrive_media_changed_needed,
1018      .fields = (VMStateField[]) {
1019          VMSTATE_UINT8(media_changed, FDrive),
1020          VMSTATE_END_OF_LIST()
1021      }
1022  };
1023  
1024  static bool fdrive_media_rate_needed(void *opaque)
1025  {
1026      FDrive *drive = opaque;
1027  
1028      return drive->fdctrl->check_media_rate;
1029  }
1030  
1031  static const VMStateDescription vmstate_fdrive_media_rate = {
1032      .name = "fdrive/media_rate",
1033      .version_id = 1,
1034      .minimum_version_id = 1,
1035      .needed = fdrive_media_rate_needed,
1036      .fields = (VMStateField[]) {
1037          VMSTATE_UINT8(media_rate, FDrive),
1038          VMSTATE_END_OF_LIST()
1039      }
1040  };
1041  
1042  static bool fdrive_perpendicular_needed(void *opaque)
1043  {
1044      FDrive *drive = opaque;
1045  
1046      return drive->perpendicular != 0;
1047  }
1048  
1049  static const VMStateDescription vmstate_fdrive_perpendicular = {
1050      .name = "fdrive/perpendicular",
1051      .version_id = 1,
1052      .minimum_version_id = 1,
1053      .needed = fdrive_perpendicular_needed,
1054      .fields = (VMStateField[]) {
1055          VMSTATE_UINT8(perpendicular, FDrive),
1056          VMSTATE_END_OF_LIST()
1057      }
1058  };
1059  
1060  static int fdrive_post_load(void *opaque, int version_id)
1061  {
1062      fd_revalidate(opaque);
1063      return 0;
1064  }
1065  
1066  static const VMStateDescription vmstate_fdrive = {
1067      .name = "fdrive",
1068      .version_id = 1,
1069      .minimum_version_id = 1,
1070      .post_load = fdrive_post_load,
1071      .fields = (VMStateField[]) {
1072          VMSTATE_UINT8(head, FDrive),
1073          VMSTATE_UINT8(track, FDrive),
1074          VMSTATE_UINT8(sect, FDrive),
1075          VMSTATE_END_OF_LIST()
1076      },
1077      .subsections = (const VMStateDescription*[]) {
1078          &vmstate_fdrive_media_changed,
1079          &vmstate_fdrive_media_rate,
1080          &vmstate_fdrive_perpendicular,
1081          NULL
1082      }
1083  };
1084  
1085  /*
1086   * Reconstructs the phase from register values according to the logic that was
1087   * implemented in qemu 2.3. This is the default value that is used if the phase
1088   * subsection is not present on migration.
1089   *
1090   * Don't change this function to reflect newer qemu versions, it is part of
1091   * the migration ABI.
1092   */
1093  static int reconstruct_phase(FDCtrl *fdctrl)
1094  {
1095      if (fdctrl->msr & FD_MSR_NONDMA) {
1096          return FD_PHASE_EXECUTION;
1097      } else if ((fdctrl->msr & FD_MSR_RQM) == 0) {
1098          /* qemu 2.3 disabled RQM only during DMA transfers */
1099          return FD_PHASE_EXECUTION;
1100      } else if (fdctrl->msr & FD_MSR_DIO) {
1101          return FD_PHASE_RESULT;
1102      } else {
1103          return FD_PHASE_COMMAND;
1104      }
1105  }
1106  
1107  static int fdc_pre_save(void *opaque)
1108  {
1109      FDCtrl *s = opaque;
1110  
1111      s->dor_vmstate = s->dor | GET_CUR_DRV(s);
1112  
1113      return 0;
1114  }
1115  
1116  static int fdc_pre_load(void *opaque)
1117  {
1118      FDCtrl *s = opaque;
1119      s->phase = FD_PHASE_RECONSTRUCT;
1120      return 0;
1121  }
1122  
1123  static int fdc_post_load(void *opaque, int version_id)
1124  {
1125      FDCtrl *s = opaque;
1126  
1127      SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK);
1128      s->dor = s->dor_vmstate & ~FD_DOR_SELMASK;
1129  
1130      if (s->phase == FD_PHASE_RECONSTRUCT) {
1131          s->phase = reconstruct_phase(s);
1132      }
1133  
1134      return 0;
1135  }
1136  
1137  static bool fdc_reset_sensei_needed(void *opaque)
1138  {
1139      FDCtrl *s = opaque;
1140  
1141      return s->reset_sensei != 0;
1142  }
1143  
1144  static const VMStateDescription vmstate_fdc_reset_sensei = {
1145      .name = "fdc/reset_sensei",
1146      .version_id = 1,
1147      .minimum_version_id = 1,
1148      .needed = fdc_reset_sensei_needed,
1149      .fields = (VMStateField[]) {
1150          VMSTATE_INT32(reset_sensei, FDCtrl),
1151          VMSTATE_END_OF_LIST()
1152      }
1153  };
1154  
1155  static bool fdc_result_timer_needed(void *opaque)
1156  {
1157      FDCtrl *s = opaque;
1158  
1159      return timer_pending(s->result_timer);
1160  }
1161  
1162  static const VMStateDescription vmstate_fdc_result_timer = {
1163      .name = "fdc/result_timer",
1164      .version_id = 1,
1165      .minimum_version_id = 1,
1166      .needed = fdc_result_timer_needed,
1167      .fields = (VMStateField[]) {
1168          VMSTATE_TIMER_PTR(result_timer, FDCtrl),
1169          VMSTATE_END_OF_LIST()
1170      }
1171  };
1172  
1173  static bool fdc_phase_needed(void *opaque)
1174  {
1175      FDCtrl *fdctrl = opaque;
1176  
1177      return reconstruct_phase(fdctrl) != fdctrl->phase;
1178  }
1179  
1180  static const VMStateDescription vmstate_fdc_phase = {
1181      .name = "fdc/phase",
1182      .version_id = 1,
1183      .minimum_version_id = 1,
1184      .needed = fdc_phase_needed,
1185      .fields = (VMStateField[]) {
1186          VMSTATE_UINT8(phase, FDCtrl),
1187          VMSTATE_END_OF_LIST()
1188      }
1189  };
1190  
1191  static const VMStateDescription vmstate_fdc = {
1192      .name = "fdc",
1193      .version_id = 2,
1194      .minimum_version_id = 2,
1195      .pre_save = fdc_pre_save,
1196      .pre_load = fdc_pre_load,
1197      .post_load = fdc_post_load,
1198      .fields = (VMStateField[]) {
1199          /* Controller State */
1200          VMSTATE_UINT8(sra, FDCtrl),
1201          VMSTATE_UINT8(srb, FDCtrl),
1202          VMSTATE_UINT8(dor_vmstate, FDCtrl),
1203          VMSTATE_UINT8(tdr, FDCtrl),
1204          VMSTATE_UINT8(dsr, FDCtrl),
1205          VMSTATE_UINT8(msr, FDCtrl),
1206          VMSTATE_UINT8(status0, FDCtrl),
1207          VMSTATE_UINT8(status1, FDCtrl),
1208          VMSTATE_UINT8(status2, FDCtrl),
1209          /* Command FIFO */
1210          VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8,
1211                               uint8_t),
1212          VMSTATE_UINT32(data_pos, FDCtrl),
1213          VMSTATE_UINT32(data_len, FDCtrl),
1214          VMSTATE_UINT8(data_state, FDCtrl),
1215          VMSTATE_UINT8(data_dir, FDCtrl),
1216          VMSTATE_UINT8(eot, FDCtrl),
1217          /* States kept only to be returned back */
1218          VMSTATE_UINT8(timer0, FDCtrl),
1219          VMSTATE_UINT8(timer1, FDCtrl),
1220          VMSTATE_UINT8(precomp_trk, FDCtrl),
1221          VMSTATE_UINT8(config, FDCtrl),
1222          VMSTATE_UINT8(lock, FDCtrl),
1223          VMSTATE_UINT8(pwrd, FDCtrl),
1224          VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl, NULL),
1225          VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
1226                               vmstate_fdrive, FDrive),
1227          VMSTATE_END_OF_LIST()
1228      },
1229      .subsections = (const VMStateDescription*[]) {
1230          &vmstate_fdc_reset_sensei,
1231          &vmstate_fdc_result_timer,
1232          &vmstate_fdc_phase,
1233          NULL
1234      }
1235  };
1236  
1237  static void fdctrl_external_reset_sysbus(DeviceState *d)
1238  {
1239      FDCtrlSysBus *sys = SYSBUS_FDC(d);
1240      FDCtrl *s = &sys->state;
1241  
1242      fdctrl_reset(s, 0);
1243  }
1244  
1245  static void fdctrl_external_reset_isa(DeviceState *d)
1246  {
1247      FDCtrlISABus *isa = ISA_FDC(d);
1248      FDCtrl *s = &isa->state;
1249  
1250      fdctrl_reset(s, 0);
1251  }
1252  
1253  static void fdctrl_handle_tc(void *opaque, int irq, int level)
1254  {
1255      //FDCtrl *s = opaque;
1256  
1257      if (level) {
1258          // XXX
1259          FLOPPY_DPRINTF("TC pulsed\n");
1260      }
1261  }
1262  
1263  /* Change IRQ state */
1264  static void fdctrl_reset_irq(FDCtrl *fdctrl)
1265  {
1266      fdctrl->status0 = 0;
1267      if (!(fdctrl->sra & FD_SRA_INTPEND))
1268          return;
1269      FLOPPY_DPRINTF("Reset interrupt\n");
1270      qemu_set_irq(fdctrl->irq, 0);
1271      fdctrl->sra &= ~FD_SRA_INTPEND;
1272  }
1273  
1274  static void fdctrl_raise_irq(FDCtrl *fdctrl)
1275  {
1276      if (!(fdctrl->sra & FD_SRA_INTPEND)) {
1277          qemu_set_irq(fdctrl->irq, 1);
1278          fdctrl->sra |= FD_SRA_INTPEND;
1279      }
1280  
1281      fdctrl->reset_sensei = 0;
1282      FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
1283  }
1284  
1285  /* Reset controller */
1286  static void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
1287  {
1288      int i;
1289  
1290      FLOPPY_DPRINTF("reset controller\n");
1291      fdctrl_reset_irq(fdctrl);
1292      /* Initialise controller */
1293      fdctrl->sra = 0;
1294      fdctrl->srb = 0xc0;
1295      if (!fdctrl->drives[1].blk) {
1296          fdctrl->sra |= FD_SRA_nDRV2;
1297      }
1298      fdctrl->cur_drv = 0;
1299      fdctrl->dor = FD_DOR_nRESET;
1300      fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
1301      fdctrl->msr = FD_MSR_RQM;
1302      fdctrl->reset_sensei = 0;
1303      timer_del(fdctrl->result_timer);
1304      /* FIFO state */
1305      fdctrl->data_pos = 0;
1306      fdctrl->data_len = 0;
1307      fdctrl->data_state = 0;
1308      fdctrl->data_dir = FD_DIR_WRITE;
1309      for (i = 0; i < MAX_FD; i++)
1310          fd_recalibrate(&fdctrl->drives[i]);
1311      fdctrl_to_command_phase(fdctrl);
1312      if (do_irq) {
1313          fdctrl->status0 |= FD_SR0_RDYCHG;
1314          fdctrl_raise_irq(fdctrl);
1315          fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
1316      }
1317  }
1318  
1319  static inline FDrive *drv0(FDCtrl *fdctrl)
1320  {
1321      return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
1322  }
1323  
1324  static inline FDrive *drv1(FDCtrl *fdctrl)
1325  {
1326      if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
1327          return &fdctrl->drives[1];
1328      else
1329          return &fdctrl->drives[0];
1330  }
1331  
1332  #if MAX_FD == 4
1333  static inline FDrive *drv2(FDCtrl *fdctrl)
1334  {
1335      if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
1336          return &fdctrl->drives[2];
1337      else
1338          return &fdctrl->drives[1];
1339  }
1340  
1341  static inline FDrive *drv3(FDCtrl *fdctrl)
1342  {
1343      if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
1344          return &fdctrl->drives[3];
1345      else
1346          return &fdctrl->drives[2];
1347  }
1348  #endif
1349  
1350  static FDrive *get_drv(FDCtrl *fdctrl, int unit)
1351  {
1352      switch (unit) {
1353          case 0: return drv0(fdctrl);
1354          case 1: return drv1(fdctrl);
1355  #if MAX_FD == 4
1356          case 2: return drv2(fdctrl);
1357          case 3: return drv3(fdctrl);
1358  #endif
1359          default: return NULL;
1360      }
1361  }
1362  
1363  static FDrive *get_cur_drv(FDCtrl *fdctrl)
1364  {
1365      return get_drv(fdctrl, fdctrl->cur_drv);
1366  }
1367  
1368  /* Status A register : 0x00 (read-only) */
1369  static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
1370  {
1371      uint32_t retval = fdctrl->sra;
1372  
1373      FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
1374  
1375      return retval;
1376  }
1377  
1378  /* Status B register : 0x01 (read-only) */
1379  static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl)
1380  {
1381      uint32_t retval = fdctrl->srb;
1382  
1383      FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
1384  
1385      return retval;
1386  }
1387  
1388  /* Digital output register : 0x02 */
1389  static uint32_t fdctrl_read_dor(FDCtrl *fdctrl)
1390  {
1391      uint32_t retval = fdctrl->dor;
1392  
1393      /* Selected drive */
1394      retval |= fdctrl->cur_drv;
1395      FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
1396  
1397      return retval;
1398  }
1399  
1400  static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value)
1401  {
1402      FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
1403  
1404      /* Motors */
1405      if (value & FD_DOR_MOTEN0)
1406          fdctrl->srb |= FD_SRB_MTR0;
1407      else
1408          fdctrl->srb &= ~FD_SRB_MTR0;
1409      if (value & FD_DOR_MOTEN1)
1410          fdctrl->srb |= FD_SRB_MTR1;
1411      else
1412          fdctrl->srb &= ~FD_SRB_MTR1;
1413  
1414      /* Drive */
1415      if (value & 1)
1416          fdctrl->srb |= FD_SRB_DR0;
1417      else
1418          fdctrl->srb &= ~FD_SRB_DR0;
1419  
1420      /* Reset */
1421      if (!(value & FD_DOR_nRESET)) {
1422          if (fdctrl->dor & FD_DOR_nRESET) {
1423              FLOPPY_DPRINTF("controller enter RESET state\n");
1424          }
1425      } else {
1426          if (!(fdctrl->dor & FD_DOR_nRESET)) {
1427              FLOPPY_DPRINTF("controller out of RESET state\n");
1428              fdctrl_reset(fdctrl, 1);
1429              fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1430          }
1431      }
1432      /* Selected drive */
1433      fdctrl->cur_drv = value & FD_DOR_SELMASK;
1434  
1435      fdctrl->dor = value;
1436  }
1437  
1438  /* Tape drive register : 0x03 */
1439  static uint32_t fdctrl_read_tape(FDCtrl *fdctrl)
1440  {
1441      uint32_t retval = fdctrl->tdr;
1442  
1443      FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
1444  
1445      return retval;
1446  }
1447  
1448  static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value)
1449  {
1450      /* Reset mode */
1451      if (!(fdctrl->dor & FD_DOR_nRESET)) {
1452          FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1453          return;
1454      }
1455      FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
1456      /* Disk boot selection indicator */
1457      fdctrl->tdr = value & FD_TDR_BOOTSEL;
1458      /* Tape indicators: never allow */
1459  }
1460  
1461  /* Main status register : 0x04 (read) */
1462  static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
1463  {
1464      uint32_t retval = fdctrl->msr;
1465  
1466      fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1467      fdctrl->dor |= FD_DOR_nRESET;
1468  
1469      FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
1470  
1471      return retval;
1472  }
1473  
1474  /* Data select rate register : 0x04 (write) */
1475  static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value)
1476  {
1477      /* Reset mode */
1478      if (!(fdctrl->dor & FD_DOR_nRESET)) {
1479          FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1480          return;
1481      }
1482      FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
1483      /* Reset: autoclear */
1484      if (value & FD_DSR_SWRESET) {
1485          fdctrl->dor &= ~FD_DOR_nRESET;
1486          fdctrl_reset(fdctrl, 1);
1487          fdctrl->dor |= FD_DOR_nRESET;
1488      }
1489      if (value & FD_DSR_PWRDOWN) {
1490          fdctrl_reset(fdctrl, 1);
1491      }
1492      fdctrl->dsr = value;
1493  }
1494  
1495  /* Configuration control register: 0x07 (write) */
1496  static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
1497  {
1498      /* Reset mode */
1499      if (!(fdctrl->dor & FD_DOR_nRESET)) {
1500          FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1501          return;
1502      }
1503      FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
1504  
1505      /* Only the rate selection bits used in AT mode, and we
1506       * store those in the DSR.
1507       */
1508      fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) |
1509                    (value & FD_DSR_DRATEMASK);
1510  }
1511  
1512  static int fdctrl_media_changed(FDrive *drv)
1513  {
1514      return drv->media_changed;
1515  }
1516  
1517  /* Digital input register : 0x07 (read-only) */
1518  static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
1519  {
1520      uint32_t retval = 0;
1521  
1522      if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
1523          retval |= FD_DIR_DSKCHG;
1524      }
1525      if (retval != 0) {
1526          FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
1527      }
1528  
1529      return retval;
1530  }
1531  
1532  /* Clear the FIFO and update the state for receiving the next command */
1533  static void fdctrl_to_command_phase(FDCtrl *fdctrl)
1534  {
1535      fdctrl->phase = FD_PHASE_COMMAND;
1536      fdctrl->data_dir = FD_DIR_WRITE;
1537      fdctrl->data_pos = 0;
1538      fdctrl->data_len = 1; /* Accept command byte, adjust for params later */
1539      fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO);
1540      fdctrl->msr |= FD_MSR_RQM;
1541  }
1542  
1543  /* Update the state to allow the guest to read out the command status.
1544   * @fifo_len is the number of result bytes to be read out. */
1545  static void fdctrl_to_result_phase(FDCtrl *fdctrl, int fifo_len)
1546  {
1547      fdctrl->phase = FD_PHASE_RESULT;
1548      fdctrl->data_dir = FD_DIR_READ;
1549      fdctrl->data_len = fifo_len;
1550      fdctrl->data_pos = 0;
1551      fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
1552  }
1553  
1554  /* Set an error: unimplemented/unknown command */
1555  static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
1556  {
1557      qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
1558                    fdctrl->fifo[0]);
1559      fdctrl->fifo[0] = FD_SR0_INVCMD;
1560      fdctrl_to_result_phase(fdctrl, 1);
1561  }
1562  
1563  /* Seek to next sector
1564   * returns 0 when end of track reached (for DBL_SIDES on head 1)
1565   * otherwise returns 1
1566   */
1567  static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv)
1568  {
1569      FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n",
1570                     cur_drv->head, cur_drv->track, cur_drv->sect,
1571                     fd_sector(cur_drv));
1572      /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
1573         error in fact */
1574      uint8_t new_head = cur_drv->head;
1575      uint8_t new_track = cur_drv->track;
1576      uint8_t new_sect = cur_drv->sect;
1577  
1578      int ret = 1;
1579  
1580      if (new_sect >= cur_drv->last_sect ||
1581          new_sect == fdctrl->eot) {
1582          new_sect = 1;
1583          if (FD_MULTI_TRACK(fdctrl->data_state)) {
1584              if (new_head == 0 &&
1585                  (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
1586                  new_head = 1;
1587              } else {
1588                  new_head = 0;
1589                  new_track++;
1590                  fdctrl->status0 |= FD_SR0_SEEK;
1591                  if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) {
1592                      ret = 0;
1593                  }
1594              }
1595          } else {
1596              fdctrl->status0 |= FD_SR0_SEEK;
1597              new_track++;
1598              ret = 0;
1599          }
1600          if (ret == 1) {
1601              FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
1602                      new_head, new_track, new_sect, fd_sector(cur_drv));
1603          }
1604      } else {
1605          new_sect++;
1606      }
1607      fd_seek(cur_drv, new_head, new_track, new_sect, 1);
1608      return ret;
1609  }
1610  
1611  /* Callback for transfer end (stop or abort) */
1612  static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
1613                                   uint8_t status1, uint8_t status2)
1614  {
1615      FDrive *cur_drv;
1616      cur_drv = get_cur_drv(fdctrl);
1617  
1618      fdctrl->status0 &= ~(FD_SR0_DS0 | FD_SR0_DS1 | FD_SR0_HEAD);
1619      fdctrl->status0 |= GET_CUR_DRV(fdctrl);
1620      if (cur_drv->head) {
1621          fdctrl->status0 |= FD_SR0_HEAD;
1622      }
1623      fdctrl->status0 |= status0;
1624  
1625      FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
1626                     status0, status1, status2, fdctrl->status0);
1627      fdctrl->fifo[0] = fdctrl->status0;
1628      fdctrl->fifo[1] = status1;
1629      fdctrl->fifo[2] = status2;
1630      fdctrl->fifo[3] = cur_drv->track;
1631      fdctrl->fifo[4] = cur_drv->head;
1632      fdctrl->fifo[5] = cur_drv->sect;
1633      fdctrl->fifo[6] = FD_SECTOR_SC;
1634      fdctrl->data_dir = FD_DIR_READ;
1635      if (fdctrl->dma_chann != -1 && !(fdctrl->msr & FD_MSR_NONDMA)) {
1636          IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
1637          k->release_DREQ(fdctrl->dma, fdctrl->dma_chann);
1638      }
1639      fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
1640      fdctrl->msr &= ~FD_MSR_NONDMA;
1641  
1642      fdctrl_to_result_phase(fdctrl, 7);
1643      fdctrl_raise_irq(fdctrl);
1644  }
1645  
1646  /* Prepare a data transfer (either DMA or FIFO) */
1647  static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
1648  {
1649      FDrive *cur_drv;
1650      uint8_t kh, kt, ks;
1651  
1652      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
1653      cur_drv = get_cur_drv(fdctrl);
1654      kt = fdctrl->fifo[2];
1655      kh = fdctrl->fifo[3];
1656      ks = fdctrl->fifo[4];
1657      FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
1658                     GET_CUR_DRV(fdctrl), kh, kt, ks,
1659                     fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
1660                                    NUM_SIDES(cur_drv)));
1661      switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
1662      case 2:
1663          /* sect too big */
1664          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1665          fdctrl->fifo[3] = kt;
1666          fdctrl->fifo[4] = kh;
1667          fdctrl->fifo[5] = ks;
1668          return;
1669      case 3:
1670          /* track too big */
1671          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
1672          fdctrl->fifo[3] = kt;
1673          fdctrl->fifo[4] = kh;
1674          fdctrl->fifo[5] = ks;
1675          return;
1676      case 4:
1677          /* No seek enabled */
1678          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1679          fdctrl->fifo[3] = kt;
1680          fdctrl->fifo[4] = kh;
1681          fdctrl->fifo[5] = ks;
1682          return;
1683      case 1:
1684          fdctrl->status0 |= FD_SR0_SEEK;
1685          break;
1686      default:
1687          break;
1688      }
1689  
1690      /* Check the data rate. If the programmed data rate does not match
1691       * the currently inserted medium, the operation has to fail. */
1692      if (fdctrl->check_media_rate &&
1693          (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
1694          FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
1695                         fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
1696          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
1697          fdctrl->fifo[3] = kt;
1698          fdctrl->fifo[4] = kh;
1699          fdctrl->fifo[5] = ks;
1700          return;
1701      }
1702  
1703      /* Set the FIFO state */
1704      fdctrl->data_dir = direction;
1705      fdctrl->data_pos = 0;
1706      assert(fdctrl->msr & FD_MSR_CMDBUSY);
1707      if (fdctrl->fifo[0] & 0x80)
1708          fdctrl->data_state |= FD_STATE_MULTI;
1709      else
1710          fdctrl->data_state &= ~FD_STATE_MULTI;
1711      if (fdctrl->fifo[5] == 0) {
1712          fdctrl->data_len = fdctrl->fifo[8];
1713      } else {
1714          int tmp;
1715          fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
1716          tmp = (fdctrl->fifo[6] - ks + 1);
1717          if (fdctrl->fifo[0] & 0x80)
1718              tmp += fdctrl->fifo[6];
1719          fdctrl->data_len *= tmp;
1720      }
1721      fdctrl->eot = fdctrl->fifo[6];
1722      if (fdctrl->dor & FD_DOR_DMAEN) {
1723          /* DMA transfer is enabled. */
1724          IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
1725  
1726          FLOPPY_DPRINTF("direction=%d (%d - %d)\n",
1727                         direction, (128 << fdctrl->fifo[5]) *
1728                         (cur_drv->last_sect - ks + 1), fdctrl->data_len);
1729  
1730          /* No access is allowed until DMA transfer has completed */
1731          fdctrl->msr &= ~FD_MSR_RQM;
1732          if (direction != FD_DIR_VERIFY) {
1733              /*
1734               * Now, we just have to wait for the DMA controller to
1735               * recall us...
1736               */
1737              k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
1738              k->schedule(fdctrl->dma);
1739          } else {
1740              /* Start transfer */
1741              fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
1742                      fdctrl->data_len);
1743          }
1744          return;
1745      }
1746      FLOPPY_DPRINTF("start non-DMA transfer\n");
1747      fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
1748      if (direction != FD_DIR_WRITE)
1749          fdctrl->msr |= FD_MSR_DIO;
1750      /* IO based transfer: calculate len */
1751      fdctrl_raise_irq(fdctrl);
1752  }
1753  
1754  /* Prepare a transfer of deleted data */
1755  static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
1756  {
1757      qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
1758  
1759      /* We don't handle deleted data,
1760       * so we don't return *ANYTHING*
1761       */
1762      fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1763  }
1764  
1765  /* handlers for DMA transfers */
1766  static int fdctrl_transfer_handler (void *opaque, int nchan,
1767                                      int dma_pos, int dma_len)
1768  {
1769      FDCtrl *fdctrl;
1770      FDrive *cur_drv;
1771      int len, start_pos, rel_pos;
1772      uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
1773      IsaDmaClass *k;
1774  
1775      fdctrl = opaque;
1776      if (fdctrl->msr & FD_MSR_RQM) {
1777          FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
1778          return 0;
1779      }
1780      k = ISADMA_GET_CLASS(fdctrl->dma);
1781      cur_drv = get_cur_drv(fdctrl);
1782      if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
1783          fdctrl->data_dir == FD_DIR_SCANH)
1784          status2 = FD_SR2_SNS;
1785      if (dma_len > fdctrl->data_len)
1786          dma_len = fdctrl->data_len;
1787      if (cur_drv->blk == NULL) {
1788          if (fdctrl->data_dir == FD_DIR_WRITE)
1789              fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1790          else
1791              fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1792          len = 0;
1793          goto transfer_error;
1794      }
1795      rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
1796      for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
1797          len = dma_len - fdctrl->data_pos;
1798          if (len + rel_pos > FD_SECTOR_LEN)
1799              len = FD_SECTOR_LEN - rel_pos;
1800          FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
1801                         "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
1802                         fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head,
1803                         cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
1804                         fd_sector(cur_drv) * FD_SECTOR_LEN);
1805          if (fdctrl->data_dir != FD_DIR_WRITE ||
1806              len < FD_SECTOR_LEN || rel_pos != 0) {
1807              /* READ & SCAN commands and realign to a sector for WRITE */
1808              if (blk_pread(cur_drv->blk, fd_offset(cur_drv),
1809                            fdctrl->fifo, BDRV_SECTOR_SIZE) < 0) {
1810                  FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
1811                                 fd_sector(cur_drv));
1812                  /* Sure, image size is too small... */
1813                  memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
1814              }
1815          }
1816          switch (fdctrl->data_dir) {
1817          case FD_DIR_READ:
1818              /* READ commands */
1819              k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
1820                              fdctrl->data_pos, len);
1821              break;
1822          case FD_DIR_WRITE:
1823              /* WRITE commands */
1824              if (cur_drv->ro) {
1825                  /* Handle readonly medium early, no need to do DMA, touch the
1826                   * LED or attempt any writes. A real floppy doesn't attempt
1827                   * to write to readonly media either. */
1828                  fdctrl_stop_transfer(fdctrl,
1829                                       FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
1830                                       0x00);
1831                  goto transfer_error;
1832              }
1833  
1834              k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
1835                             fdctrl->data_pos, len);
1836              if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv),
1837                             fdctrl->fifo, BDRV_SECTOR_SIZE, 0) < 0) {
1838                  FLOPPY_DPRINTF("error writing sector %d\n",
1839                                 fd_sector(cur_drv));
1840                  fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1841                  goto transfer_error;
1842              }
1843              break;
1844          case FD_DIR_VERIFY:
1845              /* VERIFY commands */
1846              break;
1847          default:
1848              /* SCAN commands */
1849              {
1850                  uint8_t tmpbuf[FD_SECTOR_LEN];
1851                  int ret;
1852                  k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos,
1853                                 len);
1854                  ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
1855                  if (ret == 0) {
1856                      status2 = FD_SR2_SEH;
1857                      goto end_transfer;
1858                  }
1859                  if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
1860                      (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
1861                      status2 = 0x00;
1862                      goto end_transfer;
1863                  }
1864              }
1865              break;
1866          }
1867          fdctrl->data_pos += len;
1868          rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
1869          if (rel_pos == 0) {
1870              /* Seek to next sector */
1871              if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv))
1872                  break;
1873          }
1874      }
1875   end_transfer:
1876      len = fdctrl->data_pos - start_pos;
1877      FLOPPY_DPRINTF("end transfer %d %d %d\n",
1878                     fdctrl->data_pos, len, fdctrl->data_len);
1879      if (fdctrl->data_dir == FD_DIR_SCANE ||
1880          fdctrl->data_dir == FD_DIR_SCANL ||
1881          fdctrl->data_dir == FD_DIR_SCANH)
1882          status2 = FD_SR2_SEH;
1883      fdctrl->data_len -= len;
1884      fdctrl_stop_transfer(fdctrl, status0, status1, status2);
1885   transfer_error:
1886  
1887      return len;
1888  }
1889  
1890  /* Data register : 0x05 */
1891  static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
1892  {
1893      FDrive *cur_drv;
1894      uint32_t retval = 0;
1895      uint32_t pos;
1896  
1897      cur_drv = get_cur_drv(fdctrl);
1898      fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1899      if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
1900          FLOPPY_DPRINTF("error: controller not ready for reading\n");
1901          return 0;
1902      }
1903  
1904      /* If data_len spans multiple sectors, the current position in the FIFO
1905       * wraps around while fdctrl->data_pos is the real position in the whole
1906       * request. */
1907      pos = fdctrl->data_pos;
1908      pos %= FD_SECTOR_LEN;
1909  
1910      switch (fdctrl->phase) {
1911      case FD_PHASE_EXECUTION:
1912          assert(fdctrl->msr & FD_MSR_NONDMA);
1913          if (pos == 0) {
1914              if (fdctrl->data_pos != 0)
1915                  if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
1916                      FLOPPY_DPRINTF("error seeking to next sector %d\n",
1917                                     fd_sector(cur_drv));
1918                      return 0;
1919                  }
1920              if (blk_pread(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
1921                            BDRV_SECTOR_SIZE)
1922                  < 0) {
1923                  FLOPPY_DPRINTF("error getting sector %d\n",
1924                                 fd_sector(cur_drv));
1925                  /* Sure, image size is too small... */
1926                  memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
1927              }
1928          }
1929  
1930          if (++fdctrl->data_pos == fdctrl->data_len) {
1931              fdctrl->msr &= ~FD_MSR_RQM;
1932              fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
1933          }
1934          break;
1935  
1936      case FD_PHASE_RESULT:
1937          assert(!(fdctrl->msr & FD_MSR_NONDMA));
1938          if (++fdctrl->data_pos == fdctrl->data_len) {
1939              fdctrl->msr &= ~FD_MSR_RQM;
1940              fdctrl_to_command_phase(fdctrl);
1941              fdctrl_reset_irq(fdctrl);
1942          }
1943          break;
1944  
1945      case FD_PHASE_COMMAND:
1946      default:
1947          abort();
1948      }
1949  
1950      retval = fdctrl->fifo[pos];
1951      FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
1952  
1953      return retval;
1954  }
1955  
1956  static void fdctrl_format_sector(FDCtrl *fdctrl)
1957  {
1958      FDrive *cur_drv;
1959      uint8_t kh, kt, ks;
1960  
1961      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
1962      cur_drv = get_cur_drv(fdctrl);
1963      kt = fdctrl->fifo[6];
1964      kh = fdctrl->fifo[7];
1965      ks = fdctrl->fifo[8];
1966      FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
1967                     GET_CUR_DRV(fdctrl), kh, kt, ks,
1968                     fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
1969                                    NUM_SIDES(cur_drv)));
1970      switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
1971      case 2:
1972          /* sect too big */
1973          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1974          fdctrl->fifo[3] = kt;
1975          fdctrl->fifo[4] = kh;
1976          fdctrl->fifo[5] = ks;
1977          return;
1978      case 3:
1979          /* track too big */
1980          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
1981          fdctrl->fifo[3] = kt;
1982          fdctrl->fifo[4] = kh;
1983          fdctrl->fifo[5] = ks;
1984          return;
1985      case 4:
1986          /* No seek enabled */
1987          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1988          fdctrl->fifo[3] = kt;
1989          fdctrl->fifo[4] = kh;
1990          fdctrl->fifo[5] = ks;
1991          return;
1992      case 1:
1993          fdctrl->status0 |= FD_SR0_SEEK;
1994          break;
1995      default:
1996          break;
1997      }
1998      memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
1999      if (cur_drv->blk == NULL ||
2000          blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
2001                     BDRV_SECTOR_SIZE, 0) < 0) {
2002          FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
2003          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
2004      } else {
2005          if (cur_drv->sect == cur_drv->last_sect) {
2006              fdctrl->data_state &= ~FD_STATE_FORMAT;
2007              /* Last sector done */
2008              fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2009          } else {
2010              /* More to do */
2011              fdctrl->data_pos = 0;
2012              fdctrl->data_len = 4;
2013          }
2014      }
2015  }
2016  
2017  static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction)
2018  {
2019      fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
2020      fdctrl->fifo[0] = fdctrl->lock << 4;
2021      fdctrl_to_result_phase(fdctrl, 1);
2022  }
2023  
2024  static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
2025  {
2026      FDrive *cur_drv = get_cur_drv(fdctrl);
2027  
2028      /* Drives position */
2029      fdctrl->fifo[0] = drv0(fdctrl)->track;
2030      fdctrl->fifo[1] = drv1(fdctrl)->track;
2031  #if MAX_FD == 4
2032      fdctrl->fifo[2] = drv2(fdctrl)->track;
2033      fdctrl->fifo[3] = drv3(fdctrl)->track;
2034  #else
2035      fdctrl->fifo[2] = 0;
2036      fdctrl->fifo[3] = 0;
2037  #endif
2038      /* timers */
2039      fdctrl->fifo[4] = fdctrl->timer0;
2040      fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
2041      fdctrl->fifo[6] = cur_drv->last_sect;
2042      fdctrl->fifo[7] = (fdctrl->lock << 7) |
2043          (cur_drv->perpendicular << 2);
2044      fdctrl->fifo[8] = fdctrl->config;
2045      fdctrl->fifo[9] = fdctrl->precomp_trk;
2046      fdctrl_to_result_phase(fdctrl, 10);
2047  }
2048  
2049  static void fdctrl_handle_version(FDCtrl *fdctrl, int direction)
2050  {
2051      /* Controller's version */
2052      fdctrl->fifo[0] = fdctrl->version;
2053      fdctrl_to_result_phase(fdctrl, 1);
2054  }
2055  
2056  static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
2057  {
2058      fdctrl->fifo[0] = 0x41; /* Stepping 1 */
2059      fdctrl_to_result_phase(fdctrl, 1);
2060  }
2061  
2062  static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction)
2063  {
2064      FDrive *cur_drv = get_cur_drv(fdctrl);
2065  
2066      /* Drives position */
2067      drv0(fdctrl)->track = fdctrl->fifo[3];
2068      drv1(fdctrl)->track = fdctrl->fifo[4];
2069  #if MAX_FD == 4
2070      drv2(fdctrl)->track = fdctrl->fifo[5];
2071      drv3(fdctrl)->track = fdctrl->fifo[6];
2072  #endif
2073      /* timers */
2074      fdctrl->timer0 = fdctrl->fifo[7];
2075      fdctrl->timer1 = fdctrl->fifo[8];
2076      cur_drv->last_sect = fdctrl->fifo[9];
2077      fdctrl->lock = fdctrl->fifo[10] >> 7;
2078      cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
2079      fdctrl->config = fdctrl->fifo[11];
2080      fdctrl->precomp_trk = fdctrl->fifo[12];
2081      fdctrl->pwrd = fdctrl->fifo[13];
2082      fdctrl_to_command_phase(fdctrl);
2083  }
2084  
2085  static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
2086  {
2087      FDrive *cur_drv = get_cur_drv(fdctrl);
2088  
2089      fdctrl->fifo[0] = 0;
2090      fdctrl->fifo[1] = 0;
2091      /* Drives position */
2092      fdctrl->fifo[2] = drv0(fdctrl)->track;
2093      fdctrl->fifo[3] = drv1(fdctrl)->track;
2094  #if MAX_FD == 4
2095      fdctrl->fifo[4] = drv2(fdctrl)->track;
2096      fdctrl->fifo[5] = drv3(fdctrl)->track;
2097  #else
2098      fdctrl->fifo[4] = 0;
2099      fdctrl->fifo[5] = 0;
2100  #endif
2101      /* timers */
2102      fdctrl->fifo[6] = fdctrl->timer0;
2103      fdctrl->fifo[7] = fdctrl->timer1;
2104      fdctrl->fifo[8] = cur_drv->last_sect;
2105      fdctrl->fifo[9] = (fdctrl->lock << 7) |
2106          (cur_drv->perpendicular << 2);
2107      fdctrl->fifo[10] = fdctrl->config;
2108      fdctrl->fifo[11] = fdctrl->precomp_trk;
2109      fdctrl->fifo[12] = fdctrl->pwrd;
2110      fdctrl->fifo[13] = 0;
2111      fdctrl->fifo[14] = 0;
2112      fdctrl_to_result_phase(fdctrl, 15);
2113  }
2114  
2115  static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
2116  {
2117      FDrive *cur_drv = get_cur_drv(fdctrl);
2118  
2119      cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
2120      timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
2121               (NANOSECONDS_PER_SECOND / 50));
2122  }
2123  
2124  static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
2125  {
2126      FDrive *cur_drv;
2127  
2128      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2129      cur_drv = get_cur_drv(fdctrl);
2130      fdctrl->data_state |= FD_STATE_FORMAT;
2131      if (fdctrl->fifo[0] & 0x80)
2132          fdctrl->data_state |= FD_STATE_MULTI;
2133      else
2134          fdctrl->data_state &= ~FD_STATE_MULTI;
2135      cur_drv->bps =
2136          fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
2137  #if 0
2138      cur_drv->last_sect =
2139          cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
2140          fdctrl->fifo[3] / 2;
2141  #else
2142      cur_drv->last_sect = fdctrl->fifo[3];
2143  #endif
2144      /* TODO: implement format using DMA expected by the Bochs BIOS
2145       * and Linux fdformat (read 3 bytes per sector via DMA and fill
2146       * the sector with the specified fill byte
2147       */
2148      fdctrl->data_state &= ~FD_STATE_FORMAT;
2149      fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2150  }
2151  
2152  static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction)
2153  {
2154      fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
2155      fdctrl->timer1 = fdctrl->fifo[2] >> 1;
2156      if (fdctrl->fifo[2] & 1)
2157          fdctrl->dor &= ~FD_DOR_DMAEN;
2158      else
2159          fdctrl->dor |= FD_DOR_DMAEN;
2160      /* No result back */
2161      fdctrl_to_command_phase(fdctrl);
2162  }
2163  
2164  static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction)
2165  {
2166      FDrive *cur_drv;
2167  
2168      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2169      cur_drv = get_cur_drv(fdctrl);
2170      cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
2171      /* 1 Byte status back */
2172      fdctrl->fifo[0] = (cur_drv->ro << 6) |
2173          (cur_drv->track == 0 ? 0x10 : 0x00) |
2174          (cur_drv->head << 2) |
2175          GET_CUR_DRV(fdctrl) |
2176          0x28;
2177      fdctrl_to_result_phase(fdctrl, 1);
2178  }
2179  
2180  static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction)
2181  {
2182      FDrive *cur_drv;
2183  
2184      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2185      cur_drv = get_cur_drv(fdctrl);
2186      fd_recalibrate(cur_drv);
2187      fdctrl_to_command_phase(fdctrl);
2188      /* Raise Interrupt */
2189      fdctrl->status0 |= FD_SR0_SEEK;
2190      fdctrl_raise_irq(fdctrl);
2191  }
2192  
2193  static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
2194  {
2195      FDrive *cur_drv = get_cur_drv(fdctrl);
2196  
2197      if (fdctrl->reset_sensei > 0) {
2198          fdctrl->fifo[0] =
2199              FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
2200          fdctrl->reset_sensei--;
2201      } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
2202          fdctrl->fifo[0] = FD_SR0_INVCMD;
2203          fdctrl_to_result_phase(fdctrl, 1);
2204          return;
2205      } else {
2206          fdctrl->fifo[0] =
2207                  (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
2208                  | GET_CUR_DRV(fdctrl);
2209      }
2210  
2211      fdctrl->fifo[1] = cur_drv->track;
2212      fdctrl_to_result_phase(fdctrl, 2);
2213      fdctrl_reset_irq(fdctrl);
2214      fdctrl->status0 = FD_SR0_RDYCHG;
2215  }
2216  
2217  static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction)
2218  {
2219      FDrive *cur_drv;
2220  
2221      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2222      cur_drv = get_cur_drv(fdctrl);
2223      fdctrl_to_command_phase(fdctrl);
2224      /* The seek command just sends step pulses to the drive and doesn't care if
2225       * there is a medium inserted of if it's banging the head against the drive.
2226       */
2227      fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
2228      /* Raise Interrupt */
2229      fdctrl->status0 |= FD_SR0_SEEK;
2230      fdctrl_raise_irq(fdctrl);
2231  }
2232  
2233  static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
2234  {
2235      FDrive *cur_drv = get_cur_drv(fdctrl);
2236  
2237      if (fdctrl->fifo[1] & 0x80)
2238          cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
2239      /* No result back */
2240      fdctrl_to_command_phase(fdctrl);
2241  }
2242  
2243  static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction)
2244  {
2245      fdctrl->config = fdctrl->fifo[2];
2246      fdctrl->precomp_trk =  fdctrl->fifo[3];
2247      /* No result back */
2248      fdctrl_to_command_phase(fdctrl);
2249  }
2250  
2251  static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction)
2252  {
2253      fdctrl->pwrd = fdctrl->fifo[1];
2254      fdctrl->fifo[0] = fdctrl->fifo[1];
2255      fdctrl_to_result_phase(fdctrl, 1);
2256  }
2257  
2258  static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
2259  {
2260      /* No result back */
2261      fdctrl_to_command_phase(fdctrl);
2262  }
2263  
2264  static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
2265  {
2266      FDrive *cur_drv = get_cur_drv(fdctrl);
2267      uint32_t pos;
2268  
2269      pos = fdctrl->data_pos - 1;
2270      pos %= FD_SECTOR_LEN;
2271      if (fdctrl->fifo[pos] & 0x80) {
2272          /* Command parameters done */
2273          if (fdctrl->fifo[pos] & 0x40) {
2274              fdctrl->fifo[0] = fdctrl->fifo[1];
2275              fdctrl->fifo[2] = 0;
2276              fdctrl->fifo[3] = 0;
2277              fdctrl_to_result_phase(fdctrl, 4);
2278          } else {
2279              fdctrl_to_command_phase(fdctrl);
2280          }
2281      } else if (fdctrl->data_len > 7) {
2282          /* ERROR */
2283          fdctrl->fifo[0] = 0x80 |
2284              (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
2285          fdctrl_to_result_phase(fdctrl, 1);
2286      }
2287  }
2288  
2289  static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction)
2290  {
2291      FDrive *cur_drv;
2292  
2293      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2294      cur_drv = get_cur_drv(fdctrl);
2295      if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
2296          fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
2297                  cur_drv->sect, 1);
2298      } else {
2299          fd_seek(cur_drv, cur_drv->head,
2300                  cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1);
2301      }
2302      fdctrl_to_command_phase(fdctrl);
2303      /* Raise Interrupt */
2304      fdctrl->status0 |= FD_SR0_SEEK;
2305      fdctrl_raise_irq(fdctrl);
2306  }
2307  
2308  static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction)
2309  {
2310      FDrive *cur_drv;
2311  
2312      SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2313      cur_drv = get_cur_drv(fdctrl);
2314      if (fdctrl->fifo[2] > cur_drv->track) {
2315          fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
2316      } else {
2317          fd_seek(cur_drv, cur_drv->head,
2318                  cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1);
2319      }
2320      fdctrl_to_command_phase(fdctrl);
2321      /* Raise Interrupt */
2322      fdctrl->status0 |= FD_SR0_SEEK;
2323      fdctrl_raise_irq(fdctrl);
2324  }
2325  
2326  /*
2327   * Handlers for the execution phase of each command
2328   */
2329  typedef struct FDCtrlCommand {
2330      uint8_t value;
2331      uint8_t mask;
2332      const char* name;
2333      int parameters;
2334      void (*handler)(FDCtrl *fdctrl, int direction);
2335      int direction;
2336  } FDCtrlCommand;
2337  
2338  static const FDCtrlCommand handlers[] = {
2339      { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
2340      { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
2341      { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek },
2342      { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status },
2343      { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate },
2344      { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track },
2345      { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ },
2346      { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */
2347      { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */
2348      { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ },
2349      { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE },
2350      { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_start_transfer, FD_DIR_VERIFY },
2351      { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL },
2352      { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH },
2353      { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE },
2354      { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid },
2355      { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify },
2356      { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status },
2357      { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode },
2358      { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure },
2359      { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode },
2360      { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option },
2361      { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command },
2362      { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out },
2363      { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented },
2364      { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in },
2365      { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock },
2366      { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg },
2367      { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version },
2368      { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid },
2369      { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */
2370      { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
2371  };
2372  /* Associate command to an index in the 'handlers' array */
2373  static uint8_t command_to_handler[256];
2374  
2375  static const FDCtrlCommand *get_command(uint8_t cmd)
2376  {
2377      int idx;
2378  
2379      idx = command_to_handler[cmd];
2380      FLOPPY_DPRINTF("%s command\n", handlers[idx].name);
2381      return &handlers[idx];
2382  }
2383  
2384  static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
2385  {
2386      FDrive *cur_drv;
2387      const FDCtrlCommand *cmd;
2388      uint32_t pos;
2389  
2390      /* Reset mode */
2391      if (!(fdctrl->dor & FD_DOR_nRESET)) {
2392          FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
2393          return;
2394      }
2395      if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
2396          FLOPPY_DPRINTF("error: controller not ready for writing\n");
2397          return;
2398      }
2399      fdctrl->dsr &= ~FD_DSR_PWRDOWN;
2400  
2401      FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
2402  
2403      /* If data_len spans multiple sectors, the current position in the FIFO
2404       * wraps around while fdctrl->data_pos is the real position in the whole
2405       * request. */
2406      pos = fdctrl->data_pos++;
2407      pos %= FD_SECTOR_LEN;
2408      fdctrl->fifo[pos] = value;
2409  
2410      if (fdctrl->data_pos == fdctrl->data_len) {
2411          fdctrl->msr &= ~FD_MSR_RQM;
2412      }
2413  
2414      switch (fdctrl->phase) {
2415      case FD_PHASE_EXECUTION:
2416          /* For DMA requests, RQM should be cleared during execution phase, so
2417           * we would have errored out above. */
2418          assert(fdctrl->msr & FD_MSR_NONDMA);
2419  
2420          /* FIFO data write */
2421          if (pos == FD_SECTOR_LEN - 1 ||
2422              fdctrl->data_pos == fdctrl->data_len) {
2423              cur_drv = get_cur_drv(fdctrl);
2424              if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
2425                             BDRV_SECTOR_SIZE, 0) < 0) {
2426                  FLOPPY_DPRINTF("error writing sector %d\n",
2427                                 fd_sector(cur_drv));
2428                  break;
2429              }
2430              if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
2431                  FLOPPY_DPRINTF("error seeking to next sector %d\n",
2432                                 fd_sector(cur_drv));
2433                  break;
2434              }
2435          }
2436  
2437          /* Switch to result phase when done with the transfer */
2438          if (fdctrl->data_pos == fdctrl->data_len) {
2439              fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2440          }
2441          break;
2442  
2443      case FD_PHASE_COMMAND:
2444          assert(!(fdctrl->msr & FD_MSR_NONDMA));
2445          assert(fdctrl->data_pos < FD_SECTOR_LEN);
2446  
2447          if (pos == 0) {
2448              /* The first byte specifies the command. Now we start reading
2449               * as many parameters as this command requires. */
2450              cmd = get_command(value);
2451              fdctrl->data_len = cmd->parameters + 1;
2452              if (cmd->parameters) {
2453                  fdctrl->msr |= FD_MSR_RQM;
2454              }
2455              fdctrl->msr |= FD_MSR_CMDBUSY;
2456          }
2457  
2458          if (fdctrl->data_pos == fdctrl->data_len) {
2459              /* We have all parameters now, execute the command */
2460              fdctrl->phase = FD_PHASE_EXECUTION;
2461  
2462              if (fdctrl->data_state & FD_STATE_FORMAT) {
2463                  fdctrl_format_sector(fdctrl);
2464                  break;
2465              }
2466  
2467              cmd = get_command(fdctrl->fifo[0]);
2468              FLOPPY_DPRINTF("Calling handler for '%s'\n", cmd->name);
2469              cmd->handler(fdctrl, cmd->direction);
2470          }
2471          break;
2472  
2473      case FD_PHASE_RESULT:
2474      default:
2475          abort();
2476      }
2477  }
2478  
2479  static void fdctrl_result_timer(void *opaque)
2480  {
2481      FDCtrl *fdctrl = opaque;
2482      FDrive *cur_drv = get_cur_drv(fdctrl);
2483  
2484      /* Pretend we are spinning.
2485       * This is needed for Coherent, which uses READ ID to check for
2486       * sector interleaving.
2487       */
2488      if (cur_drv->last_sect != 0) {
2489          cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
2490      }
2491      /* READ_ID can't automatically succeed! */
2492      if (fdctrl->check_media_rate &&
2493          (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
2494          FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
2495                         fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
2496          fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
2497      } else {
2498          fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2499      }
2500  }
2501  
2502  /* Init functions */
2503  
2504  static void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
2505  {
2506      DeviceState *dev;
2507      int i;
2508  
2509      for (i = 0; i < MAX_FD; i++) {
2510          if (fds[i]) {
2511              dev = qdev_new("floppy");
2512              qdev_prop_set_uint32(dev, "unit", i);
2513              qdev_prop_set_enum(dev, "drive-type", FLOPPY_DRIVE_TYPE_AUTO);
2514              qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(fds[i]),
2515                                      &error_fatal);
2516              qdev_realize_and_unref(dev, &bus->bus, &error_fatal);
2517          }
2518      }
2519  }
2520  
2521  void isa_fdc_init_drives(ISADevice *fdc, DriveInfo **fds)
2522  {
2523      fdctrl_init_drives(&ISA_FDC(fdc)->state.bus, fds);
2524  }
2525  
2526  static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
2527                                    Error **errp)
2528  {
2529      unsigned int i;
2530      FDrive *drive;
2531      DeviceState *dev;
2532      BlockBackend *blk;
2533      bool ok;
2534      const char *fdc_name, *drive_suffix;
2535  
2536      for (i = 0; i < MAX_FD; i++) {
2537          drive = &fdctrl->drives[i];
2538          drive->fdctrl = fdctrl;
2539  
2540          /* If the drive is not present, we skip creating the qdev device, but
2541           * still have to initialise the controller. */
2542          blk = fdctrl->qdev_for_drives[i].blk;
2543          if (!blk) {
2544              fd_init(drive);
2545              fd_revalidate(drive);
2546              continue;
2547          }
2548  
2549          fdc_name = object_get_typename(OBJECT(fdc_dev));
2550          drive_suffix = !strcmp(fdc_name, "SUNW,fdtwo") ? "" : i ? "B" : "A";
2551          warn_report("warning: property %s.drive%s is deprecated",
2552                      fdc_name, drive_suffix);
2553          error_printf("Use -device floppy,unit=%d,drive=... instead.\n", i);
2554  
2555          dev = qdev_new("floppy");
2556          qdev_prop_set_uint32(dev, "unit", i);
2557          qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
2558  
2559          /*
2560           * Hack alert: we move the backend from the floppy controller
2561           * device to the floppy device.  We first need to detach the
2562           * controller, or else floppy_create()'s qdev_prop_set_drive()
2563           * will die when it attaches floppy device.  We also need to
2564           * take another reference so that blk_detach_dev() doesn't
2565           * free blk while we still need it.
2566           *
2567           * The hack is probably a bad idea.
2568           */
2569          blk_ref(blk);
2570          blk_detach_dev(blk, fdc_dev);
2571          fdctrl->qdev_for_drives[i].blk = NULL;
2572          ok = qdev_prop_set_drive_err(dev, "drive", blk, errp);
2573          blk_unref(blk);
2574          if (!ok) {
2575              return;
2576          }
2577  
2578          if (!qdev_realize_and_unref(dev, &fdctrl->bus.bus, errp)) {
2579              return;
2580          }
2581      }
2582  }
2583  
2584  void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
2585                          hwaddr mmio_base, DriveInfo **fds)
2586  {
2587      FDCtrl *fdctrl;
2588      DeviceState *dev;
2589      SysBusDevice *sbd;
2590      FDCtrlSysBus *sys;
2591  
2592      dev = qdev_new("sysbus-fdc");
2593      sys = SYSBUS_FDC(dev);
2594      fdctrl = &sys->state;
2595      fdctrl->dma_chann = dma_chann; /* FIXME */
2596      sbd = SYS_BUS_DEVICE(dev);
2597      sysbus_realize_and_unref(sbd, &error_fatal);
2598      sysbus_connect_irq(sbd, 0, irq);
2599      sysbus_mmio_map(sbd, 0, mmio_base);
2600  
2601      fdctrl_init_drives(&sys->state.bus, fds);
2602  }
2603  
2604  void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
2605                         DriveInfo **fds, qemu_irq *fdc_tc)
2606  {
2607      DeviceState *dev;
2608      FDCtrlSysBus *sys;
2609  
2610      dev = qdev_new("SUNW,fdtwo");
2611      sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
2612      sys = SYSBUS_FDC(dev);
2613      sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
2614      sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
2615      *fdc_tc = qdev_get_gpio_in(dev, 0);
2616  
2617      fdctrl_init_drives(&sys->state.bus, fds);
2618  }
2619  
2620  static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
2621                                    Error **errp)
2622  {
2623      int i, j;
2624      static int command_tables_inited = 0;
2625  
2626      if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
2627          error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
2628          return;
2629      }
2630  
2631      /* Fill 'command_to_handler' lookup table */
2632      if (!command_tables_inited) {
2633          command_tables_inited = 1;
2634          for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
2635              for (j = 0; j < sizeof(command_to_handler); j++) {
2636                  if ((j & handlers[i].mask) == handlers[i].value) {
2637                      command_to_handler[j] = i;
2638                  }
2639              }
2640          }
2641      }
2642  
2643      FLOPPY_DPRINTF("init controller\n");
2644      fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
2645      memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
2646      fdctrl->fifo_size = 512;
2647      fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
2648                                               fdctrl_result_timer, fdctrl);
2649  
2650      fdctrl->version = 0x90; /* Intel 82078 controller */
2651      fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
2652      fdctrl->num_floppies = MAX_FD;
2653  
2654      if (fdctrl->dma_chann != -1) {
2655          IsaDmaClass *k;
2656          assert(fdctrl->dma);
2657          k = ISADMA_GET_CLASS(fdctrl->dma);
2658          k->register_channel(fdctrl->dma, fdctrl->dma_chann,
2659                              &fdctrl_transfer_handler, fdctrl);
2660      }
2661  
2662      floppy_bus_create(fdctrl, &fdctrl->bus, dev);
2663      fdctrl_connect_drives(fdctrl, dev, errp);
2664  }
2665  
2666  static const MemoryRegionPortio fdc_portio_list[] = {
2667      { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
2668      { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
2669      PORTIO_END_OF_LIST(),
2670  };
2671  
2672  static void isabus_fdc_realize(DeviceState *dev, Error **errp)
2673  {
2674      ISADevice *isadev = ISA_DEVICE(dev);
2675      FDCtrlISABus *isa = ISA_FDC(dev);
2676      FDCtrl *fdctrl = &isa->state;
2677      Error *err = NULL;
2678  
2679      isa_register_portio_list(isadev, &fdctrl->portio_list,
2680                               isa->iobase, fdc_portio_list, fdctrl,
2681                               "fdc");
2682  
2683      isa_init_irq(isadev, &fdctrl->irq, isa->irq);
2684      fdctrl->dma_chann = isa->dma;
2685      if (fdctrl->dma_chann != -1) {
2686          fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma);
2687          if (!fdctrl->dma) {
2688              error_setg(errp, "ISA controller does not support DMA");
2689              return;
2690          }
2691      }
2692  
2693      qdev_set_legacy_instance_id(dev, isa->iobase, 2);
2694      fdctrl_realize_common(dev, fdctrl, &err);
2695      if (err != NULL) {
2696          error_propagate(errp, err);
2697          return;
2698      }
2699  }
2700  
2701  static void sysbus_fdc_initfn(Object *obj)
2702  {
2703      SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2704      FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2705      FDCtrl *fdctrl = &sys->state;
2706  
2707      fdctrl->dma_chann = -1;
2708  
2709      memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl,
2710                            "fdc", 0x08);
2711      sysbus_init_mmio(sbd, &fdctrl->iomem);
2712  }
2713  
2714  static void sun4m_fdc_initfn(Object *obj)
2715  {
2716      SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2717      FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2718      FDCtrl *fdctrl = &sys->state;
2719  
2720      fdctrl->dma_chann = -1;
2721  
2722      memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
2723                            fdctrl, "fdctrl", 0x08);
2724      sysbus_init_mmio(sbd, &fdctrl->iomem);
2725  }
2726  
2727  static void sysbus_fdc_common_initfn(Object *obj)
2728  {
2729      DeviceState *dev = DEVICE(obj);
2730      SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
2731      FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2732      FDCtrl *fdctrl = &sys->state;
2733  
2734      qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
2735  
2736      sysbus_init_irq(sbd, &fdctrl->irq);
2737      qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
2738  }
2739  
2740  static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
2741  {
2742      FDCtrlSysBus *sys = SYSBUS_FDC(dev);
2743      FDCtrl *fdctrl = &sys->state;
2744  
2745      fdctrl_realize_common(dev, fdctrl, errp);
2746  }
2747  
2748  FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
2749  {
2750      FDCtrlISABus *isa = ISA_FDC(fdc);
2751  
2752      return isa->state.drives[i].drive;
2753  }
2754  
2755  static void isa_fdc_get_drive_max_chs(FloppyDriveType type, uint8_t *maxc,
2756                                        uint8_t *maxh, uint8_t *maxs)
2757  {
2758      const FDFormat *fdf;
2759  
2760      *maxc = *maxh = *maxs = 0;
2761      for (fdf = fd_formats; fdf->drive != FLOPPY_DRIVE_TYPE_NONE; fdf++) {
2762          if (fdf->drive != type) {
2763              continue;
2764          }
2765          if (*maxc < fdf->max_track) {
2766              *maxc = fdf->max_track;
2767          }
2768          if (*maxh < fdf->max_head) {
2769              *maxh = fdf->max_head;
2770          }
2771          if (*maxs < fdf->last_sect) {
2772              *maxs = fdf->last_sect;
2773          }
2774      }
2775      (*maxc)--;
2776  }
2777  
2778  static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
2779  {
2780      Aml *dev, *fdi;
2781      uint8_t maxc, maxh, maxs;
2782  
2783      isa_fdc_get_drive_max_chs(type, &maxc, &maxh, &maxs);
2784  
2785      dev = aml_device("FLP%c", 'A' + idx);
2786  
2787      aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
2788  
2789      fdi = aml_package(16);
2790      aml_append(fdi, aml_int(idx));  /* Drive Number */
2791      aml_append(fdi,
2792          aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
2793      /*
2794       * the values below are the limits of the drive, and are thus independent
2795       * of the inserted media
2796       */
2797      aml_append(fdi, aml_int(maxc));  /* Maximum Cylinder Number */
2798      aml_append(fdi, aml_int(maxs));  /* Maximum Sector Number */
2799      aml_append(fdi, aml_int(maxh));  /* Maximum Head Number */
2800      /*
2801       * SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
2802       * the drive type, so shall we
2803       */
2804      aml_append(fdi, aml_int(0xAF));  /* disk_specify_1 */
2805      aml_append(fdi, aml_int(0x02));  /* disk_specify_2 */
2806      aml_append(fdi, aml_int(0x25));  /* disk_motor_wait */
2807      aml_append(fdi, aml_int(0x02));  /* disk_sector_siz */
2808      aml_append(fdi, aml_int(0x12));  /* disk_eot */
2809      aml_append(fdi, aml_int(0x1B));  /* disk_rw_gap */
2810      aml_append(fdi, aml_int(0xFF));  /* disk_dtl */
2811      aml_append(fdi, aml_int(0x6C));  /* disk_formt_gap */
2812      aml_append(fdi, aml_int(0xF6));  /* disk_fill */
2813      aml_append(fdi, aml_int(0x0F));  /* disk_head_sttl */
2814      aml_append(fdi, aml_int(0x08));  /* disk_motor_strt */
2815  
2816      aml_append(dev, aml_name_decl("_FDI", fdi));
2817      return dev;
2818  }
2819  
2820  int cmos_get_fd_drive_type(FloppyDriveType fd0)
2821  {
2822      int val;
2823  
2824      switch (fd0) {
2825      case FLOPPY_DRIVE_TYPE_144:
2826          /* 1.44 Mb 3"5 drive */
2827          val = 4;
2828          break;
2829      case FLOPPY_DRIVE_TYPE_288:
2830          /* 2.88 Mb 3"5 drive */
2831          val = 5;
2832          break;
2833      case FLOPPY_DRIVE_TYPE_120:
2834          /* 1.2 Mb 5"5 drive */
2835          val = 2;
2836          break;
2837      case FLOPPY_DRIVE_TYPE_NONE:
2838      default:
2839          val = 0;
2840          break;
2841      }
2842      return val;
2843  }
2844  
2845  static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope)
2846  {
2847      Aml *dev;
2848      Aml *crs;
2849      int i;
2850  
2851  #define ACPI_FDE_MAX_FD 4
2852      uint32_t fde_buf[5] = {
2853          0, 0, 0, 0,     /* presence of floppy drives #0 - #3 */
2854          cpu_to_le32(2)  /* tape presence (2 == never present) */
2855      };
2856  
2857      crs = aml_resource_template();
2858      aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04));
2859      aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01));
2860      aml_append(crs, aml_irq_no_flags(6));
2861      aml_append(crs,
2862          aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2));
2863  
2864      dev = aml_device("FDC0");
2865      aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
2866      aml_append(dev, aml_name_decl("_CRS", crs));
2867  
2868      for (i = 0; i < MIN(MAX_FD, ACPI_FDE_MAX_FD); i++) {
2869          FloppyDriveType type = isa_fdc_get_drive_type(isadev, i);
2870  
2871          if (type < FLOPPY_DRIVE_TYPE_NONE) {
2872              fde_buf[i] = cpu_to_le32(1);  /* drive present */
2873              aml_append(dev, build_fdinfo_aml(i, type));
2874          }
2875      }
2876      aml_append(dev, aml_name_decl("_FDE",
2877                 aml_buffer(sizeof(fde_buf), (uint8_t *)fde_buf)));
2878  
2879      aml_append(scope, dev);
2880  }
2881  
2882  static const VMStateDescription vmstate_isa_fdc ={
2883      .name = "fdc",
2884      .version_id = 2,
2885      .minimum_version_id = 2,
2886      .fields = (VMStateField[]) {
2887          VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
2888          VMSTATE_END_OF_LIST()
2889      }
2890  };
2891  
2892  static Property isa_fdc_properties[] = {
2893      DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
2894      DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
2895      DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
2896      DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.qdev_for_drives[0].blk),
2897      DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
2898      DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
2899                      0, true),
2900      DEFINE_PROP_SIGNED("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
2901                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2902                          FloppyDriveType),
2903      DEFINE_PROP_SIGNED("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
2904                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2905                          FloppyDriveType),
2906      DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2907                          FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
2908                          FloppyDriveType),
2909      DEFINE_PROP_END_OF_LIST(),
2910  };
2911  
2912  static void isabus_fdc_class_init(ObjectClass *klass, void *data)
2913  {
2914      DeviceClass *dc = DEVICE_CLASS(klass);
2915      ISADeviceClass *isa = ISA_DEVICE_CLASS(klass);
2916  
2917      dc->realize = isabus_fdc_realize;
2918      dc->fw_name = "fdc";
2919      dc->reset = fdctrl_external_reset_isa;
2920      dc->vmsd = &vmstate_isa_fdc;
2921      isa->build_aml = fdc_isa_build_aml;
2922      device_class_set_props(dc, isa_fdc_properties);
2923      set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2924  }
2925  
2926  static void isabus_fdc_instance_init(Object *obj)
2927  {
2928      FDCtrlISABus *isa = ISA_FDC(obj);
2929  
2930      device_add_bootindex_property(obj, &isa->bootindexA,
2931                                    "bootindexA", "/floppy@0",
2932                                    DEVICE(obj));
2933      device_add_bootindex_property(obj, &isa->bootindexB,
2934                                    "bootindexB", "/floppy@1",
2935                                    DEVICE(obj));
2936  }
2937  
2938  static const TypeInfo isa_fdc_info = {
2939      .name          = TYPE_ISA_FDC,
2940      .parent        = TYPE_ISA_DEVICE,
2941      .instance_size = sizeof(FDCtrlISABus),
2942      .class_init    = isabus_fdc_class_init,
2943      .instance_init = isabus_fdc_instance_init,
2944  };
2945  
2946  static const VMStateDescription vmstate_sysbus_fdc ={
2947      .name = "fdc",
2948      .version_id = 2,
2949      .minimum_version_id = 2,
2950      .fields = (VMStateField[]) {
2951          VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
2952          VMSTATE_END_OF_LIST()
2953      }
2954  };
2955  
2956  static Property sysbus_fdc_properties[] = {
2957      DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2958      DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
2959      DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
2960                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2961                          FloppyDriveType),
2962      DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
2963                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2964                          FloppyDriveType),
2965      DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2966                          FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2967                          FloppyDriveType),
2968      DEFINE_PROP_END_OF_LIST(),
2969  };
2970  
2971  static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
2972  {
2973      DeviceClass *dc = DEVICE_CLASS(klass);
2974  
2975      device_class_set_props(dc, sysbus_fdc_properties);
2976      set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2977  }
2978  
2979  static const TypeInfo sysbus_fdc_info = {
2980      .name          = "sysbus-fdc",
2981      .parent        = TYPE_SYSBUS_FDC,
2982      .instance_init = sysbus_fdc_initfn,
2983      .class_init    = sysbus_fdc_class_init,
2984  };
2985  
2986  static Property sun4m_fdc_properties[] = {
2987      DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2988      DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
2989                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2990                          FloppyDriveType),
2991      DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2992                          FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2993                          FloppyDriveType),
2994      DEFINE_PROP_END_OF_LIST(),
2995  };
2996  
2997  static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
2998  {
2999      DeviceClass *dc = DEVICE_CLASS(klass);
3000  
3001      device_class_set_props(dc, sun4m_fdc_properties);
3002      set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
3003  }
3004  
3005  static const TypeInfo sun4m_fdc_info = {
3006      .name          = "SUNW,fdtwo",
3007      .parent        = TYPE_SYSBUS_FDC,
3008      .instance_init = sun4m_fdc_initfn,
3009      .class_init    = sun4m_fdc_class_init,
3010  };
3011  
3012  static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
3013  {
3014      DeviceClass *dc = DEVICE_CLASS(klass);
3015  
3016      dc->realize = sysbus_fdc_common_realize;
3017      dc->reset = fdctrl_external_reset_sysbus;
3018      dc->vmsd = &vmstate_sysbus_fdc;
3019  }
3020  
3021  static const TypeInfo sysbus_fdc_type_info = {
3022      .name          = TYPE_SYSBUS_FDC,
3023      .parent        = TYPE_SYS_BUS_DEVICE,
3024      .instance_size = sizeof(FDCtrlSysBus),
3025      .instance_init = sysbus_fdc_common_initfn,
3026      .abstract      = true,
3027      .class_init    = sysbus_fdc_common_class_init,
3028  };
3029  
3030  static void fdc_register_types(void)
3031  {
3032      type_register_static(&isa_fdc_info);
3033      type_register_static(&sysbus_fdc_type_info);
3034      type_register_static(&sysbus_fdc_info);
3035      type_register_static(&sun4m_fdc_info);
3036      type_register_static(&floppy_bus_info);
3037      type_register_static(&floppy_drive_info);
3038  }
3039  
3040  type_init(fdc_register_types)
3041