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

flush2.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Module Name: 00004 00005 flush2.c 00006 00007 Abstract: 00008 00009 This module implements IA64 version of KeFlushIoBuffers. 00010 00011 N.B. May be implemented as a macro. 00012 00013 Author: 00014 00015 07-July-1998 00016 00017 Environment: 00018 00019 Kernel mode only. 00020 00021 Revision History: 00022 00023 --*/ 00024 00025 #include "ki.h" 00026 00027 00028 VOID 00029 KeFlushIoBuffers ( 00030 IN PMDL Mdl, 00031 IN BOOLEAN ReadOperation, 00032 IN BOOLEAN DmaOperation 00033 ) 00034 /*++ 00035 00036 Routine Description: 00037 00038 This function flushes the I/O buffer specified by the memory descriptor 00039 list from the data cache on the processor which executes. 00040 00041 Arugements: 00042 00043 Mdl - Supplies a pointer to a memory descriptor list that describes the 00044 I/O buffer location. 00045 00046 ReadOperation - Supplies a boolean value that determines whether the I/O 00047 operation is a read into memory. 00048 00049 DmaOperation - Supplies a boolean value that deternines whether the I/O 00050 operation is a DMA operation. 00051 00052 Return Value: 00053 00054 None. 00055 00056 --*/ 00057 { 00058 KIRQL OldIrql; 00059 ULONG Length, PartialLength, Offset; 00060 PFN_NUMBER PageFrameIndex; 00061 PPFN_NUMBER Page; 00062 PVOID CurrentVAddress = 0; 00063 00064 ASSERT(KeGetCurrentIrql() <= KiSynchIrql); 00065 00066 // 00067 // If the operation is a DMA operation, then check if the flush 00068 // can be avoided because the host system supports the right set 00069 // of cache coherency attributes. Otherwise, the flush can also 00070 // be avoided if the operation is a programmed I/O and not a page 00071 // read. 00072 // 00073 00074 if (DmaOperation != FALSE) { 00075 if (ReadOperation != FALSE ) { 00076 00077 // 00078 // Yes, it is a DMA operation, and yes, it is a read. IA64 00079 // I-Caches DO snoop for DMA cycles. 00080 // 00081 return; 00082 } else { 00083 // 00084 // It is a DMA Write operation 00085 // 00086 __mf(); 00087 return; 00088 } 00089 00090 } else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0) { 00091 // 00092 // It is a PIO operation and it is not Page in operation 00093 // 00094 return; 00095 } else if (ReadOperation != FALSE) { 00096 00097 // 00098 // It is a PIO operation, it is Read operation and is Page in 00099 // operation. 00100 // We need to sweep the cache. 00101 // Sweeping the range covered by the mdl will be broadcast to the 00102 // other processors by the h/w coherency mechanism. 00103 // 00104 // Raise IRQL to synchronization level to prevent a context switch. 00105 // 00106 00107 OldIrql = KeRaiseIrqlToSynchLevel(); 00108 00109 // 00110 // Compute the number of pages to flush and the starting MDL page 00111 // frame address. 00112 // 00113 00114 Length = Mdl->ByteCount; 00115 00116 if ( !Length ) { 00117 return; 00118 } 00119 Offset = Mdl->ByteOffset; 00120 PartialLength = PAGE_SIZE - Offset; 00121 if (PartialLength > Length) { 00122 PartialLength = Length; 00123 } 00124 00125 Page = (PPFN_NUMBER)(Mdl + 1); 00126 PageFrameIndex = *Page; 00127 CurrentVAddress = ((PVOID)(KSEG3_BASE 00128 | ((ULONG_PTR)(PageFrameIndex) << PAGE_SHIFT) 00129 | Offset)); 00130 00131 // 00132 // Region 4 maps 1:1 Virtual address to physical address 00133 // 00134 00135 HalSweepIcacheRange ( 00136 CurrentVAddress, 00137 PartialLength 00138 ); 00139 00140 Page++; 00141 Length -= PartialLength; 00142 00143 if (Length) { 00144 PartialLength = PAGE_SIZE; 00145 do { 00146 PageFrameIndex = *Page; 00147 CurrentVAddress = ((PVOID)(KSEG3_BASE 00148 | ((ULONG_PTR)(PageFrameIndex) << PAGE_SHIFT) 00149 | Offset)); 00150 00151 if (PartialLength > Length) { 00152 PartialLength = Length; 00153 } 00154 00155 HalSweepIcacheRange ( 00156 CurrentVAddress, 00157 PartialLength 00158 ); 00159 00160 Page++; 00161 00162 Length -= PartialLength; 00163 } while (Length != 0); 00164 } 00165 00166 // 00167 // Synchronize the Instruction Prefetch pipe in the local processor. 00168 // 00169 00170 __synci(); 00171 __isrlz(); 00172 00173 // 00174 // Lower IRQL to its previous level and return. 00175 // 00176 00177 KeLowerIrql(OldIrql); 00178 return; 00179 } 00180 }

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