test: flush2.c File Reference

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

# flush2.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Functions

VOID | KeFlushIoBuffers (IN PMDL Mdl, IN BOOLEAN ReadOperation, IN BOOLEAN DmaOperation)

## Function Documentation

VOID KeFlushIoBuffers | ( | IN PMDL | Mdl,
|  | IN BOOLEAN | ReadOperation,
|  | IN BOOLEAN | DmaOperation
| ) |

Definition at line 29 of file flush2.c.

References ASSERT, FALSE, KeLowerIrql(), MDL_IO_PAGE_READ, Offset, PAGE_SHIFT, and PAGE_SIZE.

    00036                    :
    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 }
    }