共用方式為


排清 DMA 作業期間的快取數據

在某些平臺中,處理器和系統 DMA 控制器 (或總線主機 DMA 配接器) 呈現快取一致性異常。 下列指導方針可讓使用 DMA 作業介面第 1 版或 2 版的驅動程式 (請參閱 DMA_OPERATIONS) 在所有支援的處理器架構之間維持一致的快取狀態,包括不包含硬體的架構,以自動強制執行快取共通。

注意 本主題中的指導方針僅適用於使用 DMA 作業介面第 1 版和第 2 版的驅動程式。 使用此介面第 3 版的驅動程式必須遵循一組不同的指導方針。 如需詳細資訊,請參閱 DMA 作業介面的第 3 版

若要在 DMA 作業期間維護數據完整性,最低層級驅動程式必須遵循下列指導方針

  1. 在開始傳輸作業之前,請先呼叫 KeFlushIoBuffers ,以在處理器中快取的數據與記憶體中的數據之間維持一致性。

    如果驅動程式呼叫 AllocateCommonBufferCacheEnabled 參數設定為 TRUE,驅動程式必須先呼叫 KeFlushIoBuffers ,才能開始其緩衝區的傳輸作業。

  2. 在每個裝置傳輸作業結束時呼叫 FlushAdapterBuffers ,以確定系統 DMA 控制器緩衝區中的任何其餘位元組都已寫入記憶體或次級裝置。

    或者,在給定 IRP 的每個傳輸作業結束時呼叫 FlushAdapterBuffers ,以確定所有數據都已讀取到系統記憶體中,或寫出至總線主機 DMA 裝置。

下圖顯示當主機處理器和 DMA 控制器未自動維護快取共通時,使用 DMA 讀取或寫入作業之前,為何請務必先排清處理器快取。

說明使用 dma 讀取和寫入作業的圖表。

異步的 DMA 讀取或寫入作業會存取記憶體中的數據,而不是在處理器快取中。 除非在讀取之前呼叫 KeFlushIoBuffers 來排清此快取,否則如果稍後清除處理器快取,DMA 作業傳送至系統記憶體的數據可能會覆寫過時的數據。 除非在寫入之前呼叫 KeFlushIoBuffers 來排清處理器快取,否則此快取中的數據可能比記憶體中的複本更最新。

KeFlushIoBuffers 如果處理器和 DMA 控制器可以仰賴以維護快取共通,則 KeFlushIoBuffers 不會執行任何動作,因此對這個支援例程的呼叫在這類平臺中幾乎沒有任何額外負荷。

如上圖所示,由配接器物件表示的 DMA 控制器可以有內部緩衝區。 這類 DMA 控制器可以一次以固定大社區塊傳輸快取的數據,通常是八個以上的位元組。 此外,這些 DMA 控制器可以在每次傳輸作業之前,等到其內部緩衝區已滿為止。

請考慮使用次級 DMA 來讀取可變大社區塊或固定大社區塊中的數據,不是系統 DMA 控制器快取大小的整數倍數的最低層級驅動程式案例。 除非此驅動程式在每個裝置傳輸結束時呼叫 FlushAdapterBuffers ,否則無法確定驅動程式實際傳送的每個位元組何時都會轉移。

總線主機 DMA 裝置的驅動程式也應該在每個傳輸作業結束時呼叫 FlushAdapterBuffers ,以確保所有數據都已傳輸到系統記憶體或輸出到裝置。

FlushAdapterBuffers 會傳回布爾值,指出要求的排清作業是否成功。 驅動程式可以使用此值來判斷完成 DMA 讀取或寫入作業的 IRP 時,如何設定 I/O 狀態區塊。