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.

166 lines
3.5 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 system.
  8. Author:
  9. David N. Cutler (davec) 24-Apr-1991
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "halp.h"
  15. VOID
  16. HalFlushIoBuffers (
  17. IN PMDL Mdl,
  18. IN BOOLEAN ReadOperation,
  19. IN BOOLEAN DmaOperation
  20. )
  21. /*++
  22. Routine Description:
  23. This function flushes the I/O buffer specified by the memory descriptor
  24. list from the data cache on the current processor.
  25. Arguments:
  26. Mdl - Supplies a pointer to a memory descriptor list that describes the
  27. I/O buffer location.
  28. ReadOperation - Supplies a boolean value that determines whether the I/O
  29. operation is a read into memory.
  30. DmaOperation - Supplies a boolean value that determines whether the I/O
  31. operation is a DMA operation.
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. ULONG CacheSegment;
  37. ULONG Length;
  38. ULONG Offset;
  39. KIRQL OldIrql;
  40. PULONG PageFrame;
  41. ULONG Source;
  42. //
  43. // The Jazz R4000 uses a write back data cache and, therefore, must be
  44. // flushed on reads and writes.
  45. //
  46. // If the length of the I/O operation is greater than the size of the
  47. // data cache, then sweep the entire data cache. Otherwise, export or
  48. // purge individual pages from the data cache as appropriate.
  49. //
  50. Offset = Mdl->ByteOffset & PCR->DcacheAlignment;
  51. Length = (Mdl->ByteCount +
  52. PCR->DcacheAlignment + Offset) & ~PCR->DcacheAlignment;
  53. if ((Length > PCR->FirstLevelDcacheSize) &&
  54. (Length > PCR->SecondLevelDcacheSize)) {
  55. if ((ReadOperation != FALSE) &&
  56. ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0)) {
  57. HalSweepDcache();
  58. HalSweepIcache();
  59. }
  60. } else {
  61. //
  62. // Export or purge the specified pages from the data cache and
  63. // instruction caches as appropriate.
  64. //
  65. // Compute the number of pages to flush and the starting MDL page
  66. // frame address.
  67. //
  68. Offset = Mdl->ByteOffset & ~PCR->DcacheAlignment;
  69. PageFrame = (PULONG)(Mdl + 1);
  70. Source = ((ULONG)(Mdl->StartVa) & 0xfffff000) | Offset;
  71. //
  72. // Export or purge the specified page segments from the data and
  73. // instruction caches as appropriate.
  74. //
  75. do {
  76. if (Length >= (PAGE_SIZE - Offset)) {
  77. CacheSegment = PAGE_SIZE - Offset;
  78. } else {
  79. CacheSegment = Length;
  80. }
  81. if (ReadOperation == TRUE) {
  82. if (DmaOperation == FALSE) {
  83. if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
  84. HalFlushDcachePage((PVOID)Source, *PageFrame, CacheSegment);
  85. }
  86. }
  87. if ((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0) {
  88. HalPurgeIcachePage((PVOID)Source, *PageFrame, CacheSegment);
  89. }
  90. }
  91. PageFrame += 1;
  92. Length -= CacheSegment;
  93. Offset = 0;
  94. Source += CacheSegment;
  95. } while(Length != 0);
  96. }
  97. return;
  98. }
  99. ULONG
  100. HalGetDmaAlignmentRequirement (
  101. VOID
  102. )
  103. /*++
  104. Routine Description:
  105. This function returns the alignment requirements for DMA transfers on
  106. host system.
  107. Arguments:
  108. None.
  109. Return Value:
  110. The DMA alignment requirement is returned as the fucntion value.
  111. --*/
  112. {
  113. return PCR->DcacheFillSize;
  114. }