~ubuntu-branches/ubuntu/natty/qemu-linaro/natty

« back to all changes in this revision

Viewing changes to hw/fdc.c

  • Committer: Package Import Robot
  • Author(s): Steve Langasek, Loïc Minier, Steve Langasek
  • Date: 2011-03-07 22:55:03 UTC
  • Revision ID: package-import@ubuntu.com-20110307225503-3opjapw0ksg7glo6
[ Loïc Minier ]
* Also pass -fno-var-tracking on armhf.

[ Steve Langasek ]
* New upstream release.
* Build with -marm on armel/armhf; Peter Maydell reports that building for
  Thumb-2 gives an emulator that doesn't work.
* Add support for cross-compiling the package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
#define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
64
64
 
65
65
/* Floppy disk drive emulation */
66
 
typedef enum FDiskType {
67
 
    FDRIVE_DISK_288   = 0x01, /* 2.88 MB disk           */
68
 
    FDRIVE_DISK_144   = 0x02, /* 1.44 MB disk           */
69
 
    FDRIVE_DISK_720   = 0x03, /* 720 kB disk            */
70
 
    FDRIVE_DISK_USER  = 0x04, /* User defined geometry  */
71
 
    FDRIVE_DISK_NONE  = 0x05, /* No disk                */
72
 
} FDiskType;
73
 
 
74
 
typedef enum FDriveType {
75
 
    FDRIVE_DRV_144  = 0x00,   /* 1.44 MB 3"5 drive      */
76
 
    FDRIVE_DRV_288  = 0x01,   /* 2.88 MB 3"5 drive      */
77
 
    FDRIVE_DRV_120  = 0x02,   /* 1.2  MB 5"25 drive     */
78
 
    FDRIVE_DRV_NONE = 0x03,   /* No drive connected     */
79
 
} FDriveType;
80
 
 
81
66
typedef enum FDiskFlags {
82
67
    FDISK_DBL_SIDES  = 0x01,
83
68
} FDiskFlags;
178
163
    drv->sect = 1;
179
164
}
180
165
 
181
 
/* Recognize floppy formats */
182
 
typedef struct FDFormat {
183
 
    FDriveType drive;
184
 
    FDiskType  disk;
185
 
    uint8_t last_sect;
186
 
    uint8_t max_track;
187
 
    uint8_t max_head;
188
 
    const char *str;
189
 
} FDFormat;
190
 
 
191
 
static const FDFormat fd_formats[] = {
192
 
    /* First entry is default format */
193
 
    /* 1.44 MB 3"1/2 floppy disks */
194
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
195
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1,  "1.6 MB 3\"1/2", },
196
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
197
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
198
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
199
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
200
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
201
 
    { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
202
 
    /* 2.88 MB 3"1/2 floppy disks */
203
 
    { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
204
 
    { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
205
 
    { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1,  "3.2 MB 3\"1/2", },
206
 
    { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
207
 
    { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
208
 
    /* 720 kB 3"1/2 floppy disks */
209
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 1,  "720 kB 3\"1/2", },
210
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1,  "800 kB 3\"1/2", },
211
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1,  "820 kB 3\"1/2", },
212
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1,  "830 kB 3\"1/2", },
213
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
214
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
215
 
    /* 1.2 MB 5"1/4 floppy disks */
216
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1,  "1.2 kB 5\"1/4", },
217
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
218
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
219
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
220
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1,  "1.6 MB 5\"1/4", },
221
 
    /* 720 kB 5"1/4 floppy disks */
222
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 80, 1,  "720 kB 5\"1/4", },
223
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1,  "880 kB 5\"1/4", },
224
 
    /* 360 kB 5"1/4 floppy disks */
225
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 1,  "360 kB 5\"1/4", },
226
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 0,  "180 kB 5\"1/4", },
227
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1,  "410 kB 5\"1/4", },
228
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1,  "420 kB 5\"1/4", },
229
 
    /* 320 kB 5"1/4 floppy disks */
230
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 1,  "320 kB 5\"1/4", },
231
 
    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 0,  "160 kB 5\"1/4", },
232
 
    /* 360 kB must match 5"1/4 better than 3"1/2... */
233
 
    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 0,  "360 kB 3\"1/2", },
234
 
    /* end */
