|
|
1.1 root 1: /*
2: Hatari - ide.c
3:
1.1.1.7 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: This is where we intercept read/writes to/from the IDE controller hardware.
8: */
1.1.1.2 root 9:
10: #include <SDL_endian.h>
11: #include <errno.h>
12:
13: #include <sys/types.h>
14: #include <sys/stat.h>
15: #include <unistd.h>
1.1 root 16:
17: #include "main.h"
18: #include "configuration.h"
1.1.1.2 root 19: #include "file.h"
1.1 root 20: #include "ide.h"
1.1.1.9 root 21: #include "hdc.h" /* for partition counting */
1.1 root 22: #include "m68000.h"
1.1.1.2 root 23: #include "mfp.h"
1.1 root 24: #include "stMemory.h"
1.1.1.9 root 25: #include "str.h"
1.1 root 26: #include "sysdeps.h"
27:
1.1.1.2 root 28: #if HAVE_MALLOC_H
29: # include <malloc.h>
30: #endif
31:
1.1.1.9 root 32: int nIDEPartitions = 0;
1.1.1.2 root 33: struct IDEState;
34:
1.1 root 35:
1.1.1.2 root 36: static struct IDEState *opaque_ide_if;
37:
38: static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val);
39: static uint32_t ide_ioport_read(void *opaque, uint32_t addr1);
40: static uint32_t ide_status_read(void *opaque, uint32_t addr);
41: static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val);
42: static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val);
43: static uint32_t ide_data_readw(void *opaque, uint32_t addr);
44: static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
45: static uint32_t ide_data_readl(void *opaque, uint32_t addr);
46:
47:
48: /**
49: * Convert Falcon IDE registers to "normal" IDE register numbers.
50: * (taken from Aranym - cheers!)
51: */
52: static uint32_t fcha2io(uint32_t address)
53: {
54: switch (address)
55: {
56: case 0xf00000:
57: return 0x00;
58: case 0xf00005:
59: return 0x01;
60: case 0xf00009:
61: return 0x02;
62: case 0xf0000d:
63: return 0x03;
64: case 0xf00011:
65: return 0x04;
66: case 0xf00015:
67: return 0x05;
68: case 0xf00019:
69: return 0x06;
70: case 0xf0001d:
71: return 0x07;
72: case 0xf00039:
73: return 0x16;
74: default:
75: return 0xffffffff;
76: }
77: }
78:
1.1 root 79:
80: /**
81: * Handle byte read access from IDE IO memory.
82: */
1.1.1.10! root 83: uae_u32 REGPARAM3 Ide_Mem_bget(uaecptr addr)
1.1 root 84: {
1.1.1.2 root 85: int ideport;
86: uint8_t retval;
87:
1.1 root 88: addr &= 0x00ffffff; /* Use a 24 bit address */
89:
1.1.1.4 root 90: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 91: {
92: /* invalid memory addressing --> bus error */
1.1.1.9 root 93: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1 root 94: return -1;
95: }
96:
1.1.1.2 root 97: ideport = fcha2io(addr);
98:
1.1.1.3 root 99: if (ideport >= 1 && ideport <= 7)
1.1.1.2 root 100: {
101: retval = ide_ioport_read(opaque_ide_if, ideport);
1.1.1.3 root 102: }
103: else if (ideport == 8 || ideport == 22)
104: {
1.1.1.2 root 105: retval = ide_status_read(opaque_ide_if, 0);
1.1.1.3 root 106: }
107: else
108: {
1.1.1.2 root 109: retval = 0xFF;
110: }
111:
1.1.1.9 root 112: LOG_TRACE(TRACE_IDE, "IDE: bget($%x) = $%02x\n", addr, retval);
1.1.1.2 root 113: return retval;
1.1 root 114: }
115:
116:
117: /**
118: * Handle word read access from IDE IO memory.
119: */
1.1.1.10! root 120: uae_u32 REGPARAM3 Ide_Mem_wget(uaecptr addr)
1.1 root 121: {
1.1.1.2 root 122: uint16_t retval;
1.1 root 123:
124: addr &= 0x00ffffff; /* Use a 24 bit address */
125:
1.1.1.4 root 126: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 127: {
128: /* invalid memory addressing --> bus error */
1.1.1.9 root 129: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1 root 130: return -1;
131: }
132:
1.1.1.10! root 133: if (addr == 0xf00000 || addr == 0xf00002)
1.1.1.2 root 134: {
135: retval = ide_data_readw(opaque_ide_if, 0);
136: }
137: else
138: {
139: retval = 0xFFFF;
140: }
141:
1.1.1.9 root 142: LOG_TRACE(TRACE_IDE, "IDE: wget($%x) = $%04x\n", addr, retval);
1.1.1.2 root 143: return retval;
1.1 root 144: }
145:
146:
147: /**
148: * Handle long-word read access from IDE IO memory.
149: */
1.1.1.10! root 150: uae_u32 REGPARAM3 Ide_Mem_lget(uaecptr addr)
1.1 root 151: {
1.1.1.2 root 152: uint32_t retval;
1.1 root 153:
154: addr &= 0x00ffffff; /* Use a 24 bit address */
155:
1.1.1.4 root 156: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 157: {
158: /* invalid memory addressing --> bus error */
1.1.1.9 root 159: M68000_BusError(addr, BUS_ERROR_READ, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1 root 160: return -1;
161: }
162:
1.1.1.2 root 163: if (addr == 0xf00000)
164: {
165: retval = ide_data_readl(opaque_ide_if, 0);
166: }
167: else
168: {
169: retval = 0xFFFFFFFF;
170: }
171:
172: /* word swap for long access to data register */
173: retval = ((retval >> 16) & 0x0000ffff) | ((retval & 0x0000ffff) << 16);
174:
1.1.1.9 root 175: LOG_TRACE(TRACE_IDE, "IDE: lget($%x) = $%08x\n", addr, retval);
1.1.1.2 root 176: return retval;
1.1 root 177: }
178:
179:
180: /**
181: * Handle byte write access to IDE IO memory.
182: */
1.1.1.10! root 183: void REGPARAM3 Ide_Mem_bput(uaecptr addr, uae_u32 val)
1.1 root 184: {
1.1.1.2 root 185: int ideport;
1.1 root 186:
187: addr &= 0x00ffffff; /* Use a 24 bit address */
1.1.1.2 root 188: val &= 0x0ff;
189:
1.1.1.9 root 190: LOG_TRACE(TRACE_IDE, "IDE: bput($%x, $%x)\n", addr, val);
1.1 root 191:
1.1.1.4 root 192: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 193: {
194: /* invalid memory addressing --> bus error */
1.1.1.9 root 195: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_BYTE, BUS_ERROR_ACCESS_DATA);
1.1 root 196: return;
197: }
198:
1.1.1.2 root 199: ideport = fcha2io(addr);
200:
1.1.1.3 root 201: if (ideport >= 1 && ideport <= 7)
1.1.1.2 root 202: {
203: ide_ioport_write(opaque_ide_if, ideport, val);
1.1.1.3 root 204: }
205: else if (ideport == 8 || ideport == 22)
206: {
1.1.1.2 root 207: ide_cmd_write(opaque_ide_if, 0, val);
208: }
1.1 root 209: }
210:
211:
212: /**
213: * Handle word write access to IDE IO memory.
214: */
1.1.1.10! root 215: void REGPARAM3 Ide_Mem_wput(uaecptr addr, uae_u32 val)
1.1 root 216: {
217: addr &= 0x00ffffff; /* Use a 24 bit address */
1.1.1.2 root 218: val &= 0x0ffff;
219:
1.1.1.9 root 220: LOG_TRACE(TRACE_IDE, "IDE: wput($%x, $%x)\n", addr, val);
1.1 root 221:
1.1.1.4 root 222: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 223: {
224: /* invalid memory addressing --> bus error */
1.1.1.9 root 225: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_WORD, BUS_ERROR_ACCESS_DATA);
1.1 root 226: return;
227: }
228:
1.1.1.10! root 229: if (addr == 0xf00000 || addr == 0xf00002)
1.1.1.2 root 230: {
231: ide_data_writew(opaque_ide_if, 0, val);
232: }
1.1 root 233: }
234:
235:
236: /**
237: * Handle long-word write access to IDE IO memory.
238: */
1.1.1.10! root 239: void REGPARAM3 Ide_Mem_lput(uaecptr addr, uae_u32 val)
1.1 root 240: {
241: addr &= 0x00ffffff; /* Use a 24 bit address */
242:
1.1.1.9 root 243: LOG_TRACE(TRACE_IDE, "IDE: lput($%x, $%x)\n", addr, val);
1.1.1.2 root 244:
1.1.1.4 root 245: if (addr >= 0xf00040 || !ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1 root 246: {
247: /* invalid memory addressing --> bus error */
1.1.1.9 root 248: M68000_BusError(addr, BUS_ERROR_WRITE, BUS_ERROR_SIZE_LONG, BUS_ERROR_ACCESS_DATA);
1.1 root 249: return;
250: }
251:
1.1.1.2 root 252: /* word swap for long access to data register */
253: val = ((val >> 16) & 0x0000ffff) | ((val & 0x0000ffff) << 16);
254:
255: if (addr == 0xf00000)
256: {
257: ide_data_writel(opaque_ide_if, 0, val);
258: }
259: }
260:
261:
262: /*----------------------------------------------------------------------------*/
263:
264:
265: /*
266: * QEMU IDE disk and CD-ROM Emulator
267: *
268: * Copyright (c) 2003 Fabrice Bellard
269: * Copyright (c) 2006 Openedhand Ltd.
270: *
271: * Permission is hereby granted, free of charge, to any person obtaining a copy
272: * of this software and associated documentation files (the "Software"), to deal
273: * in the Software without restriction, including without limitation the rights
274: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
275: * copies of the Software, and to permit persons to whom the Software is
276: * furnished to do so, subject to the following conditions:
277: *
278: * The above copyright notice and this permission notice shall be included in
279: * all copies or substantial portions of the Software.
280: *
281: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
282: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
283: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
284: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
285: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
286: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
287: * THE SOFTWARE.
288: */
289:
290: #define FW_VERSION "1.0"
291:
292:
293: #define BDRV_TYPE_HD 0
294: #define BDRV_TYPE_CDROM 1
295: #define BDRV_TYPE_FLOPPY 2
296: #define BIOS_ATA_TRANSLATION_AUTO 0
297: #define BIOS_ATA_TRANSLATION_NONE 1
298: #define BIOS_ATA_TRANSLATION_LBA 2
299: #define BIOS_ATA_TRANSLATION_LARGE 3
300: #define BIOS_ATA_TRANSLATION_RECHS 4
301:
302: #ifndef ENOMEDIUM // It's not defined on Mac OS X for example
303: #define ENOMEDIUM ENODEV
304: #endif
305:
306:
307: typedef struct BlockDriverState BlockDriverState;
308:
309: struct BlockDriverState {
310: int64_t total_sectors; /* if we are reading a disk image, give its
311: size in sectors */
312: int read_only; /* if true, the media is read only */
313: int removable; /* if true, the media can be removed */
314: int locked; /* if true, the media cannot temporarily be ejected */
315: int sg; /* if true, the device is a /dev/sg* */
316: /* event callback when inserting/removing */
317: void (*change_cb)(void *opaque);
318: void *change_opaque;
319:
320: FILE *fhndl;
321: void *opaque;
1.1.1.10! root 322: off_t file_size;
1.1.1.2 root 323: int media_changed;
324:
325: /* I/O stats (display with "info blockstats"). */
326: uint64_t rd_bytes;
327: uint64_t wr_bytes;
328: uint64_t rd_ops;
329: uint64_t wr_ops;
330:
331: /* NOTE: the following infos are only hints for real hardware
332: drivers. They are not used by the block driver */
333: int cyls, heads, secs, translation;
334: int type;
335: };
336:
337:
338: static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
339: {
340: uint8_t *p1 = (uint8_t *)p;
341:
342: p1[0] = v >> 8;
343: p1[1] = v;
344: }
345:
346:
347: #define le32_to_cpu SDL_SwapLE32
348: #define le16_to_cpu SDL_SwapLE16
349: #define cpu_to_le32 SDL_SwapLE32
350: #define cpu_to_le16 SDL_SwapLE16
351:
352:
353: #define MIN(a, b) (((a) < (b)) ? (a) : (b))
354:
355: #define SECTOR_BITS 9
356: #define SECTOR_SIZE (1 << SECTOR_BITS)
357:
358:
359: /**
360: * return 0 as number of sectors if no device present or error
361: */
362: static void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
363: {
1.1.1.10! root 364: off_t length = bs->file_size;
1.1.1.2 root 365:
366: if (length < 0)
367: length = 0;
368: else
369: length = length >> SECTOR_BITS;
370: *nb_sectors_ptr = length;
371: }
372:
373: static void bdrv_get_geometry_hint(BlockDriverState *bs,
374: int *pcyls, int *pheads, int *psecs)
375: {
376: *pcyls = bs->cyls;
377: *pheads = bs->heads;
378: *psecs = bs->secs;
379: }
380:
381: static void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
382: {
383: bs->translation = translation;
384: }
385:
386: static void bdrv_set_geometry_hint(BlockDriverState *bs,
387: int cyls, int heads, int secs)
388: {
389: bs->cyls = cyls;
390: bs->heads = heads;
391: bs->secs = secs;
392: }
393:
394: static int bdrv_get_type_hint(BlockDriverState *bs)
395: {
396: return bs->type;
397: }
398:
399: static int bdrv_get_translation_hint(BlockDriverState *bs)
400: {
401: return bs->translation;
402: }
403:
404: /* XXX: no longer used */
405: static void bdrv_set_change_cb(BlockDriverState *bs,
406: void (*change_cb)(void *opaque), void *opaque)
407: {
408: bs->change_cb = change_cb;
409: bs->change_opaque = opaque;
410: }
411:
412:
413: /**
414: * Return TRUE if the media is present
415: */
416: static int bdrv_is_inserted(BlockDriverState *bs)
417: {
418: return (bs->fhndl != NULL);
419: }
420:
421:
422: static int bdrv_is_locked(BlockDriverState *bs)
423: {
424: return bs->locked;
425: }
426:
427: /**
428: * Lock or unlock the media (if it is locked, the user won't be able
429: * to eject it manually).
430: */
431: static void bdrv_set_locked(BlockDriverState *bs, int locked)
432: {
433: bs->locked = locked;
434: }
435:
436:
437: /* return < 0 if error. See bdrv_write() for the return codes */
438: static int bdrv_read(BlockDriverState *bs, int64_t sector_num,
439: uint8_t *buf, int nb_sectors)
440: {
1.1.1.3 root 441: int ret, len;
442:
1.1.1.2 root 443: if (!bs->fhndl)
444: return -ENOMEDIUM;
445:
1.1.1.10! root 446: len = nb_sectors * SECTOR_SIZE;
1.1.1.2 root 447:
1.1.1.10! root 448: if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
1.1.1.9 root 449: {
450: perror("bdrv_read");
451: return -errno;
452: }
1.1.1.2 root 453: ret = fread(buf, 1, len, bs->fhndl);
454: if (ret != len)
455: {
1.1.1.9 root 456: fprintf(stderr,"IDE: bdrv_read error (%d != %d length) at sector %lu!\n", ret, len, (unsigned long)sector_num);
1.1.1.2 root 457: return -EINVAL;
458: }
459: else
460: {
461: bs->rd_bytes += (unsigned) len;
462: bs->rd_ops ++;
463: return 0;
464: }
465: }
466:
467:
468: /* Return < 0 if error. Important errors are:
469: -EIO generic I/O error (may happen for all errors)
470: -ENOMEDIUM No media inserted.
471: -EINVAL Invalid sector number or nb_sectors
472: -EACCES Trying to write a read-only device
473: */
474: static int bdrv_write(BlockDriverState *bs, int64_t sector_num,
475: const uint8_t *buf, int nb_sectors)
476: {
1.1.1.3 root 477: int ret, len;
478:
1.1.1.2 root 479: if (!bs->fhndl)
480: return -ENOMEDIUM;
481: if (bs->read_only)
482: return -EACCES;
483:
1.1.1.10! root 484: len = nb_sectors * SECTOR_SIZE;
1.1.1.2 root 485:
1.1.1.10! root 486: if (fseeko(bs->fhndl, sector_num * SECTOR_SIZE, SEEK_SET) != 0)
1.1.1.9 root 487: {
488: perror("bdrv_write");
489: return -errno;
490: }
1.1.1.2 root 491: ret = fwrite(buf, 1, len, bs->fhndl);
492: if (ret != len)
493: {
1.1.1.9 root 494: fprintf(stderr,"IDE: bdrv_write error (%d != %d length) at sector %lu!\n", ret, len, (unsigned long)sector_num);
1.1.1.2 root 495: return -EIO;
496: }
497: else
498: {
499: bs->wr_bytes += (unsigned) len;
500: bs->wr_ops ++;
501: return 0;
502: }
503: }
504:
505:
506: static int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
507: {
1.1.1.9 root 508: Log_Printf(LOG_INFO, "Mounting IDE hard drive image %s\n", filename);
1.1.1.2 root 509:
510: bs->read_only = 0;
1.1.1.10! root 511: bs->file_size = HDC_CheckAndGetSize(filename);
! 512: if (bs->file_size <= 0)
! 513: return -1;
! 514: if (bs->file_size < 2 * 16 * 63 * SECTOR_SIZE)
! 515: {
! 516: Log_AlertDlg(LOG_ERROR, "IDE disk image size (%"PRId64" bytes) is "
! 517: "too small for an IDE disk image "
! 518: "(min. 1032192 byte)", bs->file_size);
! 519: return -1;
! 520: }
1.1.1.2 root 521:
522: bs->fhndl = fopen(filename, "rb+");
523: if (!bs->fhndl) {
524: /* Maybe the file is read-only? */
525: bs->fhndl = fopen(filename, "rb");
526: if (!bs->fhndl)
527: perror("bdrv_open");
528: bs->read_only = 1;
529: }
1.1.1.9 root 530: else if (!File_Lock(bs->fhndl))
531: {
532: Log_Printf(LOG_ERROR, "ERROR: cannot lock HD file for writing!\n");
533: fclose(bs->fhndl);
534: bs->fhndl = NULL;
535: }
1.1.1.2 root 536:
537: /* call the change callback */
538: bs->media_changed = 1;
539: if (bs->change_cb)
540: bs->change_cb(bs->change_opaque);
541:
542: return 0;
543: }
544:
545: static void bdrv_flush(BlockDriverState *bs)
546: {
547: fflush(bs->fhndl);
548: }
549:
550: static void bdrv_close(BlockDriverState *bs)
551: {
1.1.1.9 root 552: File_UnLock(bs->fhndl);
1.1.1.2 root 553: fclose(bs->fhndl);
554: bs->fhndl = NULL;
555: }
556:
557: /**
558: * If eject_flag is TRUE, eject the media. Otherwise, close the tray
559: */
560: static void bdrv_eject(BlockDriverState *bs, int eject_flag)
561: {
562: if (eject_flag)
563: bdrv_close(bs);
564: }
565:
566:
567: // #define USE_DMA_CDROM
568:
569: /* Bits of HD_STATUS */
570: #define ERR_STAT 0x01
571: #define INDEX_STAT 0x02
572: #define ECC_STAT 0x04 /* Corrected error */
573: #define DRQ_STAT 0x08
574: #define SEEK_STAT 0x10
575: #define SRV_STAT 0x10
576: #define WRERR_STAT 0x20
577: #define READY_STAT 0x40
578: #define BUSY_STAT 0x80
579:
580: /* Bits for HD_ERROR */
581: #define MARK_ERR 0x01 /* Bad address mark */
582: #define TRK0_ERR 0x02 /* couldn't find track 0 */
583: #define ABRT_ERR 0x04 /* Command aborted */
584: #define MCR_ERR 0x08 /* media change request */
585: #define ID_ERR 0x10 /* ID field not found */
586: #define MC_ERR 0x20 /* media changed */
587: #define ECC_ERR 0x40 /* Uncorrectable ECC error */
588: #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
589: #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
590:
591: /* Bits of HD_NSECTOR */
592: #define CD 0x01
593: #define IO 0x02
594: #define REL 0x04
595: #define TAG_MASK 0xf8
596:
597: #define IDE_CMD_RESET 0x04
598: #define IDE_CMD_DISABLE_IRQ 0x02
599:
600: /* ATA/ATAPI Commands pre T13 Spec */
601: #define WIN_NOP 0x00
602: /*
603: * 0x01->0x02 Reserved
604: */
605: #define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */
606: /*
607: * 0x04->0x07 Reserved
608: */
609: #define WIN_SRST 0x08 /* ATAPI soft reset command */
610: #define WIN_DEVICE_RESET 0x08
611: /*
612: * 0x09->0x0F Reserved
613: */
614: #define WIN_RECAL 0x10
615: #define WIN_RESTORE WIN_RECAL
616: /*
617: * 0x10->0x1F Reserved
618: */
619: #define WIN_READ 0x20 /* 28-Bit */
620: #define WIN_READ_ONCE 0x21 /* 28-Bit without retries */
621: #define WIN_READ_LONG 0x22 /* 28-Bit */
622: #define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */
623: #define WIN_READ_EXT 0x24 /* 48-Bit */
624: #define WIN_READDMA_EXT 0x25 /* 48-Bit */
625: #define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */
626: #define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
627: /*
628: * 0x28
629: */
630: #define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
631: /*
632: * 0x2A->0x2F Reserved
633: */
634: #define WIN_WRITE 0x30 /* 28-Bit */
635: #define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */
636: #define WIN_WRITE_LONG 0x32 /* 28-Bit */
637: #define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */
638: #define WIN_WRITE_EXT 0x34 /* 48-Bit */
639: #define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
640: #define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
641: #define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
642: #define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */
643: #define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
644: /*
645: * 0x3A->0x3B Reserved
646: */
647: #define WIN_WRITE_VERIFY 0x3C /* 28-Bit */
648: /*
649: * 0x3D->0x3F Reserved
650: */
651: #define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
652: #define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */
653: #define WIN_VERIFY_EXT 0x42 /* 48-Bit */
654: /*
655: * 0x43->0x4F Reserved
656: */
657: #define WIN_FORMAT 0x50
658: /*
659: * 0x51->0x5F Reserved
660: */
661: #define WIN_INIT 0x60
662: /*
663: * 0x61->0x5F Reserved
664: */
665: #define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */
666: #define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
667: #define WIN_DIAGNOSE 0x90
668: #define WIN_SPECIFY 0x91 /* set drive geometry translation */
669: #define WIN_DOWNLOAD_MICROCODE 0x92
670: #define WIN_STANDBYNOW2 0x94
671: #define CFA_IDLEIMMEDIATE 0x95 /* force drive to become "ready" */
672: #define WIN_STANDBY2 0x96
673: #define WIN_SETIDLE2 0x97
674: #define WIN_CHECKPOWERMODE2 0x98
675: #define WIN_SLEEPNOW2 0x99
676: /*
677: * 0x9A VENDOR
678: */
679: #define WIN_PACKETCMD 0xA0 /* Send a packet command. */
680: #define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
681: #define WIN_QUEUED_SERVICE 0xA2
682: #define WIN_SMART 0xB0 /* self-monitoring and reporting */
683: #define CFA_ACCESS_METADATA_STORAGE 0xB8
684: #define CFA_ERASE_SECTORS 0xC0 /* microdrives implement as NOP */
685: #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/
686: #define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
687: #define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
688: #define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
689: #define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
690: #define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */
691: #define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
692: #define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */
693: #define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
694: #define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */
695: #define WIN_GETMEDIASTATUS 0xDA
696: #define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */
697: #define WIN_POSTBOOT 0xDC
698: #define WIN_PREBOOT 0xDD
699: #define WIN_DOORLOCK 0xDE /* lock door on removable drives */
700: #define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
701: #define WIN_STANDBYNOW1 0xE0
702: #define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
703: #define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
704: #define WIN_SETIDLE1 0xE3
705: #define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
706: #define WIN_CHECKPOWERMODE1 0xE5
707: #define WIN_SLEEPNOW1 0xE6
708: #define WIN_FLUSH_CACHE 0xE7
709: #define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
710: #define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */
711: /* SET_FEATURES 0x22 or 0xDD */
712: #define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
713: #define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
714: #define WIN_MEDIAEJECT 0xED
715: #define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
716: #define WIN_SETFEATURES 0xEF /* set special drive features */
717: #define EXABYTE_ENABLE_NEST 0xF0
718: #define IBM_SENSE_CONDITION 0xF0 /* measure disk temperature */
719: #define WIN_SECURITY_SET_PASS 0xF1
720: #define WIN_SECURITY_UNLOCK 0xF2
721: #define WIN_SECURITY_ERASE_PREPARE 0xF3
722: #define WIN_SECURITY_ERASE_UNIT 0xF4
723: #define WIN_SECURITY_FREEZE_LOCK 0xF5
724: #define CFA_WEAR_LEVEL 0xF5 /* microdrives implement as NOP */
725: #define WIN_SECURITY_DISABLE 0xF6
726: #define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */
727: #define WIN_SET_MAX 0xF9
728: #define DISABLE_SEAGATE 0xFB
729:
730: /* set to 1 set disable mult support */
731: #define MAX_MULT_SECTORS 16
732:
733: /* ATAPI defines */
734:
735: #define ATAPI_PACKET_SIZE 12
736:
737: /* The generic packet command opcodes for CD/DVD Logical Units,
738: * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
739: #define GPCMD_BLANK 0xa1
740: #define GPCMD_CLOSE_TRACK 0x5b
741: #define GPCMD_FLUSH_CACHE 0x35
742: #define GPCMD_FORMAT_UNIT 0x04
743: #define GPCMD_GET_CONFIGURATION 0x46
744: #define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
745: #define GPCMD_GET_PERFORMANCE 0xac
746: #define GPCMD_INQUIRY 0x12
747: #define GPCMD_LOAD_UNLOAD 0xa6
748: #define GPCMD_MECHANISM_STATUS 0xbd
749: #define GPCMD_MODE_SELECT_10 0x55
750: #define GPCMD_MODE_SENSE_10 0x5a
751: #define GPCMD_PAUSE_RESUME 0x4b
752: #define GPCMD_PLAY_AUDIO_10 0x45
753: #define GPCMD_PLAY_AUDIO_MSF 0x47
754: #define GPCMD_PLAY_AUDIO_TI 0x48
755: #define GPCMD_PLAY_CD 0xbc
756: #define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
757: #define GPCMD_READ_10 0x28
758: #define GPCMD_READ_12 0xa8
759: #define GPCMD_READ_CDVD_CAPACITY 0x25
760: #define GPCMD_READ_CD 0xbe
761: #define GPCMD_READ_CD_MSF 0xb9
762: #define GPCMD_READ_DISC_INFO 0x51
763: #define GPCMD_READ_DVD_STRUCTURE 0xad
764: #define GPCMD_READ_FORMAT_CAPACITIES 0x23
765: #define GPCMD_READ_HEADER 0x44
766: #define GPCMD_READ_TRACK_RZONE_INFO 0x52
767: #define GPCMD_READ_SUBCHANNEL 0x42
768: #define GPCMD_READ_TOC_PMA_ATIP 0x43
769: #define GPCMD_REPAIR_RZONE_TRACK 0x58
770: #define GPCMD_REPORT_KEY 0xa4
771: #define GPCMD_REQUEST_SENSE 0x03
772: #define GPCMD_RESERVE_RZONE_TRACK 0x53
773: #define GPCMD_SCAN 0xba
774: #define GPCMD_SEEK 0x2b
775: #define GPCMD_SEND_DVD_STRUCTURE 0xad
776: #define GPCMD_SEND_EVENT 0xa2
777: #define GPCMD_SEND_KEY 0xa3
778: #define GPCMD_SEND_OPC 0x54
779: #define GPCMD_SET_READ_AHEAD 0xa7
780: #define GPCMD_SET_STREAMING 0xb6
781: #define GPCMD_START_STOP_UNIT 0x1b
782: #define GPCMD_STOP_PLAY_SCAN 0x4e
783: #define GPCMD_TEST_UNIT_READY 0x00
784: #define GPCMD_VERIFY_10 0x2f
785: #define GPCMD_WRITE_10 0x2a
786: #define GPCMD_WRITE_AND_VERIFY_10 0x2e
787: /* This is listed as optional in ATAPI 2.6, but is (curiously)
788: * missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji
789: * Table 377 as an MMC command for SCSi devices though... Most ATAPI
790: * drives support it. */
791: #define GPCMD_SET_SPEED 0xbb
792: /* This seems to be a SCSI specific CD-ROM opcode
793: * to play data at track/index */
794: #define GPCMD_PLAYAUDIO_TI 0x48
795: /*
796: * From MS Media Status Notification Support Specification. For
797: * older drives only.
798: */
799: #define GPCMD_GET_MEDIA_STATUS 0xda
800: #define GPCMD_MODE_SENSE_6 0x1a
801:
802: /* Mode page codes for mode sense/set */
803: #define GPMODE_R_W_ERROR_PAGE 0x01
804: #define GPMODE_WRITE_PARMS_PAGE 0x05
805: #define GPMODE_AUDIO_CTL_PAGE 0x0e
806: #define GPMODE_POWER_PAGE 0x1a
807: #define GPMODE_FAULT_FAIL_PAGE 0x1c
808: #define GPMODE_TO_PROTECT_PAGE 0x1d
809: #define GPMODE_CAPABILITIES_PAGE 0x2a
810: #define GPMODE_ALL_PAGES 0x3f
811: /* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
812: * of MODE_SENSE_POWER_PAGE */
813: #define GPMODE_CDROM_PAGE 0x0d
814:
815: #define ATAPI_INT_REASON_CD 0x01 /* 0 = data transfer */
816: #define ATAPI_INT_REASON_IO 0x02 /* 1 = transfer to the host */
817: #define ATAPI_INT_REASON_REL 0x04
818: #define ATAPI_INT_REASON_TAG 0xf8
819:
820: /* same constants as bochs */
821: #define ASC_ILLEGAL_OPCODE 0x20
822: #define ASC_LOGICAL_BLOCK_OOR 0x21
823: #define ASC_INV_FIELD_IN_CMD_PACKET 0x24
824: #define ASC_MEDIUM_NOT_PRESENT 0x3a
825: #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
826:
827: #define SENSE_NONE 0
828: #define SENSE_NOT_READY 2
829: #define SENSE_ILLEGAL_REQUEST 5
830: #define SENSE_UNIT_ATTENTION 6
831:
832: typedef void EndTransferFunc(struct IDEState *);
833:
834: /* NOTE: IDEState represents in fact one drive */
835: typedef struct IDEState
836: {
837: /* ide config */
838: int is_cdrom;
839: int cylinders, heads, sectors;
840: int64_t nb_sectors;
841: int mult_sectors;
842: int identify_set;
843: uint16_t identify_data[256];
844: int drive_serial;
845: /* ide regs */
846: uint8_t feature;
847: uint8_t error;
848: uint32_t nsector;
849: uint8_t sector;
850: uint8_t lcyl;
851: uint8_t hcyl;
852: /* other part of tf for lba48 support */
853: uint8_t hob_feature;
854: uint8_t hob_nsector;
855: uint8_t hob_sector;
856: uint8_t hob_lcyl;
857: uint8_t hob_hcyl;
858:
859: uint8_t select;
860: uint8_t status;
861:
862: /* 0x3f6 command, only meaningful for drive 0 */
863: uint8_t cmd;
864: /* set for lba48 access */
865: uint8_t lba48;
866: /* depends on bit 4 in select, only meaningful for drive 0 */
867: struct IDEState *cur_drive;
868: BlockDriverState *bs;
869: /* ATAPI specific */
870: uint8_t sense_key;
871: uint8_t asc;
872: int packet_transfer_size;
873: int elementary_transfer_size;
874: int io_buffer_index;
875: int lba;
876: int cd_sector_size;
877: /* ATA DMA state */
878: int io_buffer_size;
879: /* PIO transfer handling */
880: int req_nb_sectors; /* number of sectors per interrupt */
881: EndTransferFunc *end_transfer_func;
882: uint8_t *data_ptr;
883: uint8_t *data_end;
884: uint8_t *io_buffer;
885: int media_changed;
886: } IDEState;
887:
888:
889: static void padstr(char *str, const char *src, int len)
890: {
891: int i, v;
892: for (i = 0; i < len; i++)
893: {
894: if (*src)
895: v = *src++;
896: else
897: v = ' ';
898: str[i^1] = v;
899: }
900: }
901:
902: static void padstr8(uint8_t *buf, int buf_size, const char *src)
903: {
904: int i;
905: for (i = 0; i < buf_size; i++)
906: {
907: if (*src)
908: buf[i] = *src++;
909: else
910: buf[i] = ' ';
911: }
912: }
913:
914: static void put_le16(uint16_t *p, unsigned int v)
915: {
916: *p = SDL_SwapLE16(v);
917: }
918:
919: static void ide_identify(IDEState *s)
920: {
921: uint16_t *p;
922: unsigned int oldsize;
923: char buf[20];
924:
925: if (s->identify_set)
926: {
927: memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
928: return;
929: }
930:
931: memset(s->io_buffer, 0, 512);
932: p = (uint16_t *)s->io_buffer;
933: put_le16(p + 0, 0x0040);
934: put_le16(p + 1, s->cylinders);
935: put_le16(p + 3, s->heads);
936: put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
937: put_le16(p + 5, 512); /* XXX: retired, remove ? */
938: put_le16(p + 6, s->sectors);
939: snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
940: padstr((char *)(p + 10), buf, 20); /* serial number */
941: put_le16(p + 20, 3); /* XXX: retired, remove ? */
942: put_le16(p + 21, 512); /* cache size in sectors */
943: put_le16(p + 22, 4); /* ecc bytes */
944: padstr((char *)(p + 23), FW_VERSION, 8); /* firmware version */
1.1.1.4 root 945: if(s == opaque_ide_if) /* model */
946: {
947: padstr((char *)(p + 27), "Hatari IDE master disk", 40);
948: }
949: else
950: {
951: padstr((char *)(p + 27), "Hatari IDE slave disk", 40);
952: }
1.1.1.2 root 953: #if MAX_MULT_SECTORS > 1
954: put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
955: #endif
956: put_le16(p + 48, 1); /* dword I/O */
957: put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8)); /* DMA and LBA supported */
958: put_le16(p + 51, 0x200); /* PIO transfer cycle */
959: put_le16(p + 52, 0x200); /* DMA transfer cycle */
960: put_le16(p + 53, 1 | (1 << 1) | (1 << 2)); /* words 54-58,64-70,88 are valid */
961: put_le16(p + 54, s->cylinders);
962: put_le16(p + 55, s->heads);
963: put_le16(p + 56, s->sectors);
964: oldsize = s->cylinders * s->heads * s->sectors;
965: put_le16(p + 57, oldsize);
966: put_le16(p + 58, oldsize >> 16);
967: if (s->mult_sectors)
968: put_le16(p + 59, 0x100 | s->mult_sectors);
969: put_le16(p + 60, s->nb_sectors);
970: put_le16(p + 61, s->nb_sectors >> 16);
971: put_le16(p + 63, 0x07); /* mdma0-2 supported */
972: put_le16(p + 65, 120);
973: put_le16(p + 66, 120);
974: put_le16(p + 67, 120);
975: put_le16(p + 68, 120);
976: put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
977: put_le16(p + 81, 0x16); /* conforms to ata5 */
978: put_le16(p + 82, (1 << 14));
979: /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
980: put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
981: put_le16(p + 84, (1 << 14));
982: put_le16(p + 85, (1 << 14));
983: /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
984: put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
985: put_le16(p + 87, (1 << 14));
986: put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
987: put_le16(p + 93, 1 | (1 << 14) | 0x2000);
988: put_le16(p + 100, s->nb_sectors);
989: put_le16(p + 101, s->nb_sectors >> 16);
990: put_le16(p + 102, s->nb_sectors >> 32);
991: put_le16(p + 103, s->nb_sectors >> 48);
992:
993: memcpy(s->identify_data, p, sizeof(s->identify_data));
994: s->identify_set = 1;
995: }
996:
997: static void ide_atapi_identify(IDEState *s)
998: {
999: uint16_t *p;
1000: char buf[20];
1001:
1002: if (s->identify_set)
1003: {
1004: memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
1005: return;
1006: }
1007:
1008: memset(s->io_buffer, 0, 512);
1009: p = (uint16_t *)s->io_buffer;
1010: /* Removable CDROM, 50us response, 12 byte packets */
1011: put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
1012: snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
1013: padstr((char *)(p + 10), buf, 20); /* serial number */
1014: put_le16(p + 20, 3); /* buffer type */
1015: put_le16(p + 21, 512); /* cache size in sectors */
1016: put_le16(p + 22, 4); /* ecc bytes */
1017: padstr((char *)(p + 23), FW_VERSION, 8); /* firmware version */
1018: padstr((char *)(p + 27), "Hatari CD-ROM", 40); /* model */
1019: put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
1020: #ifdef USE_DMA_CDROM
1021: put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
1022: put_le16(p + 53, 7); /* words 64-70, 54-58, 88 valid */
1023: put_le16(p + 63, 7); /* mdma0-2 supported */
1024: put_le16(p + 64, 0x3f); /* PIO modes supported */
1025: #else
1026: put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
1027: put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
1028: put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
1029: put_le16(p + 64, 1); /* PIO modes */
1030: #endif
1031: put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
1032: put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
1033: put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
1034: put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
1035:
1036: put_le16(p + 71, 30); /* in ns */
1037: put_le16(p + 72, 30); /* in ns */
1038:
1039: put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
1040: #ifdef USE_DMA_CDROM
1041: put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
1042: #endif
1043: memcpy(s->identify_data, p, sizeof(s->identify_data));
1044: s->identify_set = 1;
1045: }
1046:
1047:
1048: static void ide_set_signature(IDEState *s)
1049: {
1050: s->select &= 0xf0; /* clear head */
1051: /* put signature */
1052: s->nsector = 1;
1053: s->sector = 1;
1054: if (s->is_cdrom)
1055: {
1056: s->lcyl = 0x14;
1057: s->hcyl = 0xeb;
1058: }
1059: else if (s->bs)
1060: {
1061: s->lcyl = 0;
1062: s->hcyl = 0;
1063: }
1064: else
1065: {
1066: s->lcyl = 0xff;
1067: s->hcyl = 0xff;
1068: }
1069: }
1070:
1071: static inline void ide_abort_command(IDEState *s)
1072: {
1073: s->status = READY_STAT | ERR_STAT;
1074: s->error = ABRT_ERR;
1075: }
1076:
1077: static inline void ide_set_irq(IDEState *s)
1078: {
1079: if (!(s->cmd & IDE_CMD_DISABLE_IRQ))
1080: {
1.1.1.9 root 1081: /* Set IRQ (set line to low) */
1082: MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_FDC_HDC , MFP_GPIP_STATE_LOW );
1.1.1.2 root 1083: }
1084: }
1085:
1086: /* prepare data transfer and tell what to do after */
1087: static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
1088: EndTransferFunc *end_transfer_func)
1089: {
1090: s->end_transfer_func = end_transfer_func;
1091: s->data_ptr = buf;
1092: s->data_end = buf + size;
1093: if (!(s->status & ERR_STAT))
1094: s->status |= DRQ_STAT;
1095: }
1096:
1097: static void ide_transfer_stop(IDEState *s)
1098: {
1099: s->end_transfer_func = ide_transfer_stop;
1100: s->data_ptr = s->io_buffer;
1101: s->data_end = s->io_buffer;
1102: s->status &= ~DRQ_STAT;
1103: }
1104:
1105: static int64_t ide_get_sector(IDEState *s)
1106: {
1107: int64_t sector_num;
1108: if (s->select & 0x40)
1109: {
1110: /* lba */
1111: if (!s->lba48)
1112: {
1113: sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
1114: (s->lcyl << 8) | s->sector;
1115: }
1116: else
1117: {
1118: sector_num = ((int64_t)s->hob_hcyl << 40) |
1119: ((int64_t) s->hob_lcyl << 32) |
1120: ((int64_t) s->hob_sector << 24) |
1121: ((int64_t) s->hcyl << 16) |
1122: ((int64_t) s->lcyl << 8) | s->sector;
1123: }
1124: }
1125: else
1126: {
1127: sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
1128: (s->select & 0x0f) * s->sectors + (s->sector - 1);
1129: }
1130: return sector_num;
1131: }
1132:
1133: static void ide_set_sector(IDEState *s, int64_t sector_num)
1134: {
1135: unsigned int cyl, r;
1136: if (s->select & 0x40)
1137: {
1138: if (!s->lba48)
1139: {
1140: s->select = (s->select & 0xf0) | (sector_num >> 24);
1141: s->hcyl = (sector_num >> 16);
1142: s->lcyl = (sector_num >> 8);
1143: s->sector = (sector_num);
1144: }
1145: else
1146: {
1147: s->sector = sector_num;
1148: s->lcyl = sector_num >> 8;
1149: s->hcyl = sector_num >> 16;
1150: s->hob_sector = sector_num >> 24;
1151: s->hob_lcyl = sector_num >> 32;
1152: s->hob_hcyl = sector_num >> 40;
1153: }
1154: }
1155: else
1156: {
1157: cyl = sector_num / (s->heads * s->sectors);
1158: r = sector_num % (s->heads * s->sectors);
1159: s->hcyl = cyl >> 8;
1160: s->lcyl = cyl;
1161: s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
1162: s->sector = (r % s->sectors) + 1;
1163: }
1164: }
1165:
1166: static void ide_sector_read(IDEState *s)
1167: {
1168: int64_t sector_num;
1169: int ret, n;
1170:
1171: s->status = READY_STAT | SEEK_STAT;
1172: s->error = 0; /* not needed by IDE spec, but needed by Windows */
1173: sector_num = ide_get_sector(s);
1174: n = s->nsector;
1175: if (n == 0)
1176: {
1177: /* no more sector to read from disk */
1178: ide_transfer_stop(s);
1179: }
1180: else
1181: {
1.1.1.9 root 1182: LOG_TRACE(TRACE_IDE, "IDE: read sector=%"PRId64"\n", sector_num);
1183:
1.1.1.2 root 1184: if (n > s->req_nb_sectors)
1185: n = s->req_nb_sectors;
1186: ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
1.1.1.4 root 1187: if (ret != 0)
1188: {
1189: ide_abort_command(s);
1190: ide_set_irq(s);
1191: return;
1192: }
1.1.1.2 root 1193: ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
1194: ide_set_irq(s);
1195: ide_set_sector(s, sector_num + n);
1196: s->nsector -= n;
1197: }
1198: }
1199:
1200:
1201: static void ide_sector_write(IDEState *s)
1202: {
1203: int64_t sector_num;
1204: int ret, n, n1;
1205:
1206: s->status = READY_STAT | SEEK_STAT;
1207: sector_num = ide_get_sector(s);
1.1.1.9 root 1208: LOG_TRACE(TRACE_IDE, "IDE: write sector=%"PRId64"\n", sector_num);
1209:
1.1.1.2 root 1210: n = s->nsector;
1211: if (n > s->req_nb_sectors)
1212: n = s->req_nb_sectors;
1213: ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
1.1.1.4 root 1214: if (ret != 0)
1215: {
1216: ide_abort_command(s);
1217: ide_set_irq(s);
1218: return;
1219: }
1.1.1.2 root 1220: s->nsector -= n;
1221: if (s->nsector == 0)
1222: {
1223: /* no more sectors to write */
1224: ide_transfer_stop(s);
1225: }
1226: else
1227: {
1228: n1 = s->nsector;
1229: if (n1 > s->req_nb_sectors)
1230: n1 = s->req_nb_sectors;
1231: ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
1232: }
1233: ide_set_sector(s, sector_num + n);
1234:
1235: ide_set_irq(s);
1236: }
1237:
1238:
1239: static void ide_atapi_cmd_ok(IDEState *s)
1240: {
1241: s->error = 0;
1242: s->status = READY_STAT;
1243: s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1244: ide_set_irq(s);
1245: }
1246:
1247: static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
1248: {
1.1.1.9 root 1249: LOG_TRACE(TRACE_IDE, "IDE: ATAPI cmd error sense=0x%x asc=0x%x\n", sense_key, asc);
1250:
1.1.1.2 root 1251: s->error = sense_key << 4;
1252: s->status = READY_STAT | ERR_STAT;
1253: s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1254: s->sense_key = sense_key;
1255: s->asc = asc;
1256: ide_set_irq(s);
1257: }
1258:
1259: static inline void cpu_to_ube16(uint8_t *buf, int val)
1260: {
1261: buf[0] = val >> 8;
1262: buf[1] = val;
1263: }
1264:
1265: static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
1266: {
1267: buf[0] = val >> 24;
1268: buf[1] = val >> 16;
1269: buf[2] = val >> 8;
1270: buf[3] = val;
1271: }
1272:
1273: static inline int ube16_to_cpu(const uint8_t *buf)
1274: {
1275: return (buf[0] << 8) | buf[1];
1276: }
1277:
1278: static inline int ube32_to_cpu(const uint8_t *buf)
1279: {
1280: return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1281: }
1282:
1283: static void lba_to_msf(uint8_t *buf, int lba)
1284: {
1285: lba += 150;
1286: buf[0] = (lba / 75) / 60;
1287: buf[1] = (lba / 75) % 60;
1288: buf[2] = lba % 75;
1289: }
1290:
1291: static void cd_data_to_raw(uint8_t *buf, int lba)
1292: {
1293: /* sync bytes */
1294: buf[0] = 0x00;
1295: memset(buf + 1, 0xff, 10);
1296: buf[11] = 0x00;
1297: buf += 12;
1298: /* MSF */
1299: lba_to_msf(buf, lba);
1300: buf[3] = 0x01; /* mode 1 data */
1301: buf += 4;
1302: /* data */
1303: buf += 2048;
1304: /* XXX: ECC not computed */
1305: memset(buf, 0, 288);
1306: }
1307:
1308: static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
1309: int sector_size)
1310: {
1311: int ret;
1312:
1313: switch (sector_size)
1314: {
1315: case 2048:
1316: ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
1317: break;
1318: case 2352:
1319: ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
1320: if (ret < 0)
1321: return ret;
1322: cd_data_to_raw(buf, lba);
1323: break;
1324: default:
1325: ret = -EIO;
1326: break;
1327: }
1328: return ret;
1329: }
1330:
1331: static void ide_atapi_io_error(IDEState *s, int ret)
1332: {
1333: /* XXX: handle more errors */
1334: if (ret == -ENOMEDIUM)
1335: {
1336: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1337: ASC_MEDIUM_NOT_PRESENT);
1338: }
1339: else
1340: {
1341: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1342: ASC_LOGICAL_BLOCK_OOR);
1343: }
1344: }
1345:
1346: /* The whole ATAPI transfer logic is handled in this function */
1347: static void ide_atapi_cmd_reply_end(IDEState *s)
1348: {
1349: int byte_count_limit, size, ret;
1.1.1.9 root 1350:
1351: LOG_TRACE(TRACE_IDE, "IDE: ATAPI reply tx_size=%d elem_tx_size=%d index=%d\n",
1.1.1.2 root 1352: s->packet_transfer_size,
1353: s->elementary_transfer_size,
1354: s->io_buffer_index);
1.1.1.9 root 1355:
1.1.1.2 root 1356: if (s->packet_transfer_size <= 0)
1357: {
1358: /* end of transfer */
1359: ide_transfer_stop(s);
1360: s->status = READY_STAT;
1361: s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
1362: ide_set_irq(s);
1.1.1.9 root 1363: LOG_TRACE(TRACE_IDE, "IDE: ATAPI status=0x%x\n", s->status);
1.1.1.2 root 1364: }
1365: else
1366: {
1367: /* see if a new sector must be read */
1368: if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size)
1369: {
1370: ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
1371: if (ret < 0)
1372: {
1373: ide_transfer_stop(s);
1374: ide_atapi_io_error(s, ret);
1375: return;
1376: }
1377: s->lba++;
1378: s->io_buffer_index = 0;
1379: }
1380: if (s->elementary_transfer_size > 0)
1381: {
1382: /* there are some data left to transmit in this elementary
1383: transfer */
1384: size = s->cd_sector_size - s->io_buffer_index;
1385: if (size > s->elementary_transfer_size)
1386: size = s->elementary_transfer_size;
1387: ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1388: size, ide_atapi_cmd_reply_end);
1389: s->packet_transfer_size -= size;
1390: s->elementary_transfer_size -= size;
1391: s->io_buffer_index += size;
1392: }
1393: else
1394: {
1395: /* a new transfer is needed */
1396: s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
1397: byte_count_limit = s->lcyl | (s->hcyl << 8);
1.1.1.9 root 1398: LOG_TRACE(TRACE_IDE, "IDE: ATAPI byte_count_limit=%d\n", byte_count_limit);
1399:
1.1.1.2 root 1400: if (byte_count_limit == 0xffff)
1401: byte_count_limit--;
1402: size = s->packet_transfer_size;
1403: if (size > byte_count_limit)
1404: {
1405: /* byte count limit must be even if this case */
1406: if (byte_count_limit & 1)
1407: byte_count_limit--;
1408: size = byte_count_limit;
1409: }
1410: s->lcyl = size;
1411: s->hcyl = size >> 8;
1412: s->elementary_transfer_size = size;
1413: /* we cannot transmit more than one sector at a time */
1414: if (s->lba != -1)
1415: {
1416: if (size > (s->cd_sector_size - s->io_buffer_index))
1417: size = (s->cd_sector_size - s->io_buffer_index);
1418: }
1419: ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
1420: size, ide_atapi_cmd_reply_end);
1421: s->packet_transfer_size -= size;
1422: s->elementary_transfer_size -= size;
1423: s->io_buffer_index += size;
1424: ide_set_irq(s);
1.1.1.9 root 1425:
1426: LOG_TRACE(TRACE_IDE, "IDE: ATAPI status=0x%x\n", s->status);
1.1.1.2 root 1427: }
1428: }
1429: }
1430:
1431: /* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
1432: static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
1433: {
1434: if (size > max_size)
1435: size = max_size;
1436: s->lba = -1; /* no sector read */
1437: s->packet_transfer_size = size;
1438: s->io_buffer_size = size; /* dma: send the reply data as one chunk */
1439: s->elementary_transfer_size = 0;
1440: s->io_buffer_index = 0;
1441:
1442: s->status = READY_STAT;
1443: ide_atapi_cmd_reply_end(s);
1444: }
1445:
1446: /* start a CD-CDROM read command */
1447: static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
1448: int sector_size)
1449: {
1.1.1.9 root 1450: LOG_TRACE(TRACE_IDE, "IDE: ATAPI read pio LBA=%d nb_sectors=%d\n", lba, nb_sectors);
1451:
1.1.1.2 root 1452: s->lba = lba;
1453: s->packet_transfer_size = nb_sectors * sector_size;
1454: s->elementary_transfer_size = 0;
1455: s->io_buffer_index = sector_size;
1456: s->cd_sector_size = sector_size;
1457:
1458: s->status = READY_STAT;
1459: ide_atapi_cmd_reply_end(s);
1460: }
1461:
1462:
1463: static void ide_atapi_cmd(IDEState *s)
1464: {
1465: const uint8_t *packet;
1466: uint8_t *buf;
1467: int max_len;
1468:
1469: packet = s->io_buffer;
1470: buf = s->io_buffer;
1.1.1.9 root 1471: if (LOG_TRACE_LEVEL(TRACE_IDE))
1.1.1.2 root 1472: {
1473: int i;
1.1.1.9 root 1474: LOG_TRACE_PRINT("IDE: ATAPI limit=0x%x packet", s->lcyl | (s->hcyl << 8));
1.1.1.2 root 1475: for (i = 0; i < ATAPI_PACKET_SIZE; i++)
1476: {
1477: printf(" %02x", packet[i]);
1478: }
1479: printf("\n");
1480: }
1.1.1.9 root 1481:
1.1.1.2 root 1482: switch (s->io_buffer[0])
1483: {
1484: case GPCMD_TEST_UNIT_READY:
1485: if (bdrv_is_inserted(s->bs))
1486: {
1487: ide_atapi_cmd_ok(s);
1488: }
1489: else
1490: {
1491: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1492: ASC_MEDIUM_NOT_PRESENT);
1493: }
1494: break;
1495: case GPCMD_MODE_SENSE_6:
1496: case GPCMD_MODE_SENSE_10:
1497: {
1498: int action, code;
1499: if (packet[0] == GPCMD_MODE_SENSE_10)
1500: max_len = ube16_to_cpu(packet + 7);
1501: else
1502: max_len = packet[4];
1503: action = packet[2] >> 6;
1504: code = packet[2] & 0x3f;
1505: switch (action)
1506: {
1507: case 0: /* current values */
1508: switch (code)
1509: {
1510: case 0x01: /* error recovery */
1511: cpu_to_ube16(&buf[0], 16 + 6);
1512: buf[2] = 0x70;
1513: buf[3] = 0;
1514: buf[4] = 0;
1515: buf[5] = 0;
1516: buf[6] = 0;
1517: buf[7] = 0;
1518:
1519: buf[8] = 0x01;
1520: buf[9] = 0x06;
1521: buf[10] = 0x00;
1522: buf[11] = 0x05;
1523: buf[12] = 0x00;
1524: buf[13] = 0x00;
1525: buf[14] = 0x00;
1526: buf[15] = 0x00;
1527: ide_atapi_cmd_reply(s, 16, max_len);
1528: break;
1529: case 0x2a:
1530: cpu_to_ube16(&buf[0], 28 + 6);
1531: buf[2] = 0x70;
1532: buf[3] = 0;
1533: buf[4] = 0;
1534: buf[5] = 0;
1535: buf[6] = 0;
1536: buf[7] = 0;
1537:
1538: buf[8] = 0x2a;
1539: buf[9] = 0x12;
1540: buf[10] = 0x00;
1541: buf[11] = 0x00;
1542:
1543: buf[12] = 0x70;
1544: buf[13] = 3 << 5;
1545: buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
1546: if (bdrv_is_locked(s->bs))
1547: buf[6] |= 1 << 1;
1548: buf[15] = 0x00;
1549: cpu_to_ube16(&buf[16], 706);
1550: buf[18] = 0;
1551: buf[19] = 2;
1552: cpu_to_ube16(&buf[20], 512);
1553: cpu_to_ube16(&buf[22], 706);
1554: buf[24] = 0;
1555: buf[25] = 0;
1556: buf[26] = 0;
1557: buf[27] = 0;
1558: ide_atapi_cmd_reply(s, 28, max_len);
1559: break;
1560: default:
1561: goto error_cmd;
1562: }
1563: break;
1564: case 1: /* changeable values */
1565: goto error_cmd;
1566: case 2: /* default values */
1567: goto error_cmd;
1568: default:
1569: case 3: /* saved values */
1570: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1571: ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1572: break;
1573: }
1574: }
1575: break;
1576: case GPCMD_REQUEST_SENSE:
1577: max_len = packet[4];
1578: memset(buf, 0, 18);
1579: buf[0] = 0x70 | (1 << 7);
1580: buf[2] = s->sense_key;
1581: buf[7] = 10;
1582: buf[12] = s->asc;
1583: ide_atapi_cmd_reply(s, 18, max_len);
1584: break;
1585: case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
1586: if (bdrv_is_inserted(s->bs))
1587: {
1588: bdrv_set_locked(s->bs, packet[4] & 1);
1589: ide_atapi_cmd_ok(s);
1590: }
1591: else
1592: {
1593: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1594: ASC_MEDIUM_NOT_PRESENT);
1595: }
1596: break;
1597: case GPCMD_READ_10:
1598: case GPCMD_READ_12:
1599: {
1600: int nb_sectors, lba;
1601:
1602: if (packet[0] == GPCMD_READ_10)
1603: nb_sectors = ube16_to_cpu(packet + 7);
1604: else
1605: nb_sectors = ube32_to_cpu(packet + 6);
1606: lba = ube32_to_cpu(packet + 2);
1607: if (nb_sectors == 0)
1608: {
1609: ide_atapi_cmd_ok(s);
1610: break;
1611: }
1612: ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1613: }
1614: break;
1615: case GPCMD_READ_CD:
1616: {
1617: int nb_sectors, lba, transfer_request;
1618:
1619: nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
1620: lba = ube32_to_cpu(packet + 2);
1621: if (nb_sectors == 0)
1622: {
1623: ide_atapi_cmd_ok(s);
1624: break;
1625: }
1626: transfer_request = packet[9];
1627: switch (transfer_request & 0xf8)
1628: {
1629: case 0x00:
1630: /* nothing */
1631: ide_atapi_cmd_ok(s);
1632: break;
1633: case 0x10:
1634: /* normal read */
1635: ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
1636: break;
1637: case 0xf8:
1638: /* read all data */
1639: ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
1640: break;
1641: default:
1642: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1643: ASC_INV_FIELD_IN_CMD_PACKET);
1644: break;
1645: }
1646: }
1647: break;
1648: case GPCMD_SEEK:
1649: {
1650: unsigned int lba;
1651: uint64_t total_sectors;
1652:
1653: bdrv_get_geometry(s->bs, &total_sectors);
1654: total_sectors >>= 2;
1655: if (total_sectors == 0)
1656: {
1657: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1658: ASC_MEDIUM_NOT_PRESENT);
1659: break;
1660: }
1661: lba = ube32_to_cpu(packet + 2);
1662: if (lba >= total_sectors)
1663: {
1664: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1665: ASC_LOGICAL_BLOCK_OOR);
1666: break;
1667: }
1668: ide_atapi_cmd_ok(s);
1669: }
1670: break;
1671: case GPCMD_START_STOP_UNIT:
1672: {
1673: int start, eject;
1674: start = packet[4] & 1;
1675: eject = (packet[4] >> 1) & 1;
1676:
1677: if (eject && !start)
1678: {
1679: /* eject the disk */
1680: bdrv_eject(s->bs, 1);
1681: }
1682: else if (eject && start)
1683: {
1684: /* close the tray */
1685: bdrv_eject(s->bs, 0);
1686: }
1687: ide_atapi_cmd_ok(s);
1688: }
1689: break;
1690: case GPCMD_MECHANISM_STATUS:
1691: {
1692: max_len = ube16_to_cpu(packet + 8);
1693: cpu_to_ube16(buf, 0);
1694: /* no current LBA */
1695: buf[2] = 0;
1696: buf[3] = 0;
1697: buf[4] = 0;
1698: buf[5] = 1;
1699: cpu_to_ube16(buf + 6, 0);
1700: ide_atapi_cmd_reply(s, 8, max_len);
1701: }
1702: break;
1703: case GPCMD_READ_TOC_PMA_ATIP:
1704: {
1.1.1.6 root 1705: int format, len;
1706: // int msf, start_track;
1.1.1.2 root 1707: uint64_t total_sectors;
1708:
1709: bdrv_get_geometry(s->bs, &total_sectors);
1710: total_sectors >>= 2;
1711: if (total_sectors == 0)
1712: {
1713: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1714: ASC_MEDIUM_NOT_PRESENT);
1715: break;
1716: }
1717: max_len = ube16_to_cpu(packet + 7);
1718: format = packet[9] >> 6;
1.1.1.6 root 1719: // msf = (packet[1] >> 1) & 1;
1720: // start_track = packet[6];
1.1.1.2 root 1721: switch (format)
1722: {
1723: case 0:
1.1.1.4 root 1724: fprintf(stderr,"IDE FIXME: cdrom_read_toc");
1.1.1.2 root 1725: len=-1;
1726: //len = cdrom_read_toc(total_sectors, buf, msf, start_track);
1727: if (len < 0)
1728: goto error_cmd;
1729: ide_atapi_cmd_reply(s, len, max_len);
1730: break;
1731: case 1:
1732: /* multi session : only a single session defined */
1733: memset(buf, 0, 12);
1734: buf[1] = 0x0a;
1735: buf[2] = 0x01;
1736: buf[3] = 0x01;
1737: ide_atapi_cmd_reply(s, 12, max_len);
1738: break;
1739: case 2:
1.1.1.4 root 1740: fprintf(stderr,"IDE FIXME: cdrom_read_toc_raw");
1.1.1.2 root 1741: len=-1;
1742: //len = cdrom_read_toc_raw(total_sectors, buf, msf, start_track);
1743: if (len < 0)
1744: goto error_cmd;
1745: ide_atapi_cmd_reply(s, len, max_len);
1746: break;
1747: default:
1748: error_cmd:
1749: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1750: ASC_INV_FIELD_IN_CMD_PACKET);
1751: break;
1752: }
1753: }
1754: break;
1755: case GPCMD_READ_CDVD_CAPACITY:
1756: {
1757: uint64_t total_sectors;
1758:
1759: bdrv_get_geometry(s->bs, &total_sectors);
1760: total_sectors >>= 2;
1761: if (total_sectors == 0)
1762: {
1763: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1764: ASC_MEDIUM_NOT_PRESENT);
1765: break;
1766: }
1767: /* NOTE: it is really the number of sectors minus 1 */
1768: cpu_to_ube32(buf, total_sectors - 1);
1769: cpu_to_ube32(buf + 4, 2048);
1770: ide_atapi_cmd_reply(s, 8, 8);
1771: }
1772: break;
1773: case GPCMD_READ_DVD_STRUCTURE:
1774: {
1775: int media = packet[1];
1776: int layer = packet[6];
1777: int format = packet[2];
1778: uint64_t total_sectors;
1779:
1780: if (media != 0 || layer != 0)
1781: {
1782: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1783: ASC_INV_FIELD_IN_CMD_PACKET);
1784: }
1785:
1786: switch (format)
1787: {
1788: case 0:
1789: bdrv_get_geometry(s->bs, &total_sectors);
1790: total_sectors >>= 2;
1791: if (total_sectors == 0)
1792: {
1793: ide_atapi_cmd_error(s, SENSE_NOT_READY,
1794: ASC_MEDIUM_NOT_PRESENT);
1795: break;
1796: }
1797:
1798: memset(buf, 0, 2052);
1799:
1800: buf[4] = 1; // DVD-ROM, part version 1
1801: buf[5] = 0xf; // 120mm disc, maximum rate unspecified
1802: buf[6] = 0; // one layer, embossed data
1803: buf[7] = 0;
1804:
1805: cpu_to_ube32(buf + 8, 0);
1806: cpu_to_ube32(buf + 12, total_sectors - 1);
1807: cpu_to_ube32(buf + 16, total_sectors - 1);
1808:
1809: cpu_to_be16wu((uint16_t *)buf, 2048 + 4);
1810:
1811: ide_atapi_cmd_reply(s, 2048 + 3, 2048 + 4);
1812: break;
1813:
1814: default:
1815: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1816: ASC_INV_FIELD_IN_CMD_PACKET);
1817: break;
1818: }
1819: }
1820: break;
1821: case GPCMD_SET_SPEED:
1822: ide_atapi_cmd_ok(s);
1823: break;
1824: case GPCMD_INQUIRY:
1825: max_len = packet[4];
1826: buf[0] = 0x05; /* CD-ROM */
1827: buf[1] = 0x80; /* removable */
1828: buf[2] = 0x00; /* ISO */
1829: buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
1830: buf[4] = 31; /* additional length */
1831: buf[5] = 0; /* reserved */
1832: buf[6] = 0; /* reserved */
1833: buf[7] = 0; /* reserved */
1834: padstr8(buf + 8, 8, "QEMU");
1835: padstr8(buf + 16, 16, "QEMU CD-ROM");
1836: padstr8(buf + 32, 4, FW_VERSION);
1837: ide_atapi_cmd_reply(s, 36, max_len);
1838: break;
1839: case GPCMD_GET_CONFIGURATION:
1840: {
1841: uint64_t total_sectors;
1842:
1843: /* only feature 0 is supported */
1844: if (packet[2] != 0 || packet[3] != 0)
1845: {
1846: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1847: ASC_INV_FIELD_IN_CMD_PACKET);
1848: break;
1849: }
1850: memset(buf, 0, 32);
1851: bdrv_get_geometry(s->bs, &total_sectors);
1852: buf[3] = 16;
1853: buf[7] = total_sectors <= 1433600 ? 0x08 : 0x10; /* current profile */
1854: buf[10] = 0x10 | 0x1;
1855: buf[11] = 0x08; /* size of profile list */
1856: buf[13] = 0x10; /* DVD-ROM profile */
1857: buf[14] = buf[7] == 0x10; /* (in)active */
1858: buf[17] = 0x08; /* CD-ROM profile */
1859: buf[18] = buf[7] == 0x08; /* (in)active */
1860: ide_atapi_cmd_reply(s, 32, 32);
1861: break;
1862: }
1863: default:
1864: ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
1865: ASC_ILLEGAL_OPCODE);
1866: break;
1867: }
1868: }
1869:
1870:
1871: /* called when the inserted state of the media has changed */
1872: static void cdrom_change_cb(void *opaque)
1873: {
1874: IDEState *s = opaque;
1875: uint64_t nb_sectors;
1876:
1877: /* XXX: send interrupt too */
1878: bdrv_get_geometry(s->bs, &nb_sectors);
1879: s->nb_sectors = nb_sectors;
1880: }
1881:
1882: static void ide_cmd_lba48_transform(IDEState *s, int lba48)
1883: {
1884: s->lba48 = lba48;
1885:
1886: /* handle the 'magic' 0 nsector count conversion here. to avoid
1887: * fiddling with the rest of the read logic, we just store the
1888: * full sector count in ->nsector and ignore ->hob_nsector from now
1889: */
1890: if (!s->lba48)
1891: {
1892: if (!s->nsector)
1893: s->nsector = 256;
1894: }
1895: else
1896: {
1897: if (!s->nsector && !s->hob_nsector)
1898: s->nsector = 65536;
1899: else
1900: {
1901: int lo = s->nsector;
1902: int hi = s->hob_nsector;
1903:
1904: s->nsector = (hi << 8) | lo;
1905: }
1906: }
1907: }
1908:
1909: static void ide_clear_hob(IDEState *ide_if)
1910: {
1911: /* any write clears HOB high bit of device control register */
1912: ide_if[0].select &= ~(1 << 7);
1913: ide_if[1].select &= ~(1 << 7);
1914: }
1915:
1916: static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1917: {
1918: IDEState *ide_if = opaque;
1919: IDEState *s;
1920: int unit, n;
1921: int lba48 = 0;
1922:
1.1.1.9 root 1923: LOG_TRACE(TRACE_IDE, "IDE: write addr=0x%x val=0x%02x\n", addr, val);
1.1.1.2 root 1924:
1925: addr &= 7;
1926: switch (addr)
1927: {
1928: case 0:
1929: break;
1930: case 1:
1931: ide_clear_hob(ide_if);
1932: /* NOTE: data is written to the two drives */
1933: ide_if[0].hob_feature = ide_if[0].feature;
1934: ide_if[1].hob_feature = ide_if[1].feature;
1935: ide_if[0].feature = val;
1936: ide_if[1].feature = val;
1937: break;
1938: case 2:
1939: ide_clear_hob(ide_if);
1940: ide_if[0].hob_nsector = ide_if[0].nsector;
1941: ide_if[1].hob_nsector = ide_if[1].nsector;
1942: ide_if[0].nsector = val;
1943: ide_if[1].nsector = val;
1944: break;
1945: case 3:
1946: ide_clear_hob(ide_if);
1947: ide_if[0].hob_sector = ide_if[0].sector;
1948: ide_if[1].hob_sector = ide_if[1].sector;
1949: ide_if[0].sector = val;
1950: ide_if[1].sector = val;
1951: break;
1952: case 4:
1953: ide_clear_hob(ide_if);
1954: ide_if[0].hob_lcyl = ide_if[0].lcyl;
1955: ide_if[1].hob_lcyl = ide_if[1].lcyl;
1956: ide_if[0].lcyl = val;
1957: ide_if[1].lcyl = val;
1958: break;
1959: case 5:
1960: ide_clear_hob(ide_if);
1961: ide_if[0].hob_hcyl = ide_if[0].hcyl;
1962: ide_if[1].hob_hcyl = ide_if[1].hcyl;
1963: ide_if[0].hcyl = val;
1964: ide_if[1].hcyl = val;
1965: break;
1966: case 6:
1967: /* FIXME: HOB readback uses bit 7 */
1968: ide_if[0].select = (val & ~0x10) | 0xa0;
1969: ide_if[1].select = (val | 0x10) | 0xa0;
1970: /* select drive */
1971: unit = (val >> 4) & 1;
1972: s = ide_if + unit;
1973: ide_if->cur_drive = s;
1974: break;
1975: default:
1976: case 7:
1977: /* command */
1.1.1.9 root 1978: LOG_TRACE(TRACE_IDE, "IDE: CMD=%02x\n", val);
1979:
1.1.1.2 root 1980: s = ide_if->cur_drive;
1.1.1.7 root 1981: /* ignore commands to non existent slave */
1.1.1.2 root 1982: if (s != ide_if && !s->bs)
1983: {
1.1.1.4 root 1984: fprintf(stderr,"IDE: CMD to non-existant slave!\n");
1.1.1.2 root 1985: break;
1986: }
1987:
1988: switch (val)
1989: {
1990: case WIN_IDENTIFY:
1991: if (s->bs && !s->is_cdrom)
1992: {
1993: ide_identify(s);
1994: s->status = READY_STAT | SEEK_STAT;
1995: ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
1996: }
1997: else
1998: {
1999: if (s->is_cdrom)
2000: {
2001: ide_set_signature(s);
2002: }
2003: ide_abort_command(s);
2004: }
2005: ide_set_irq(s);
2006: break;
2007: case WIN_SPECIFY:
2008: case WIN_RECAL:
2009: s->error = 0;
2010: s->status = READY_STAT | SEEK_STAT;
2011: ide_set_irq(s);
2012: break;
2013: case WIN_SETMULT:
2014: if ((s->nsector & 0xff) != 0 &&
2015: ((s->nsector & 0xff) > MAX_MULT_SECTORS ||
2016: (s->nsector & (s->nsector - 1)) != 0))
2017: {
2018: ide_abort_command(s);
2019: }
2020: else
2021: {
2022: s->mult_sectors = s->nsector & 0xff;
2023: s->status = READY_STAT;
2024: }
2025: ide_set_irq(s);
2026: break;
2027: case WIN_VERIFY_EXT:
2028: lba48 = 1;
2029: case WIN_VERIFY:
2030: case WIN_VERIFY_ONCE:
2031: /* do sector number check ? */
2032: ide_cmd_lba48_transform(s, lba48);
2033: s->status = READY_STAT;
2034: ide_set_irq(s);
2035: break;
1.1.1.4 root 2036: case WIN_FORMAT:
2037: ide_cmd_lba48_transform(s, lba48);
2038: s->error = 0;
2039: s->status = READY_STAT | SEEK_STAT;
2040: s->req_nb_sectors = s->mult_sectors;
2041: n = s->nsector;
2042: if (n > s->req_nb_sectors)
2043: n = s->req_nb_sectors;
2044: ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
2045: s->media_changed = 1;
2046: break;
1.1.1.2 root 2047: case WIN_READ_EXT:
2048: lba48 = 1;
2049: case WIN_READ:
2050: case WIN_READ_ONCE:
2051: if (!s->bs)
2052: goto abort_cmd;
2053: ide_cmd_lba48_transform(s, lba48);
2054: s->req_nb_sectors = 1;
2055: ide_sector_read(s);
2056: break;
2057: case WIN_WRITE_EXT:
2058: lba48 = 1;
2059: case WIN_WRITE:
2060: case WIN_WRITE_ONCE:
2061: case CFA_WRITE_SECT_WO_ERASE:
2062: case WIN_WRITE_VERIFY:
2063: ide_cmd_lba48_transform(s, lba48);
2064: s->error = 0;
2065: s->status = SEEK_STAT | READY_STAT;
2066: s->req_nb_sectors = 1;
2067: ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
2068: s->media_changed = 1;
2069: break;
2070: case WIN_MULTREAD_EXT:
2071: lba48 = 1;
2072: case WIN_MULTREAD:
2073: if (!s->mult_sectors)
2074: goto abort_cmd;
2075: ide_cmd_lba48_transform(s, lba48);
2076: s->req_nb_sectors = s->mult_sectors;
2077: ide_sector_read(s);
2078: break;
2079: case WIN_MULTWRITE_EXT:
2080: lba48 = 1;
2081: case WIN_MULTWRITE:
2082: case CFA_WRITE_MULTI_WO_ERASE:
2083: if (!s->mult_sectors)
2084: goto abort_cmd;
2085: ide_cmd_lba48_transform(s, lba48);
2086: s->error = 0;
2087: s->status = SEEK_STAT | READY_STAT;
2088: s->req_nb_sectors = s->mult_sectors;
2089: n = s->nsector;
2090: if (n > s->req_nb_sectors)
2091: n = s->req_nb_sectors;
2092: ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
2093: s->media_changed = 1;
2094: break;
2095: case WIN_READDMA_EXT:
2096: lba48 = 1;
2097: case WIN_READDMA:
2098: case WIN_READDMA_ONCE:
2099: if (!s->bs)
2100: goto abort_cmd;
2101: ide_cmd_lba48_transform(s, lba48);
2102: // ide_sector_read_dma(s);
2103: fprintf(stderr, "IDE: DMA read not supported!\n");
2104: break;
2105: case WIN_WRITEDMA_EXT:
2106: lba48 = 1;
2107: case WIN_WRITEDMA:
2108: case WIN_WRITEDMA_ONCE:
2109: if (!s->bs)
2110: goto abort_cmd;
2111: ide_cmd_lba48_transform(s, lba48);
2112: // ide_sector_write_dma(s);
2113: fprintf(stderr, "IDE: DMA write not supported!\n");
2114: s->media_changed = 1;
2115: break;
2116: case WIN_READ_NATIVE_MAX_EXT:
2117: lba48 = 1;
2118: case WIN_READ_NATIVE_MAX:
2119: ide_cmd_lba48_transform(s, lba48);
2120: ide_set_sector(s, s->nb_sectors - 1);
2121: s->status = READY_STAT;
2122: ide_set_irq(s);
2123: break;
2124: case WIN_CHECKPOWERMODE1:
2125: case WIN_CHECKPOWERMODE2:
2126: s->nsector = 0xff; /* device active or idle */
2127: s->status = READY_STAT;
2128: ide_set_irq(s);
2129: break;
2130: case WIN_SETFEATURES:
2131: if (!s->bs)
2132: goto abort_cmd;
2133: /* XXX: valid for CDROM ? */
2134: switch (s->feature)
2135: {
2136: case 0xcc: /* reverting to power-on defaults enable */
2137: case 0x66: /* reverting to power-on defaults disable */
2138: case 0x02: /* write cache enable */
2139: case 0x82: /* write cache disable */
2140: case 0xaa: /* read look-ahead enable */
2141: case 0x55: /* read look-ahead disable */
2142: case 0x05: /* set advanced power management mode */
2143: case 0x85: /* disable advanced power management mode */
2144: case 0x69: /* NOP */
2145: case 0x67: /* NOP */
2146: case 0x96: /* NOP */
2147: case 0x9a: /* NOP */
2148: case 0x42: /* enable Automatic Acoustic Mode */
2149: case 0xc2: /* disable Automatic Acoustic Mode */
2150: s->status = READY_STAT | SEEK_STAT;
2151: ide_set_irq(s);
2152: break;
2153: case 0x03: /* set transfer mode */
2154: {
1.1.1.10! root 2155: uint8_t mval = s->nsector & 0x07;
1.1.1.2 root 2156:
2157: switch (s->nsector >> 3)
2158: {
2159: case 0x00: /* pio default */
2160: case 0x01: /* pio mode */
2161: put_le16(s->identify_data + 63,0x07);
2162: put_le16(s->identify_data + 88,0x3f);
2163: break;
2164: case 0x04: /* mdma mode */
1.1.1.10! root 2165: put_le16(s->identify_data + 63,0x07 | (1 << (mval + 8)));
1.1.1.2 root 2166: put_le16(s->identify_data + 88,0x3f);
2167: break;
2168: case 0x08: /* udma mode */
2169: put_le16(s->identify_data + 63,0x07);
1.1.1.10! root 2170: put_le16(s->identify_data + 88,0x3f | (1 << (mval + 8)));
1.1.1.2 root 2171: break;
2172: default:
2173: goto abort_cmd;
2174: }
2175: s->status = READY_STAT | SEEK_STAT;
2176: ide_set_irq(s);
2177: break;
2178: }
2179: default:
2180: goto abort_cmd;
2181: }
2182: break;
2183: case WIN_FLUSH_CACHE:
2184: case WIN_FLUSH_CACHE_EXT:
2185: if (s->bs)
2186: bdrv_flush(s->bs);
2187: s->status = READY_STAT;
2188: ide_set_irq(s);
2189: break;
2190: case WIN_STANDBY:
2191: case WIN_STANDBY2:
2192: case WIN_STANDBYNOW1:
2193: case WIN_STANDBYNOW2:
2194: case WIN_IDLEIMMEDIATE:
2195: case CFA_IDLEIMMEDIATE:
2196: case WIN_SETIDLE1:
2197: case WIN_SETIDLE2:
2198: case WIN_SLEEPNOW1:
2199: case WIN_SLEEPNOW2:
2200: s->status = READY_STAT;
2201: ide_set_irq(s);
2202: break;
2203: /* ATAPI commands */
2204: case WIN_PIDENTIFY:
2205: if (s->is_cdrom)
2206: {
2207: ide_atapi_identify(s);
2208: s->status = READY_STAT | SEEK_STAT;
2209: ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
2210: }
2211: else
2212: {
2213: ide_abort_command(s);
2214: }
2215: ide_set_irq(s);
2216: break;
2217: case WIN_DIAGNOSE:
2218: ide_set_signature(s);
2219: s->status = 0x00; /* NOTE: READY is _not_ set */
2220: s->error = 0x01;
2221: ide_set_irq(s);
2222: break;
2223: case WIN_SRST:
2224: if (!s->is_cdrom)
2225: goto abort_cmd;
2226: ide_set_signature(s);
2227: s->status = 0x00; /* NOTE: READY is _not_ set */
2228: s->error = 0x01;
2229: break;
2230: case WIN_PACKETCMD:
2231: if (!s->is_cdrom)
2232: goto abort_cmd;
2233: /* overlapping commands not supported */
2234: if (s->feature & 0x02)
2235: goto abort_cmd;
2236: s->status = READY_STAT;
2237: // s->atapi_dma = s->feature & 1;
2238: s->nsector = 1;
2239: ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
2240: ide_atapi_cmd);
2241: break;
2242: default:
2243: abort_cmd:
2244: ide_abort_command(s);
2245: ide_set_irq(s);
2246: break;
2247: }
2248: }
2249: }
2250:
2251: static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
2252: {
2253: IDEState *ide_if = opaque;
2254: IDEState *s = ide_if->cur_drive;
2255: uint32_t addr;
1.1.1.9 root 2256: int ret;
1.1.1.2 root 2257:
2258: /* FIXME: HOB readback uses bit 7, but it's always set right now */
1.1.1.9 root 2259: //int hob = s->select & (1 << 7);
2260: const int hob = 0;
2261:
2262: addr = addr1 & 7;
1.1.1.2 root 2263: switch (addr)
2264: {
2265: case 0:
2266: ret = 0xff;
2267: break;
2268: case 1:
2269: if (!ide_if[0].bs && !ide_if[1].bs)
2270: ret = 0;
2271: else if (!hob)
2272: ret = s->error;
2273: else
2274: ret = s->hob_feature;
2275: break;
2276: case 2:
2277: if (!ide_if[0].bs && !ide_if[1].bs)
2278: ret = 0;
2279: else if (!hob)
2280: ret = s->nsector & 0xff;
2281: else
2282: ret = s->hob_nsector;
2283: break;
2284: case 3:
2285: if (!ide_if[0].bs && !ide_if[1].bs)
2286: ret = 0;
2287: else if (!hob)
2288: ret = s->sector;
2289: else
2290: ret = s->hob_sector;
2291: break;
2292: case 4:
2293: if (!ide_if[0].bs && !ide_if[1].bs)
2294: ret = 0;
2295: else if (!hob)
2296: ret = s->lcyl;
2297: else
2298: ret = s->hob_lcyl;
2299: break;
2300: case 5:
2301: if (!ide_if[0].bs && !ide_if[1].bs)
2302: ret = 0;
2303: else if (!hob)
2304: ret = s->hcyl;
2305: else
2306: ret = s->hob_hcyl;
2307: break;
2308: case 6:
2309: if (!ide_if[0].bs && !ide_if[1].bs)
2310: ret = 0;
2311: else
2312: ret = s->select;
2313: break;
2314: default:
2315: case 7:
2316: if ((!ide_if[0].bs && !ide_if[1].bs) ||
2317: (s != ide_if && !s->bs))
2318: ret = 0;
2319: else
2320: ret = s->status;
1.1.1.9 root 2321:
2322: /* Clear IRQ (set line to high) */
2323: MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_FDC_HDC , MFP_GPIP_STATE_HIGH );
1.1.1.2 root 2324: break;
2325: }
1.1.1.9 root 2326: LOG_TRACE(TRACE_IDE, "IDE: read addr=0x%x val=%02x\n", addr1, ret);
1.1.1.2 root 2327: return ret;
2328: }
2329:
2330: static uint32_t ide_status_read(void *opaque, uint32_t addr)
2331: {
2332: IDEState *ide_if = opaque;
2333: IDEState *s = ide_if->cur_drive;
2334: int ret;
2335:
2336: if ((!ide_if[0].bs && !ide_if[1].bs) ||
2337: (s != ide_if && !s->bs))
2338: ret = 0;
2339: else
2340: ret = s->status;
1.1.1.9 root 2341:
2342: LOG_TRACE(TRACE_IDE, "IDE: read status addr=0x%x val=%02x\n", addr, ret);
1.1.1.2 root 2343: return ret;
2344: }
2345:
2346: static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
2347: {
2348: IDEState *ide_if = opaque;
2349: IDEState *s;
2350: int i;
2351:
1.1.1.9 root 2352: LOG_TRACE(TRACE_IDE, "IDE: write control addr=0x%x val=%02x\n", addr, val);
2353:
1.1.1.2 root 2354: /* common for both drives */
2355: if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
2356: (val & IDE_CMD_RESET))
2357: {
2358: /* reset low to high */
2359: for (i = 0;i < 2; i++)
2360: {
2361: s = &ide_if[i];
2362: s->status = BUSY_STAT | SEEK_STAT;
2363: s->error = 0x01;
2364: }
2365: }
2366: else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
2367: !(val & IDE_CMD_RESET))
2368: {
2369: /* high to low */
2370: for (i = 0;i < 2; i++)
2371: {
2372: s = &ide_if[i];
2373: if (s->is_cdrom)
2374: s->status = 0x00; /* NOTE: READY is _not_ set */
2375: else
2376: s->status = READY_STAT | SEEK_STAT;
2377: ide_set_signature(s);
2378: }
2379: }
2380:
2381: ide_if[0].cmd = val;
2382: ide_if[1].cmd = val;
2383: }
2384:
2385: static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
2386: {
2387: IDEState *s = ((IDEState *)opaque)->cur_drive;
2388: uint8_t *p;
2389:
2390: p = s->data_ptr;
2391: *(uint16_t *)p = le16_to_cpu(val);
2392: p += 2;
2393: s->data_ptr = p;
2394: if (p >= s->data_end)
2395: s->end_transfer_func(s);
2396: }
2397:
2398: static uint32_t ide_data_readw(void *opaque, uint32_t addr)
2399: {
2400: IDEState *s = ((IDEState *)opaque)->cur_drive;
2401: uint8_t *p;
2402: int ret;
2403: p = s->data_ptr;
2404: ret = cpu_to_le16(*(uint16_t *)p);
2405: p += 2;
2406: s->data_ptr = p;
2407: if (p >= s->data_end)
2408: s->end_transfer_func(s);
2409: return ret;
2410: }
2411:
2412: static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
2413: {
2414: IDEState *s = ((IDEState *)opaque)->cur_drive;
2415: uint8_t *p;
2416:
2417: p = s->data_ptr;
2418: *(uint32_t *)p = le32_to_cpu(val);
2419: p += 4;
2420: s->data_ptr = p;
2421: if (p >= s->data_end)
2422: s->end_transfer_func(s);
2423: }
2424:
2425: static uint32_t ide_data_readl(void *opaque, uint32_t addr)
2426: {
2427: IDEState *s = ((IDEState *)opaque)->cur_drive;
2428: uint8_t *p;
2429: int ret;
2430:
2431: p = s->data_ptr;
2432: ret = cpu_to_le32(*(uint32_t *)p);
2433: p += 4;
2434: s->data_ptr = p;
2435: if (p >= s->data_end)
2436: s->end_transfer_func(s);
2437: return ret;
2438: }
2439:
2440: static void ide_dummy_transfer_stop(IDEState *s)
2441: {
2442: s->data_ptr = s->io_buffer;
2443: s->data_end = s->io_buffer;
2444: s->io_buffer[0] = 0xff;
2445: s->io_buffer[1] = 0xff;
2446: s->io_buffer[2] = 0xff;
2447: s->io_buffer[3] = 0xff;
2448: }
2449:
2450: static void ide_reset(IDEState *s)
2451: {
2452: s->mult_sectors = MAX_MULT_SECTORS;
2453: s->cur_drive = s;
2454: s->select = 0xa0;
2455: s->status = READY_STAT | SEEK_STAT;
2456:
2457: ide_set_signature(s);
2458: /* init the transfer handler so that 0xffff is returned on data
2459: accesses */
2460: s->end_transfer_func = ide_dummy_transfer_stop;
2461: ide_dummy_transfer_stop(s);
2462: s->media_changed = 0;
2463: }
2464:
2465: struct partition
2466: {
2467: uint8_t boot_ind; /* 0x80 - active */
2468: uint8_t head; /* starting head */
2469: uint8_t sector; /* starting sector */
2470: uint8_t cyl; /* starting cylinder */
2471: uint8_t sys_ind; /* What partition type */
2472: uint8_t end_head; /* end head */
2473: uint8_t end_sector; /* end sector */
2474: uint8_t end_cyl; /* end cylinder */
2475: uint32_t start_sect; /* starting sector counting from 0 */
2476: uint32_t nr_sects; /* nr of sectors in partition */
1.1.1.10! root 2477: };
1.1.1.2 root 2478:
2479: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
2480: static int guess_disk_lchs(IDEState *s,
2481: int *pcylinders, int *pheads, int *psectors)
2482: {
2483: uint8_t *buf;
2484: int ret, i, heads, sectors, cylinders;
2485: struct partition *p;
2486: uint32_t nr_sects;
2487:
1.1.1.10! root 2488: buf = malloc(SECTOR_SIZE);
1.1.1.2 root 2489: if (buf == NULL)
2490: return -1;
2491: ret = bdrv_read(s->bs, 0, buf, 1);
2492: if (ret < 0)
2493: {
1.1.1.10! root 2494: free(buf);
1.1.1.2 root 2495: return -1;
2496: }
2497: /* test msdos magic */
2498: if (buf[510] != 0x55 || buf[511] != 0xaa)
2499: {
1.1.1.10! root 2500: free(buf);
1.1.1.2 root 2501: return -1;
2502: }
2503: for (i = 0; i < 4; i++)
2504: {
2505: p = ((struct partition *)(buf + 0x1be)) + i;
2506: nr_sects = le32_to_cpu(p->nr_sects);
2507: if (nr_sects && p->end_head)
2508: {
2509: /* We make the assumption that the partition terminates on
2510: a cylinder boundary */
2511: heads = p->end_head + 1;
2512: sectors = p->end_sector & 63;
2513: if (sectors == 0)
2514: continue;
2515: cylinders = s->nb_sectors / (heads * sectors);
2516: if (cylinders < 1 || cylinders > 16383)
2517: continue;
2518: *pheads = heads;
2519: *psectors = sectors;
2520: *pcylinders = cylinders;
1.1.1.9 root 2521: LOG_TRACE(TRACE_IDE, "IDE: guessed geometry LCHS=%d %d %d\n",
1.1.1.2 root 2522: cylinders, heads, sectors);
1.1.1.10! root 2523: free(buf);
1.1.1.2 root 2524: return 0;
2525: }
2526: }
1.1.1.10! root 2527: free(buf);
1.1.1.2 root 2528: return -1;
2529: }
2530:
2531: static void ide_init2(IDEState *ide_state, BlockDriverState *hd0,
2532: BlockDriverState *hd1)
2533: {
2534: IDEState *s;
2535: static int drive_serial = 1;
2536: int i, cylinders, heads, secs, translation, lba_detected = 0;
2537: uint64_t nb_sectors;
2538:
2539: for (i = 0; i < 2; i++)
2540: {
2541: s = ide_state + i;
1.1.1.10! root 2542: s->io_buffer = malloc(MAX_MULT_SECTORS * 512 + 4);
1.1.1.4 root 2543: assert(s->io_buffer);
1.1.1.2 root 2544: if (i == 0)
2545: s->bs = hd0;
2546: else
2547: s->bs = hd1;
2548: if (s->bs)
2549: {
2550: bdrv_get_geometry(s->bs, &nb_sectors);
2551: s->nb_sectors = nb_sectors;
2552: /* if a geometry hint is available, use it */
2553: bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
2554: translation = bdrv_get_translation_hint(s->bs);
2555: if (cylinders != 0)
2556: {
2557: s->cylinders = cylinders;
2558: s->heads = heads;
2559: s->sectors = secs;
2560: }
2561: else
2562: {
2563: if (guess_disk_lchs(s, &cylinders, &heads, &secs) == 0)
2564: {
2565: if (heads > 16)
2566: {
2567: /* if heads > 16, it means that a BIOS LBA
2568: translation was active, so the default
2569: hardware geometry is OK */
2570: lba_detected = 1;
2571: goto default_geometry;
2572: }
2573: else
2574: {
2575: s->cylinders = cylinders;
2576: s->heads = heads;
2577: s->sectors = secs;
2578: /* disable any translation to be in sync with
2579: the logical geometry */
2580: if (translation == BIOS_ATA_TRANSLATION_AUTO)
2581: {
2582: bdrv_set_translation_hint(s->bs,
2583: BIOS_ATA_TRANSLATION_NONE);
2584: }
2585: }
2586: }
2587: else
2588: {
2589: default_geometry:
2590: /* if no geometry, use a standard physical disk geometry */
2591: cylinders = nb_sectors / (16 * 63);
2592: if (cylinders > 16383)
2593: cylinders = 16383;
2594: else if (cylinders < 2)
2595: cylinders = 2;
2596: s->cylinders = cylinders;
2597: s->heads = 16;
2598: s->sectors = 63;
2599: if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO))
2600: {
2601: if ((s->cylinders * s->heads) <= 131072)
2602: {
2603: bdrv_set_translation_hint(s->bs,
2604: BIOS_ATA_TRANSLATION_LARGE);
2605: }
2606: else
2607: {
2608: bdrv_set_translation_hint(s->bs,
2609: BIOS_ATA_TRANSLATION_LBA);
2610: }
2611: }
2612: }
2613: bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
2614: }
2615: if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM)
2616: {
2617: s->is_cdrom = 1;
2618: bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
2619: }
2620: }
2621: s->drive_serial = drive_serial++;
2622:
2623: ide_reset(s);
2624: }
2625: }
2626:
2627:
2628: /*----------------------------------------------------------------------------*/
2629:
2630:
2631: static BlockDriverState *hd_table[2];
2632:
2633:
2634: /**
2635: * Initialize the IDE subsystem
2636: */
2637: void Ide_Init(void)
2638: {
1.1.1.4 root 2639: if (!ConfigureParams.HardDisk.bUseIdeMasterHardDiskImage)
1.1.1.2 root 2640: return;
2641:
1.1.1.10! root 2642: opaque_ide_if = calloc(2, sizeof(IDEState));
1.1.1.2 root 2643: hd_table[0] = malloc(sizeof(BlockDriverState));
2644: hd_table[1] = malloc(sizeof(BlockDriverState));
2645:
1.1.1.4 root 2646: assert(opaque_ide_if && hd_table[0] && hd_table[1]);
1.1.1.2 root 2647:
2648: memset(hd_table[0], 0, sizeof(BlockDriverState));
2649: memset(hd_table[1], 0, sizeof(BlockDriverState));
2650:
1.1.1.4 root 2651: bdrv_open(hd_table[0], ConfigureParams.HardDisk.szIdeMasterHardDiskImage, 0);
1.1.1.9 root 2652: nIDEPartitions += HDC_PartitionCount(hd_table[0]->fhndl, TRACE_IDE);
1.1.1.2 root 2653:
1.1.1.4 root 2654: if (ConfigureParams.HardDisk.bUseIdeSlaveHardDiskImage)
2655: {
2656: bdrv_open(hd_table[1], ConfigureParams.HardDisk.szIdeSlaveHardDiskImage, 0);
1.1.1.9 root 2657: nIDEPartitions += HDC_PartitionCount(hd_table[1]->fhndl, TRACE_IDE);
1.1.1.4 root 2658:
2659: ide_init2(&opaque_ide_if[0], hd_table[0], hd_table[1]);
2660: }
2661: else
2662: {
2663: ide_init2(&opaque_ide_if[0], hd_table[0], NULL);
2664: }
1.1.1.2 root 2665: }
2666:
2667:
2668: /**
2669: * Free resources from the IDE subsystem
2670: */
2671: void Ide_UnInit(void)
2672: {
2673: int i;
2674:
2675: for (i = 0; i < 2; i++)
2676: {
2677: if (hd_table[i])
2678: {
2679: if (bdrv_is_inserted(hd_table[i]))
2680: {
2681: bdrv_close(hd_table[i]);
2682: }
2683: free(hd_table[i]);
2684: hd_table[i] = NULL;
2685: }
2686: }
2687:
2688: if (opaque_ide_if)
1.1.1.4 root 2689: {
2690: for (i = 0; i < 2; i++)
2691: {
2692: if (opaque_ide_if[i].io_buffer)
2693: {
2694: free(opaque_ide_if[i].io_buffer);
2695: opaque_ide_if[i].io_buffer = NULL;
2696: }
2697: }
1.1.1.2 root 2698: free(opaque_ide_if);
1.1.1.4 root 2699: opaque_ide_if = NULL;
2700: }
1.1.1.9 root 2701:
2702: nIDEPartitions = 0;
1.1 root 2703: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.