BOOL CPCIDisk::BeginDMA( BOOL fRead ) { BYTE bStatus, bCommand; CacheSync(CACHE_SYNC_DISCARD); WriteBMCommand(0); ASSERT(0 == m_pPRDPhys.HighPart); WriteBMTable(m_pPRDPhys.LowPart); bStatus = ReadBMStatus(); bStatus |= 0x06; // bStatus |= 0x66; WriteBMStatus(bStatus); if (fRead) { bCommand = 0x08 | 0x01; } else { bCommand = 0x00 | 0x01; } WriteBMCommand(bCommand); bStatus = ReadBMStatus(); return TRUE; }
SysStatusUval FCMDefault::getForkPage( PageDesc* callerPg, uval& returnUval, FCMComputationRef& childRef, PageFaultNotification *fn, uval copyOnWrite) { SysStatusUval rc; PageDesc *pg; uval fileOffset; fileOffset = callerPg->fileOffset; rc = getPageInternal(fileOffset, fn, pg, copyOnWrite); /* * rc == 0 if page was gotten and FCM was locked * rc >0 if io is in progress and fn will be posted * rc <0 failure */ if (_SUCCESS(rc) && (rc == 0)) { //available callerPg->paddr = pg->paddr; // cant do copyonwrite to we can call back to unmap #if 0 /* check for copy on write first. Thus, a frame that * we could give to the child is instead mapped * copyOnWrite. * * The normal case is a child/parent pair (the shell) * continuously creating a new second child which then * terminates. * * In that case, this order collects all the read only * data pages in the fork parent, and they never are * unmapped in the shell. Only the written pages * will be moved from the shell child to the parent * at fork. * * The down side is that a read/write sequence on a * page which could be moved up will be more expensive, * particularly if the page is already dirty so we could * have mapped it read/write in the child immediately. * * The alternative is to move this check below the * check for giving the frame to the parent. */ if (copyOnWrite) { //caller can accept copy on write mapping callerPg->paddr = pg->paddr; pg->ppset |= uval(1) << Scheduler::GetVP(); if (pg->cacheSynced == PageDesc::CLEAR) { // Machine dependent operation. setPFBit(CacheSynced); CacheSync(pg); } if (pg->mapped != PageDesc::SET) { // mark page mapped pg->mapped = PageDesc::SET; // also mark framearray to indicate page is now mapped // PageAllocatorKernPinned::setAccessed(pg->paddr); } lock.release(); return MAPPAGE; } #endif // page lock held until unLockPage call pg->doingIO = PageDesc::SET; // copy our ppset to caller to it can unmap if needed // (only happens if copyonwrite logic is enabled) callerPg->ppset = pg->ppset; callerPg->mapped = pg->mapped; returnUval = uval(pg); // caller needs this to unlock lock.release(); return FRAMETOCOPY; } // doingIO return (rc>0)?DOINGIO:rc; }