VOID HalFlushDcache ( IN BOOLEAN AllProcessors ) /*++ Routine Description: This function flushes the data cache on all processors that are currently running threads which are children of the current process or flushes the data cache on all processors in the host configuration. Arguments: AllProcessors - Supplies a boolean value that determines which data caches are flushed. Return Value: None. --*/ { // // Sweep (index/writeback/invalidate) the data cache. // HalSweepDcache(); return; }
VOID FwFlushAllCaches ( VOID ) /*++ Routine Description: TEMPTEMP Fix this up soon!! Arguments: None. Return Value: --*/ { #ifndef _ALPHA_ HalSweepIcache(); HalSweepDcache(); #else // Alpha code // // The functional definition of this function is nowhere to be found. For // safety, we issue two MB's (so the EV4 write buffers are purged, // and not just serialized) and one IMB. // AlphaInstIMB(); AlphaInstMB(); AlphaInstMB(); #endif return; }
VOID NTAPI KiInitializeKernel(IN PKPROCESS InitProcess, IN PKTHREAD InitThread, IN PVOID IdleStack, IN PKPRCB Prcb, IN CCHAR Number, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PKIPCR Pcr = (PKIPCR)KeGetPcr(); ULONG PageDirectory[2]; ULONG i; /* Set the default NX policy (opt-in) */ SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN; /* Initialize spinlocks and DPC data */ KiInitSpinLocks(Prcb, Number); /* Set stack pointers */ Pcr->InitialStack = IdleStack; /* Check if this is the Boot CPU */ if (!Number) { /* Setup the unexpected interrupt */ KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt; for (i = 0; i < 4; i++) { /* Copy the template code */ KxUnexpectedInterrupt.DispatchCode[i] = ((PULONG)KiInterruptTemplate)[i]; } /* Set DMA coherency */ KiDmaIoCoherency = 0; /* Sweep D-Cache */ HalSweepDcache(); /* Set boot-level flags */ KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM; KeFeatureBits = 0; KeProcessorLevel = (USHORT)(Pcr->ProcessorId >> 8); KeProcessorRevision = (USHORT)(Pcr->ProcessorId & 0xFF); /* Set the current MP Master KPRCB to the Boot PRCB */ Prcb->MultiThreadSetMaster = Prcb; /* Lower to APC_LEVEL */ KeLowerIrql(APC_LEVEL); /* Initialize portable parts of the OS */ KiInitSystem(); /* Initialize the Idle Process and the Process Listhead */ InitializeListHead(&KiProcessListHead); PageDirectory[0] = 0; PageDirectory[1] = 0; KeInitializeProcess(InitProcess, 0, 0xFFFFFFFF, PageDirectory, FALSE); InitProcess->QuantumReset = MAXCHAR; }
VOID HalFlushIoBuffers ( IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation ) /*++ Routine Description: This function flushes the I/O buffer specified by the memory descriptor list from the data cache on the current processor. Arguments: Mdl - Supplies a pointer to a memory descriptor list that describes the I/O buffer location. ReadOperation - Supplies a boolean value that determines whether the I/O operation is a read into memory. DmaOperation - Supplies a boolean value that determines whether the I/O operation is a DMA operation. Return Value: None. --*/ { ULONG CacheSegment; ULONG Length; ULONG Offset; PULONG PageFrame; ULONG Source; // // The SNI MIPS R4x00 machines use a write back data cache and, therefore, must be // flushed on reads and writes. // // If the length of the I/O operation is greater than the size of the // data cache, then sweep the entire data cache. Otherwise, flush // individual pages from the data cache as appropriate. // Offset = Mdl->ByteOffset & PCR->DcacheAlignment; Length = (Mdl->ByteCount + PCR->DcacheAlignment + Offset) & ~PCR->DcacheAlignment; if ((Length > PCR->FirstLevelDcacheSize) && (Length > PCR->SecondLevelDcacheSize)) { // // If the I/O operation is a DMA operation, or the I/O operation is // not a DMA operation and the I/O operation is a page read operation, // then sweep (index/writeback/invalidate) the entire data cache. // if ((DmaOperation != FALSE) || ((DmaOperation == FALSE) && (ReadOperation != FALSE) && ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0))) { HalSweepDcache(); } // // If the I/O operation is a page read, then sweep (index/invalidate) // the entire instruction cache. // if ((ReadOperation != FALSE) && ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0)) { HalSweepIcache(); } } else { // // Flush or purge the specified pages from the data cache and // instruction caches as appropriate. // // Compute the number of pages to flush and the starting MDL page // frame address. // Offset = Mdl->ByteOffset & ~PCR->DcacheAlignment; PageFrame = (PULONG)(Mdl + 1); Source = ((ULONG)(Mdl->StartVa) & 0xfffff000) | Offset; // // Flush or purge the specified page segments from the data and // instruction caches as appropriate. // do { if (Length >= (PAGE_SIZE - Offset)) { CacheSegment = PAGE_SIZE - Offset; } else { CacheSegment = Length; } if (ReadOperation == FALSE) { // // The I/O operation is a write and the data only needs to // to be copied back into memory if the operation is also // a DMA operation. // if (DmaOperation != FALSE) { HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment); } } else { // // If the I/O operation is a DMA read or a page read // operation, then flush the data cache. // if (DmaOperation != FALSE) { HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment); } else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) { HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment); } // // If the I/O operation is a page read, then the instruction // cache must be purged. // if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) { HalPurgeIcachePage((PVOID)Source, *PageFrame, CacheSegment); } } PageFrame += 1; Length -= CacheSegment; Offset = 0; Source += CacheSegment; } while(Length != 0); } return; }
VOID FwpRestart( IN VOID ) /*++ Routine Description: This routine implements the Firmware Restart termination function. If a valid restart block is detected, It is loaded and execution continues at the restart address. If no valid restart block is found, a soft reset is generated and the normal boot sequence takes place. Arguments: None. Return Value: Does not return to the caller. --*/ { PRESTART_BLOCK RestartBlock; PULONG BlockPointer; ULONG Checksum; ULONG WhoAmI; #ifdef DUO WhoAmI = READ_REGISTER_ULONG(&DMA_CONTROL->WhoAmI.Long); #else WhoAmI = 0; #endif RestartBlock = SYSTEM_BLOCK->RestartBlock; while ((RestartBlock != NULL) && (RestartBlock->ProcessorId != WhoAmI)) { RestartBlock = RestartBlock->NextRestartBlock; } if (RestartBlock != NULL) { // // Check signature; // if (RestartBlock->Signature == 0x42545352) { // // Check checksum. // //Checksum = 0; //BlockPointer = (PULONG) RestartBlock; // //BlockPointer += sizeof(RESTART_BLOCK)/sizeof(ULONG); //do { // BlockPointer--; // Checksum+= *BlockPointer; //} while (BlockPointer != (PULONG)RestartBlock); //if (Checksum == 0) { // // A valid restart block has been detected // Flush the data cache and restart the processor. // HalSweepDcache(); VenRestartBlock(RestartBlock); return; //} } } // // No valid restart block found. Reset. // return; //ResetSystem(); }