Revision 5fafdf24 hw/ide.c
b/hw/ide.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU IDE disk and CD-ROM Emulator |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2003 Fabrice Bellard |
5 | 5 |
* Copyright (c) 2006 Openedhand Ltd. |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | 8 |
* of this software and associated documentation files (the "Software"), to deal |
9 | 9 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
156 | 156 |
#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */ |
157 | 157 |
#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */ |
158 | 158 |
#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */ |
159 |
#define WIN_GETMEDIASTATUS 0xDA
|
|
159 |
#define WIN_GETMEDIASTATUS 0xDA |
|
160 | 160 |
#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */ |
161 | 161 |
#define WIN_POSTBOOT 0xDC |
162 | 162 |
#define WIN_PREBOOT 0xDD |
... | ... | |
248 | 248 |
#define GPCMD_VERIFY_10 0x2f |
249 | 249 |
#define GPCMD_WRITE_10 0x2a |
250 | 250 |
#define GPCMD_WRITE_AND_VERIFY_10 0x2e |
251 |
/* This is listed as optional in ATAPI 2.6, but is (curiously)
|
|
251 |
/* This is listed as optional in ATAPI 2.6, but is (curiously) |
|
252 | 252 |
* missing from Mt. Fuji, Table 57. It _is_ mentioned in Mt. Fuji |
253 | 253 |
* Table 377 as an MMC command for SCSi devices though... Most ATAPI |
254 | 254 |
* drives support it. */ |
255 | 255 |
#define GPCMD_SET_SPEED 0xbb |
256 |
/* This seems to be a SCSI specific CD-ROM opcode
|
|
256 |
/* This seems to be a SCSI specific CD-ROM opcode |
|
257 | 257 |
* to play data at track/index */ |
258 | 258 |
#define GPCMD_PLAYAUDIO_TI 0x48 |
259 | 259 |
/* |
... | ... | |
339 | 339 |
/* set for lba48 access */ |
340 | 340 |
uint8_t lba48; |
341 | 341 |
/* depends on bit 4 in select, only meaningful for drive 0 */ |
342 |
struct IDEState *cur_drive;
|
|
342 |
struct IDEState *cur_drive; |
|
343 | 343 |
BlockDriverState *bs; |
344 | 344 |
/* ATAPI specific */ |
345 | 345 |
uint8_t sense_key; |
... | ... | |
392 | 392 |
uint8_t cmd; |
393 | 393 |
uint8_t status; |
394 | 394 |
uint32_t addr; |
395 |
|
|
395 |
|
|
396 | 396 |
struct PCIIDEState *pci_dev; |
397 | 397 |
/* current transfer state */ |
398 | 398 |
uint32_t cur_addr; |
... | ... | |
457 | 457 |
memset(s->io_buffer, 0, 512); |
458 | 458 |
p = (uint16_t *)s->io_buffer; |
459 | 459 |
put_le16(p + 0, 0x0040); |
460 |
put_le16(p + 1, s->cylinders);
|
|
460 |
put_le16(p + 1, s->cylinders); |
|
461 | 461 |
put_le16(p + 3, s->heads); |
462 | 462 |
put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */ |
463 | 463 |
put_le16(p + 5, 512); /* XXX: retired, remove ? */ |
464 |
put_le16(p + 6, s->sectors);
|
|
464 |
put_le16(p + 6, s->sectors); |
|
465 | 465 |
snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial); |
466 | 466 |
padstr((uint8_t *)(p + 10), buf, 20); /* serial number */ |
467 | 467 |
put_le16(p + 20, 3); /* XXX: retired, remove ? */ |
... | ... | |
469 | 469 |
put_le16(p + 22, 4); /* ecc bytes */ |
470 | 470 |
padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */ |
471 | 471 |
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */ |
472 |
#if MAX_MULT_SECTORS > 1
|
|
472 |
#if MAX_MULT_SECTORS > 1 |
|
473 | 473 |
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS); |
474 | 474 |
#endif |
475 | 475 |
put_le16(p + 48, 1); /* dword I/O */ |
... | ... | |
666 | 666 |
} |
667 | 667 |
|
668 | 668 |
/* prepare data transfer and tell what to do after */ |
669 |
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size,
|
|
669 |
static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, |
|
670 | 670 |
EndTransferFunc *end_transfer_func) |
671 | 671 |
{ |
672 | 672 |
s->end_transfer_func = end_transfer_func; |
... | ... | |
771 | 771 |
|
772 | 772 |
for(;;) { |
773 | 773 |
l = s->io_buffer_size - s->io_buffer_index; |
774 |
if (l <= 0)
|
|
774 |
if (l <= 0) |
|
775 | 775 |
break; |
776 | 776 |
if (bm->cur_prd_len == 0) { |
777 | 777 |
/* end of table (with a fail safe of one page) */ |
... | ... | |
793 | 793 |
l = bm->cur_prd_len; |
794 | 794 |
if (l > 0) { |
795 | 795 |
if (is_write) { |
796 |
cpu_physical_memory_write(bm->cur_prd_addr,
|
|
796 |
cpu_physical_memory_write(bm->cur_prd_addr, |
|
797 | 797 |
s->io_buffer + s->io_buffer_index, l); |
798 | 798 |
} else { |
799 |
cpu_physical_memory_read(bm->cur_prd_addr,
|
|
799 |
cpu_physical_memory_read(bm->cur_prd_addr, |
|
800 | 800 |
s->io_buffer + s->io_buffer_index, l); |
801 | 801 |
} |
802 | 802 |
bm->cur_prd_addr += l; |
... | ... | |
847 | 847 |
#ifdef DEBUG_AIO |
848 | 848 |
printf("aio_read: sector_num=%lld n=%d\n", sector_num, n); |
849 | 849 |
#endif |
850 |
bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n,
|
|
850 |
bm->aiocb = bdrv_aio_read(s->bs, sector_num, s->io_buffer, n, |
|
851 | 851 |
ide_read_dma_cb, bm); |
852 | 852 |
} |
853 | 853 |
|
... | ... | |
923 | 923 |
ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write); |
924 | 924 |
} |
925 | 925 |
ide_set_sector(s, sector_num + n); |
926 |
|
|
926 |
|
|
927 | 927 |
bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n, |
928 | 928 |
ide_sector_write_aio_cb, bm); |
929 | 929 |
} |
... | ... | |
969 | 969 |
#ifdef DEBUG_AIO |
970 | 970 |
printf("aio_write: sector_num=%lld n=%d\n", sector_num, n); |
971 | 971 |
#endif |
972 |
bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n,
|
|
972 |
bm->aiocb = bdrv_aio_write(s->bs, sector_num, s->io_buffer, n, |
|
973 | 973 |
ide_write_dma_cb, bm); |
974 | 974 |
} |
975 | 975 |
|
... | ... | |
1051 | 1051 |
memset(buf, 0, 288); |
1052 | 1052 |
} |
1053 | 1053 |
|
1054 |
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
|
|
1054 |
static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, |
|
1055 | 1055 |
int sector_size) |
1056 | 1056 |
{ |
1057 | 1057 |
int ret; |
... | ... | |
1077 | 1077 |
{ |
1078 | 1078 |
/* XXX: handle more errors */ |
1079 | 1079 |
if (ret == -ENOMEDIUM) { |
1080 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1080 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1081 | 1081 |
ASC_MEDIUM_NOT_PRESENT); |
1082 | 1082 |
} else { |
1083 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1083 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1084 | 1084 |
ASC_LOGICAL_BLOCK_OOR); |
1085 | 1085 |
} |
1086 | 1086 |
} |
... | ... | |
1090 | 1090 |
{ |
1091 | 1091 |
int byte_count_limit, size, ret; |
1092 | 1092 |
#ifdef DEBUG_IDE_ATAPI |
1093 |
printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
|
|
1093 |
printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", |
|
1094 | 1094 |
s->packet_transfer_size, |
1095 | 1095 |
s->elementary_transfer_size, |
1096 | 1096 |
s->io_buffer_index); |
... | ... | |
1122 | 1122 |
size = s->cd_sector_size - s->io_buffer_index; |
1123 | 1123 |
if (size > s->elementary_transfer_size) |
1124 | 1124 |
size = s->elementary_transfer_size; |
1125 |
ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
|
|
1125 |
ide_transfer_start(s, s->io_buffer + s->io_buffer_index, |
|
1126 | 1126 |
size, ide_atapi_cmd_reply_end); |
1127 | 1127 |
s->packet_transfer_size -= size; |
1128 | 1128 |
s->elementary_transfer_size -= size; |
... | ... | |
1151 | 1151 |
if (size > (s->cd_sector_size - s->io_buffer_index)) |
1152 | 1152 |
size = (s->cd_sector_size - s->io_buffer_index); |
1153 | 1153 |
} |
1154 |
ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
|
|
1154 |
ide_transfer_start(s, s->io_buffer + s->io_buffer_index, |
|
1155 | 1155 |
size, ide_atapi_cmd_reply_end); |
1156 | 1156 |
s->packet_transfer_size -= size; |
1157 | 1157 |
s->elementary_transfer_size -= size; |
... | ... | |
1246 | 1246 |
bm->aiocb = NULL; |
1247 | 1247 |
return; |
1248 | 1248 |
} |
1249 |
|
|
1249 |
|
|
1250 | 1250 |
s->io_buffer_index = 0; |
1251 | 1251 |
if (s->cd_sector_size == 2352) { |
1252 | 1252 |
n = 1; |
... | ... | |
1262 | 1262 |
#ifdef DEBUG_AIO |
1263 | 1263 |
printf("aio_read_cd: lba=%u n=%d\n", s->lba, n); |
1264 | 1264 |
#endif |
1265 |
bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2,
|
|
1266 |
s->io_buffer + data_offset, n * 4,
|
|
1265 |
bm->aiocb = bdrv_aio_read(s->bs, (int64_t)s->lba << 2, |
|
1266 |
s->io_buffer + data_offset, n * 4, |
|
1267 | 1267 |
ide_atapi_cmd_read_dma_cb, bm); |
1268 | 1268 |
if (!bm->aiocb) { |
1269 | 1269 |
/* Note: media not present is the most likely case */ |
1270 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1270 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1271 | 1271 |
ASC_MEDIUM_NOT_PRESENT); |
1272 | 1272 |
goto eot; |
1273 | 1273 |
} |
... | ... | |
1289 | 1289 |
ide_dma_start(s, ide_atapi_cmd_read_dma_cb); |
1290 | 1290 |
} |
1291 | 1291 |
|
1292 |
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
|
|
1292 |
static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, |
|
1293 | 1293 |
int sector_size) |
1294 | 1294 |
{ |
1295 | 1295 |
#ifdef DEBUG_IDE_ATAPI |
... | ... | |
1326 | 1326 |
if (bdrv_is_inserted(s->bs)) { |
1327 | 1327 |
ide_atapi_cmd_ok(s); |
1328 | 1328 |
} else { |
1329 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1329 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1330 | 1330 |
ASC_MEDIUM_NOT_PRESENT); |
1331 | 1331 |
} |
1332 | 1332 |
break; |
... | ... | |
1375 | 1375 |
buf[9] = 0x12; |
1376 | 1376 |
buf[10] = 0x08; |
1377 | 1377 |
buf[11] = 0x00; |
1378 |
|
|
1378 |
|
|
1379 | 1379 |
buf[12] = 0x70; |
1380 | 1380 |
buf[13] = 3 << 5; |
1381 | 1381 |
buf[14] = (1 << 0) | (1 << 3) | (1 << 5); |
... | ... | |
1403 | 1403 |
goto error_cmd; |
1404 | 1404 |
default: |
1405 | 1405 |
case 3: /* saved values */ |
1406 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1406 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1407 | 1407 |
ASC_SAVING_PARAMETERS_NOT_SUPPORTED); |
1408 | 1408 |
break; |
1409 | 1409 |
} |
... | ... | |
1423 | 1423 |
bdrv_set_locked(s->bs, packet[4] & 1); |
1424 | 1424 |
ide_atapi_cmd_ok(s); |
1425 | 1425 |
} else { |
1426 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1426 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1427 | 1427 |
ASC_MEDIUM_NOT_PRESENT); |
1428 | 1428 |
} |
1429 | 1429 |
break; |
... | ... | |
1469 | 1469 |
ide_atapi_cmd_read(s, lba, nb_sectors, 2352); |
1470 | 1470 |
break; |
1471 | 1471 |
default: |
1472 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1472 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1473 | 1473 |
ASC_INV_FIELD_IN_CMD_PACKET); |
1474 | 1474 |
break; |
1475 | 1475 |
} |
... | ... | |
1483 | 1483 |
bdrv_get_geometry(s->bs, &total_sectors); |
1484 | 1484 |
total_sectors >>= 2; |
1485 | 1485 |
if (total_sectors <= 0) { |
1486 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1486 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1487 | 1487 |
ASC_MEDIUM_NOT_PRESENT); |
1488 | 1488 |
break; |
1489 | 1489 |
} |
1490 | 1490 |
lba = ube32_to_cpu(packet + 2); |
1491 | 1491 |
if (lba >= total_sectors) { |
1492 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1492 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1493 | 1493 |
ASC_LOGICAL_BLOCK_OOR); |
1494 | 1494 |
break; |
1495 | 1495 |
} |
... | ... | |
1501 | 1501 |
int start, eject; |
1502 | 1502 |
start = packet[4] & 1; |
1503 | 1503 |
eject = (packet[4] >> 1) & 1; |
1504 |
|
|
1504 |
|
|
1505 | 1505 |
if (eject && !start) { |
1506 | 1506 |
/* eject the disk */ |
1507 | 1507 |
bdrv_eject(s->bs, 1); |
... | ... | |
1533 | 1533 |
bdrv_get_geometry(s->bs, &total_sectors); |
1534 | 1534 |
total_sectors >>= 2; |
1535 | 1535 |
if (total_sectors <= 0) { |
1536 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1536 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1537 | 1537 |
ASC_MEDIUM_NOT_PRESENT); |
1538 | 1538 |
break; |
1539 | 1539 |
} |
... | ... | |
1564 | 1564 |
break; |
1565 | 1565 |
default: |
1566 | 1566 |
error_cmd: |
1567 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1567 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1568 | 1568 |
ASC_INV_FIELD_IN_CMD_PACKET); |
1569 | 1569 |
break; |
1570 | 1570 |
} |
... | ... | |
1577 | 1577 |
bdrv_get_geometry(s->bs, &total_sectors); |
1578 | 1578 |
total_sectors >>= 2; |
1579 | 1579 |
if (total_sectors <= 0) { |
1580 |
ide_atapi_cmd_error(s, SENSE_NOT_READY,
|
|
1580 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, |
|
1581 | 1581 |
ASC_MEDIUM_NOT_PRESENT); |
1582 | 1582 |
break; |
1583 | 1583 |
} |
... | ... | |
1670 | 1670 |
break; |
1671 | 1671 |
} |
1672 | 1672 |
default: |
1673 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
|
|
1673 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1674 | 1674 |
ASC_ILLEGAL_OPCODE); |
1675 | 1675 |
break; |
1676 | 1676 |
} |
... | ... | |
1838 | 1838 |
#endif |
1839 | 1839 |
s = ide_if->cur_drive; |
1840 | 1840 |
/* ignore commands to non existant slave */ |
1841 |
if (s != ide_if && !s->bs)
|
|
1841 |
if (s != ide_if && !s->bs) |
|
1842 | 1842 |
break; |
1843 | 1843 |
|
1844 | 1844 |
switch(val) { |
... | ... | |
1892 | 1892 |
lba48 = 1; |
1893 | 1893 |
case WIN_READ: |
1894 | 1894 |
case WIN_READ_ONCE: |
1895 |
if (!s->bs)
|
|
1895 |
if (!s->bs) |
|
1896 | 1896 |
goto abort_cmd; |
1897 | 1897 |
ide_cmd_lba48_transform(s, lba48); |
1898 | 1898 |
s->req_nb_sectors = 1; |
... | ... | |
1940 | 1940 |
lba48 = 1; |
1941 | 1941 |
case WIN_READDMA: |
1942 | 1942 |
case WIN_READDMA_ONCE: |
1943 |
if (!s->bs)
|
|
1943 |
if (!s->bs) |
|
1944 | 1944 |
goto abort_cmd; |
1945 | 1945 |
ide_cmd_lba48_transform(s, lba48); |
1946 | 1946 |
ide_sector_read_dma(s); |
... | ... | |
1949 | 1949 |
lba48 = 1; |
1950 | 1950 |
case WIN_WRITEDMA: |
1951 | 1951 |
case WIN_WRITEDMA_ONCE: |
1952 |
if (!s->bs)
|
|
1952 |
if (!s->bs) |
|
1953 | 1953 |
goto abort_cmd; |
1954 | 1954 |
ide_cmd_lba48_transform(s, lba48); |
1955 | 1955 |
ide_sector_write_dma(s); |
... | ... | |
2071 | 2071 |
s->status = READY_STAT; |
2072 | 2072 |
s->atapi_dma = s->feature & 1; |
2073 | 2073 |
s->nsector = 1; |
2074 |
ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
|
|
2074 |
ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, |
|
2075 | 2075 |
ide_atapi_cmd); |
2076 | 2076 |
break; |
2077 | 2077 |
/* CF-ATA commands */ |
... | ... | |
2330 | 2330 |
IDEState *s = ((IDEState *)opaque)->cur_drive; |
2331 | 2331 |
uint8_t *p; |
2332 | 2332 |
int ret; |
2333 |
|
|
2333 |
|
|
2334 | 2334 |
p = s->data_ptr; |
2335 | 2335 |
ret = cpu_to_le32(*(uint32_t *)p); |
2336 | 2336 |
p += 4; |
... | ... | |
2381 | 2381 |
} __attribute__((packed)); |
2382 | 2382 |
|
2383 | 2383 |
/* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */ |
2384 |
static int guess_disk_lchs(IDEState *s,
|
|
2384 |
static int guess_disk_lchs(IDEState *s, |
|
2385 | 2385 |
int *pcylinders, int *pheads, int *psectors) |
2386 | 2386 |
{ |
2387 | 2387 |
uint8_t buf[512]; |
... | ... | |
2412 | 2412 |
*psectors = sectors; |
2413 | 2413 |
*pcylinders = cylinders; |
2414 | 2414 |
#if 0 |
2415 |
printf("guessed geometry: LCHS=%d %d %d\n",
|
|
2415 |
printf("guessed geometry: LCHS=%d %d %d\n", |
|
2416 | 2416 |
cylinders, heads, sectors); |
2417 | 2417 |
#endif |
2418 | 2418 |
return 0; |
... | ... | |
2495 | 2495 |
} |
2496 | 2496 |
s->drive_serial = drive_serial++; |
2497 | 2497 |
s->irq = irq; |
2498 |
s->sector_write_timer = qemu_new_timer(vm_clock,
|
|
2498 |
s->sector_write_timer = qemu_new_timer(vm_clock, |
|
2499 | 2499 |
ide_sector_write_timer_cb, s); |
2500 | 2500 |
ide_reset(s); |
2501 | 2501 |
} |
... | ... | |
2509 | 2509 |
register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state); |
2510 | 2510 |
register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state); |
2511 | 2511 |
} |
2512 |
|
|
2512 |
|
|
2513 | 2513 |
/* data ports */ |
2514 | 2514 |
register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state); |
2515 | 2515 |
register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state); |
... | ... | |
2584 | 2584 |
ide_state = qemu_mallocz(sizeof(IDEState) * 2); |
2585 | 2585 |
if (!ide_state) |
2586 | 2586 |
return; |
2587 |
|
|
2587 |
|
|
2588 | 2588 |
ide_init2(ide_state, hd0, hd1, irq); |
2589 | 2589 |
ide_init_ioport(ide_state, iobase, iobase2); |
2590 | 2590 |
} |
... | ... | |
2594 | 2594 |
|
2595 | 2595 |
static void cmd646_update_irq(PCIIDEState *d); |
2596 | 2596 |
|
2597 |
static void ide_map(PCIDevice *pci_dev, int region_num,
|
|
2597 |
static void ide_map(PCIDevice *pci_dev, int region_num, |
|
2598 | 2598 |
uint32_t addr, uint32_t size, int type) |
2599 | 2599 |
{ |
2600 | 2600 |
PCIIDEState *d = (PCIIDEState *)pci_dev; |
... | ... | |
2671 | 2671 |
BMDMAState *bm = opaque; |
2672 | 2672 |
PCIIDEState *pci_dev; |
2673 | 2673 |
uint32_t val; |
2674 |
|
|
2674 |
|
|
2675 | 2675 |
switch(addr & 3) { |
2676 |
case 0:
|
|
2676 |
case 0: |
|
2677 | 2677 |
val = bm->cmd; |
2678 | 2678 |
break; |
2679 | 2679 |
case 1: |
... | ... | |
2719 | 2719 |
case 1: |
2720 | 2720 |
pci_dev = bm->pci_dev; |
2721 | 2721 |
if (pci_dev->type == IDE_TYPE_CMD646) { |
2722 |
pci_dev->dev.config[MRDMODE] =
|
|
2722 |
pci_dev->dev.config[MRDMODE] = |
|
2723 | 2723 |
(pci_dev->dev.config[MRDMODE] & ~0x30) | (val & 0x30); |
2724 | 2724 |
cmd646_update_irq(pci_dev); |
2725 | 2725 |
} |
... | ... | |
2760 | 2760 |
bm->cur_addr = bm->addr; |
2761 | 2761 |
} |
2762 | 2762 |
|
2763 |
static void bmdma_map(PCIDevice *pci_dev, int region_num,
|
|
2763 |
static void bmdma_map(PCIDevice *pci_dev, int region_num, |
|
2764 | 2764 |
uint32_t addr, uint32_t size, int type) |
2765 | 2765 |
{ |
2766 | 2766 |
PCIIDEState *d = (PCIIDEState *)pci_dev; |
... | ... | |
2818 | 2818 |
int i; |
2819 | 2819 |
qemu_irq *irq; |
2820 | 2820 |
|
2821 |
d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
|
|
2821 |
d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", |
|
2822 | 2822 |
sizeof(PCIIDEState), |
2823 |
-1,
|
|
2823 |
-1, |
|
2824 | 2824 |
NULL, NULL); |
2825 | 2825 |
d->type = IDE_TYPE_CMD646; |
2826 | 2826 |
pci_conf = d->dev.config; |
... | ... | |
2830 | 2830 |
pci_conf[0x03] = 0x06; |
2831 | 2831 |
|
2832 | 2832 |
pci_conf[0x08] = 0x07; // IDE controller revision |
2833 |
pci_conf[0x09] = 0x8f;
|
|
2833 |
pci_conf[0x09] = 0x8f; |
|
2834 | 2834 |
|
2835 | 2835 |
pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE |
2836 | 2836 |
pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage |
2837 | 2837 |
pci_conf[0x0e] = 0x00; // header_type |
2838 |
|
|
2838 |
|
|
2839 | 2839 |
if (secondary_ide_enabled) { |
2840 | 2840 |
/* XXX: if not enabled, really disable the seconday IDE controller */ |
2841 | 2841 |
pci_conf[0x51] = 0x80; /* enable IDE1 */ |
2842 | 2842 |
} |
2843 | 2843 |
|
2844 |
pci_register_io_region((PCIDevice *)d, 0, 0x8,
|
|
2844 |
pci_register_io_region((PCIDevice *)d, 0, 0x8, |
|
2845 | 2845 |
PCI_ADDRESS_SPACE_IO, ide_map); |
2846 |
pci_register_io_region((PCIDevice *)d, 1, 0x4,
|
|
2846 |
pci_register_io_region((PCIDevice *)d, 1, 0x4, |
|
2847 | 2847 |
PCI_ADDRESS_SPACE_IO, ide_map); |
2848 |
pci_register_io_region((PCIDevice *)d, 2, 0x8,
|
|
2848 |
pci_register_io_region((PCIDevice *)d, 2, 0x8, |
|
2849 | 2849 |
PCI_ADDRESS_SPACE_IO, ide_map); |
2850 |
pci_register_io_region((PCIDevice *)d, 3, 0x4,
|
|
2850 |
pci_register_io_region((PCIDevice *)d, 3, 0x4, |
|
2851 | 2851 |
PCI_ADDRESS_SPACE_IO, ide_map); |
2852 |
pci_register_io_region((PCIDevice *)d, 4, 0x10,
|
|
2852 |
pci_register_io_region((PCIDevice *)d, 4, 0x10, |
|
2853 | 2853 |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
2854 | 2854 |
|
2855 | 2855 |
pci_conf[0x3d] = 0x01; // interrupt on pin 1 |
2856 |
|
|
2856 |
|
|
2857 | 2857 |
for(i = 0; i < 4; i++) |
2858 | 2858 |
d->ide_if[i].pci_dev = (PCIDevice *)d; |
2859 | 2859 |
|
... | ... | |
2945 | 2945 |
{ |
2946 | 2946 |
PCIIDEState *d; |
2947 | 2947 |
uint8_t *pci_conf; |
2948 |
|
|
2948 |
|
|
2949 | 2949 |
/* register a function 1 of PIIX3 */ |
2950 |
d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE",
|
|
2950 |
d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", |
|
2951 | 2951 |
sizeof(PCIIDEState), |
2952 | 2952 |
devfn, |
2953 | 2953 |
NULL, NULL); |
... | ... | |
2965 | 2965 |
|
2966 | 2966 |
piix3_reset(d); |
2967 | 2967 |
|
2968 |
pci_register_io_region((PCIDevice *)d, 4, 0x10,
|
|
2968 |
pci_register_io_region((PCIDevice *)d, 4, 0x10, |
|
2969 | 2969 |
PCI_ADDRESS_SPACE_IO, bmdma_map); |
2970 | 2970 |
|
2971 | 2971 |
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]); |
... | ... | |
3021 | 3021 |
static void pmac_ide_writeb (void *opaque, |
3022 | 3022 |
target_phys_addr_t addr, uint32_t val) |
3023 | 3023 |
{ |
3024 |
addr = (addr & 0xFFF) >> 4;
|
|
3024 |
addr = (addr & 0xFFF) >> 4; |
|
3025 | 3025 |
switch (addr) { |
3026 | 3026 |
case 1 ... 7: |
3027 | 3027 |
ide_ioport_write(opaque, addr, val); |
... | ... | |
3058 | 3058 |
static void pmac_ide_writew (void *opaque, |
3059 | 3059 |
target_phys_addr_t addr, uint32_t val) |
3060 | 3060 |
{ |
3061 |
addr = (addr & 0xFFF) >> 4;
|
|
3061 |
addr = (addr & 0xFFF) >> 4; |
|
3062 | 3062 |
#ifdef TARGET_WORDS_BIGENDIAN |
3063 | 3063 |
val = bswap16(val); |
3064 | 3064 |
#endif |
... | ... | |
3071 | 3071 |
{ |
3072 | 3072 |
uint16_t retval; |
3073 | 3073 |
|
3074 |
addr = (addr & 0xFFF) >> 4;
|
|
3074 |
addr = (addr & 0xFFF) >> 4; |
|
3075 | 3075 |
if (addr == 0) { |
3076 | 3076 |
retval = ide_data_readw(opaque, 0); |
3077 | 3077 |
} else { |
... | ... | |
3086 | 3086 |
static void pmac_ide_writel (void *opaque, |
3087 | 3087 |
target_phys_addr_t addr, uint32_t val) |
3088 | 3088 |
{ |
3089 |
addr = (addr & 0xFFF) >> 4;
|
|
3089 |
addr = (addr & 0xFFF) >> 4; |
|
3090 | 3090 |
#ifdef TARGET_WORDS_BIGENDIAN |
3091 | 3091 |
val = bswap32(val); |
3092 | 3092 |
#endif |
... | ... | |
3099 | 3099 |
{ |
3100 | 3100 |
uint32_t retval; |
3101 | 3101 |
|
3102 |
addr = (addr & 0xFFF) >> 4;
|
|
3102 |
addr = (addr & 0xFFF) >> 4; |
|
3103 | 3103 |
if (addr == 0) { |
3104 | 3104 |
retval = ide_data_readl(opaque, 0); |
3105 | 3105 |
} else { |
... | ... | |
3133 | 3133 |
|
3134 | 3134 |
ide_if = qemu_mallocz(sizeof(IDEState) * 2); |
3135 | 3135 |
ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq); |
3136 |
|
|
3136 |
|
|
3137 | 3137 |
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
3138 | 3138 |
pmac_ide_write, &ide_if[0]); |
3139 | 3139 |
return pmac_ide_memory; |
Also available in: Unified diff