Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
5.0 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. j4flshio.c
  5. Abstract:
  6. This module implements the system dependent kernel function to flush
  7. the data cache for I/O transfers on a MIPS R4000 Jazz, Fision, Fusion,
  8. or Duo system.
  9. Author:
  10. David N. Cutler (davec) 24-Apr-1991
  11. Environment:
  12. Kernel mode only.
  13. Revision History:
  14. --*/
  15. #include "halp.h"
  16. VOID
  17. HalFlushIoBuffers (
  18. IN PMDL Mdl,
  19. IN BOOLEAN ReadOperation,
  20. IN BOOLEAN DmaOperation
  21. )
  22. /*++
  23. Routine Description:
  24. This function flushes the I/O buffer specified by the memory descriptor
  25. list from the data cache on the current processor.
  26. Arguments:
  27. Mdl - Supplies a pointer to a memory descriptor list that describes the
  28. I/O buffer location.
  29. ReadOperation - Supplies a boolean value that determines whether the I/O
  30. operation is a read into memory.
  31. DmaOperation - Supplies a boolean value that determines whether the I/O
  32. operation is a DMA operation.
  33. Return Value:
  34. None.
  35. --*/
  36. {
  37. ULONG CacheSegment;
  38. ULONG Length;
  39. ULONG Offset;
  40. KIRQL OldIrql;
  41. PULONG PageFrame;
  42. ULONG Source;
  43. //
  44. // The Jazz R4000 uses a write back data cache and, therefore, must be
  45. // flushed on reads and writes.
  46. //
  47. // If the length of the I/O operation is greater than the size of the
  48. // data cache, then sweep the entire data cache. Otherwise, flush or
  49. // purge individual pages from the data cache as appropriate.
  50. //
  51. Offset = Mdl->ByteOffset & PCR->DcacheAlignment;
  52. Length = (Mdl->ByteCount +
  53. PCR->DcacheAlignment + Offset) & ~PCR->DcacheAlignment;
  54. if ((Length > PCR->FirstLevelDcacheSize) &&
  55. (Length > PCR->SecondLevelDcacheSize)) {
  56. //
  57. // If the I/O operation is a DMA operation, or the I/O operation is
  58. // not a DMA operation and the I/O operation is a page read operation,
  59. // then sweep (index/writeback/invalidate) the entire data cache.
  60. //
  61. if ((DmaOperation != FALSE) ||
  62. ((DmaOperation == FALSE) &&
  63. (ReadOperation != FALSE) &&
  64. ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0))) {
  65. HalSweepDcache();
  66. }
  67. //
  68. // If the I/O operation is a page read, then sweep (index/invalidate)
  69. // the entire instruction cache.
  70. //
  71. if ((ReadOperation != FALSE) &&
  72. ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0)) {
  73. HalSweepIcache();
  74. }
  75. } else {
  76. //
  77. // Flush or purge the specified pages from the data cache and
  78. // instruction caches as appropriate.
  79. //
  80. // Compute the number of pages to flush and the starting MDL page
  81. // frame address.
  82. //
  83. Offset = Mdl->ByteOffset & ~PCR->DcacheAlignment;
  84. PageFrame = (PULONG)(Mdl + 1);
  85. Source = ((ULONG)(Mdl->StartVa) & 0xfffff000) | Offset;
  86. //
  87. // Flush or purge the specified page segments from the data and
  88. // instruction caches as appropriate.
  89. //
  90. do {
  91. if (Length >= (PAGE_SIZE - Offset)) {
  92. CacheSegment = PAGE_SIZE - Offset;
  93. } else {
  94. CacheSegment = Length;
  95. }
  96. if (ReadOperation == FALSE) {
  97. //
  98. // The I/O operation is a write and the data only needs to
  99. // to be copied back into memory if the operation is also
  100. // a DMA operation.
  101. //
  102. if (DmaOperation != FALSE) {
  103. HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment);
  104. }
  105. } else {
  106. //
  107. // If the I/O operation is a DMA operation, then purge the
  108. // data cache. Otherwise, is the I/O operation is a page read
  109. // operation, then flush the data cache.
  110. //
  111. if (DmaOperation != FALSE) {
  112. HalPurgeDcachePage((PVOID)Source, *PageFrame, CacheSegment);
  113. } else if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
  114. HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment);
  115. }
  116. //
  117. // If the I/O operation is a page read, then the instruction
  118. // cache must be purged.
  119. //
  120. if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
  121. HalPurgeIcachePage((PVOID)Source, *PageFrame, CacheSegment);
  122. }
  123. }
  124. PageFrame += 1;
  125. Length -= CacheSegment;
  126. Offset = 0;
  127. Source += CacheSegment;
  128. } while(Length != 0);
  129. }
  130. return;
  131. }
  132. ULONG
  133. HalGetDmaAlignmentRequirement (
  134. VOID
  135. )
  136. /*++
  137. Routine Description:
  138. This function returns the alignment requirements for DMA transfers on
  139. host system.
  140. Arguments:
  141. None.
  142. Return Value:
  143. The DMA alignment requirement is returned as the fucntion value.
  144. --*/
  145. {
  146. return PCR->DcacheFillSize;
  147. }