Changeset 44574 in vbox
- Timestamp:
- Feb 6, 2013 5:48:18 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83644
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevAHCI.cpp
r44571 r44574 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox storage devices: AHCI controller device (disk and cdrom). 4 * Implements the AHCI standard 1.1 3 * DevAHCI - AHCI controller device (disk and cdrom). 4 * 5 * Implements the AHCI standard 1.1 5 6 */ 6 7 … … 2156 2157 * 2157 2158 * @param pAhci The AHCI instance. 2158 * @param uReg The register to write. 2159 * @param pv Where to fetch the result. 2160 * @param cb Number of bytes to write. 2161 */ 2162 static int ahciRegisterWrite(PAHCI pAhci, uint32_t uReg, void const *pv, unsigned cb) 2163 { 2164 int rc = VINF_SUCCESS; 2159 * @param offReg The offset of the register to write to. 2160 * @param u32Value The value to write. 2161 */ 2162 static int ahciRegisterWrite(PAHCI pAhci, uint32_t offReg, uint32_t u32Value) 2163 { 2164 int rc; 2165 2165 uint32_t iReg; 2166 2166 2167 if (uReg < AHCI_HBA_GLOBAL_SIZE) 2167 /* 2168 * If the access offset is smaller than 100h the guest accesses the global registers. 2169 * Otherwise it accesses the registers of a port. 2170 */ 2171 if (offReg < AHCI_HBA_GLOBAL_SIZE) 2168 2172 { 2169 2173 Log3(("Write global HBA register\n")); 2170 iReg = uReg >> 2;2174 iReg = offReg >> 2; 2171 2175 if (iReg < RT_ELEMENTS(g_aOpRegs)) 2172 2176 { 2173 2177 const AHCIOPREG *pReg = &g_aOpRegs[iReg]; 2174 rc = pReg->pfnWrite(pAhci, iReg, *(uint32_t *)pv);2178 rc = pReg->pfnWrite(pAhci, iReg, u32Value); 2175 2179 } 2176 2180 else … … 2185 2189 Log3(("Write Port register\n")); 2186 2190 /* Calculate accessed port. */ 2187 uReg -= AHCI_HBA_GLOBAL_SIZE;2188 iPort = uReg / AHCI_PORT_REGISTER_SIZE;2189 iReg = (uReg % AHCI_PORT_REGISTER_SIZE) >> 2;2191 offReg -= AHCI_HBA_GLOBAL_SIZE; 2192 iPort = offReg / AHCI_PORT_REGISTER_SIZE; 2193 iReg = (offReg % AHCI_PORT_REGISTER_SIZE) >> 2; 2190 2194 Log3(("%s: Trying to write to port %u and register %u\n", __FUNCTION__, iPort, iReg)); 2191 2195 if (RT_LIKELY( iPort < pAhci->cPortsImpl … … 2193 2197 { 2194 2198 const AHCIPORTOPREG *pPortReg = &g_aPortOpRegs[iReg]; 2195 rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, *(uint32_t *)pv);2199 rc = pPortReg->pfnWrite(pAhci, &pAhci->ahciPort[iPort], iReg, u32Value); 2196 2200 } 2197 2201 else … … 2219 2223 { 2220 2224 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 2221 int rc = VINF_SUCCESS; 2222 2223 /* Break up 64 bits reads into two dword reads. */ 2224 if (cb == 8) 2225 { 2226 rc = ahciMMIORead(pDevIns, pvUser, GCPhysAddr, pv, 4); 2227 if (RT_FAILURE(rc)) 2228 return rc; 2229 2230 return ahciMMIORead(pDevIns, pvUser, GCPhysAddr + 4, (uint8_t *)pv + 4, 4); 2231 } 2232 2233 Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n", 2234 pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr, rc)); 2235 2236 uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase); 2237 rc = ahciRegisterRead(pAhci, uOffset, pv, cb); 2225 Log2(("#%d ahciMMIORead: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n", 2226 pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr)); 2227 2228 int rc = ahciRegisterRead(pAhci, GCPhysAddr - pAhci->MMIOBase, pv, cb); 2238 2229 2239 2230 Log2(("#%d ahciMMIORead: return pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp rc=%Rrc\n", … … 2257 2248 { 2258 2249 PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI); 2259 int rc = VINF_SUCCESS; 2250 Assert(cb == 4 || cb == 8); 2251 Assert(!(GCPhysAddr & (cb - 1))); 2260 2252 2261 2253 /* Break up 64 bits writes into two dword writes. */ 2254 /** @todo Eliminate this code once the IOM/EM starts taking care of these 2255 * situations. */ 2262 2256 if (cb == 8) 2263 2257 { … … 2269 2263 * which can cause errors in the guest. 2270 2264 */ 2265 int rc = VINF_SUCCESS; 2271 2266 if (!pAhci->f8ByteMMIO4BytesWrittenSuccessfully) 2272 2267 { … … 2289 2284 } 2290 2285 2291 Log2(("#%d ahciMMIOWrite: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n", 2292 pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr)); 2293 2294 /* Validate access. */ 2295 if (cb != sizeof(uint32_t)) 2296 { 2297 Log2(("%s: Bad write size!!! GCPhysAddr=%RGp cb=%d\n", __FUNCTION__, GCPhysAddr, cb)); 2298 return VINF_SUCCESS; 2299 } 2300 if (GCPhysAddr & 0x3) 2301 { 2302 Log2(("%s: Unaligned write!!! GCPhysAddr=%RGp cb=%d\n", __FUNCTION__, GCPhysAddr, cb)); 2303 return VINF_SUCCESS; 2304 } 2305 2306 /* 2307 * If the access offset is smaller than 100h the guest accesses the global registers. 2308 * Otherwise it accesses the registers of a port. 2309 */ 2310 uint32_t uOffset = (GCPhysAddr - pAhci->MMIOBase); 2311 rc = ahciRegisterWrite(pAhci, uOffset, pv, cb); 2312 2313 return rc; 2286 /* Do the access. */ 2287 Log2(("#%d ahciMMIOWrite: pvUser=%p:{%.*Rhxs} cb=%d GCPhysAddr=%RGp\n", pDevIns->iInstance, pv, cb, pv, cb, GCPhysAddr)); 2288 return ahciRegisterWrite(pAhci, GCPhysAddr - pAhci->MMIOBase, *(uint32_t const *)pv); 2314 2289 } 2315 2290 … … 2355 2330 else 2356 2331 { 2332 /** @todo range check? */ 2357 2333 Assert(iReg == 1); 2358 rc = ahciRegisterWrite(pAhci, pAhci->regIdx, &u32, cb);2334 rc = ahciRegisterWrite(pAhci, pAhci->regIdx, u32); 2359 2335 if (rc == VINF_IOM_R3_MMIO_WRITE) 2360 2336 rc = VINF_IOM_R3_IOPORT_WRITE; … … 2398 2374 { 2399 2375 Assert(iReg == 1); 2376 /** @todo range check? */ 2400 2377 rc = ahciRegisterRead(pAhci, pAhci->regIdx, pu32, cb); 2401 2378 if (rc == VINF_IOM_R3_MMIO_READ) … … 2425 2402 2426 2403 /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */ 2404 /** @todo change this to IOMMMIO_FLAGS_WRITE_ONLY_DWORD once EM/IOM starts 2405 * handling 2nd DWORD failures on split accesses correctly. */ 2427 2406 rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/, 2428 IOMMMIO_FLAGS_READ_ PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,2407 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD, 2429 2408 ahciMMIOWrite, ahciMMIORead, "AHCI"); 2430 2409 if (RT_FAILURE(rc)) … … 5828 5807 * @param rcReq IPRT Status code of the completed request. 5829 5808 */ 5830 static DECLCALLBACK(int) ahci TransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq)5809 static DECLCALLBACK(int) ahciR3TransferCompleteNotify(PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq) 5831 5810 { 5832 5811 PAHCIPort pAhciPort = PDMIBLOCKASYNCPORT_2_PAHCIPORT(pInterface); … … 7188 7167 * @param pInterface Pointer to the interface structure containing the called function pointer. 7189 7168 */ 7190 static DECLCALLBACK(void) ahci MountNotify(PPDMIMOUNTNOTIFY pInterface)7169 static DECLCALLBACK(void) ahciR3MountNotify(PPDMIMOUNTNOTIFY pInterface) 7191 7170 { 7192 7171 PAHCIPort pAhciPort = PDMIMOUNTNOTIFY_2_PAHCIPORT(pInterface); … … 7217 7196 * @param pInterface Pointer to the interface structure containing the called function pointer. 7218 7197 */ 7219 static DECLCALLBACK(void) ahci UnmountNotify(PPDMIMOUNTNOTIFY pInterface)7198 static DECLCALLBACK(void) ahciR3UnmountNotify(PPDMIMOUNTNOTIFY pInterface) 7220 7199 { 7221 7200 PAHCIPort pAhciPort = PDMIMOUNTNOTIFY_2_PAHCIPORT(pInterface); … … 8108 8087 */ 8109 8088 pAhciPort->IBase.pfnQueryInterface = ahciR3PortQueryInterface; 8110 pAhciPort->IPortAsync.pfnTransferCompleteNotify = ahci TransferCompleteNotify;8089 pAhciPort->IPortAsync.pfnTransferCompleteNotify = ahciR3TransferCompleteNotify; 8111 8090 pAhciPort->IPort.pfnQueryDeviceLocation = ahciR3PortQueryDeviceLocation; 8112 pAhciPort->IMountNotify.pfnMountNotify = ahci MountNotify;8113 pAhciPort->IMountNotify.pfnUnmountNotify = ahci UnmountNotify;8091 pAhciPort->IMountNotify.pfnMountNotify = ahciR3MountNotify; 8092 pAhciPort->IMountNotify.pfnUnmountNotify = ahciR3UnmountNotify; 8114 8093 pAhciPort->fAsyncIOThreadIdle = true; 8115 8094 … … 8187 8166 return PDMDEV_SET_ERROR(pDevIns, rc, N_("AHCI cannot attach to status driver")); 8188 8167 } 8189 rc = PDMDevHlpSSMRegisterEx(pDevIns, AHCI_SAVED_STATE_VERSION, sizeof(*pThis) +cbTotalBufferSize, NULL,8168 rc = PDMDevHlpSSMRegisterEx(pDevIns, AHCI_SAVED_STATE_VERSION, sizeof(*pThis) + cbTotalBufferSize, NULL, 8190 8169 NULL, ahciR3LiveExec, NULL, 8191 8170 ahciR3SavePrep, ahciR3SaveExec, NULL,
Note:
See TracChangeset
for help on using the changeset viewer.