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