Commit 98087450722d974b814e19a056ea82699440c0a7

Authored by bellard
1 parent 02ba45c5

BMDMA support - CDROM fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@971 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 546 additions and 26 deletions
hw/ide.c
... ... @@ -299,6 +299,7 @@ typedef struct IDEState {
299 299 int irq;
300 300 openpic_t *openpic;
301 301 PCIDevice *pci_dev;
  302 + struct BMDMAState *bmdma;
302 303 int drive_serial;
303 304 /* ide regs */
304 305 uint8_t feature;
... ... @@ -321,7 +322,11 @@ typedef struct IDEState {
321 322 int elementary_transfer_size;
322 323 int io_buffer_index;
323 324 int lba;
324   - /* transfer handling */
  325 + int cd_sector_size;
  326 + int atapi_dma; /* true if dma is requested for the packet cmd */
  327 + /* ATA DMA state */
  328 + int io_buffer_size;
  329 + /* PIO transfer handling */
325 330 int req_nb_sectors; /* number of sectors per interrupt */
326 331 EndTransferFunc *end_transfer_func;
327 332 uint8_t *data_ptr;
... ... @@ -329,6 +334,34 @@ typedef struct IDEState {
329 334 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
330 335 } IDEState;
331 336  
  337 +#define BM_STATUS_DMAING 0x01
  338 +#define BM_STATUS_ERROR 0x02
  339 +#define BM_STATUS_INT 0x04
  340 +
  341 +#define BM_CMD_START 0x01
  342 +#define BM_CMD_READ 0x08
  343 +
  344 +typedef int IDEDMAFunc(IDEState *s,
  345 + target_phys_addr_t phys_addr,
  346 + int transfer_size1);
  347 +
  348 +typedef struct BMDMAState {
  349 + uint8_t cmd;
  350 + uint8_t status;
  351 + uint32_t addr;
  352 + /* current transfer state */
  353 + IDEState *ide_if;
  354 + IDEDMAFunc *dma_cb;
  355 +} BMDMAState;
  356 +
  357 +typedef struct PCIIDEState {
  358 + PCIDevice dev;
  359 + IDEState ide_if[4];
  360 + BMDMAState bmdma[2];
  361 +} PCIIDEState;
  362 +
  363 +static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
  364 +
332 365 static void padstr(char *str, const char *src, int len)
333 366 {
334 367 int i, v;
... ... @@ -554,6 +587,59 @@ static void ide_sector_read(IDEState *s)
554 587 }
555 588 }
556 589  
  590 +static int ide_read_dma_cb(IDEState *s,
  591 + target_phys_addr_t phys_addr,
  592 + int transfer_size1)
  593 +{
  594 + int len, transfer_size, n;
  595 + int64_t sector_num;
  596 +
  597 + transfer_size = transfer_size1;
  598 + while (transfer_size > 0) {
  599 + len = s->io_buffer_size - s->io_buffer_index;
  600 + if (len <= 0) {
  601 + /* transfert next data */
  602 + n = s->nsector;
  603 + if (n == 0)
  604 + break;
  605 + if (n > MAX_MULT_SECTORS)
  606 + n = MAX_MULT_SECTORS;
  607 + sector_num = ide_get_sector(s);
  608 + bdrv_read(s->bs, sector_num, s->io_buffer, n);
  609 + s->io_buffer_index = 0;
  610 + s->io_buffer_size = n * 512;
  611 + len = s->io_buffer_size;
  612 + sector_num += n;
  613 + ide_set_sector(s, sector_num);
  614 + s->nsector -= n;
  615 + }
  616 + if (len > transfer_size)
  617 + len = transfer_size;
  618 + cpu_physical_memory_write(phys_addr,
  619 + s->io_buffer + s->io_buffer_index, len);
  620 + s->io_buffer_index += len;
  621 + transfer_size -= len;
  622 + phys_addr += len;
  623 + }
  624 + if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
  625 + s->status = READY_STAT | SEEK_STAT;
  626 + ide_set_irq(s);
  627 +#ifdef DEBUG_IDE_ATAPI
  628 + printf("dma status=0x%x\n", s->status);
  629 +#endif
  630 + return 0;
  631 + }
  632 + return transfer_size1 - transfer_size;
  633 +}
  634 +
  635 +static void ide_sector_read_dma(IDEState *s)
  636 +{
  637 + s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
  638 + s->io_buffer_index = 0;
  639 + s->io_buffer_size = 0;
  640 + ide_dma_start(s, ide_read_dma_cb);
  641 +}
  642 +
557 643 static void ide_sector_write(IDEState *s)
558 644 {
559 645 int64_t sector_num;
... ... @@ -582,6 +668,62 @@ static void ide_sector_write(IDEState *s)
582 668 ide_set_irq(s);
583 669 }
584 670  
  671 +static int ide_write_dma_cb(IDEState *s,
  672 + target_phys_addr_t phys_addr,
  673 + int transfer_size1)
  674 +{
  675 + int len, transfer_size, n;
  676 + int64_t sector_num;
  677 +
  678 + transfer_size = transfer_size1;
  679 + for(;;) {
  680 + len = s->io_buffer_size - s->io_buffer_index;
  681 + if (len == 0) {
  682 + n = s->io_buffer_size >> 9;
  683 + sector_num = ide_get_sector(s);
  684 + bdrv_write(s->bs, sector_num, s->io_buffer,
  685 + s->io_buffer_size >> 9);
  686 + sector_num += n;
  687 + ide_set_sector(s, sector_num);
  688 + s->nsector -= n;
  689 + n = s->nsector;
  690 + if (n == 0) {
  691 + /* end of transfer */
  692 + s->status = READY_STAT | SEEK_STAT;
  693 + ide_set_irq(s);
  694 + return 0;
  695 + }
  696 + if (n > MAX_MULT_SECTORS)
  697 + n = MAX_MULT_SECTORS;
  698 + s->io_buffer_index = 0;
  699 + s->io_buffer_size = n * 512;
  700 + len = s->io_buffer_size;
  701 + }
  702 + if (transfer_size <= 0)
  703 + break;
  704 + if (len > transfer_size)
  705 + len = transfer_size;
  706 + cpu_physical_memory_read(phys_addr,
  707 + s->io_buffer + s->io_buffer_index, len);
  708 + s->io_buffer_index += len;
  709 + transfer_size -= len;
  710 + phys_addr += len;
  711 + }
  712 + return transfer_size1 - transfer_size;
  713 +}
  714 +
  715 +static void ide_sector_write_dma(IDEState *s)
  716 +{
  717 + int n;
  718 + s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
  719 + n = s->nsector;
  720 + if (n > MAX_MULT_SECTORS)
  721 + n = MAX_MULT_SECTORS;
  722 + s->io_buffer_index = 0;
  723 + s->io_buffer_size = n * 512;
  724 + ide_dma_start(s, ide_write_dma_cb);
  725 +}
  726 +
585 727 static void ide_atapi_cmd_ok(IDEState *s)
586 728 {
587 729 s->error = 0;
... ... @@ -627,6 +769,41 @@ static inline int ube32_to_cpu(const uint8_t *buf)
627 769 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
628 770 }
629 771  
  772 +static void lba_to_msf(uint8_t *buf, int lba)
  773 +{
  774 + lba += 150;
  775 + buf[0] = (lba / 75) / 60;
  776 + buf[1] = (lba / 75) % 60;
  777 + buf[2] = lba % 75;
  778 +}
  779 +
  780 +static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
  781 + int sector_size)
  782 +{
  783 + switch(sector_size) {
  784 + case 2048:
  785 + bdrv_read(bs, (int64_t)lba << 2, buf, 4);
  786 + break;
  787 + case 2352:
  788 + /* sync bytes */
  789 + buf[0] = 0x00;
  790 + memset(buf + 1, 0xff, 11);
  791 + buf += 12;
  792 + /* MSF */
  793 + lba_to_msf(buf, lba);
  794 + buf[3] = 0x01; /* mode 1 data */
  795 + buf += 4;
  796 + /* data */
  797 + bdrv_read(bs, (int64_t)lba << 2, buf, 4);
  798 + buf += 2048;
  799 + /* ECC */
  800 + memset(buf, 0, 288);
  801 + break;
  802 + default:
  803 + break;
  804 + }
  805 +}
  806 +
630 807 /* The whole ATAPI transfer logic is handled in this function */
631 808 static void ide_atapi_cmd_reply_end(IDEState *s)
632 809 {
... ... @@ -648,15 +825,15 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
648 825 #endif
649 826 } else {
650 827 /* see if a new sector must be read */
651   - if (s->lba != -1 && s->io_buffer_index >= 2048) {
652   - bdrv_read(s->bs, (int64_t)s->lba << 2, s->io_buffer, 4);
  828 + if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
  829 + cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
653 830 s->lba++;
654 831 s->io_buffer_index = 0;
655 832 }
656 833 if (s->elementary_transfer_size > 0) {
657 834 /* there are some data left to transmit in this elementary
658 835 transfer */
659   - size = 2048 - s->io_buffer_index;
  836 + size = s->cd_sector_size - s->io_buffer_index;
660 837 if (size > s->elementary_transfer_size)
661 838 size = s->elementary_transfer_size;
662 839 ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
... ... @@ -685,8 +862,8 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
685 862 s->elementary_transfer_size = size;
686 863 /* we cannot transmit more than one sector at a time */
687 864 if (s->lba != -1) {
688   - if (size > (2048 - s->io_buffer_index))
689   - size = (2048 - s->io_buffer_index);
  865 + if (size > (s->cd_sector_size - s->io_buffer_index))
  866 + size = (s->cd_sector_size - s->io_buffer_index);
690 867 }
691 868 ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
692 869 size, ide_atapi_cmd_reply_end);
... ... @@ -716,21 +893,88 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
716 893 }
717 894  
718 895 /* start a CD-CDROM read command */
719   -static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors)
  896 +static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
  897 + int sector_size)
720 898 {
721   -#ifdef DEBUG_IDE_ATAPI
722   - printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
723   -#endif
724 899 s->lba = lba;
725   - s->packet_transfer_size = nb_sectors * 2048;
  900 + s->packet_transfer_size = nb_sectors * sector_size;
726 901 s->elementary_transfer_size = 0;
727   - s->io_buffer_index = 2048;
  902 + s->io_buffer_index = sector_size;
  903 + s->cd_sector_size = sector_size;
728 904  
729 905 s->status = READY_STAT;
730 906 ide_atapi_cmd_reply_end(s);
731 907 }
732 908  
  909 +/* ATAPI DMA support */
  910 +static int ide_atapi_cmd_read_dma_cb(IDEState *s,
  911 + target_phys_addr_t phys_addr,
  912 + int transfer_size1)
  913 +{
  914 + int len, transfer_size;
  915 +
  916 + transfer_size = transfer_size1;
  917 + while (transfer_size > 0) {
  918 + if (s->packet_transfer_size <= 0)
  919 + break;
  920 + len = s->cd_sector_size - s->io_buffer_index;
  921 + if (len <= 0) {
  922 + /* transfert next data */
  923 + cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
  924 + s->lba++;
  925 + s->io_buffer_index = 0;
  926 + len = s->cd_sector_size;
  927 + }
  928 + if (len > transfer_size)
  929 + len = transfer_size;
  930 + cpu_physical_memory_write(phys_addr,
  931 + s->io_buffer + s->io_buffer_index, len);
  932 + s->packet_transfer_size -= len;
  933 + s->io_buffer_index += len;
  934 + transfer_size -= len;
  935 + phys_addr += len;
  936 + }
  937 + if (s->packet_transfer_size <= 0) {
  938 + s->status = READY_STAT;
  939 + s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
  940 + ide_set_irq(s);
  941 +#ifdef DEBUG_IDE_ATAPI
  942 + printf("dma status=0x%x\n", s->status);
  943 +#endif
  944 + return 0;
  945 + }
  946 + return transfer_size1 - transfer_size;
  947 +}
  948 +
  949 +/* start a CD-CDROM read command with DMA */
  950 +/* XXX: test if DMA is available */
  951 +static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
  952 + int sector_size)
  953 +{
  954 + s->lba = lba;
  955 + s->packet_transfer_size = nb_sectors * sector_size;
  956 + s->io_buffer_index = sector_size;
  957 + s->cd_sector_size = sector_size;
  958 +
  959 + s->status = READY_STAT | DRQ_STAT;
  960 + ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
  961 +}
  962 +
  963 +static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
  964 + int sector_size)
  965 +{
  966 +#ifdef DEBUG_IDE_ATAPI
  967 + printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
  968 +#endif
  969 + if (s->atapi_dma) {
  970 + ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
  971 + } else {
  972 + ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
  973 + }
  974 +}
  975 +
733 976 /* same toc as bochs. Return -1 if error or the toc length */
  977 +/* XXX: check this */
734 978 static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
735 979 {
736 980 uint8_t *q;
... ... @@ -739,8 +983,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
739 983 if (start_track > 1 && start_track != 0xaa)
740 984 return -1;
741 985 q = buf + 2;
742   - *q++ = 1;
743   - *q++ = 1;
  986 + *q++ = 1; /* first session */
  987 + *q++ = 1; /* last session */
744 988 if (start_track <= 1) {
745 989 *q++ = 0; /* reserved */
746 990 *q++ = 0x14; /* ADR, control */
... ... @@ -765,9 +1009,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
765 1009 nb_sectors = s->nb_sectors >> 2;
766 1010 if (msf) {
767 1011 *q++ = 0; /* reserved */
768   - *q++ = ((nb_sectors + 150) / 75) / 60;
769   - *q++ = ((nb_sectors + 150) / 75) % 60;
770   - *q++ = (nb_sectors + 150) % 75;
  1012 + lba_to_msf(q, nb_sectors);
  1013 + q += 3;
771 1014 } else {
772 1015 cpu_to_ube32(q, nb_sectors);
773 1016 q += 4;
... ... @@ -777,6 +1020,75 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
777 1020 return len;
778 1021 }
779 1022  
  1023 +/* mostly same info as PearPc */
  1024 +static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf,
  1025 + int session_num)
  1026 +{
  1027 + uint8_t *q;
  1028 + int nb_sectors, len;
  1029 +
  1030 + q = buf + 2;
  1031 + *q++ = 1; /* first session */
  1032 + *q++ = 1; /* last session */
  1033 +
  1034 + *q++ = 1; /* session number */
  1035 + *q++ = 0x14; /* data track */
  1036 + *q++ = 0; /* track number */
  1037 + *q++ = 0xa0; /* lead-in */
  1038 + *q++ = 0; /* min */
  1039 + *q++ = 0; /* sec */
  1040 + *q++ = 0; /* frame */
  1041 + *q++ = 0;
  1042 + *q++ = 1; /* first track */
  1043 + *q++ = 0x00; /* disk type */
  1044 + *q++ = 0x00;
  1045 +
  1046 + *q++ = 1; /* session number */
  1047 + *q++ = 0x14; /* data track */
  1048 + *q++ = 0; /* track number */
  1049 + *q++ = 0xa1;
  1050 + *q++ = 0; /* min */
  1051 + *q++ = 0; /* sec */
  1052 + *q++ = 0; /* frame */
  1053 + *q++ = 0;
  1054 + *q++ = 1; /* last track */
  1055 + *q++ = 0x00;
  1056 + *q++ = 0x00;
  1057 +
  1058 + *q++ = 1; /* session number */
  1059 + *q++ = 0x14; /* data track */
  1060 + *q++ = 0; /* track number */
  1061 + *q++ = 0xa2; /* lead-out */
  1062 + *q++ = 0; /* min */
  1063 + *q++ = 0; /* sec */
  1064 + *q++ = 0; /* frame */
  1065 + nb_sectors = s->nb_sectors >> 2;
  1066 + if (msf) {
  1067 + *q++ = 0; /* reserved */
  1068 + lba_to_msf(q, nb_sectors);
  1069 + q += 3;
  1070 + } else {
  1071 + cpu_to_ube32(q, nb_sectors);
  1072 + q += 4;
  1073 + }
  1074 +
  1075 + *q++ = 1; /* session number */
  1076 + *q++ = 0x14; /* ADR, control */
  1077 + *q++ = 0; /* track number */
  1078 + *q++ = 1; /* point */
  1079 + *q++ = 0; /* min */
  1080 + *q++ = 0; /* sec */
  1081 + *q++ = 0; /* frame */
  1082 + *q++ = 0;
  1083 + *q++ = 0;
  1084 + *q++ = 0;
  1085 + *q++ = 0;
  1086 +
  1087 + len = q - buf;
  1088 + cpu_to_ube16(buf, len - 2);
  1089 + return len;
  1090 +}
  1091 +
780 1092 static void ide_atapi_cmd(IDEState *s)
781 1093 {
782 1094 const uint8_t *packet;
... ... @@ -921,7 +1233,48 @@ static void ide_atapi_cmd(IDEState *s)
921 1233 ASC_LOGICAL_BLOCK_OOR);
922 1234 break;
923 1235 }
924   - ide_atapi_cmd_read(s, lba, nb_sectors);
  1236 + ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
  1237 + }
  1238 + break;
  1239 + case GPCMD_READ_CD:
  1240 + {
  1241 + int nb_sectors, lba, transfer_request;
  1242 +
  1243 + if (!bdrv_is_inserted(s->bs)) {
  1244 + ide_atapi_cmd_error(s, SENSE_NOT_READY,
  1245 + ASC_MEDIUM_NOT_PRESENT);
  1246 + break;
  1247 + }
  1248 + nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
  1249 + lba = ube32_to_cpu(packet + 2);
  1250 + if (nb_sectors == 0) {
  1251 + ide_atapi_cmd_ok(s);
  1252 + break;
  1253 + }
  1254 + if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
  1255 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  1256 + ASC_LOGICAL_BLOCK_OOR);
  1257 + break;
  1258 + }
  1259 + transfer_request = packet[9];
  1260 + switch(transfer_request & 0xf8) {
  1261 + case 0x00:
  1262 + /* nothing */
  1263 + ide_atapi_cmd_ok(s);
  1264 + break;
  1265 + case 0x10:
  1266 + /* normal read */
  1267 + ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
  1268 + break;
  1269 + case 0xf8:
  1270 + /* read all data */
  1271 + ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
  1272 + break;
  1273 + default:
  1274 + ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
  1275 + ASC_INV_FIELD_IN_CMD_PACKET);
  1276 + break;
  1277 + }
925 1278 }
926 1279 break;
927 1280 case GPCMD_SEEK:
... ... @@ -995,6 +1348,12 @@ static void ide_atapi_cmd(IDEState *s)
995 1348 buf[3] = 0x01;
996 1349 ide_atapi_cmd_reply(s, 12, max_len);
997 1350 break;
  1351 + case 2:
  1352 + len = cdrom_read_toc_raw(s, buf, msf, start_track);
  1353 + if (len < 0)
  1354 + goto error_cmd;
  1355 + ide_atapi_cmd_reply(s, len, max_len);
  1356 + break;
998 1357 default:
999 1358 error_cmd:
1000 1359 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST,
... ... @@ -1169,6 +1528,18 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1169 1528 n = s->req_nb_sectors;
1170 1529 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1171 1530 break;
  1531 + case WIN_READDMA:
  1532 + case WIN_READDMA_ONCE:
  1533 + if (!s->bs)
  1534 + goto abort_cmd;
  1535 + ide_sector_read_dma(s);
  1536 + break;
  1537 + case WIN_WRITEDMA:
  1538 + case WIN_WRITEDMA_ONCE:
  1539 + if (!s->bs)
  1540 + goto abort_cmd;
  1541 + ide_sector_write_dma(s);
  1542 + break;
1172 1543 case WIN_READ_NATIVE_MAX:
1173 1544 ide_set_sector(s, s->nb_sectors - 1);
1174 1545 s->status = READY_STAT;
... ... @@ -1185,6 +1556,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1185 1556 /* XXX: valid for CDROM ? */
1186 1557 switch(s->feature) {
1187 1558 case 0x02: /* write cache enable */
  1559 + case 0x03: /* set transfer mode */
1188 1560 case 0x82: /* write cache disable */
1189 1561 case 0xaa: /* read look-ahead enable */
1190 1562 case 0x55: /* read look-ahead disable */
... ... @@ -1216,9 +1588,10 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1216 1588 case WIN_PACKETCMD:
1217 1589 if (!s->is_cdrom)
1218 1590 goto abort_cmd;
1219   - /* DMA or overlapping commands not supported */
1220   - if ((s->feature & 0x03) != 0)
  1591 + /* overlapping commands not supported */
  1592 + if (s->feature & 0x02)
1221 1593 goto abort_cmd;
  1594 + s->atapi_dma = s->feature & 1;
1222 1595 s->nsector = 1;
1223 1596 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1224 1597 ide_atapi_cmd);
... ... @@ -1549,11 +1922,6 @@ void isa_ide_init(int iobase, int iobase2, int irq,
1549 1922 /***********************************************************/
1550 1923 /* PCI IDE definitions */
1551 1924  
1552   -typedef struct PCIIDEState {
1553   - PCIDevice dev;
1554   - IDEState ide_if[4];
1555   -} PCIIDEState;
1556   -
1557 1925 static void ide_map(PCIDevice *pci_dev, int region_num,
1558 1926 uint32_t addr, uint32_t size, int type)
1559 1927 {
... ... @@ -1578,6 +1946,155 @@ static void ide_map(PCIDevice *pci_dev, int region_num,
1578 1946 }
1579 1947 }
1580 1948  
  1949 +/* XXX: full callback usage to prepare non blocking I/Os support -
  1950 + error handling */
  1951 +static void ide_dma_loop(BMDMAState *bm)
  1952 +{
  1953 + struct {
  1954 + uint32_t addr;
  1955 + uint32_t size;
  1956 + } prd;
  1957 + target_phys_addr_t cur_addr;
  1958 + int len, i, len1;
  1959 +
  1960 + cur_addr = bm->addr;
  1961 + /* at most one page to avoid hanging if erroneous parameters */
  1962 + for(i = 0; i < 512; i++) {
  1963 + cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
  1964 + prd.addr = le32_to_cpu(prd.addr);
  1965 + prd.size = le32_to_cpu(prd.size);
  1966 +#ifdef DEBUG_IDE
  1967 + printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n",
  1968 + (int)cur_addr, prd.addr, prd.size);
  1969 +#endif
  1970 + len = prd.size & 0xfffe;
  1971 + if (len == 0)
  1972 + len = 0x10000;
  1973 + while (len > 0) {
  1974 + len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
  1975 + if (len1 == 0)
  1976 + goto the_end;
  1977 + prd.addr += len1;
  1978 + len -= len1;
  1979 + }
  1980 + /* end of transfer */
  1981 + if (prd.size & 0x80000000)
  1982 + break;
  1983 + cur_addr += 8;
  1984 + }
  1985 + /* end of transfer */
  1986 + the_end:
  1987 + bm->status &= ~BM_STATUS_DMAING;
  1988 + bm->status |= BM_STATUS_INT;
  1989 + bm->dma_cb = NULL;
  1990 + bm->ide_if = NULL;
  1991 +}
  1992 +
  1993 +static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
  1994 +{
  1995 + BMDMAState *bm = s->bmdma;
  1996 + if(!bm)
  1997 + return;
  1998 + bm->ide_if = s;
  1999 + bm->dma_cb = dma_cb;
  2000 + if (bm->status & BM_STATUS_DMAING) {
  2001 + ide_dma_loop(bm);
  2002 + }
  2003 +}
  2004 +
  2005 +static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr)
  2006 +{
  2007 + BMDMAState *bm = opaque;
  2008 + uint32_t val;
  2009 + val = bm->cmd;
  2010 +#ifdef DEBUG_IDE
  2011 + printf("%s: 0x%08x\n", __func__, val);
  2012 +#endif
  2013 + return val;
  2014 +}
  2015 +
  2016 +static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
  2017 +{
  2018 + BMDMAState *bm = opaque;
  2019 +#ifdef DEBUG_IDE
  2020 + printf("%s: 0x%08x\n", __func__, val);
  2021 +#endif
  2022 + if (!(val & BM_CMD_START)) {
  2023 + /* XXX: do it better */
  2024 + bm->status &= ~BM_STATUS_DMAING;
  2025 + bm->cmd = val & 0x09;
  2026 + } else {
  2027 + bm->status |= BM_STATUS_DMAING;
  2028 + bm->cmd = val & 0x09;
  2029 + /* start dma transfer if possible */
  2030 + if (bm->dma_cb)
  2031 + ide_dma_loop(bm);
  2032 + }
  2033 +}
  2034 +
  2035 +static uint32_t bmdma_status_readb(void *opaque, uint32_t addr)
  2036 +{
  2037 + BMDMAState *bm = opaque;
  2038 + uint32_t val;
  2039 + val = bm->status;
  2040 +#ifdef DEBUG_IDE
  2041 + printf("%s: 0x%08x\n", __func__, val);
  2042 +#endif
  2043 + return val;
  2044 +}
  2045 +
  2046 +static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val)
  2047 +{
  2048 + BMDMAState *bm = opaque;
  2049 +#ifdef DEBUG_IDE
  2050 + printf("%s: 0x%08x\n", __func__, val);
  2051 +#endif
  2052 + bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
  2053 +}
  2054 +
  2055 +static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
  2056 +{
  2057 + BMDMAState *bm = opaque;
  2058 + uint32_t val;
  2059 + val = bm->addr;
  2060 +#ifdef DEBUG_IDE
  2061 + printf("%s: 0x%08x\n", __func__, val);
  2062 +#endif
  2063 + return val;
  2064 +}
  2065 +
  2066 +static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
  2067 +{
  2068 + BMDMAState *bm = opaque;
  2069 +#ifdef DEBUG_IDE
  2070 + printf("%s: 0x%08x\n", __func__, val);
  2071 +#endif
  2072 + bm->addr = val & ~3;
  2073 +}
  2074 +
  2075 +static void bmdma_map(PCIDevice *pci_dev, int region_num,
  2076 + uint32_t addr, uint32_t size, int type)
  2077 +{
  2078 + PCIIDEState *d = (PCIIDEState *)pci_dev;
  2079 + int i;
  2080 +
  2081 + for(i = 0;i < 2; i++) {
  2082 + BMDMAState *bm = &d->bmdma[i];
  2083 + d->ide_if[2 * i].bmdma = bm;
  2084 + d->ide_if[2 * i + 1].bmdma = bm;
  2085 +
  2086 + register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
  2087 + register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm);
  2088 +
  2089 + register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm);
  2090 + register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm);
  2091 +
  2092 + register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
  2093 + register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
  2094 + addr += 8;
  2095 + }
  2096 +}
  2097 +
1581 2098 /* hd_table must contain 4 block drivers */
1582 2099 void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
1583 2100 {
... ... @@ -1610,6 +2127,8 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
1610 2127 PCI_ADDRESS_SPACE_IO, ide_map);
1611 2128 pci_register_io_region((PCIDevice *)d, 3, 0x4,
1612 2129 PCI_ADDRESS_SPACE_IO, ide_map);
  2130 + pci_register_io_region((PCIDevice *)d, 4, 0x10,
  2131 + PCI_ADDRESS_SPACE_IO, bmdma_map);
1613 2132  
1614 2133 pci_conf[0x3d] = 0x01; // interrupt on pin 1
1615 2134  
... ... @@ -1640,7 +2159,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
1640 2159 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
1641 2160 pci_conf[0x0e] = 0x00; // header_type
1642 2161  
1643   - /* XXX: must add BMDMA support to be fully compliant */
  2162 + pci_register_io_region((PCIDevice *)d, 4, 0x10,
  2163 + PCI_ADDRESS_SPACE_IO, bmdma_map);
1644 2164  
1645 2165 ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
1646 2166 ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);
... ...