Use Cases
1370
SPRUH82C – April 2013 – Revised September 2016
Copyright © 2013–2016, Texas Instruments Incorporated
Serial ATA (SATA) Controller
28.3.3 Example of DMA Write Transfer
void performDmaWrite(void) {
// WRITE DMA
/*
When performing the Non-Queued Command "Write DMA" the following captures the FISes that are
communicated between Host (HBA) and Device (SpeedBridge or SATA Drive).
HBA ==> Device
H2D FIS (Command FIS that has the "Write DMA" Command within H2D.Command
field).
Device ==> HBA
DMA Activate FIS (Device notifies HBA that it's ready to receive data).
HBA ==> Device
Data FIS (Actual Data Requested and pointed by the DMA/PRD Contents within
Command Table).
Device ==> HBA
D2H FIS (Completion Status from Device)
If need to capture Interrupt (just have only the Flag set) at:
Global Level (IS Register), need to enable P0IE.Interrupt field.
Port Level (No Enable bit needs to be set. P0IS will be set if D2H FIS DW0.Byte1.bit6 is set).
If need to generate Interrupt at:
Global Level (enable interrupt by setting GHC.IE bit field and P0IE.xxx should be set to
enable particular interrupt). Port Level interrupt handling is a subset of Global Level.
Port Level (So long as Global Level interrupt is not enabled, GHC.IE is set, Interrupt will
not be sent to CPU just from Port Level only).
*/
// Write to Disk
cmdSlot2Use=0;
associateSysMem2Hba(cmdSlot2Use);
// Associate Sys Memory to CmdList and PRDs to Cmd Table
//Initialize PRD Data Buffer Memory
//
initMemory((Uint32 *)&prdTableDataBuff[cmdSlot2Use],
(sata_input_prdLength*DATABUFFERLEN/4), 0x12345678, 0x01010101);
// Configure Device 28 bit LBA Address (Start Address for Rd/Wr Transfer);
Dev28bitLbaAddress
= sata_input_startAddress; // 28-Bit LBA Address
// If problem exist when setuping CmdList, stay here. If not continue
setupCfisEntriesForDataRdWr(&CmdLists[cmdSlot2Use], DATA_DIR_WR, DMA_PROTOCOL); // Usage:
setupCfisEntriesForDataRdWr(CmdListHeader *, DataDir, xferProtocol)
// DataDir = DATA_DIR_RD or
DATA_DIR_WR, xferProtocol = PIO/DMA_PROTOCOL
// Write cfis Data
buildCmdFis(&CmdTable[cmdSlot2Use]);
//getCmdFis(&CmdTable[0]);
startCmdListProcessing(); // Stay here if unable to start processing command list.
submitCmd (NON_QUEUED_CMD, cmdSlot2Use);
// Usage: CommandType (QUEUED(NON_QUEUED)_CMD,
Command Slot);
if(intHandlingMethod == USE_INT_HANDLER) { //
USE_POLLING or USE_INT_HANDLER
while(intIsrFlag==0);
intIsrFlag=0;
}
else
while(sataRegs-
>IS == 0);
// Stay here until an interrupt is received.
// If P0IS.DPS is set, A PRD with the 'I' bit set has transferred all of its data.
// This bitfield might not bit set for Non-Queued DMA. Applicable for Queued DMA
//while(getRegStatus((Uint32*)&sataRegs-
>P0IS, AHCI_P0IS_DPS) == 0); // getRegStatus(ptr2int,field Mask)