The Pedigree Project  0.1
Public Member Functions | Private Types | Private Attributes | List of all members
BusMasterIde Class Reference

#include <BusMasterIde.h>

+ Collaboration diagram for BusMasterIde:

Public Member Functions

bool initialise (IoBase *pBase)
 Initialises DMA for a specific channel. More...
 
bool add (uintptr_t buffer, size_t nBytes)
 Adds a buffer to a DMA transaction. More...
 
bool begin (bool bWrite)
 Begin a DMA operation. More...
 
bool hasInterrupt ()
 Determines if an INTERRUPT has occurred on this channel. More...
 
bool hasError ()
 Determines if an ERROR has occurred on this channel. More...
 
bool hasCompleted ()
 Determines if the CURRENT TRANSFER has completed. More...
 
void commandComplete ()
 Called by drivers when a command completes. More...
 
bool isActive () const
 Is there currently a DMA transaction taking place? More...
 

Private Types

enum  BusMasterIdeRegs {
  Command = 0, DeviceSpecific1 = 1, Status = 2, DeviceSpecific2 = 3,
  PrdTableAddr = 4
}
 

Private Attributes

IoBasem_pBase
 
Mutex m_PrdTableLock
 
PhysicalRegionDescriptor * m_PrdTable
 
size_t m_LastPrdTableOffset
 
physical_uintptr_t m_PrdTablePhys
 
MemoryRegion m_PrdTableMemRegion
 
bool m_bActive
 
enum BusMasterIde::BusMasterIdeRegs __attribute__
 

Detailed Description

Generic Bus Master IDE object. Given to devices that can use DMA by their controller, this class provides a set of routines for setting up and completing DMA transactions in conjunction with other devices on the same channel. The idea is to hide away as much of the gritty implementation of IDE DMA so that drivers have a clean and easy interface to use when performing DMA operations. This should also reduce code duplication.

Definition at line 95 of file BusMasterIde.h.

Member Enumeration Documentation

Register layout

Definition at line 220 of file BusMasterIde.h.

Member Function Documentation

bool BusMasterIde::add ( uintptr_t  buffer,
size_t  nBytes 
)

Adds a buffer to a DMA transaction.

Parameters
bufferAddress of the buffer to be used for the transaction
nBytesSize of the buffer
bWriteWhether or not this is a write operation
Returns
True if setting up the transaction is successful, false otherwise.

This will add a buffer to an existing transaction, or begin a new one if no transaction already exists. Calling will remove all pending buffer (as they are complete).

Todo:
Can't write if a read is in progress, and vice versa

Definition at line 86 of file BusMasterIde.cc.

References ERROR, FATAL, VirtualAddressSpace::getMapping(), Hex, Processor::information(), and VirtualAddressSpace::isMapped().

bool BusMasterIde::begin ( bool  bWrite)

Begin a DMA operation.

Parameters
bWriteWhether or not this is a write operation.
Returns
True if beginning the transaction is successful, false otherwise.

Driver code calls this to begin an operation. This call will store the buffer, and will begin the Bus Master operation if it is not already in progress. For every buffer, device driver software should send a command to the respective device.

Definition at line 192 of file BusMasterIde.cc.

References FATAL, and WARNING.

void BusMasterIde::commandComplete ( )

Called by drivers when a command completes.

The interface requires that we reset the command register's start bit upon command completion or failure. However, we don't want to do that in hasInterrupt or hasError because that may leave the interface in an unknown state. This function allows driver code to reset this bit at a convenient time.

Note
This effectively resets the interface. That means the return values from hasInterrupt and hasError will both be invalid after calling this function.

Definition at line 257 of file BusMasterIde.cc.

References NOTICE.

Referenced by PciAtaController::irq().

+ Here is the caller graph for this function:

bool BusMasterIde::hasCompleted ( )

Determines if the CURRENT TRANSFER has completed.

Returns
True if the transfer has completed, false otherwise.

Some bus mastering controllers don't provide an IRQ line and others may need this particular function to be waited upon to be sure that the transfer has completed even if an IRQ is fired.

Definition at line 246 of file BusMasterIde.cc.

bool BusMasterIde::hasError ( )

Determines if an ERROR has occurred on this channel.

Returns
True if an error has occurred, false otherwise.

If the interrupt status has been raised, it is imperative for driver software to check if an error occurred in their transfer. The specific error can be obtained through a device-specific method; this merely provides notification that the transfer failed

Definition at line 235 of file BusMasterIde.cc.

bool BusMasterIde::hasInterrupt ( )

Determines if an INTERRUPT has occurred on this channel.

Returns
True if an interrupt has occurred, false otherwise.

When writing driver code that uses a DMA transaction, waiting on an IRQ is the normal way to wait for the transaction to complete. This function call allows driver code to determine if an interrupt has been triggered on the DMA channel in order to filter spurious interrupts coming in.

Definition at line 224 of file BusMasterIde.cc.

bool BusMasterIde::initialise ( IoBase pBase)

Initialises DMA for a specific channel.

Parameters
pBaseThe IO base for this channel. This is, for example, BAR4 when working with PIIX's IDE interface.
Returns
True if the channel is set up and ready, false if not.

In the off chance the given IO base is not usable (null, wrong ports/mmio addresses, for example), being able to return false means controllers can detect a failure condition and avoid giving devices DMA information.

Definition at line 47 of file BusMasterIde.cc.

References PhysicalMemoryManager::allocateRegion(), PhysicalMemoryManager::continuous, ERROR, Hex, PhysicalMemoryManager::instance(), NOTICE, IoBase::size(), and VirtualAddressSpace::Write.

Referenced by PciAtaController::PciAtaController().

+ Here is the caller graph for this function:

bool BusMasterIde::isActive ( ) const
inline

Is there currently a DMA transaction taking place?

Calling begin() will begin a transaction, and calling commandComplete will end it. This is useful for controllers that may need to ACK an interrupt status for non-DMA transfers on IRQ. Simply clearing the status manually would cause pending DMA transfers to lose their status information.

Definition at line 191 of file BusMasterIde.h.

Referenced by PciAtaController::irq().

+ Here is the caller graph for this function:

Member Data Documentation

bool BusMasterIde::m_bActive
private

Whether or not a DMA transfer is currently active.

Definition at line 217 of file BusMasterIde.h.

Referenced by CacheManager::executeRequest(), and CacheManager::initialise().

size_t BusMasterIde::m_LastPrdTableOffset
private

Last used offset into the PRD table (so we can run multiple ops at once)

Definition at line 208 of file BusMasterIde.h.

IoBase* BusMasterIde::m_pBase
private

Internal I/O base

Definition at line 198 of file BusMasterIde.h.

PhysicalRegionDescriptor* BusMasterIde::m_PrdTable
private

PRD table (virtual)

Definition at line 204 of file BusMasterIde.h.

Mutex BusMasterIde::m_PrdTableLock
private

PRD table lock. This is used when inserting items to the PRDT

Definition at line 201 of file BusMasterIde.h.

MemoryRegion BusMasterIde::m_PrdTableMemRegion
private

MemoryRegion for the PRD table

Definition at line 214 of file BusMasterIde.h.

physical_uintptr_t BusMasterIde::m_PrdTablePhys
private

PRD table (physical)

Definition at line 211 of file BusMasterIde.h.


The documentation for this class was generated from the following files: