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,6 +299,7 @@ typedef struct IDEState {
299 int irq; 299 int irq;
300 openpic_t *openpic; 300 openpic_t *openpic;
301 PCIDevice *pci_dev; 301 PCIDevice *pci_dev;
  302 + struct BMDMAState *bmdma;
302 int drive_serial; 303 int drive_serial;
303 /* ide regs */ 304 /* ide regs */
304 uint8_t feature; 305 uint8_t feature;
@@ -321,7 +322,11 @@ typedef struct IDEState { @@ -321,7 +322,11 @@ typedef struct IDEState {
321 int elementary_transfer_size; 322 int elementary_transfer_size;
322 int io_buffer_index; 323 int io_buffer_index;
323 int lba; 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 int req_nb_sectors; /* number of sectors per interrupt */ 330 int req_nb_sectors; /* number of sectors per interrupt */
326 EndTransferFunc *end_transfer_func; 331 EndTransferFunc *end_transfer_func;
327 uint8_t *data_ptr; 332 uint8_t *data_ptr;
@@ -329,6 +334,34 @@ typedef struct IDEState { @@ -329,6 +334,34 @@ typedef struct IDEState {
329 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; 334 uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
330 } IDEState; 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 static void padstr(char *str, const char *src, int len) 365 static void padstr(char *str, const char *src, int len)
333 { 366 {
334 int i, v; 367 int i, v;
@@ -554,6 +587,59 @@ static void ide_sector_read(IDEState *s) @@ -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 static void ide_sector_write(IDEState *s) 643 static void ide_sector_write(IDEState *s)
558 { 644 {
559 int64_t sector_num; 645 int64_t sector_num;
@@ -582,6 +668,62 @@ static void ide_sector_write(IDEState *s) @@ -582,6 +668,62 @@ static void ide_sector_write(IDEState *s)
582 ide_set_irq(s); 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 static void ide_atapi_cmd_ok(IDEState *s) 727 static void ide_atapi_cmd_ok(IDEState *s)
586 { 728 {
587 s->error = 0; 729 s->error = 0;
@@ -627,6 +769,41 @@ static inline int ube32_to_cpu(const uint8_t *buf) @@ -627,6 +769,41 @@ static inline int ube32_to_cpu(const uint8_t *buf)
627 return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; 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 /* The whole ATAPI transfer logic is handled in this function */ 807 /* The whole ATAPI transfer logic is handled in this function */
631 static void ide_atapi_cmd_reply_end(IDEState *s) 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,15 +825,15 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
648 #endif 825 #endif
649 } else { 826 } else {
650 /* see if a new sector must be read */ 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 s->lba++; 830 s->lba++;
654 s->io_buffer_index = 0; 831 s->io_buffer_index = 0;
655 } 832 }
656 if (s->elementary_transfer_size > 0) { 833 if (s->elementary_transfer_size > 0) {
657 /* there are some data left to transmit in this elementary 834 /* there are some data left to transmit in this elementary
658 transfer */ 835 transfer */
659 - size = 2048 - s->io_buffer_index; 836 + size = s->cd_sector_size - s->io_buffer_index;
660 if (size > s->elementary_transfer_size) 837 if (size > s->elementary_transfer_size)
661 size = s->elementary_transfer_size; 838 size = s->elementary_transfer_size;
662 ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 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,8 +862,8 @@ static void ide_atapi_cmd_reply_end(IDEState *s)
685 s->elementary_transfer_size = size; 862 s->elementary_transfer_size = size;
686 /* we cannot transmit more than one sector at a time */ 863 /* we cannot transmit more than one sector at a time */
687 if (s->lba != -1) { 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 ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 868 ide_transfer_start(s, s->io_buffer + s->io_buffer_index,
692 size, ide_atapi_cmd_reply_end); 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,21 +893,88 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
716 } 893 }
717 894
718 /* start a CD-CDROM read command */ 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 s->lba = lba; 899 s->lba = lba;
725 - s->packet_transfer_size = nb_sectors * 2048; 900 + s->packet_transfer_size = nb_sectors * sector_size;
726 s->elementary_transfer_size = 0; 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 s->status = READY_STAT; 905 s->status = READY_STAT;
730 ide_atapi_cmd_reply_end(s); 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 /* same toc as bochs. Return -1 if error or the toc length */ 976 /* same toc as bochs. Return -1 if error or the toc length */
  977 +/* XXX: check this */
734 static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) 978 static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
735 { 979 {
736 uint8_t *q; 980 uint8_t *q;
@@ -739,8 +983,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) @@ -739,8 +983,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
739 if (start_track > 1 && start_track != 0xaa) 983 if (start_track > 1 && start_track != 0xaa)
740 return -1; 984 return -1;
741 q = buf + 2; 985 q = buf + 2;
742 - *q++ = 1;  
743 - *q++ = 1; 986 + *q++ = 1; /* first session */
  987 + *q++ = 1; /* last session */
744 if (start_track <= 1) { 988 if (start_track <= 1) {
745 *q++ = 0; /* reserved */ 989 *q++ = 0; /* reserved */
746 *q++ = 0x14; /* ADR, control */ 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,9 +1009,8 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
765 nb_sectors = s->nb_sectors >> 2; 1009 nb_sectors = s->nb_sectors >> 2;
766 if (msf) { 1010 if (msf) {
767 *q++ = 0; /* reserved */ 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 } else { 1014 } else {
772 cpu_to_ube32(q, nb_sectors); 1015 cpu_to_ube32(q, nb_sectors);
773 q += 4; 1016 q += 4;
@@ -777,6 +1020,75 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track) @@ -777,6 +1020,75 @@ static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
777 return len; 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 static void ide_atapi_cmd(IDEState *s) 1092 static void ide_atapi_cmd(IDEState *s)
781 { 1093 {
782 const uint8_t *packet; 1094 const uint8_t *packet;
@@ -921,7 +1233,48 @@ static void ide_atapi_cmd(IDEState *s) @@ -921,7 +1233,48 @@ static void ide_atapi_cmd(IDEState *s)
921 ASC_LOGICAL_BLOCK_OOR); 1233 ASC_LOGICAL_BLOCK_OOR);
922 break; 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 break; 1279 break;
927 case GPCMD_SEEK: 1280 case GPCMD_SEEK:
@@ -995,6 +1348,12 @@ static void ide_atapi_cmd(IDEState *s) @@ -995,6 +1348,12 @@ static void ide_atapi_cmd(IDEState *s)
995 buf[3] = 0x01; 1348 buf[3] = 0x01;
996 ide_atapi_cmd_reply(s, 12, max_len); 1349 ide_atapi_cmd_reply(s, 12, max_len);
997 break; 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 default: 1357 default:
999 error_cmd: 1358 error_cmd:
1000 ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 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,6 +1528,18 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1169 n = s->req_nb_sectors; 1528 n = s->req_nb_sectors;
1170 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write); 1529 ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
1171 break; 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 case WIN_READ_NATIVE_MAX: 1543 case WIN_READ_NATIVE_MAX:
1173 ide_set_sector(s, s->nb_sectors - 1); 1544 ide_set_sector(s, s->nb_sectors - 1);
1174 s->status = READY_STAT; 1545 s->status = READY_STAT;
@@ -1185,6 +1556,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) @@ -1185,6 +1556,7 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1185 /* XXX: valid for CDROM ? */ 1556 /* XXX: valid for CDROM ? */
1186 switch(s->feature) { 1557 switch(s->feature) {
1187 case 0x02: /* write cache enable */ 1558 case 0x02: /* write cache enable */
  1559 + case 0x03: /* set transfer mode */
1188 case 0x82: /* write cache disable */ 1560 case 0x82: /* write cache disable */
1189 case 0xaa: /* read look-ahead enable */ 1561 case 0xaa: /* read look-ahead enable */
1190 case 0x55: /* read look-ahead disable */ 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,9 +1588,10 @@ static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1216 case WIN_PACKETCMD: 1588 case WIN_PACKETCMD:
1217 if (!s->is_cdrom) 1589 if (!s->is_cdrom)
1218 goto abort_cmd; 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 goto abort_cmd; 1593 goto abort_cmd;
  1594 + s->atapi_dma = s->feature & 1;
1222 s->nsector = 1; 1595 s->nsector = 1;
1223 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 1596 ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
1224 ide_atapi_cmd); 1597 ide_atapi_cmd);
@@ -1549,11 +1922,6 @@ void isa_ide_init(int iobase, int iobase2, int irq, @@ -1549,11 +1922,6 @@ void isa_ide_init(int iobase, int iobase2, int irq,
1549 /***********************************************************/ 1922 /***********************************************************/
1550 /* PCI IDE definitions */ 1923 /* PCI IDE definitions */
1551 1924
1552 -typedef struct PCIIDEState {  
1553 - PCIDevice dev;  
1554 - IDEState ide_if[4];  
1555 -} PCIIDEState;  
1556 -  
1557 static void ide_map(PCIDevice *pci_dev, int region_num, 1925 static void ide_map(PCIDevice *pci_dev, int region_num,
1558 uint32_t addr, uint32_t size, int type) 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,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 /* hd_table must contain 4 block drivers */ 2098 /* hd_table must contain 4 block drivers */
1582 void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) 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,6 +2127,8 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
1610 PCI_ADDRESS_SPACE_IO, ide_map); 2127 PCI_ADDRESS_SPACE_IO, ide_map);
1611 pci_register_io_region((PCIDevice *)d, 3, 0x4, 2128 pci_register_io_region((PCIDevice *)d, 3, 0x4,
1612 PCI_ADDRESS_SPACE_IO, ide_map); 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 pci_conf[0x3d] = 0x01; // interrupt on pin 1 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,7 +2159,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
1640 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage 2159 pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
1641 pci_conf[0x0e] = 0x00; // header_type 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 ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]); 2165 ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
1646 ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); 2166 ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);