test: flushtb.c Source File

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

# flushtb.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1992-1998  Microsoft Corporation
    00004 Copyright (c) 1993  Digital Equipment Corporation
    00005
    00006 Module Name:
    00007
    00008     flushtb.c
    00009
    00010 Abstract:
    00011
    00012     This module implements machine dependent functions to flush the
    00013     translation buffers and synchronize PIDs in an Alpha AXP MP system.
    00014
    00015     N.B. This module contains only MP versions of the TB flush routines.
    00016          The UP versions are macros in ke.h
    00017          KeFlushEntireTb remains a routine for the UP system since it is
    00018          exported from the kernel for backwards compatibility.
    00019
    00020 Author:
    00021
    00022     David N. Cutler (davec) 13-May-1989
    00023     Joe Notarangelo  29-Nov-1993
    00024
    00025 Environment:
    00026
    00027     Kernel mode only.
    00028
    00029 Revision History:
    00030
    00031
    00032 --*/
    00033
    00034 #include "ki.h"
    00035
    00036 //
    00037 // Define forward referenced prototypes.
    00038 //
    00039
    00040 VOID
    00041 KiFlushEntireTbTarget (
    00042     IN PKIPI_CONTEXT SignalDone,
    00043     IN PVOID Parameter1,
    00044     IN PVOID Parameter2,
    00045     IN PVOID Parameter3
    00046     );
    00047
    00048 VOID
    00049 KiFlushMultipleTbTarget (
    00050     IN PKIPI_CONTEXT SignalDone,
    00051     IN PVOID Number,
    00052     IN PVOID Virtual,
    00053     IN PVOID Pid
    00054     );
    00055
    00056 VOID
    00057 KiFlushSingleTbTarget (
    00058     IN PKIPI_CONTEXT SignalDone,
    00059     IN PVOID Virtual,
    00060     IN PVOID Pid,
    00061     IN PVOID Parameter3
    00062     );
    00063
    00064 VOID
    00065 KiFlushMultipleTbTarget64 (
    00066     IN PKIPI_CONTEXT SignalDone,
    00067     IN PVOID Number,
    00068     IN PVOID Virtual,
    00069     IN PVOID Pid
    00070     );
    00071
    00072 VOID
    00073 KiFlushSingleTbTarget64 (
    00074     IN PKIPI_CONTEXT SignalDone,
    00075     IN PVOID Virtual,
    00076     IN PVOID Pid,
    00077     IN PVOID Parameter3
    00078     );
    00079
    00080 #if defined(NT_UP)
    00081 #undef KeFlushEntireTb
    00082 #endif
    00083
    00084
    00085 VOID
    00086 KeFlushEntireTb (
    00087     IN BOOLEAN Invalid,
    00088     IN BOOLEAN AllProcessors
    00089     )
    00090
    00091 /*++
    00092
    00093 Routine Description:
    00094
    00095     This function flushes the entire translation buffer (TB) on all
    00096     processors that are currently running threads which are children
    00097     of the current process or flushes the entire translation buffer
    00098     on all processors in the host configuration.
    00099
    00100 Arguments:
    00101
    00102     Invalid - Supplies a boolean value that specifies the reason for
    00103         flushing the translation buffer.
    00104
    00105     AllProcessors - Supplies a boolean value that determines which
    00106         translation buffers are to be flushed.
    00107
    00108 Return Value:
    00109
    00110     None.
    00111
    00112 --*/
    00113
    00114 {
    00115
    00116     KIRQL OldIrql;
    00117     PKPROCESS Process;
    00118     PKTHREAD Thread;
    00119     KAFFINITY TargetProcessors;
    00120
    00121     //
    00122     // Compute the target set of processors, disable context switching,
    00123     // and send the flush entire parameters to the target processors,
    00124     // if any, for execution.
    00125     //
    00126
    00127 #if defined(NT_UP)
    00128
    00129     __tbia();
    00130
    00131 #else
    00132
    00133     if (AllProcessors != FALSE) {
    00134         OldIrql = KeRaiseIrqlToSynchLevel();
    00135         TargetProcessors = KeActiveProcessors;
    00136
    00137     } else {
    00138         KiLockContextSwap(&OldIrql);
    00139         Thread = KeGetCurrentThread();
    00140         Process = Thread->ApcState.Process;
    00141         TargetProcessors = Process->ActiveProcessors;
    00142         if (TargetProcessors != Process->RunOnProcessors) {
    00143             Process->ProcessSequence = KiMasterSequence - 1;
    00144         }
    00145     }
    00146
    00147     TargetProcessors &= PCR->NotMember;
    00148     if (TargetProcessors != 0) {
    00149         KiIpiSendPacket(TargetProcessors,
    00150                         KiFlushEntireTbTarget,
    00151                         NULL,
    00152                         NULL,
    00153                         NULL);
    00154     }
    00155
    00156     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb);
    00157
    00158     //
    00159     // Flush TB on current processor.
    00160     //
    00161
    00162     // KeFlushCurrentTb();
    00163     __tbia();
    00164
    00165     //
    00166     // Wait until all target processors have finished.
    00167     //
    00168
    00169     if (TargetProcessors != 0) {
    00170         KiIpiStallOnPacketTargets(TargetProcessors);
    00171     }
    00172
    00173     if (AllProcessors != FALSE) {
    00174         KeLowerIrql(OldIrql);
    00175     } else {
    00176         KiUnlockContextSwap(OldIrql);
    00177     }
    00178
    00179 #endif
    00180
    00181     return;
    00182 }
    00183
    00184 #if !defined(NT_UP)
    00185
    00186
    00187 VOID
    00188 KiFlushEntireTbTarget (
    00189     IN PKIPI_CONTEXT SignalDone,
    00190     IN PVOID Parameter1,
    00191     IN PVOID Parameter2,
    00192     IN PVOID Parameter3
    00193     )
    00194
    00195 /*++
    00196
    00197 Routine Description:
    00198
    00199     This is the target function for flushing the entire TB.
    00200
    00201 Arguments:
    00202
    00203     SignalDone - Supplies a pointer to a variable that is cleared when the
    00204         requested operation has been performed.
    00205
    00206     Parameter1 - Parameter3 - not used
    00207
    00208 Return Value:
    00209
    00210     None.
    00211
    00212 --*/
    00213
    00214 {
    00215
    00216     //
    00217     // Flush the entire TB on the current processor
    00218     //
    00219
    00220     KiIpiSignalPacketDone(SignalDone);
    00221
    00222     // KeFlushCurrentTb();
    00223     __tbia();
    00224
    00225     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushEntireTb);
    00226
    00227     return;
    00228 }
    00229
    00230 VOID
    00231 KeFlushMultipleTb (
    00232     IN ULONG Number,
    00233     IN PVOID *Virtual,
    00234     IN BOOLEAN Invalid,
    00235     IN BOOLEAN AllProcessors,
    00236     IN PHARDWARE_PTE *PtePointer OPTIONAL,
    00237     IN HARDWARE_PTE PteValue
    00238     )
    00239
    00240 /*++
    00241
    00242 Routine Description:
    00243
    00244     This function flushes multiple entries from the translation buffer
    00245     on all processors that are currently running threads which are
    00246     children of the current process or flushes a multiple entries from
    00247     the translation buffer on all processors in the host configuration.
    00248
    00249 Arguments:
    00250
    00251     Number - Supplies the number of TB entries to flush.
    00252
    00253     Virtual - Supplies a pointer to an array of virtual addresses that
    00254         are within the pages whose translation buffer entries are to be
    00255         flushed.
    00256
    00257     Invalid - Supplies a boolean value that specifies the reason for
    00258         flushing the translation buffer.
    00259
    00260     AllProcessors - Supplies a boolean value that determines which
    00261         translation buffers are to be flushed.
    00262
    00263     PtePointer - Supplies an optional pointer to an array of pointers to
    00264        page table entries that receive the specified page table entry
    00265        value.
    00266
    00267     PteValue - Supplies the the new page table entry value.
    00268
    00269 Return Value:
    00270
    00271     The previous contents of the specified page table entry is returned
    00272     as the function value.
    00273
    00274 --*/
    00275
    00276 {
    00277
    00278     ULONG Index;
    00279     KIRQL OldIrql;
    00280     PKPROCESS Process;
    00281     KAFFINITY TargetProcessors;
    00282     PKTHREAD Thread;
    00283
    00284     //
    00285     // Compute the target set of processors and send the flush multiple
    00286     // parameters to the target processors, if any, for execution.
    00287     //
    00288
    00289     if (AllProcessors != FALSE) {
    00290         OldIrql = KeRaiseIrqlToSynchLevel();
    00291         TargetProcessors = KeActiveProcessors;
    00292
    00293     } else {
    00294         KiLockContextSwap(&OldIrql);
    00295         Thread = KeGetCurrentThread();
    00296         Process = Thread->ApcState.Process;
    00297         TargetProcessors = Process->ActiveProcessors;
    00298         if (TargetProcessors != Process->RunOnProcessors) {
    00299             Process->ProcessSequence = KiMasterSequence - 1;
    00300         }
    00301     }
    00302
    00303     //
    00304     // If a page table entry address address is specified, then set the
    00305     // specified page table entries to the specific value.
    00306     //
    00307
    00308     if (ARGUMENT_PRESENT(PtePointer)) {
    00309         for (Index = 0; Index < Number; Index += 1) {
    00310             *PtePointer[Index] = PteValue;
    00311         }
    00312     }
    00313
    00314     TargetProcessors &= PCR->NotMember;
    00315     if (TargetProcessors != 0) {
    00316         KiIpiSendPacket(TargetProcessors,
    00317                         KiFlushMultipleTbTarget,
    00318                         ULongToPtr(Number),
    00319                         (PVOID)Virtual,
    00320                         NULL);
    00321     }
    00322
    00323     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushMultipleTb);
    00324
    00325     //
    00326     // Flush the specified entries from the TB on the current processor.
    00327     //
    00328
    00329     KiFlushMultipleTb(Invalid, &Virtual[0], Number);
    00330
    00331     //
    00332     // Wait until all target processors have finished.
    00333     //
    00334
    00335     if (TargetProcessors != 0) {
    00336         KiIpiStallOnPacketTargets(TargetProcessors);
    00337     }
    00338
    00339     //
    00340     // If the context swap lock was acquired, release it.
    00341     //
    00342     if (AllProcessors != FALSE) {
    00343         KeLowerIrql(OldIrql);
    00344
    00345     } else {
    00346         KiUnlockContextSwap(OldIrql);
    00347     }
    00348
    00349     return;
    00350 }
    00351
    00352 VOID
    00353 KiFlushMultipleTbTarget (
    00354     IN PKIPI_CONTEXT SignalDone,
    00355     IN PVOID Number,
    00356     IN PVOID Virtual,
    00357     IN PVOID Pid
    00358     )
    00359
    00360 /*++
    00361
    00362 Routine Description:
    00363
    00364     This is the target function for flushing multiple TB entries.
    00365
    00366 Arguments:
    00367
    00368     SignalDone Supplies a pointer to a variable that is cleared when the
    00369         requested operation has been performed.
    00370
    00371     Number - Supplies the number of TB entries to flush.
    00372
    00373     Virtual - Supplies a pointer to an array of virtual addresses that
    00374         are within the pages whose translation buffer entries are to be
    00375         flushed.
    00376
    00377     Pid - Supplies the PID of the TB entries to flush.
    00378
    00379 Return Value:
    00380
    00381     None.
    00382
    00383 --*/
    00384
    00385 {
    00386
    00387     ULONG Index;
    00388     ULONG Limit;
    00389     PVOID Array[FLUSH_MULTIPLE_MAXIMUM];
    00390
    00391     //
    00392     // Flush multiple entries from the TB on the current processor
    00393     //
    00394
    00395     //
    00396     // Capture the virtual addresses that are to be flushed from the TB
    00397     // on the current processor and clear the packet address.
    00398     //
    00399
    00400     Limit = (ULONG)((ULONG_PTR)Number);
    00401     for (Index = 0; Index < Limit; Index += 1) {
    00402         Array[Index] = ((PVOID *)(Virtual))[Index];
    00403     }
    00404
    00405     KiIpiSignalPacketDone(SignalDone);
    00406
    00407     //
    00408     // Flush the specified virtual addresses from the TB on the current
    00409     // processor.
    00410     //
    00411
    00412     KiFlushMultipleTb(TRUE, &Array[0], Limit);
    00413
    00414     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushMultipleTb);
    00415
    00416     return;
    00417 }
    00418
    00419 HARDWARE_PTE
    00420 KeFlushSingleTb (
    00421     IN PVOID Virtual,
    00422     IN BOOLEAN Invalid,
    00423     IN BOOLEAN AllProcessors,
    00424     IN PHARDWARE_PTE PtePointer,
    00425     IN HARDWARE_PTE PteValue
    00426     )
    00427
    00428 /*++
    00429
    00430 Routine Description:
    00431
    00432     This function flushes a single entry from the translation buffer
    00433     on all processors that are currently running threads which are
    00434     children of the current process or flushes a single entry from
    00435     the translation buffer on all processors in the host configuration.
    00436
    00437 Arguments:
    00438
    00439     Virtual - Supplies a virtual address that is within the page whose
    00440         translation buffer entry is to be flushed.
    00441
    00442     Invalid - Supplies a boolean value that specifies the reason for
    00443         flushing the translation buffer.
    00444
    00445     AllProcessors - Supplies a boolean value that determines which
    00446         translation buffers are to be flushed.
    00447
    00448     PtePointer - Supplies a pointer to the page table entry which
    00449         receives the specified value.
    00450
    00451     PteValue - Supplies the the new page table entry value.
    00452
    00453 Return Value:
    00454
    00455     The previous contents of the specified page table entry is returned
    00456     as the function value.
    00457
    00458 --*/
    00459
    00460 {
    00461
    00462     KIRQL OldIrql;
    00463     HARDWARE_PTE OldPte;
    00464     PKPROCESS Process;
    00465     KAFFINITY TargetProcessors;
    00466     PKTHREAD Thread;
    00467
    00468     //
    00469     // Compute the target set of processors and send the flush single
    00470     // paramters to the target processors, if any, for execution.
    00471     //
    00472
    00473     if (AllProcessors != FALSE) {
    00474         OldIrql = KeRaiseIrqlToSynchLevel();
    00475         TargetProcessors = KeActiveProcessors;
    00476
    00477     } else {
    00478         KiLockContextSwap(&OldIrql);
    00479         Thread = KeGetCurrentThread();
    00480         Process = Thread->ApcState.Process;
    00481         TargetProcessors = Process->ActiveProcessors;
    00482         if (TargetProcessors != Process->RunOnProcessors) {
    00483             Process->ProcessSequence = KiMasterSequence - 1;
    00484         }
    00485     }
    00486
    00487     //
    00488     // Capture the previous contents of the page table entry and set the
    00489     // page table entry to the new value.
    00490     //
    00491
    00492     OldPte = *PtePointer;
    00493     *PtePointer = PteValue;
    00494     TargetProcessors &= PCR->NotMember;
    00495     if (TargetProcessors != 0) {
    00496         KiIpiSendPacket(TargetProcessors,
    00497                         KiFlushSingleTbTarget,
    00498                         (PVOID)Virtual,
    00499                         NULL,
    00500                         NULL);
    00501     }
    00502
    00503     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb);
    00504
    00505     //
    00506     // Flush the specified entry from the TB on the current processor.
    00507     //
    00508
    00509 //    KiFlushSingleTb(Invalid, Virtual);
    00510     __tbis(Virtual);
    00511
    00512     //
    00513     // Wait until all target processors have finished.
    00514     //
    00515
    00516     if (TargetProcessors != 0) {
    00517         KiIpiStallOnPacketTargets(TargetProcessors);
    00518     }
    00519
    00520     if (AllProcessors != FALSE) {
    00521         KeLowerIrql(OldIrql);
    00522
    00523     } else {
    00524         KiUnlockContextSwap(OldIrql);
    00525     }
    00526
    00527     //
    00528     // return the previous page table entry value.
    00529     //
    00530
    00531     return OldPte;
    00532 }
    00533
    00534 VOID
    00535 KiFlushSingleTbTarget (
    00536     IN PKIPI_CONTEXT SignalDone,
    00537     IN PVOID Virtual,
    00538     IN PVOID Pid,
    00539     IN PVOID Parameter3
    00540     )
    00541
    00542 /*++
    00543
    00544 Routine Description:
    00545
    00546     This is the target function for flushing a single TB entry.
    00547
    00548 Arguments:
    00549
    00550     SignalDone Supplies a pointer to a variable that is cleared when the
    00551         requested operation has been performed.
    00552
    00553     Virtual - Supplies a virtual address that is within the page whose
    00554         translation buffer entry is to be flushed.
    00555
    00556     RequestPacket - Supplies a pointer to a flush single TB packet address.
    00557
    00558     Pid - Supplies the PID of the TB entries to flush.
    00559
    00560     Parameter3 - Not used.
    00561
    00562 Return Value:
    00563
    00564     None.
    00565
    00566 --*/
    00567
    00568 {
    00569
    00570     //
    00571     // Flush a single entry form the TB on the current processor.
    00572     //
    00573
    00574     KiIpiSignalPacketDone(SignalDone);
    00575 //    KiFlushSingleTb(TRUE, Virtual);
    00576     __tbis(Virtual);
    00577
    00578     IPI_INSTRUMENT_COUNT(KeGetCurrentPrcb()->Number, FlushSingleTb);
    00579
    00580     return;
    00581 }
    00582
    00583 #endif // !defined(NT_UP)
    00584
    00585
    00586 VOID
    00587 KeFlushMultipleTb64 (
    00588     IN ULONG Number,
    00589     IN PULONG_PTR Virtual,
    00590     IN BOOLEAN Invalid,
    00591     IN BOOLEAN AllProcessors,
    00592     IN PHARDWARE_PTE *PtePointer OPTIONAL,
    00593     IN HARDWARE_PTE PteValue
    00594     )
    00595
    00596 /*++
    00597
    00598 Routine Description:
    00599
    00600     This function flushes multiple entries from the translation buffer
    00601     on all processors that are currently running threads which are
    00602     children of the current process or flushes a multiple entries from
    00603     the translation buffer on all processors in the host configuration.
    00604
    00605 Arguments:
    00606
    00607     Number - Supplies the number of TB entries to flush.
    00608
    00609     Virtual - Supplies a pointer to an array of virtual page numbers that
    00610         are flushed from the TB.
    00611
    00612     Invalid - Supplies a boolean value that specifies the reason for
    00613         flushing the translation buffer.
    00614
    00615     AllProcessors - Supplies a boolean value that determines which
    00616         translation buffers are to be flushed.
    00617
    00618     PtePointer - Supplies an optional pointer to an array of pointers to
    00619        page table entries that receive the specified page table entry
    00620        value.
    00621
    00622     PteValue - Supplies the the new page table entry value.
    00623
    00624 Return Value:
    00625
    00626     The previous contents of the specified page table entry is returned
    00627     as the function value.
    00628
    00629 --*/
    00630
    00631 {
    00632
    00633     ULONG Index;
    00634     KIRQL OldIrql;
    00635     PKPROCESS Process;
    00636     KAFFINITY TargetProcessors;
    00637     PKTHREAD Thread;
    00638
    00639     ASSERT(Number <= FLUSH_MULTIPLE_MAXIMUM);
    00640
    00641     //
    00642     // Compute the target set of processors.
    00643     //
    00644
    00645 #if defined(NT_UP)
    00646
    00647     OldIrql = KeRaiseIrqlToSynchLevel();
    00648
    00649 #else
    00650
    00651     if (AllProcessors != FALSE) {
    00652         OldIrql = KeRaiseIrqlToSynchLevel();
    00653         TargetProcessors = KeActiveProcessors;
    00654
    00655     } else {
    00656         KiLockContextSwap(&OldIrql);
    00657         Thread = KeGetCurrentThread();
    00658         Process = Thread->ApcState.Process;
    00659         TargetProcessors = Process->ActiveProcessors;
    00660         if (TargetProcessors != Process->RunOnProcessors) {
    00661             Process->ProcessSequence = KiMasterSequence - 1;
    00662         }
    00663     }
    00664
    00665     TargetProcessors &= PCR->NotMember;
    00666
    00667 #endif
    00668
    00669     //
    00670     // If a page table entry address array is specified, then set the
    00671     // specified page table entries to the specific value.
    00672     //
    00673
    00674     if (ARGUMENT_PRESENT(PtePointer)) {
    00675         for (Index = 0; Index < Number; Index += 1) {
    00676             *PtePointer[Index] = PteValue;
    00677         }
    00678     }
    00679
    00680     //
    00681     // If any target processors are specified, then send a flush multiple
    00682     // packet to the target set of processor.
    00683     //
    00684
    00685 #if !defined(NT_UP)
    00686
    00687     if (TargetProcessors != 0) {
    00688         KiIpiSendPacket(TargetProcessors,
    00689                         KiFlushMultipleTbTarget64,
    00690                         ULongToPtr(Number),
    00691                         (PVOID)Virtual,
    00692                         NULL);
    00693     }
    00694
    00695 #endif
    00696
    00697     //
    00698     // Flush the specified entries from the TB on the current processor.
    00699     //
    00700
    00701     KiFlushMultipleTb64(Invalid, &Virtual[0], Number);
    00702
    00703     //
    00704     // Wait until all target processors have finished.
    00705     //
    00706
    00707 #if defined(NT_UP)
    00708
    00709     KeLowerIrql(OldIrql);
    00710
    00711 #else
    00712
    00713     if (TargetProcessors != 0) {
    00714         KiIpiStallOnPacketTargets(TargetProcessors);
    00715     }
    00716
    00717     if (AllProcessors != FALSE) {
    00718         KeLowerIrql(OldIrql);
    00719
    00720     } else {
    00721         KiUnlockContextSwap(OldIrql);
    00722     }
    00723
    00724 #endif
    00725
    00726     return;
    00727 }
    00728
    00729 #if !defined(NT_UP)
    00730
    00731
    00732 VOID
    00733 KiFlushMultipleTbTarget64 (
    00734     IN PKIPI_CONTEXT SignalDone,
    00735     IN PVOID Number,
    00736     IN PVOID Virtual,
    00737     IN PVOID Pid
    00738     )
    00739
    00740 /*++
    00741
    00742 Routine Description:
    00743
    00744     This is the target function for flushing multiple TB entries.
    00745
    00746 Arguments:
    00747
    00748     SignalDone Supplies a pointer to a variable that is cleared when the
    00749         requested operation has been performed.
    00750
    00751     Number - Supplies the number of TB entries to flush.
    00752
    00753     Virtual - Supplies a pointer to an array of virtual page numbers that
    00754         are flushed from the TB.
    00755
    00756     Pid - Supplies the PID of the TB entries to flush.
    00757
    00758 Return Value:
    00759
    00760     None.
    00761
    00762 --*/
    00763
    00764 {
    00765
    00766     ULONG Index;
    00767     ULONG Limit;
    00768     ULONG_PTR Array[FLUSH_MULTIPLE_MAXIMUM];
    00769
    00770     ASSERT((ULONG_PTR)Number <= FLUSH_MULTIPLE_MAXIMUM);
    00771
    00772     //
    00773     // Capture the virtual addresses that are to be flushed from the TB
    00774     // on the current processor and clear the packet address.
    00775     //
    00776
    00777     Limit = (ULONG)((ULONG_PTR)Number);
    00778     for (Index = 0; Index < Limit; Index += 1) {
    00779         Array[Index] = ((PULONG_PTR)(Virtual))[Index];
    00780     }
    00781
    00782     KiIpiSignalPacketDone(SignalDone);
    00783
    00784     //
    00785     // Flush the specified virtual addresses from the TB on the current
    00786     // processor.
    00787     //
    00788
    00789     KiFlushMultipleTb64(TRUE, &Array[0], Limit);
    00790     return;
    00791 }
    00792
    00793 #endif
    00794
    00795
    00796 HARDWARE_PTE
    00797 KeFlushSingleTb64 (
    00798     IN ULONG_PTR Virtual,
    00799     IN BOOLEAN Invalid,
    00800     IN BOOLEAN AllProcessors,
    00801     IN PHARDWARE_PTE PtePointer,
    00802     IN HARDWARE_PTE PteValue
    00803     )
    00804
    00805 /*++
    00806
    00807 Routine Description:
    00808
    00809     This function flushes a single entry from the translation buffer
    00810     on all processors that are currently running threads which are
    00811     children of the current process or flushes a single entry from
    00812     the translation buffer on all processors in the host configuration.
    00813
    00814 Arguments:
    00815
    00816     Virtual - Supplies a virtual page number that is flushed from the TB.
    00817
    00818     Invalid - Supplies a boolean value that specifies the reason for
    00819         flushing the translation buffer.
    00820
    00821     AllProcessors - Supplies a boolean value that determines which
    00822         translation buffers are to be flushed.
    00823
    00824     PtePointer - Supplies a pointer to the page table entry which
    00825         receives the specified value.
    00826
    00827     PteValue - Supplies the the new page table entry value.
    00828
    00829 Return Value:
    00830
    00831     The previous contents of the specified page table entry is returned
    00832     as the function value.
    00833
    00834 --*/
    00835
    00836 {
    00837
    00838     KIRQL OldIrql;
    00839     HARDWARE_PTE OldPte;
    00840     PKPROCESS Process;
    00841     KAFFINITY TargetProcessors;
    00842     PKTHREAD Thread;
    00843
    00844     //
    00845     // Compute the target set of processors.
    00846     //
    00847
    00848 #if defined(NT_UP)
    00849
    00850     OldIrql = KeRaiseIrqlToSynchLevel();
    00851
    00852 #else
    00853
    00854     if (AllProcessors != FALSE) {
    00855         OldIrql = KeRaiseIrqlToSynchLevel();
    00856         TargetProcessors = KeActiveProcessors;
    00857
    00858     } else {
    00859         KiLockContextSwap(&OldIrql);
    00860         Thread = KeGetCurrentThread();
    00861         Process = Thread->ApcState.Process;
    00862         TargetProcessors = Process->ActiveProcessors;
    00863         if (TargetProcessors != Process->RunOnProcessors) {
    00864             Process->ProcessSequence = KiMasterSequence - 1;
    00865         }
    00866     }
    00867
    00868     TargetProcessors &= PCR->NotMember;
    00869
    00870 #endif
    00871
    00872     //
    00873     // Capture the previous contents of the page table entry and set the
    00874     // page table entry to the new value.
    00875     //
    00876
    00877     OldPte = *PtePointer;
    00878     *PtePointer = PteValue;
    00879
    00880     //
    00881     // If any target processors are specified, then send a flush single
    00882     // packet to the target set of processors.
    00883
    00884 #if !defined(NT_UP)
    00885
    00886     if (TargetProcessors != 0) {
    00887         KiIpiSendPacket(TargetProcessors,
    00888                         KiFlushSingleTbTarget64,
    00889                         (PVOID)Virtual,
    00890                         NULL,
    00891                         NULL);
    00892     }
    00893
    00894 #endif
    00895
    00896     //
    00897     // Flush the specified entry from the TB on the current processor.
    00898     //
    00899
    00900     KiFlushSingleTb64(Invalid, Virtual);
    00901
    00902     //
    00903     // Wait until all target processors have finished.
    00904     //
    00905
    00906 #if defined(NT_UP)
    00907
    00908     KeLowerIrql(OldIrql);
    00909
    00910 #else
    00911
    00912     if (TargetProcessors != 0) {
    00913         KiIpiStallOnPacketTargets(TargetProcessors);
    00914     }
    00915
    00916     if (AllProcessors != FALSE) {
    00917         KeLowerIrql(OldIrql);
    00918
    00919     } else {
    00920         KiUnlockContextSwap(OldIrql);
    00921     }
    00922
    00923 #endif
    00924
    00925     return OldPte;
    00926 }
    00927
    00928 #if !defined(NT_UP)
    00929
    00930
    00931 VOID
    00932 KiFlushSingleTbTarget64 (
    00933     IN PKIPI_CONTEXT SignalDone,
    00934     IN PVOID Virtual,
    00935     IN PVOID Pid,
    00936     IN PVOID Parameter3
    00937     )
    00938
    00939 /*++
    00940
    00941 Routine Description:
    00942
    00943     This is the target function for flushing a single TB entry.
    00944
    00945 Arguments:
    00946
    00947     SignalDone Supplies a pointer to a variable that is cleared when the
    00948         requested operation has been performed.
    00949
    00950     Virtual - Supplies a virtual page number that is flushed from the TB.
    00951
    00952     RequestPacket - Supplies a pointer to a flush single TB packet address.
    00953
    00954     Pid - Not used.
    00955
    00956     Parameter3 - Not used.
    00957
    00958 Return Value:
    00959
    00960     None.
    00961
    00962 --*/
    00963
    00964 {
    00965
    00966     //
    00967     // Flush a single entry form the TB on the current processor.
    00968     //
    00969
    00970     KiIpiSignalPacketDone(SignalDone);
    00971     KiFlushSingleTb64(TRUE, (ULONG_PTR)Virtual);
    00972     return;
    00973 }
    00974
    00975 #endif