235
 
    { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
236
 
};
237
 
 
238
166
/* Revalidate a disk drive after a disk change */
239
167
static void fd_revalidate(FDrive *drv)
240
168
{
241
 
    const FDFormat *parse;
242
 
    uint64_t nb_sectors, size;
243
 
    int i, first_match, match;
244
169
    int nb_heads, max_track, last_sect, ro;
 
170
    FDriveType drive;
245
171
 
246
172
    FLOPPY_DPRINTF("revalidate\n");
247
173
    if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
248
174
        ro = bdrv_is_read_only(drv->bs);
249
 
        bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
 
175
        bdrv_get_floppy_geometry_hint(drv->bs, &nb_heads, &max_track,
 
176
                                      &last_sect, drv->drive, &drive);
250
177
        if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
251
178
            FLOPPY_DPRINTF("User defined disk (%d %d %d)",
252
179
                           nb_heads - 1, max_track, last_sect);
253
180
        } else {
254
 
            bdrv_get_geometry(drv->bs, &nb_sectors);
255
 
            match = -1;
256
 
            first_match = -1;
257
 
            for (i = 0;; i++) {
258
 
                parse = &fd_formats[i];
259
 
                if (parse->drive == FDRIVE_DRV_NONE)
260
 
                    break;
261
 
                if (drv->drive == parse->drive ||
262
 
                    drv->drive == FDRIVE_DRV_NONE) {
263
 
                    size = (parse->max_head + 1) * parse->max_track *
264
 
                        parse->last_sect;
265
 
                    if (nb_sectors == size) {
266
 
                        match = i;
267
 
                        break;
268
 
                    }
269
 
                    if (first_match == -1)
270
 
                        first_match = i;
271
 
                }
272
 
            }
273
 
            if (match == -1) {
274
 
                if (first_match == -1)
275
 
                    match = 1;
276
 
                else
277
 
                    match = first_match;
278
 
                parse = &fd_formats[match];
279
 
            }
280
 
            nb_heads = parse->max_head + 1;
281
 
            max_track = parse->max_track;
282
 
            last_sect = parse->last_sect;
283
 
            drv->drive = parse->drive;
284
 
            FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
285
 
                           nb_heads, max_track, last_sect, ro ? "ro" : "rw");
 
181
            FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
 
182
                           max_track, last_sect, ro ? "ro" : "rw");
286
183
        }
287
184
        if (nb_heads == 1) {
288
185
            drv->flags &= ~FDISK_DBL_SIDES;
292
189
        drv->max_track = max_track;
293
190
        drv->last_sect = last_sect;
294
191
        drv->ro = ro;
 
192
        drv->drive = drive;
295
193
    } else {
296
194
        FLOPPY_DPRINTF("No disk in drive\n");
297
195
        drv->last_sect = 0;
303
201
/********************************************************/
304
202
/* Intel 82078 floppy disk controller emulation          */
305
203
 
 
204
typedef struct FDCtrl FDCtrl;
 
205
 
306
206
static void fdctrl_reset(FDCtrl *fdctrl, int do_irq);
307
207
static void fdctrl_reset_fifo(FDCtrl *fdctrl);
308
208
static int fdctrl_transfer_handler (void *opaque, int nchan,
728
628
    }
729
629
}
730
630
 
731
 
/* XXX: may change if moved to bdrv */
732
 
int fdctrl_get_drive_type(FDCtrl *fdctrl, int drive_num)
733
 
{
734
 
    return fdctrl->drives[drive_num].drive;
735
 
}
736
 
 
737
631
/* Change IRQ state */
738
632
static void fdctrl_reset_irq(FDCtrl *fdctrl)
739
633
{
1877
1771
    return 0;
1878
1772
}
1879
1773
 
1880
 
FDCtrl *fdctrl_init_isa(DriveInfo **fds)
1881
 
{
1882
 
    ISADevice *dev;
1883
 
 
1884
 
    dev = isa_create("isa-fdc");
1885
 
    if (fds[0]) {
1886
 
        qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
1887
 
    }
1888
 
    if (fds[1]) {
1889
 
        qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
1890
 
    }
1891
 
    qdev_init_nofail(&dev->qdev);
1892
 
    return &(DO_UPCAST(FDCtrlISABus, busdev, dev)->state);
1893
 
}
1894
 
 
1895
 
FDCtrl *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
1896
 
                           target_phys_addr_t mmio_base, DriveInfo **fds)
 
1774
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
 
1775
                        target_phys_addr_t mmio_base, DriveInfo **fds)
1897
1776
{
1898
1777
    FDCtrl *fdctrl;
1899
1778
    DeviceState *dev;
1912
1791
    qdev_init_nofail(dev);
1913
1792
    sysbus_connect_irq(&sys->busdev, 0, irq);
1914
1793
    sysbus_mmio_map(&sys->busdev, 0, mmio_base);
1915
 
 
1916
 
    return fdctrl;
1917
1794
}
1918
1795
 
1919
 
FDCtrl *sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
1920
 
                          DriveInfo **fds, qemu_irq *fdc_tc)
 
1796
void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
 
1797
                       DriveInfo **fds, qemu_irq *fdc_tc)
1921
1798
{
1922
1799
    DeviceState *dev;
1923
1800
    FDCtrlSysBus *sys;
1924
 
    FDCtrl *fdctrl;
1925
1801
 
1926
1802
    dev = qdev_create(NULL, "SUNW,fdtwo");
1927
1803
    if (fds[0]) {
1929
1805
    }
1930
1806
    qdev_init_nofail(dev);
1931
1807
    sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
1932
 
    fdctrl = &sys->state;
1933
1808
    sysbus_connect_irq(&sys->busdev, 0, irq);
1934
1809
    sysbus_mmio_map(&sys->busdev, 0, io_base);
1935
1810
    *fdc_tc = qdev_get_gpio_in(dev, 0);
1936
 
 
1937
 
    return fdctrl;
1938
1811
}
1939
1812
 
1940
1813
static int fdctrl_init_common(FDCtrl *fdctrl)