Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

flush.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiChangeColorPageTarget (IN PULONG SignalDone, IN PVOID NewColor, IN PVOID OldColor, IN PVOID PageFrame)
VOID KiSweepDcacheTarget (IN PULONG SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID KiSweepIcacheTarget (IN PULONG SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID KiSweepIcacheRangeTarget (IN PULONG SignalDone, IN PVOID BaseAddress, IN PVOID Length, IN PVOID Parameter3)
VOID KiFlushIoBuffersTarget (IN PULONG SignalDone, IN PVOID Mdl, IN PVOID ReadOperation, IN PVOID DmaOperation)
VOID KeChangeColorPage (IN PVOID NewColor, IN PVOID OldColor, IN ULONG PageFrame)
VOID KeSweepDcache (IN BOOLEAN AllProcessors)
VOID KeSweepIcache (IN BOOLEAN AllProcessors)
VOID KeSweepIcacheRange (IN BOOLEAN AllProcessors, IN PVOID BaseAddress, IN ULONG Length)
VOID KeFlushIoBuffers (IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation)


Function Documentation

VOID KeChangeColorPage IN PVOID  NewColor,
IN PVOID  OldColor,
IN ULONG  PageFrame
 

Definition at line 77 of file ppc/flush.c.

References ASSERT, KeActiveProcessors, KeLowerIrql(), KiChangeColorPageTarget(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), and SYNCH_LEVEL.

00085 : 00086 00087 This routine changes the color of a page. 00088 00089 Arguments: 00090 00091 NewColor - Supplies the page aligned virtual address of the new color 00092 the page to change. 00093 00094 OldColor - Supplies the page aligned virtual address of the old color 00095 of the page to change. 00096 00097 PageFrame - Supplies the page frame number of the page that is changed. 00098 00099 Return Value: 00100 00101 None. 00102 00103 --*/ 00104 00105 { 00106 KIRQL OldIrql; 00107 KAFFINITY TargetProcessors; 00108 00109 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00110 00111 // 00112 // Raise IRQL to synchronization level to prevent a context switch. 00113 // 00114 00115 #if !defined(NT_UP) 00116 00117 OldIrql = KeRaiseIrqlToSynchLevel(); 00118 00119 // 00120 // Compute the set of target processors and send the change color 00121 // parameters to the target processors, if any, for execution. 00122 // 00123 00124 TargetProcessors = KeActiveProcessors & PCR->NotMember; 00125 if (TargetProcessors != 0) { 00126 KiIpiSendPacket(TargetProcessors, 00127 KiChangeColorPageTarget, 00128 (PVOID)NewColor, 00129 (PVOID)OldColor, 00130 (PVOID)PageFrame); 00131 } 00132 00133 #endif 00134 00135 #ifdef COLORED_PAGES 00136 // 00137 // Change the color of the page on the current processor. 00138 // 00139 00140 HalChangeColorPage(NewColor, OldColor, PageFrame); 00141 00142 #endif 00143 00144 // 00145 // Wait until all target processors have finished changing the color 00146 // of the page. 00147 // 00148 00149 #if !defined(NT_UP) 00150 00151 if (TargetProcessors != 0) { 00152 KiIpiStallOnPacketTargets(); 00153 } 00154 00155 // 00156 // Lower IRQL to its previous level and return. 00157 // 00158 00159 KeLowerIrql(OldIrql); 00160 00161 #endif 00162 00163 return; 00164 }

VOID KeFlushIoBuffers IN PMDL  Mdl,
IN BOOLEAN  ReadOperation,
IN BOOLEAN  DmaOperation
 

Definition at line 693 of file ppc/flush.c.

References ASSERT, DMA_READ_DCACHE_INVALIDATE, DMA_READ_ICACHE_INVALIDATE, DMA_WRITE_DCACHE_SNOOP, FALSE, KeActiveProcessors, KeLowerIrql(), KeNumberProcessors, KiDmaIoCoherency, KiFlushIoBuffersTarget(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), MDL_IO_PAGE_READ, and SYNCH_LEVEL.

Referenced by UdfNonCachedRead().

00701 : 00702 00703 This function flushes the I/O buffer specified by the memory descriptor 00704 list from the data cache on all processors. 00705 00706 Arguments: 00707 00708 Mdl - Supplies a pointer to a memory descriptor list that describes the 00709 I/O buffer location. 00710 00711 ReadOperation - Supplies a boolean value that determines whether the I/O 00712 operation is a read into memory. 00713 00714 DmaOperation - Supplies a boolean value that determines whether the I/O 00715 operation is a DMA operation. 00716 00717 Return Value: 00718 00719 None. 00720 00721 --*/ 00722 00723 { 00724 00725 KIRQL OldIrql; 00726 KAFFINITY TargetProcessors; 00727 ULONG MaxLocalSweep; 00728 00729 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00730 00731 // 00732 // If the operation is a DMA operation, then check if the flush 00733 // can be avoided because the host system supports the right set 00734 // of cache coherency attributes. Otherwise, the flush can also 00735 // be avoided if the operation is a programmed I/O and not a page 00736 // read. 00737 // 00738 00739 if (DmaOperation != FALSE) { 00740 if (ReadOperation != FALSE) { 00741 00742 #if DBG 00743 00744 // 00745 // Yes, it's a DMA operation, and yes, it's a read. PPC 00746 // I-Caches do not snoop so this code is here only in debug 00747 // systems to ensure KiDmaIoCoherency is set reasonably. 00748 // 00749 00750 if ((KiDmaIoCoherency & DMA_READ_ICACHE_INVALIDATE) != 0) { 00751 00752 ASSERT((KiDmaIoCoherency & DMA_READ_DCACHE_INVALIDATE) != 0); 00753 00754 return; 00755 } 00756 00757 #endif 00758 00759 // 00760 // If the operation is NOT a page read, then the read will 00761 // not affect the I-Cache. The PPC architecture ensures the 00762 // D-Cache will remain coherent. 00763 // 00764 00765 if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0) { 00766 ASSERT((KiDmaIoCoherency & DMA_READ_DCACHE_INVALIDATE) != 0); 00767 return; 00768 } 00769 00770 } else if ((KiDmaIoCoherency & DMA_WRITE_DCACHE_SNOOP) != 0) { 00771 return; 00772 } 00773 00774 } else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0) { 00775 return; 00776 } 00777 00778 // 00779 // If the processor has a unified cache (currently the only 00780 // PowerPC to fall into this category is a 601) then there 00781 // are no problems with the I-Cache not snooping and D-Cache 00782 // coherency is architected. 00783 // 00784 00785 if ((KeGetPvr() >> 16) == 1) { 00786 return; 00787 } 00788 00789 // 00790 // Either the operation is a DMA operation and the right coherency 00791 // atributes are not supported by the host system, or the operation 00792 // is programmed I/O and a page read. 00793 // 00794 // If the amount of data to sweep is large, sweep the entire 00795 // data and inctruction caches on all processors, otherwise, 00796 // sweep the explicit range covered by the mdl. 00797 // 00798 // Sweeping the range covered by the mdl will be broadcast 00799 // to the other processors by the PPC h/w coherency mechanism. 00800 // (1 DCBST + 1 ICBI per block) 00801 // Sweeping the entire D-Cache involves (potentially) loading 00802 // and broadcasting a DCBST for each block in the D-Cache on 00803 // every processor. 00804 // 00805 // For this reason we only sweep all if the amount to flush 00806 // is greater than the First Level D Cache size * number of 00807 // processors in the system. 00808 // 00809 00810 MaxLocalSweep = PCR->FirstLevelDcacheSize; 00811 00812 #if !defined(NT_UP) 00813 00814 MaxLocalSweep *= KeNumberProcessors; 00815 00816 #endif 00817 00818 if (Mdl->ByteCount > MaxLocalSweep) { 00819 00820 // 00821 // Raise IRQL to synchronization level to prevent a context switch. 00822 // 00823 00824 OldIrql = KeRaiseIrqlToSynchLevel(); 00825 00826 #if !defined(NT_UP) 00827 00828 // 00829 // Compute the set of target processors and send the sweep parameters 00830 // to the target processors, if any, for execution. 00831 // 00832 00833 TargetProcessors = KeActiveProcessors & PCR->NotMember; 00834 if (TargetProcessors != 0) { 00835 00836 KiIpiSendPacket(TargetProcessors, 00837 KiFlushIoBuffersTarget, 00838 (PVOID)Mdl, 00839 (PVOID)((ULONG)ReadOperation), 00840 (PVOID)((ULONG)DmaOperation)); 00841 00842 } 00843 00844 #endif 00845 00846 // 00847 // Flush the caches on the current processor. 00848 // 00849 00850 HalSweepDcache(); 00851 00852 HalSweepIcache(); 00853 00854 // 00855 // Wait until all target processors have finished 00856 // flushing their caches. 00857 // 00858 00859 #if !defined(NT_UP) 00860 00861 if (TargetProcessors != 0) { 00862 KiIpiStallOnPacketTargets(); 00863 } 00864 00865 #endif 00866 00867 // 00868 // Lower IRQL to its previous level and return. 00869 // 00870 00871 KeLowerIrql(OldIrql); 00872 00873 return; 00874 } 00875 00876 // 00877 // The amount of data to be flushed is sufficiently small that it 00878 // should be done on this processor only, allowing the h/w to ensure 00879 // coherency. 00880 // 00881 00882 HalFlushIoBuffers(Mdl, ReadOperation, DmaOperation); 00883 00884 }

VOID KeSweepDcache IN BOOLEAN  AllProcessors  ) 
 

Definition at line 220 of file ppc/flush.c.

References ASSERT, KeActiveProcessors, KeLowerIrql(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiSweepDcacheTarget(), NULL, and SYNCH_LEVEL.

Referenced by CcZeroData(), ExFreePool(), KeInitializeInterrupt(), MiInitMachineDependent(), MmAllocateContiguousMemorySpecifyCache(), and MmAllocateNonCachedMemory().

00226 : 00227 00228 This function flushes the data cache on all processors that are currently 00229 running threads which are children of the current process or flushes the 00230 data cache on all processors in the host configuration. 00231 00232 N.B. PowerPC maintains cache coherency across processors however 00233 in this routine, the range of addresses being flushed is unknown 00234 so we must still broadcast the request to the other processors. 00235 00236 Arguments: 00237 00238 AllProcessors - Supplies a boolean value that determines which data 00239 caches are flushed. 00240 00241 Return Value: 00242 00243 None. 00244 00245 --*/ 00246 00247 { 00248 00249 KIRQL OldIrql; 00250 KAFFINITY TargetProcessors; 00251 00252 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00253 00254 // 00255 // Raise IRQL to synchronization level to prevent a context switch. 00256 // 00257 00258 #if !defined(NT_UP) 00259 00260 OldIrql = KeRaiseIrqlToSynchLevel(); 00261 00262 // 00263 // Compute the set of target processors and send the sweep parameters 00264 // to the target processors, if any, for execution. 00265 // 00266 00267 TargetProcessors = KeActiveProcessors & PCR->NotMember; 00268 if (TargetProcessors != 0) { 00269 KiIpiSendPacket(TargetProcessors, 00270 KiSweepDcacheTarget, 00271 NULL, 00272 NULL, 00273 NULL); 00274 } 00275 00276 #endif 00277 00278 // 00279 // Sweep the data cache on the current processor. 00280 // 00281 00282 HalSweepDcache(); 00283 00284 // 00285 // Wait until all target processors have finished sweeping the their 00286 // data cache. 00287 // 00288 00289 #if !defined(NT_UP) 00290 00291 if (TargetProcessors != 0) { 00292 KiIpiStallOnPacketTargets(); 00293 } 00294 00295 // 00296 // Lower IRQL to its previous level and return. 00297 // 00298 00299 KeLowerIrql(OldIrql); 00300 00301 #endif 00302 00303 return; 00304 }

VOID KeSweepIcache IN BOOLEAN  AllProcessors  ) 
 

Definition at line 356 of file ppc/flush.c.

References ASSERT, KeActiveProcessors, KeLowerIrql(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiSweepIcacheTarget(), NULL, and SYNCH_LEVEL.

Referenced by KeDisconnectInterrupt(), KeInitializeInterrupt(), KeSweepIcacheRange(), MiLoadSystemImage(), and NtFlushInstructionCache().

00362 : 00363 00364 This function flushes the instruction cache on all processors that are 00365 currently running threads which are children of the current process or 00366 flushes the instruction cache on all processors in the host configuration. 00367 00368 N.B. Although PowerPC maintains cache coherency across processors, we 00369 use the flash invalidate function (h/w) for I-Cache sweeps which doesn't 00370 maintain coherency so we still do the MP I-Cache flush in s/w. plj. 00371 00372 Arguments: 00373 00374 AllProcessors - Supplies a boolean value that determines which instruction 00375 caches are flushed. 00376 00377 Return Value: 00378 00379 None. 00380 00381 --*/ 00382 00383 { 00384 00385 KIRQL OldIrql; 00386 KAFFINITY TargetProcessors; 00387 00388 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00389 00390 // 00391 // Raise IRQL to synchronization level to prevent a context switch. 00392 // 00393 00394 #if !defined(NT_UP) 00395 00396 OldIrql = KeRaiseIrqlToSynchLevel(); 00397 00398 // 00399 // Compute the set of target processors and send the sweep parameters 00400 // to the target processors, if any, for execution. 00401 // 00402 00403 TargetProcessors = KeActiveProcessors & PCR->NotMember; 00404 if (TargetProcessors != 0) { 00405 KiIpiSendPacket(TargetProcessors, 00406 KiSweepIcacheTarget, 00407 NULL, 00408 NULL, 00409 NULL); 00410 } 00411 00412 #endif 00413 00414 // 00415 // Sweep the instruction cache on the current processor. 00416 // 00417 // If the processor is not a 601, flush the data cache first. 00418 // 00419 00420 if ( ( (KeGetPvr() >> 16 ) & 0xffff ) > 1 ) { 00421 HalSweepDcache(); 00422 } 00423 00424 HalSweepIcache(); 00425 00426 // 00427 // Wait until all target processors have finished sweeping their 00428 // instruction caches. 00429 // 00430 00431 #if !defined(NT_UP) 00432 00433 if (TargetProcessors != 0) { 00434 KiIpiStallOnPacketTargets(); 00435 } 00436 00437 // 00438 // Lower IRQL to its previous level and return. 00439 // 00440 00441 KeLowerIrql(OldIrql); 00442 00443 #endif 00444 00445 return; 00446 }

VOID KeSweepIcacheRange IN BOOLEAN  AllProcessors,
IN PVOID  BaseAddress,
IN ULONG  Length
 

Definition at line 502 of file ppc/flush.c.

References ASSERT, KeActiveProcessors, KeLowerIrql(), KeSweepIcache(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiSweepIcacheRangeTarget(), NULL, Offset, and SYNCH_LEVEL.

Referenced by NtFlushInstructionCache().

00510 : 00511 00512 This function is used to flush a range of virtual addresses from the 00513 primary instruction cache on all processors that are currently running 00514 threads which are children of the current process or flushes the range 00515 of virtual addresses from the primary instruction cache on all 00516 processors in the host configuration. 00517 00518 Arguments: 00519 00520 AllProcessors - Supplies a boolean value that determines which instruction 00521 caches are flushed. 00522 00523 BaseAddress - Supplies a pointer to the base of the range that is flushed. 00524 00525 Length - Supplies the length of the range that is flushed if the base 00526 address is specified. 00527 00528 Return Value: 00529 00530 None. 00531 00532 --*/ 00533 00534 { 00535 00536 ULONG Offset; 00537 KIRQL OldIrql; 00538 KAFFINITY TargetProcessors; 00539 ULONG ProcessorType; 00540 ULONG DcacheAlignment; 00541 ULONG IcacheAlignment; 00542 00543 ASSERT(KeGetCurrentIrql() <= SYNCH_LEVEL); 00544 00545 // 00546 // If the length of the range is greater than the size of the primary 00547 // instruction cache, then flush the entire cache. 00548 // 00549 // N.B. It is assumed that the size of the primary instruction and 00550 // data caches are the same. 00551 // 00552 00553 if (Length > PCR->FirstLevelIcacheSize) { 00554 KeSweepIcache(AllProcessors); 00555 return; 00556 } 00557 00558 ProcessorType = KeGetPvr() >> 16; 00559 00560 if (ProcessorType != 1) { 00561 00562 // PowerPc 601 has a unified cache; all others have dual caches. 00563 // Flush the Dcache prior to sweeping the Icache in case we need 00564 // to fetch a modified instruction currently Dcache resident. 00565 00566 DcacheAlignment = PCR->DcacheAlignment; 00567 Offset = (ULONG)BaseAddress & DcacheAlignment; 00568 HalSweepDcacheRange( 00569 (PVOID)((ULONG)BaseAddress & ~DcacheAlignment), 00570 (Offset + Length + DcacheAlignment) & ~DcacheAlignment); 00571 } 00572 00573 #if 0 00574 00575 // 00576 // PowerPC h/w maintains coherency across processors. No need 00577 // to send IPI request. 00578 // 00579 00580 // 00581 // Raise IRQL to synchronization level to prevent a context switch. 00582 // 00583 00584 OldIrql = KeRaiseIrqlToSynchLevel(); 00585 00586 // 00587 // Compute the set of target processors, and send the sweep range 00588 // parameters to the target processors, if any, for execution. 00589 // 00590 00591 TargetProcessors = KeActiveProcessors & PCR->NotMember; 00592 if (TargetProcessors != 0) { 00593 KiIpiSendPacket(TargetProcessors, 00594 KiSweepIcacheRangeTarget, 00595 (PVOID)BaseAddress, 00596 (PVOID)Length, 00597 NULL); 00598 } 00599 00600 #endif 00601 00602 // 00603 // Flush the specified range of virtual addresses from the primary 00604 // instruction cache. 00605 // 00606 00607 IcacheAlignment = PCR->IcacheAlignment; 00608 Offset = (ULONG)BaseAddress & IcacheAlignment; 00609 HalSweepIcacheRange((PVOID)((ULONG)BaseAddress & ~IcacheAlignment), 00610 (Offset + Length + IcacheAlignment) & ~IcacheAlignment); 00611 00612 // 00613 // Wait until all target processors have finished sweeping the specified 00614 // range of addresses from the instruction cache. 00615 // 00616 00617 #if 0 00618 00619 if (TargetProcessors != 0) { 00620 KiIpiStallOnPacketTargets(); 00621 } 00622 00623 // 00624 // Lower IRQL to its previous level and return. 00625 // 00626 00627 KeLowerIrql(OldIrql); 00628 00629 #endif 00630 00631 return; 00632 }

VOID KiChangeColorPageTarget IN PULONG  SignalDone,
IN PVOID  NewColor,
IN PVOID  OldColor,
IN PVOID  PageFrame
 

VOID KiFlushIoBuffersTarget IN PULONG  SignalDone,
IN PVOID  Mdl,
IN PVOID  ReadOperation,
IN PVOID  DmaOperation
 

VOID KiSweepDcacheTarget IN PULONG  SignalDone,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 

VOID KiSweepIcacheRangeTarget IN PULONG  SignalDone,
IN PVOID  BaseAddress,
IN PVOID  Length,
IN PVOID  Parameter3
 

VOID KiSweepIcacheTarget IN PULONG  SignalDone,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 


Generated on Sat May 15 19:43:43 2004 for test by doxygen 1.3.7