1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include "hw.h"
26: #include "pc.h"
27: #include "pci.h"
28: #include "scsi-disk.h"
29: #include "pcmcia.h"
30: #include "block.h"
31: #include "qemu-timer.h"
32: #include "sysemu.h"
33: #include "ppc_mac.h"
34:
35:
36:
37:
38:
39: #define USE_DMA_CDROM
40:
41:
42: #define ERR_STAT 0x01
43: #define INDEX_STAT 0x02
44: #define ECC_STAT 0x04
45: #define DRQ_STAT 0x08
46: #define SEEK_STAT 0x10
47: #define SRV_STAT 0x10
48: #define WRERR_STAT 0x20
49: #define READY_STAT 0x40
50: #define BUSY_STAT 0x80
51:
52:
53: #define MARK_ERR 0x01
54: #define TRK0_ERR 0x02
55: #define ABRT_ERR 0x04
56: #define MCR_ERR 0x08
57: #define ID_ERR 0x10
58: #define MC_ERR 0x20
59: #define ECC_ERR 0x40
60: #define BBD_ERR 0x80
61: #define ICRC_ERR 0x80
62:
63:
64: #define CD 0x01
65: #define IO 0x02
66: #define REL 0x04
67: #define TAG_MASK 0xf8
68:
69: #define IDE_CMD_RESET 0x04
70: #define IDE_CMD_DISABLE_IRQ 0x02
71:
72:
73: #define WIN_NOP 0x00
74:
75:
76:
77: #define CFA_REQ_EXT_ERROR_CODE 0x03
78:
79:
80:
81: #define WIN_SRST 0x08
82: #define WIN_DEVICE_RESET 0x08
83:
84:
85:
86: #define WIN_RECAL 0x10
87: #define WIN_RESTORE WIN_RECAL
88:
89:
90:
91: #define WIN_READ 0x20
92: #define WIN_READ_ONCE 0x21
93: #define WIN_READ_LONG 0x22
94: #define WIN_READ_LONG_ONCE 0x23
95: #define WIN_READ_EXT 0x24
96: #define WIN_READDMA_EXT 0x25
97: #define WIN_READDMA_QUEUED_EXT 0x26
98: #define WIN_READ_NATIVE_MAX_EXT 0x27
99:
100:
101:
102: #define WIN_MULTREAD_EXT 0x29
103:
104:
105:
106: #define WIN_WRITE 0x30
107: #define WIN_WRITE_ONCE 0x31
108: #define WIN_WRITE_LONG 0x32
109: #define WIN_WRITE_LONG_ONCE 0x33
110: #define WIN_WRITE_EXT 0x34
111: #define WIN_WRITEDMA_EXT 0x35
112: #define WIN_WRITEDMA_QUEUED_EXT 0x36
113: #define WIN_SET_MAX_EXT 0x37
114: #define CFA_WRITE_SECT_WO_ERASE 0x38
115: #define WIN_MULTWRITE_EXT 0x39
116:
117:
118:
119: #define WIN_WRITE_VERIFY 0x3C
120:
121:
122:
123: #define WIN_VERIFY 0x40
124: #define WIN_VERIFY_ONCE 0x41
125: #define WIN_VERIFY_EXT 0x42
126:
127:
128:
129: #define WIN_FORMAT 0x50
130:
131:
132:
133: #define WIN_INIT 0x60
134:
135:
136:
137: #define WIN_SEEK 0x70
138: #define CFA_TRANSLATE_SECTOR 0x87
139: #define WIN_DIAGNOSE 0x90
140: #define WIN_SPECIFY 0x91
141: #define WIN_DOWNLOAD_MICROCODE 0x92
142: #define WIN_STANDBYNOW2 0x94
143: #define CFA_IDLEIMMEDIATE 0x95
144: #define WIN_STANDBY2 0x96
145: #define WIN_SETIDLE2 0x97
146: #define WIN_CHECKPOWERMODE2 0x98
147: #define WIN_SLEEPNOW2 0x99
148:
149:
150:
151: #define WIN_PACKETCMD 0xA0
152: #define WIN_PIDENTIFY 0xA1
153: #define WIN_QUEUED_SERVICE 0xA2
154: #define WIN_SMART 0xB0
155: #define CFA_ACCESS_METADATA_STORAGE 0xB8
156: #define CFA_ERASE_SECTORS 0xC0
157: #define WIN_MULTREAD 0xC4
158: #define WIN_MULTWRITE 0xC5
159: #define WIN_SETMULT 0xC6
160: #define WIN_READDMA_QUEUED 0xC7
161: #define WIN_READDMA 0xC8
162: #define WIN_READDMA_ONCE 0xC9
163: #define WIN_WRITEDMA 0xCA
164: #define WIN_WRITEDMA_ONCE 0xCB
165: #define WIN_WRITEDMA_QUEUED 0xCC
166: #define CFA_WRITE_MULTI_WO_ERASE 0xCD
167: #define WIN_GETMEDIASTATUS 0xDA
168: #define WIN_ACKMEDIACHANGE 0xDB
169: #define WIN_POSTBOOT 0xDC
170: #define WIN_PREBOOT 0xDD
171: #define WIN_DOORLOCK 0xDE
172: #define WIN_DOORUNLOCK 0xDF
173: #define WIN_STANDBYNOW1 0xE0
174: #define WIN_IDLEIMMEDIATE 0xE1
175: #define WIN_STANDBY 0xE2
176: #define WIN_SETIDLE1 0xE3
177: #define WIN_READ_BUFFER 0xE4
178: #define WIN_CHECKPOWERMODE1 0xE5
179: #define WIN_SLEEPNOW1 0xE6
180: #define WIN_FLUSH_CACHE 0xE7
181: #define WIN_WRITE_BUFFER 0xE8
182: #define WIN_WRITE_SAME 0xE9
183:
184: #define WIN_FLUSH_CACHE_EXT 0xEA
185: #define WIN_IDENTIFY 0xEC
186: #define WIN_MEDIAEJECT 0xED
187: #define WIN_IDENTIFY_DMA 0xEE
188: #define WIN_SETFEATURES 0xEF
189: #define EXABYTE_ENABLE_NEST 0xF0
190: #define IBM_SENSE_CONDITION 0xF0
191: #define WIN_SECURITY_SET_PASS 0xF1
192: #define WIN_SECURITY_UNLOCK 0xF2
193: #define WIN_SECURITY_ERASE_PREPARE 0xF3
194: #define WIN_SECURITY_ERASE_UNIT 0xF4
195: #define WIN_SECURITY_FREEZE_LOCK 0xF5
196: #define CFA_WEAR_LEVEL 0xF5
197: #define WIN_SECURITY_DISABLE 0xF6
198: #define WIN_READ_NATIVE_MAX 0xF8
199: #define WIN_SET_MAX 0xF9
200: #define DISABLE_SEAGATE 0xFB
201:
202:
203: #define MAX_MULT_SECTORS 16
204:
205:
206:
207: #define ATAPI_PACKET_SIZE 12
208:
209:
210:
211: #define GPCMD_BLANK 0xa1
212: #define GPCMD_CLOSE_TRACK 0x5b
213: #define GPCMD_FLUSH_CACHE 0x35
214: #define GPCMD_FORMAT_UNIT 0x04
215: #define GPCMD_GET_CONFIGURATION 0x46
216: #define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
217: #define GPCMD_GET_PERFORMANCE 0xac
218: #define GPCMD_INQUIRY 0x12
219: #define GPCMD_LOAD_UNLOAD 0xa6
220: #define GPCMD_MECHANISM_STATUS 0xbd
221: #define GPCMD_MODE_SELECT_10 0x55
222: #define GPCMD_MODE_SENSE_10 0x5a
223: #define GPCMD_PAUSE_RESUME 0x4b
224: #define GPCMD_PLAY_AUDIO_10 0x45
225: #define GPCMD_PLAY_AUDIO_MSF 0x47
226: #define GPCMD_PLAY_AUDIO_TI 0x48
227: #define GPCMD_PLAY_CD 0xbc
228: #define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
229: #define GPCMD_READ_10 0x28
230: #define GPCMD_READ_12 0xa8
231: #define GPCMD_READ_CDVD_CAPACITY 0x25
232: #define GPCMD_READ_CD 0xbe
233: #define GPCMD_READ_CD_MSF 0xb9
234: #define GPCMD_READ_DISC_INFO 0x51
235: #define GPCMD_READ_DVD_STRUCTURE 0xad
236: #define GPCMD_READ_FORMAT_CAPACITIES 0x23
237: #define GPCMD_READ_HEADER 0x44
238: #define GPCMD_READ_TRACK_RZONE_INFO 0x52
239: #define GPCMD_READ_SUBCHANNEL 0x42
240: #define GPCMD_READ_TOC_PMA_ATIP 0x43
241: #define GPCMD_REPAIR_RZONE_TRACK 0x58
242: #define GPCMD_REPORT_KEY 0xa4
243: #define GPCMD_REQUEST_SENSE 0x03
244: #define GPCMD_RESERVE_RZONE_TRACK 0x53
245: #define GPCMD_SCAN 0xba
246: #define GPCMD_SEEK 0x2b
247: #define GPCMD_SEND_DVD_STRUCTURE 0xad
248: #define GPCMD_SEND_EVENT 0xa2
249: #define GPCMD_SEND_KEY 0xa3
250: #define GPCMD_SEND_OPC 0x54
251: #define GPCMD_SET_READ_AHEAD 0xa7
252: #define GPCMD_SET_STREAMING 0xb6
253: #define GPCMD_START_STOP_UNIT 0x1b
254: #define GPCMD_STOP_PLAY_SCAN 0x4e
255: #define GPCMD_TEST_UNIT_READY 0x00
256: #define GPCMD_VERIFY_10 0x2f
257: #define GPCMD_WRITE_10 0x2a
258: #define GPCMD_WRITE_AND_VERIFY_10 0x2e
259:
260:
261:
262:
263: #define GPCMD_SET_SPEED 0xbb
264:
265:
266: #define GPCMD_PLAYAUDIO_TI 0x48
267:
268:
269:
270:
271: #define GPCMD_GET_MEDIA_STATUS 0xda
272: #define GPCMD_MODE_SENSE_6 0x1a
273:
274:
275: #define GPMODE_R_W_ERROR_PAGE 0x01
276: #define GPMODE_WRITE_PARMS_PAGE 0x05
277: #define GPMODE_AUDIO_CTL_PAGE 0x0e
278: #define GPMODE_POWER_PAGE 0x1a
279: #define GPMODE_FAULT_FAIL_PAGE 0x1c
280: #define GPMODE_TO_PROTECT_PAGE 0x1d
281: #define GPMODE_CAPABILITIES_PAGE 0x2a
282: #define GPMODE_ALL_PAGES 0x3f
283:
284:
285: #define GPMODE_CDROM_PAGE 0x0d
286:
287: #define ATAPI_INT_REASON_CD 0x01
288: #define ATAPI_INT_REASON_IO 0x02
289: #define ATAPI_INT_REASON_REL 0x04
290: #define ATAPI_INT_REASON_TAG 0xf8
291:
292:
293: #define ASC_ILLEGAL_OPCODE 0x20
294: #define ASC_LOGICAL_BLOCK_OOR 0x21
295: #define ASC_INV_FIELD_IN_CMD_PACKET 0x24
296: #define ASC_MEDIUM_NOT_PRESENT 0x3a
297: #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
298:
299: #define CFA_NO_ERROR 0x00
300: #define CFA_MISC_ERROR 0x09
301: #define CFA_INVALID_COMMAND 0x20
302: #define CFA_INVALID_ADDRESS 0x21
303: #define CFA_ADDRESS_OVERFLOW 0x2f
304:
305: #define SENSE_NONE 0
306: #define SENSE_NOT_READY 2
307: #define SENSE_ILLEGAL_REQUEST 5
308: #define SENSE_UNIT_ATTENTION 6
309:
310: struct IDEState;
311:
312: typedef void EndTransferFunc(struct IDEState *);
313:
314:
315: typedef struct IDEState {
316:
317: int is_cdrom;
318: int is_cf;
319: int cylinders, heads, sectors;
320: int64_t nb_sectors;
321: int mult_sectors;
322: int identify_set;
323: uint16_t identify_data[256];
324: qemu_irq irq;
325: PCIDevice *pci_dev;
326: struct BMDMAState *bmdma;
327: int drive_serial;
328:
329: uint8_t feature;
330: uint8_t error;
331: uint32_t nsector;
332: uint8_t sector;
333: uint8_t lcyl;
334: uint8_t hcyl;
335:
336: uint8_t hob_feature;
337: uint8_t hob_nsector;
338: uint8_t hob_sector;
339: uint8_t hob_lcyl;
340: uint8_t hob_hcyl;
341:
342: uint8_t select;
343: uint8_t status;
344:
345:
346: uint8_t cmd;
347:
348: uint8_t lba48;
349:
350: struct IDEState *cur_drive;
351: BlockDriverState *bs;
352:
353: uint8_t sense_key;
354: uint8_t asc;
355: int packet_transfer_size;
356: int elementary_transfer_size;
357: int io_buffer_index;
358: int lba;
359: int cd_sector_size;
360: int atapi_dma;
361:
362: int io_buffer_size;
363:
364: int req_nb_sectors;
365: EndTransferFunc *end_transfer_func;
366: uint8_t *data_ptr;
367: uint8_t *data_end;
368: uint8_t *io_buffer;
369: QEMUTimer *sector_write_timer;
370: uint32_t irq_count;
371:
372: uint8_t ext_error;
373:
374: uint32_t mdata_size;
375: uint8_t *mdata_storage;
376: int media_changed;
377: } IDEState;
378:
379: #define BM_STATUS_DMAING 0x01
380: #define BM_STATUS_ERROR 0x02
381: #define BM_STATUS_INT 0x04
382:
383: #define BM_CMD_START 0x01
384: #define BM_CMD_READ 0x08
385:
386: #define IDE_TYPE_PIIX3 0
387: #define IDE_TYPE_CMD646 1
388: #define IDE_TYPE_PIIX4 2
389:
390:
391: #define MRDMODE 0x71
392: #define MRDMODE_INTR_CH0 0x04
393: #define MRDMODE_INTR_CH1 0x08
394: #define MRDMODE_BLK_CH0 0x10
395: #define MRDMODE_BLK_CH1 0x20
396: #define UDIDETCR0 0x73
397: #define UDIDETCR1 0x7B
398:
399: typedef struct BMDMAState {
400: uint8_t cmd;
401: uint8_t status;
402: uint32_t addr;
403:
404: struct PCIIDEState *pci_dev;
405:
406: uint32_t cur_addr;
407: uint32_t cur_prd_last;
408: uint32_t cur_prd_addr;
409: uint32_t cur_prd_len;
410: IDEState *ide_if;
411: BlockDriverCompletionFunc *dma_cb;
412: BlockDriverAIOCB *aiocb;
413: } BMDMAState;
414:
415: typedef struct PCIIDEState {
416: PCIDevice dev;
417: IDEState ide_if[4];
418: BMDMAState bmdma[2];
419: int type;
420: } PCIIDEState;
421:
422: static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
423: static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
424:
425: static void padstr(char *str, const char *src, int len)
426: {
427: int i, v;
428: for(i = 0; i < len; i++) {
429: if (*src)
430: v = *src++;
431: else
432: v = ' ';
433: str[i^1] = v;
434: }
435: }
436:
437: static void padstr8(uint8_t *buf, int buf_size, const char *src)
438: {
439: int i;
440: for(i = 0; i < buf_size; i++) {
441: if (*src)
442: buf[i] = *src++;
443: else
444: buf[i] = ' ';
445: }
446: }
447:
448: static void put_le16(uint16_t *p, unsigned int v)
449: {
450: *p = cpu_to_le16(v);
451: }
452:
453: static void ide_identify(IDEState *s)
454: {
455: uint16_t *p;
456: unsigned int oldsize;
457: char buf[20];
458:
459: if (s->identify_set) {
460: memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
461: return;
462: }
463:
464: memset(s->io_buffer, 0, 512);
465: p = (uint16_t *)s->io_buffer;
466: put_le16(p + 0, 0x0040);
467: put_le16(p + 1, s->cylinders);
468: put_le16(p + 3, s->heads);
469: put_le16(p + 4, 512 * s->sectors);
470: put_le16(p + 5, 512);
471: put_le16(p + 6, s->sectors);
472: snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
473: padstr((char *)(p + 10), buf, 20);
474: put_le16(p + 20, 3);
475: put_le16(p + 21, 512);
476: put_le16(p + 22, 4);
477: padstr((char *)(p + 23), QEMU_VERSION, 8);
478: padstr((char *)(p + 27), "QEMU HARDDISK", 40);
479: #if MAX_MULT_SECTORS > 1
480: put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
481: #endif
482: put_le16(p + 48, 1);
483: put_le16(p + 49, (1 << 11) | (1 << 9) | (1 << 8));
484: put_le16(p + 51, 0x200);
485: put_le16(p + 52, 0x200);
486: put_le16(p + 53, 1 | (1 << 1) | (1 << 2));
487: put_le16(p + 54, s->cylinders);
488: put_le16(p + 55, s->heads);
489: put_le16(p + 56, s->sectors);
490: oldsize = s->cylinders * s->heads * s->sectors;
491: put_le16(p + 57, oldsize);
492: put_le16(p + 58, oldsize >> 16);