Changeset 56404 in vbox
- Timestamp:
- Jun 13, 2015 6:39:47 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 101005
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevATA.cpp
r56402 r56404 575 575 } 576 576 577 #ifdef IN_RING3 578 577 #if defined(IN_RING3) || defined(IN_RING0) 578 579 # ifdef IN_RING3 579 580 typedef void (*PBeginTransferFunc)(ATADevState *); 580 581 typedef bool (*PSourceSinkFunc)(ATADevState *); … … 609 610 static bool atapiR3PassthroughSS(ATADevState *); 610 611 static bool atapiR3ReadDVDStructureSS(ATADevState *); 612 # endif /* IN_RING3 */ 611 613 612 614 /** … … 623 625 } ATAFNBT; 624 626 627 # ifdef IN_RING3 625 628 /** 626 629 * Array of end transfer functions, the index is ATAFNET. … … 635 638 atapiR3PassthroughCmdBT, 636 639 }; 640 # endif /* IN_RING3 */ 637 641 638 642 /** … … 669 673 } ATAFNSS; 670 674 675 # ifdef IN_RING3 671 676 /** 672 677 * Array of source/sink functions, the index is ATAFNSS. … … 701 706 atapiR3ReadDVDStructureSS 702 707 }; 708 # endif /* IN_RING3 */ 703 709 704 710 … … 708 714 static const ATARequest g_ataResetCRequest = { ATA_AIO_RESET_CLEARED, { { 0, 0, 0, 0, 0 } } }; 709 715 716 # ifdef IN_RING3 710 717 static void ataR3AsyncIOClearRequests(PATACONTROLLER pCtl) 711 718 { … … 719 726 AssertRC(rc); 720 727 } 721 722 723 static void ata R3AsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq)728 # endif /* IN_RING3 */ 729 730 static void ataHCAsyncIOPutRequest(PATACONTROLLER pCtl, const ATARequest *pReq) 724 731 { 725 732 int rc = PDMCritSectEnter(&pCtl->AsyncIORequestLock, VINF_SUCCESS); … … 742 749 } 743 750 751 # ifdef IN_RING3 744 752 745 753 static const ATARequest *ataR3AsyncIOGetCurrentRequest(PATACONTROLLER pCtl) … … 909 917 */ 910 918 Log2(("%s: Ctl#%d: message to async I/O thread, new request\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 911 ata R3AsyncIOPutRequest(pCtl, &Req);919 ataHCAsyncIOPutRequest(pCtl, &Req); 912 920 } 913 921 … … 938 946 ataSetStatus(s, ATA_STAT_BUSY); 939 947 Log2(("%s: Ctl#%d: message to async I/O thread, abort command on LUN#%d\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl), s->iLUN)); 940 ata R3AsyncIOPutRequest(pCtl, &Req);941 } 942 943 944 static void ata R3SetIRQ(ATADevState *s)948 ataHCAsyncIOPutRequest(pCtl, &Req); 949 } 950 # endif /* IN_RING3 */ 951 952 static void ataHCSetIRQ(ATADevState *s) 945 953 { 946 954 PATACONTROLLER pCtl = ATADEVSTATE_2_CONTROLLER(s); … … 968 976 } 969 977 970 #endif /* IN_RING 3 */978 #endif /* IN_RING0 || IN_RING3 */ 971 979 972 980 static void ataUnsetIRQ(ATADevState *s) … … 990 998 } 991 999 992 #if def IN_RING3993 994 static void ata R3PIOTransferStart(ATADevState *s, uint32_t start, uint32_t size)1000 #if defined(IN_RING0) || defined(IN_RING3) 1001 1002 static void ataHCPIOTransferStart(ATADevState *s, uint32_t start, uint32_t size) 995 1003 { 996 1004 Log2(("%s: LUN#%d start %d size %d\n", __FUNCTION__, s->iLUN, start, size)); … … 1002 1010 1003 1011 1004 static void ata R3PIOTransferStop(ATADevState *s)1012 static void ataHCPIOTransferStop(ATADevState *s) 1005 1013 { 1006 1014 Log2(("%s: LUN#%d\n", __FUNCTION__, s->iLUN)); … … 1009 1017 s->uATARegNSector = (s->uATARegNSector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD; 1010 1018 Log2(("%s: interrupt reason %#04x\n", __FUNCTION__, s->uATARegNSector)); 1011 ata R3SetIRQ(s);1019 ataHCSetIRQ(s); 1012 1020 s->fATAPITransfer = false; 1013 1021 } … … 1021 1029 1022 1030 1023 static void ata R3PIOTransferLimitATAPI(ATADevState *s)1031 static void ataHCPIOTransferLimitATAPI(ATADevState *s) 1024 1032 { 1025 1033 uint32_t cbLimit, cbTransfer; … … 1045 1053 } 1046 1054 1055 # ifdef IN_RING3 1047 1056 1048 1057 static uint32_t ataR3GetNSectors(ATADevState *s) … … 4008 4017 ataR3CmdError(s, ABRT_ERR); 4009 4018 ataUnsetStatus(s, ATA_STAT_READY); 4010 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4019 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4011 4020 } 4012 4021 break; … … 4017 4026 case ATA_INITIALIZE_DEVICE_PARAMETERS: 4018 4027 ataR3CmdOK(s, ATA_STAT_SEEK); 4019 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4028 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4020 4029 break; 4021 4030 case ATA_SET_MULTIPLE_MODE: … … 4032 4041 ataR3CmdOK(s, 0); 4033 4042 } 4034 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4043 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4035 4044 break; 4036 4045 case ATA_READ_VERIFY_SECTORS_EXT: … … 4040 4049 /* do sector number check ? */ 4041 4050 ataR3CmdOK(s, ATA_STAT_SEEK); 4042 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4051 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4043 4052 break; 4044 4053 case ATA_READ_SECTORS_EXT: … … 4100 4109 ataR3SetSector(s, s->cTotalSectors - 1); 4101 4110 ataR3CmdOK(s, 0); 4102 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4111 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4103 4112 break; 4104 4113 case ATA_SEEK: /* Used by the SCO OpenServer. Command is marked as obsolete */ 4105 4114 ataR3CmdOK(s, 0); 4106 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4115 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4107 4116 break; 4108 4117 case ATA_READ_NATIVE_MAX_ADDRESS: 4109 4118 ataR3SetSector(s, RT_MIN(s->cTotalSectors, 1 << 28) - 1); 4110 4119 ataR3CmdOK(s, 0); 4111 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4120 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4112 4121 break; 4113 4122 case ATA_CHECK_POWER_MODE: 4114 4123 s->uATARegNSector = 0xff; /* drive active or idle */ 4115 4124 ataR3CmdOK(s, 0); 4116 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4125 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4117 4126 break; 4118 4127 case ATA_SET_FEATURES: … … 4125 4134 Log2(("%s: write cache enable\n", __FUNCTION__)); 4126 4135 ataR3CmdOK(s, ATA_STAT_SEEK); 4127 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4136 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4128 4137 break; 4129 4138 case 0xaa: /* read look-ahead enable */ 4130 4139 Log2(("%s: read look-ahead enable\n", __FUNCTION__)); 4131 4140 ataR3CmdOK(s, ATA_STAT_SEEK); 4132 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4141 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4133 4142 break; 4134 4143 case 0x55: /* read look-ahead disable */ 4135 4144 Log2(("%s: read look-ahead disable\n", __FUNCTION__)); 4136 4145 ataR3CmdOK(s, ATA_STAT_SEEK); 4137 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4146 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4138 4147 break; 4139 4148 case 0xcc: /* reverting to power-on defaults enable */ 4140 4149 Log2(("%s: revert to power-on defaults enable\n", __FUNCTION__)); 4141 4150 ataR3CmdOK(s, ATA_STAT_SEEK); 4142 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4151 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4143 4152 break; 4144 4153 case 0x66: /* reverting to power-on defaults disable */ 4145 4154 Log2(("%s: revert to power-on defaults disable\n", __FUNCTION__)); 4146 4155 ataR3CmdOK(s, ATA_STAT_SEEK); 4147 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4156 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4148 4157 break; 4149 4158 case 0x82: /* write cache disable */ … … 4170 4179 } 4171 4180 ataR3CmdOK(s, ATA_STAT_SEEK); 4172 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4181 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4173 4182 break; 4174 4183 } … … 4192 4201 case ATA_STANDBY_IMMEDIATE: 4193 4202 ataR3CmdOK(s, 0); 4194 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4203 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4195 4204 break; 4196 4205 case ATA_IDLE_IMMEDIATE: … … 4200 4209 case ATA_SLEEP: 4201 4210 ataR3CmdOK(s, 0); 4202 ata R3SetIRQ(s);4211 ataHCSetIRQ(s); 4203 4212 break; 4204 4213 /* ATAPI commands */ … … 4209 4218 { 4210 4219 ataR3CmdError(s, ABRT_ERR); 4211 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4220 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4212 4221 } 4213 4222 break; … … 4243 4252 if (s->fATAPI) 4244 4253 ataUnsetStatus(s, ATA_STAT_READY); 4245 ata R3SetIRQ(s); /* Shortcut, do not use AIO thread. */4254 ataHCSetIRQ(s); /* Shortcut, do not use AIO thread. */ 4246 4255 break; 4247 4256 } 4248 4257 } 4249 4258 4250 #endif /* IN_RING3 */ 4259 # endif /* IN_RING3 */ 4260 #endif /* IN_RING0 || IN_RING3 */ 4251 4261 4252 4262 /* … … 4389 4399 if (pCtl->iSelectedIf) /* Device 1 selected, Device 0 responding for it. */ 4390 4400 { 4391 if (!pCtl->aIfs[0].pDrvBlock) /* @todo:this case should never get here! */4401 if (!pCtl->aIfs[0].pDrvBlock) /** @todo this case should never get here! */ 4392 4402 { 4393 4403 Log2(("%s: addr=%#x: no device on channel\n", __FUNCTION__, addr)); … … 4519 4529 val = s->uATARegStatus; 4520 4530 #else /* !IN_RING3 */ 4521 /* Cannot yield CPU in guest context. And switching to host4522 * context for each and every busy status is too costly,4531 /* Cannot yield CPU in raw-mode and ring-0 context. And switching 4532 * to host context for each and every busy status is too costly, 4523 4533 * especially on SMP systems where we don't gain much by 4524 4534 * yielding the CPU to someone else. */ … … 4610 4620 4611 4621 /* Issue the reset request now. */ 4612 ata R3AsyncIOPutRequest(pCtl, &g_ataResetARequest);4622 ataHCAsyncIOPutRequest(pCtl, &g_ataResetARequest); 4613 4623 #else /* !IN_RING3 */ 4614 4624 AssertMsgFailed(("RESET handling is too complicated for GC\n")); … … 4627 4637 Log2(("%s: ignored setting HOB\n", __FUNCTION__)); 4628 4638 } 4629 ata R3AsyncIOPutRequest(pCtl, &g_ataResetCRequest);4639 ataHCAsyncIOPutRequest(pCtl, &g_ataResetCRequest); 4630 4640 #else /* !IN_RING3 */ 4631 4641 AssertMsgFailed(("RESET handling is too complicated for GC\n")); … … 4669 4679 } 4670 4680 4671 #if def IN_RING34672 4673 static void ata R3PIOTransfer(PATACONTROLLER pCtl)4681 #if defined(IN_RING0) || defined(IN_RING3) 4682 4683 static void ataHCPIOTransfer(PATACONTROLLER pCtl) 4674 4684 { 4675 4685 ATADevState *s; … … 4680 4690 if (s->cbTotalTransfer && s->iIOBufferCur > s->iIOBufferEnd) 4681 4691 { 4692 # ifdef IN_RING3 4682 4693 LogRel(("PIIX3 ATA: LUN#%d: %s data in the middle of a PIO transfer - VERY SLOW\n", s->iLUN, s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE ? "loading" : "storing")); 4683 4694 /* Any guest OS that triggers this case has a pathetic ATA driver. … … 4699 4710 s->iIOBufferEnd = s->cbElementaryTransfer; 4700 4711 } 4712 # else 4713 AssertReleaseFailed(); 4714 # endif 4701 4715 } 4702 4716 if (s->cbTotalTransfer) 4703 4717 { 4704 4718 if (s->fATAPITransfer) 4705 ata R3PIOTransferLimitATAPI(s);4719 ataHCPIOTransferLimitATAPI(s); 4706 4720 4707 4721 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE && s->cbElementaryTransfer > s->cbTotalTransfer) … … 4712 4726 s->cbTotalTransfer, s->cbElementaryTransfer, 4713 4727 s->iIOBufferCur, s->iIOBufferEnd)); 4714 ata R3PIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer);4728 ataHCPIOTransferStart(s, s->iIOBufferCur, s->cbElementaryTransfer); 4715 4729 s->cbTotalTransfer -= s->cbElementaryTransfer; 4716 4730 s->iIOBufferCur += s->cbElementaryTransfer; … … 4720 4734 } 4721 4735 else 4722 ata R3PIOTransferStop(s);4723 } 4724 4725 4726 DECLINLINE(void) ata R3PIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s)4736 ataHCPIOTransferStop(s); 4737 } 4738 4739 4740 DECLINLINE(void) ataHCPIOTransferFinish(PATACONTROLLER pCtl, ATADevState *s) 4727 4741 { 4728 4742 /* Do not interfere with RESET processing if the PIO transfer finishes … … 4745 4759 4746 4760 Log2(("%s: Ctl#%d: message to async I/O thread, continuing PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 4747 ata R3AsyncIOPutRequest(pCtl, &g_ataPIORequest);4761 ataHCAsyncIOPutRequest(pCtl, &g_ataPIORequest); 4748 4762 } 4749 4763 else … … 4760 4774 /* There is more to transfer, happens usually for large ATAPI 4761 4775 * reads - the protocol limits the chunk size to 65534 bytes. */ 4762 ata R3PIOTransfer(pCtl);4763 ata R3SetIRQ(s);4776 ataHCPIOTransfer(pCtl); 4777 ataHCSetIRQ(s); 4764 4778 } 4765 4779 else … … 4767 4781 Log2(("%s: Ctl#%d: skipping message to async I/O thread, ending PIO transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 4768 4782 /* Finish PIO transfer. */ 4769 ata R3PIOTransfer(pCtl);4783 ataHCPIOTransfer(pCtl); 4770 4784 Assert(!pCtl->fRedo); 4771 4785 } … … 4773 4787 } 4774 4788 4775 #endif /* IN_RING3 */ 4789 #endif /* IN_RING0 || IN_RING3 */ 4790 4791 /** 4792 * Fallback for ataCopyPioData124 that handles unaligned and out of bounds cases. 4793 * 4794 * @param pIf The device interface to work with. 4795 * @param pbDst The destination buffer. 4796 * @param pbSrc The source buffer. 4797 * @param cbCopy The number of bytes to copy, either 1, 2 or 4 bytes. 4798 */ 4799 DECL_NO_INLINE(static, void) ataCopyPioData124Slow(ATADevState *pIf, uint8_t *pbDst, const uint8_t *pbSrc, uint32_t cbCopy) 4800 { 4801 uint32_t const offStart = pIf->iIOBufferPIODataStart; 4802 uint32_t const offNext = offStart + cbCopy; 4803 4804 if (offStart + cbCopy > pIf->cbIOBuffer) 4805 { 4806 Log(("%s: cbCopy=%#x offStart=%#x cbIOBuffer=%#x offNext=%#x (iIOBufferPIODataEnd=%#x)\n", 4807 __FUNCTION__, cbCopy, offStart, pIf->cbIOBuffer, offNext, pIf->iIOBufferPIODataEnd)); 4808 if (offStart < pIf->cbIOBuffer) 4809 cbCopy = pIf->cbIOBuffer - offStart; 4810 else 4811 cbCopy = 0; 4812 } 4813 4814 switch (cbCopy) 4815 { 4816 case 4: pbDst[3] = pbSrc[3]; /* fall thru */ 4817 case 3: pbDst[2] = pbSrc[2]; /* fall thru */ 4818 case 2: pbDst[1] = pbSrc[1]; /* fall thru */ 4819 case 1: pbDst[0] = pbSrc[0]; /* fall thru */ 4820 case 0: break; 4821 default: AssertFailed(); /* impossible */ 4822 } 4823 4824 pIf->iIOBufferPIODataStart = offNext; 4825 4826 } 4827 4828 4829 /** 4830 * Work for ataDataWrite & ataDataRead that copies data without using memcpy. 4831 * 4832 * This also updates pIf->iIOBufferPIODataStart. 4833 * 4834 * The two buffers are either stack (32-bit aligned) or somewhere within 4835 * pIf->pbIOBuffer. 4836 * 4837 * @param pIf The device interface to work with. 4838 * @param pbDst The destination buffer. 4839 * @param pbSrc The source buffer. 4840 * @param cbCopy The number of bytes to copy, either 1, 2 or 4 bytes. 4841 */ 4842 DECLINLINE(void) ataCopyPioData124(ATADevState *pIf, uint8_t *pbDst, const uint8_t *pbSrc, uint32_t cbCopy) 4843 { 4844 /* 4845 * Quick bounds checking can be done by checking that the pbIOBuffer offset 4846 * (iIOBufferPIODataStart) is aligned at the transfer size (which is ASSUMED 4847 * to be 1, 2 or 4). However, since we're paranoid and don't currently 4848 * trust iIOBufferPIODataEnd to be within bounds, we current check against the 4849 * IO buffer size too. 4850 */ 4851 Assert(cbCopy == 1 || cbCopy == 2 || cbCopy == 4); 4852 uint32_t const offStart = pIf->iIOBufferPIODataStart; 4853 if (RT_LIKELY( !(offStart & (cbCopy - 1)) 4854 && offStart + cbCopy <= pIf->cbIOBuffer)) 4855 { 4856 switch (cbCopy) 4857 { 4858 case 4: *(uint32_t *)pbDst = *(uint32_t const *)pbSrc; break; 4859 case 2: *(uint16_t *)pbDst = *(uint16_t const *)pbSrc; break; 4860 case 1: *pbDst = *pbSrc; break; 4861 } 4862 pIf->iIOBufferPIODataStart = offStart + cbCopy; 4863 } 4864 else 4865 ataCopyPioData124Slow(pIf, pbDst, pbSrc, cbCopy); 4866 } 4776 4867 4777 4868 static int ataDataWrite(PATACONTROLLER pCtl, uint32_t addr, uint32_t cbSize, const uint8_t *pbBuf) 4778 4869 { 4779 4870 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf]; 4780 uint8_t *p;4781 4871 4782 4872 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd) 4783 4873 { 4784 4874 Assert(s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE); 4785 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart; 4786 #ifndef IN_RING3 4787 /* All but the last transfer unit is simple enough for GC, but 4788 * sending a request to the async IO thread is too complicated. */ 4875 uint8_t *pbDst = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart; 4876 4877 #ifdef IN_RC 4878 /* Raw-mode: The ataHCPIOTransfer following the last transfer unit 4879 requires I/O thread signalling, we must go to ring-3 for that. */ 4789 4880 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd) 4790 { 4791 memcpy(p, pbBuf, cbSize); 4792 s->iIOBufferPIODataStart += cbSize; 4793 } 4881 ataCopyPioData124(s, pbDst, pbBuf, cbSize); 4794 4882 else 4795 4883 return VINF_IOM_R3_IOPORT_WRITE; 4796 #else /* IN_RING3 */ 4797 memcpy(p, pbBuf, cbSize); 4798 s->iIOBufferPIODataStart += cbSize; 4884 4885 #elif defined(IN_RING0) 4886 /* Ring-0: We can do I/O thread signalling here, however for paranoid reasons 4887 triggered by a special case in ataHCPIOTransferFinish, we take extra care here. */ 4888 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd) 4889 ataCopyPioData124(s, pbDst, pbBuf, cbSize); 4890 else if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE) /* paranoia */ 4891 { 4892 ataCopyPioData124(s, pbDst, pbBuf, cbSize); 4893 ataHCPIOTransferFinish(pCtl, s); 4894 } 4895 else 4896 { 4897 Log(("%s: Unexpected\n",__FUNCTION__)); 4898 return VINF_IOM_R3_IOPORT_WRITE; 4899 } 4900 4901 #else /* IN_RING 3*/ 4902 ataCopyPioData124(s, pbDst, pbBuf, cbSize); 4799 4903 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd) 4800 ata R3PIOTransferFinish(pCtl, s);4801 #endif /* IN_RING 3*/4904 ataHCPIOTransferFinish(pCtl, s); 4905 #endif /* IN_RING 3*/ 4802 4906 } 4803 4907 else … … 4810 4914 { 4811 4915 ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf]; 4812 uint8_t *p;4813 4916 4814 4917 if (s->iIOBufferPIODataStart < s->iIOBufferPIODataEnd) 4815 4918 { 4816 4919 Assert(s->uTxDir == PDMBLOCKTXDIR_FROM_DEVICE); 4817 p = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart; 4818 #ifndef IN_RING3 4920 uint8_t const *pbSrc = s->CTX_SUFF(pbIOBuffer) + s->iIOBufferPIODataStart; 4921 4922 #ifdef IN_RC 4819 4923 /* All but the last transfer unit is simple enough for RC, but 4820 4924 * sending a request to the async IO thread is too complicated. */ 4821 4925 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd) 4822 { 4823 memcpy(pbBuf, p, cbSize); 4824 s->iIOBufferPIODataStart += cbSize; 4825 } 4926 ataCopyPioData124(s, pbBuf, pbSrc, cbSize); 4826 4927 else 4827 4928 return VINF_IOM_R3_IOPORT_READ; 4929 4930 #elif defined(IN_RING0) 4931 /* Ring-0: We can do I/O thread signalling here. However there is one 4932 case in ataHCPIOTransfer that does a LogRel and would (but not from 4933 here) call directly into the driver code. We detect that odd case 4934 here cand return to ring-3 to handle it. */ 4935 if (s->iIOBufferPIODataStart + cbSize < s->iIOBufferPIODataEnd) 4936 ataCopyPioData124(s, pbBuf, pbSrc, cbSize); 4937 else if ( s->cbTotalTransfer == 0 4938 || s->iSourceSink != ATAFN_SS_NULL 4939 || s->iIOBufferCur <= s->iIOBufferEnd) 4940 { 4941 ataCopyPioData124(s, pbBuf, pbSrc, cbSize); 4942 ataHCPIOTransferFinish(pCtl, s); 4943 } 4944 else 4945 { 4946 Log(("%s: Unexpected\n",__FUNCTION__)); 4947 return VINF_IOM_R3_IOPORT_READ; 4948 } 4949 4828 4950 #else /* IN_RING3 */ 4829 memcpy(pbBuf, p, cbSize); 4830 s->iIOBufferPIODataStart += cbSize; 4951 ataCopyPioData124(s, pbBuf, pbSrc, cbSize); 4831 4952 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd) 4832 ata R3PIOTransferFinish(pCtl, s);4953 ataHCPIOTransferFinish(pCtl, s); 4833 4954 #endif /* IN_RING3 */ 4834 4955 } … … 5216 5337 * request. Occurs very rarely, not worth optimizing. */ 5217 5338 LogRel(("%s: Ctl#%d: redo entire operation\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 5218 ata R3AsyncIOPutRequest(pCtl, pReq);5339 ataHCAsyncIOPutRequest(pCtl, pReq); 5219 5340 break; 5220 5341 } … … 5244 5365 { 5245 5366 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer immediately\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 5246 ata R3AsyncIOPutRequest(pCtl, &g_ataDMARequest);5367 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest); 5247 5368 } 5248 5369 } … … 5252 5373 /* Finish DMA transfer. */ 5253 5374 ataR3DMATransferStop(s); 5254 ata R3SetIRQ(s);5375 ataHCSetIRQ(s); 5255 5376 pCtl->uAsyncIOState = ATA_AIO_NEW; 5256 5377 } … … 5260 5381 if (s->cbTotalTransfer) 5261 5382 { 5262 ata R3PIOTransfer(pCtl);5383 ataHCPIOTransfer(pCtl); 5263 5384 Assert(!pCtl->fRedo); 5264 5385 if (s->fATAPITransfer || s->uTxDir != PDMBLOCKTXDIR_TO_DEVICE) 5265 ata R3SetIRQ(s);5386 ataHCSetIRQ(s); 5266 5387 5267 5388 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL) … … 5288 5409 Assert(s->uTxDir == PDMBLOCKTXDIR_NONE); /* Any transfer which has an initial transfer size of 0 must be marked as such. */ 5289 5410 /* Finish PIO transfer. */ 5290 ata R3PIOTransfer(pCtl);5411 ataHCPIOTransfer(pCtl); 5291 5412 Assert(!pCtl->fRedo); 5292 5413 if (!s->fATAPITransfer) 5293 ata R3SetIRQ(s);5414 ataHCSetIRQ(s); 5294 5415 pCtl->uAsyncIOState = ATA_AIO_NEW; 5295 5416 } … … 5320 5441 { 5321 5442 LogRel(("PIIX3 ATA: Ctl#%d: redo DMA operation\n", ATACONTROLLER_IDX(pCtl))); 5322 ata R3AsyncIOPutRequest(pCtl, &g_ataDMARequest);5443 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest); 5323 5444 break; 5324 5445 } … … 5348 5469 s->fATAPITransfer = false; 5349 5470 } 5350 ata R3SetIRQ(s);5471 ataHCSetIRQ(s); 5351 5472 pCtl->uAsyncIOState = ATA_AIO_NEW; 5352 5473 break; … … 5365 5486 { 5366 5487 LogRel(("PIIX3 ATA: Ctl#%d: redo PIO operation\n", ATACONTROLLER_IDX(pCtl))); 5367 ata R3AsyncIOPutRequest(pCtl, &g_ataPIORequest);5488 ataHCAsyncIOPutRequest(pCtl, &g_ataPIORequest); 5368 5489 break; 5369 5490 } … … 5388 5509 if (s->cbTotalTransfer) 5389 5510 { 5390 ata R3PIOTransfer(pCtl);5391 ata R3SetIRQ(s);5511 ataHCPIOTransfer(pCtl); 5512 ataHCSetIRQ(s); 5392 5513 5393 5514 if (s->uTxDir == PDMBLOCKTXDIR_TO_DEVICE || s->iSourceSink != ATAFN_SS_NULL) … … 5413 5534 { 5414 5535 /* Finish PIO transfer. */ 5415 ata R3PIOTransfer(pCtl);5536 ataHCPIOTransfer(pCtl); 5416 5537 if ( !pCtl->fChainedTransfer 5417 5538 && !s->fATAPITransfer 5418 5539 && s->uTxDir != PDMBLOCKTXDIR_FROM_DEVICE) 5419 5540 { 5420 ata R3SetIRQ(s);5541 ataHCSetIRQ(s); 5421 5542 } 5422 5543 pCtl->uAsyncIOState = ATA_AIO_NEW; … … 5426 5547 case ATA_AIO_RESET_ASSERTED: 5427 5548 pCtl->uAsyncIOState = ATA_AIO_RESET_CLEARED; 5428 ata R3PIOTransferStop(&pCtl->aIfs[0]);5429 ata R3PIOTransferStop(&pCtl->aIfs[1]);5549 ataHCPIOTransferStop(&pCtl->aIfs[0]); 5550 ataHCPIOTransferStop(&pCtl->aIfs[1]); 5430 5551 /* Do not change the DMA registers, they are not affected by the 5431 5552 * ATA controller reset logic. It should be sufficient to issue a … … 5471 5592 /* Stop any pending DMA transfer. */ 5472 5593 s->fDMA = false; 5473 ata R3PIOTransferStop(s);5594 ataHCPIOTransferStop(s); 5474 5595 ataUnsetStatus(s, ATA_STAT_BUSY | ATA_STAT_DRQ | ATA_STAT_SEEK | ATA_STAT_ERR); 5475 5596 ataSetStatus(s, ATA_STAT_READY); 5476 ata R3SetIRQ(s);5597 ataHCSetIRQ(s); 5477 5598 } 5478 5599 break; … … 5600 5721 { 5601 5722 Log2(("%s: Ctl#%d: message to async I/O thread, continuing DMA transfer\n", __FUNCTION__, ATACONTROLLER_IDX(pCtl))); 5602 ata R3AsyncIOPutRequest(pCtl, &g_ataDMARequest);5723 ataHCAsyncIOPutRequest(pCtl, &g_ataDMARequest); 5603 5724 } 5604 5725 #else /* !IN_RING3 */ … … 5942 6063 PDMCritSectLeave(&pCtl->lock); 5943 6064 } 6065 5944 6066 return rc; 5945 6067 } … … 6007 6129 # ifdef IN_RING3 6008 6130 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd) 6009 ata R3PIOTransferFinish(pCtl, s);6131 ataHCPIOTransferFinish(pCtl, s); 6010 6132 # endif /* IN_RING3 */ 6011 6133 } … … 6076 6198 # ifdef IN_RING3 6077 6199 if (s->iIOBufferPIODataStart >= s->iIOBufferPIODataEnd) 6078 ata R3PIOTransferFinish(pCtl, s);6200 ataHCPIOTransferFinish(pCtl, s); 6079 6201 # endif /* IN_RING3 */ 6080 6202 } … … 6911 7033 ataR3AsyncIOClearRequests(&pThis->aCts[i]); 6912 7034 Log2(("%s: Ctl#%d: message to async I/O thread, reset controller\n", __FUNCTION__, i)); 6913 ata R3AsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest);6914 ata R3AsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest);7035 ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetARequest); 7036 ataHCAsyncIOPutRequest(&pThis->aCts[i], &g_ataResetCRequest); 6915 7037 6916 7038 PDMCritSectLeave(&pThis->aCts[i].lock); … … 7305 7427 { 7306 7428 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTHCPTR)(uintptr_t)i, 7307 ataIOPortWrite1, ataIOPortRead1, ataIOPortWriteStr1, ataIOPortReadStr1, "ATA I/O Base 1"); 7429 ataIOPortWrite1, ataIOPortRead1, 7430 ataIOPortWriteStr1, ataIOPortReadStr1, 7431 "ATA I/O Base 1"); 7308 7432 if (RT_FAILURE(rc)) 7309 7433 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers")); … … 7312 7436 { 7313 7437 rc = PDMDevHlpIOPortRegisterRC(pDevIns, pThis->aCts[i].IOPortBase1, 8, (RTGCPTR)i, 7314 "ataIOPortWrite1", "ataIOPortRead1", "ataIOPortWriteStr1", "ataIOPortReadStr1", "ATA I/O Base 1"); 7438 "ataIOPortWrite1", "ataIOPortRead1", 7439 "ataIOPortWriteStr1", "ataIOPortReadStr1", 7440 "ATA I/O Base 1"); 7315 7441 if (RT_FAILURE(rc)) 7316 7442 return PDMDEV_SET_ERROR(pDevIns, rc, N_("PIIX3 cannot register I/O handlers (GC)")); -
trunk/src/VBox/VMM/VMMR0/VMMR0.def
r55980 r56404 24 24 PDMCritSectIsOwner 25 25 PDMCritSectLeave 26 PDMHCCritSectScheduleExitEvent 26 27 PDMCritSectTryEnter 27 28 PDMCritSectTryEnterDebug
Note:
See TracChangeset
for help on using the changeset viewer.