Files
admin
base
basedrv
boot
busdrv
cluster
cmd
crts
ddk
dload
dloadhandler
efiutil
eventlog
firmware
fs
fsrec
hals
headless
inc
mspatch
mvdm
ntdll
ntdllsym
ntos
arb
cache
config
dbgk
ex
fsrtl
fstub
inc
init
io
kd64
ke
alpha
amd64
axp64
i386
ia64
alignem.c
allproc.c
apcint.s
apcuser.c
callback.c
callout.s
clock.c
context.c
ctxswap.s
debugctx.s
em_prototypes.h
em_support.h
em_types.h
emfloat.h
exceptn.c
fedefs.h
fehelper.c
fehelper.h
feinstr.c
feinstr.h
feproto.h
fepublic.h
festate.c
festate.h
fesupprt.c
fesupprt.h
fetypes.h
floatem.c
floatem.h
flush.c
flush2.c
flushtb.c
fpmisc.s
fpswa.h
genbld.cmd
genia64.m4
getsetrg.c
ia32def.h
ia32emul.c
ia32trap.c
iafptrap.c
initkr.c
intobj.c
intsup.s
intsupc.c
irql.s
irql2.s
ivtlog.s
ktrace.c
ktrace.h
ktracep.h
miscs.s
mpipi.c
mpipis.s
ntfpia64.h
processr.s
qlock.c
region.c
services.stb
sources
spinlock.s
start.s
table.stb
tb.s
threadbg.s
thredini.c
timindex.s
trap.s
trapc.c
zeropag.s
mp
pae
paemp
tests
up
aligntrk.c
apcobj.c
apcsup.c
balmgr.c
bugcheck.c
channel.c
config.c
debug.c
devquobj.c
dirs
dpcobj.c
dpcsup.c
eventobj.c
genxx.h
genxx.inc
interobj.c
kernldat.c
kevutil.c
ki.h
kiinit.c
miscc.c
mutntobj.c
procobj.c
profobj.c
queueobj.c
raisexcp.c
semphobj.c
services.tab
sources.inc
thredobj.c
thredsup.c
timerobj.c
timersup.c
wait.c
waitsup.c
xipi.c
yield.c
lpc
mm
nls
ntsym
ob
perf
po
ps
raw
rtl
se
vdm
verifier
wmi
dirs
makefil0
ntoskrnl.inc
project.mk
wdm.mng
ntsetup
pnp
published
qfe
remoteboot
screg
seaudit
strsafe
stublibs
subsys
testlockout
tools
urtl
wdmdrv
wdmlib
win32
wmi
wow64
xip
zlib
dirs
prerelease.inc
project.mk
com
developer
drivers
ds
enduser
inetcore
inetsrv
loc
mergedcomponents
multimedia
net
printscan
public
published
sdktools
shell
termsrv
tools
windows
dirs
makefil0
2025-04-27 07:49:33 -04:00

181 lines
4.2 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Module Name:
flush2.c
Abstract:
This module implements IA64 version of KeFlushIoBuffers.
N.B. May be implemented as a macro.
Author:
07-July-1998
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
VOID
KeFlushIoBuffers (
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 processor which executes.
Arugements:
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 deternines whether the I/O
operation is a DMA operation.
Return Value:
None.
--*/
{
KIRQL OldIrql;
ULONG Length, PartialLength, Offset;
PFN_NUMBER PageFrameIndex;
PPFN_NUMBER Page;
PVOID CurrentVAddress = 0;
ASSERT(KeGetCurrentIrql() <= KiSynchIrql);
//
// If the operation is a DMA operation, then check if the flush
// can be avoided because the host system supports the right set
// of cache coherency attributes. Otherwise, the flush can also
// be avoided if the operation is a programmed I/O and not a page
// read.
//
if (DmaOperation != FALSE) {
if (ReadOperation != FALSE ) {
//
// Yes, it is a DMA operation, and yes, it is a read. IA64
// I-Caches DO snoop for DMA cycles.
//
return;
} else {
//
// It is a DMA Write operation
//
__mf();
return;
}
} else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0) {
//
// It is a PIO operation and it is not Page in operation
//
return;
} else if (ReadOperation != FALSE) {
//
// It is a PIO operation, it is Read operation and is Page in
// operation.
// We need to sweep the cache.
// Sweeping the range covered by the mdl will be broadcast to the
// other processors by the h/w coherency mechanism.
//
// Raise IRQL to synchronization level to prevent a context switch.
//
OldIrql = KeRaiseIrqlToSynchLevel();
//
// Compute the number of pages to flush and the starting MDL page
// frame address.
//
Length = Mdl->ByteCount;
if ( !Length ) {
return;
}
Offset = Mdl->ByteOffset;
PartialLength = PAGE_SIZE - Offset;
if (PartialLength > Length) {
PartialLength = Length;
}
Page = (PPFN_NUMBER)(Mdl + 1);
PageFrameIndex = *Page;
CurrentVAddress = ((PVOID)(KSEG3_BASE
| ((ULONG_PTR)(PageFrameIndex) << PAGE_SHIFT)
| Offset));
//
// Region 4 maps 1:1 Virtual address to physical address
//
HalSweepIcacheRange (
CurrentVAddress,
PartialLength
);
Page++;
Length -= PartialLength;
if (Length) {
PartialLength = PAGE_SIZE;
do {
PageFrameIndex = *Page;
CurrentVAddress = ((PVOID)(KSEG3_BASE
| ((ULONG_PTR)(PageFrameIndex) << PAGE_SHIFT)
| Offset));
if (PartialLength > Length) {
PartialLength = Length;
}
HalSweepIcacheRange (
CurrentVAddress,
PartialLength
);
Page++;
Length -= PartialLength;
} while (Length != 0);
}
//
// Synchronize the Instruction Prefetch pipe in the local processor.
//
__synci();
__isrlz();
//
// Lower IRQL to its previous level and return.
//
KeLowerIrql(OldIrql);
return;
}
}