/ATF2/control-software/PS_Firmware/EPSC_080115/Modified_Netburner/buffers.cpp
C++ | 806 lines | 629 code | 90 blank | 87 comment | 103 complexity | 437ff1a81f018f1061d1d13ec1e7ba1d MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
- /* Rev:$Revision: 1.1.1.1 $ */
-
- #include "predef.h"
- #include <stdio.h>
- #include <string.h>
- #include "basictypes.h"
- #include "ucosmcfc.h"
- #include "constants.h"
- #include "utils.h"
- #include "ucos.h"
- #include "buffers.h"
-
- extern "C"
- {
- DWORD memcpysum( void *to, const void *frm, int len );
- void fmemcpy( void *out, const void *in, size_t n );
- }
-
- class BufferCriticalLock
- {
- OS_CRIT *pcrit;
- public:
- BufferCriticalLock( OS_CRIT &ocrit )
- {
- pcrit = &ocrit;
- if ( pcrit->OSCritTaskNum == 0xFF )
- {
- USER_ENTER_CRITICAL();
- }
- else
- {
- OSCritEnter( &ocrit, 0 );
- }
- };
-
- ~BufferCriticalLock()
- {
- if ( pcrit->OSCritTaskNum == 0xFF )
- {
- USER_EXIT_CRITICAL();
- }
- else
- {
- OSCritLeave( pcrit );
- }
- }
- };
-
- /*-------------------------------------------------------**
- ** Allocate the global buffer pool as a static variable. **
- **-------------------------------------------------------*/
-
-
- // ***** added alignment on 4096 byte boundary 06/02/06 DJM *****
- pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__((aligned(0x2000))); //06/02/06
- // ***** static declaration removed to convert to global 10/30/05 DJM *****
- //pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__((aligned(16)));
- //static pool_buffer static_pool_buffers[BUFFER_POOL_SIZE] __attribute__( ( aligned( 16 ) ) ); ;
-
- /*--------------------**
- ** Create a free list **
- **--------------------*/
-
- buffer_list free_list;
- unsigned char free_list_is_initialized;
-
- void ShowBuffers()
- {
- #ifdef BUFFER_DIAG
- BOOL bOneHit = FALSE;
- for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
- {
- if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
- {
- iprintf( "Buf[%d]=", i );
- switch ( static_pool_buffers[i].bBuffer_state )
- {
- case BO_UNUSED :
- /*iprintf("BO_UNUSED ");*/ break;
- case BO_SOFTWARE:
- iprintf( "BO_SOFTWARE" ); break;
- case BO_PRX :
- iprintf( "BO_PRX " ); break;
- case BO_PTXF :
- iprintf( "BO_PTXF " ); break;
- case BO_PTXS :
- iprintf( "BO_PTXS " ); break;
- default:
- iprintf( "Unknown State" );
- }
- if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
- {
- bOneHit = TRUE;
- iprintf( " File = %s Line = %d\n",
- static_pool_buffers[i].m_fAlloc,
- static_pool_buffers[i].m_fline );
- }
- else
- {
- iprintf( "\n" );
- }
- }
- }
- if ( !bOneHit )
- {
- iprintf( "All are BO_UNUSED\n" );
- }
- #endif
- }
-
- void ShowIPBuffer( PoolPtr p );
-
- void DumpBuffers()
- {
- #ifdef BUFFER_DIAG
- char c = ' ';
- for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
- {
- iprintf( "Buf[%d]=", i );
- switch ( static_pool_buffers[i].bBuffer_state )
- {
- case BO_UNUSED :
- iprintf( "BO_UNUSED " ); break;
- case BO_SOFTWARE:
- iprintf( "BO_SOFTWARE" ); break;
- case BO_PRX :
- iprintf( "BO_PRX " ); break;
- case BO_PTXF :
- iprintf( "BO_PTXF " ); break;
- case BO_PTXS :
- iprintf( "BO_PTXS " ); break;
- default:
- iprintf( "Unknown State" );
- }
- if ( static_pool_buffers[i].bBuffer_state != BO_UNUSED )
- {
- iprintf( " File = %s Line = %d\n",
- static_pool_buffers[i].m_fAlloc,
- static_pool_buffers[i].m_fline );
- ShowIPBuffer( static_pool_buffers + i );
- iprintf( "Hit n to continue..." );
- iprintf( "Hit 'c' to loop ...." );
- do
- {
- if ( c != 'c' )
- {
- c = getchar();
- }
- }
- while ( ( c != 'n' ) && ( c != 'c' ) );
- }
- else
- {
- iprintf( "\n" );
- }
- }
- #endif
- }
-
- /*----------------------------------**
- ** The Initialize buffers function. **
- **This sets up the system buffers **
- **----------------------------------*/
- void InitBuffers()
- {
- if ( free_list_is_initialized )
- {
- return;
- }
- //Initialize the static free list as it may not get constructed in a embedded environment
- free_list.m_Head = free_list.m_Tail = NULL;
- free_list.m_wElements = 0;
- for ( int i = 0; i < BUFFER_POOL_SIZE; i++ )
- {
- PoolPtr pp;
- pp = static_pool_buffers + i;
- pp->bUsageCount = 1;
- FreeBuffer( pp );
- }
- free_list_is_initialized = 1;
- }
-
- void IncUsageCount( PoolPtr pp )
- {
- if ( pp != NULL )
- {
- pp->bUsageCount++;
- }
- }
-
- /*---------------------------------------------------**
- ** **
- ** Frees a buffer and places it in the unused state. **
- ** **
- **---------------------------------------------------*/
- #ifdef BUFFER_DIAG
- void FreeBufferX( PoolPtr pp, PCSTR f, int l )
- #else
- void FreeBuffer( PoolPtr pp )
- #endif
- {
- if ( pp->bUsageCount )
- {
- pp->bUsageCount--;
- }
- if ( pp->bUsageCount )
- {
- return;
- }
- pp->bBuffer_state = BO_UNUSED;
- #ifdef BUFFER_DIAG
- pp->m_fAlloc = "FREE";
- pp->m_fline = 0;
- #endif
- free_list.InsertHead( pp );
- }
-
- /*-----------------------------------------------------------**
- ** **
- ** Alocates a Software buffer and returns the buffer number. **
- ** **
- **-----------------------------------------------------------*/
- #ifdef BUFFER_DIAG
- PoolPtr GetBufferX( PCSTR f, int l )
- #else
- PoolPtr GetBuffer()
- #endif
- {
- PoolPtr pp = free_list.RemoveHead();
- if ( pp != NULL )
- {
- pp->bBuffer_state = BO_SOFTWARE;
- pp->bUsageCount = 1;
- }
- #ifdef BUFFER_DIAG
- if ( pp == NULL )
- {
- DBPRINT( DB_BUFFER, "NULL BUFFER" );
- }
- else
- {
- pp->m_fAlloc = f;
- pp->m_fline = l;
- }
- #else
- if ( pp == NULL )
- {
- DBPRINT( DB_BUFFER, "NULL BUFFER" );
- }
- #endif
- return pp;
- }
- #ifdef BUFFER_DIAG
- void ChangeOwnerX( PoolPtr pp, PCSTR f, int l )
- {
- if ( pp != NULL )
- {
- pp->m_fAlloc = f;
- pp->m_fline = l;
- }
- }
- #endif
- WORD GetFreeCount()
- {
- return free_list.GetCount();
- };
-
- /*---------------------------------------------------------------------**
- ** The folowing functions implment the buffer_list class **
- ** This class is used to manage lists of buffers. **
- ** All the buffers it manages are from the main buffer pool. **
- ** This is setup to be fast, very little error checking is done. **
- ** If perform an insert before, remove or insert after with buffer **
- ** values that are not part of the buffer list BAD things will happen. **
- ** **
- ** **
- ** All of the internal functions are wrapped in the DISABLE_INTS **
- ** ENABLE_INTS Macros. This ensures List Coherency **
- ** **
- ** **
- ** **
- **---------------------------------------------------------------------*/
-
- /*-------------------------------------------**
- ** Insert a buffer at the head of this list. **
- **-------------------------------------------*/
- void buffer_list::InsertHead( PoolPtr pp )
- {
- USER_ENTER_CRITICAL();
- pp->pPoolNext = m_Head;
- pp->pPoolPrev = NULL;
- if ( m_Head != NULL )
- {
- m_Head->pPoolPrev = pp;
- }
- else
- {
- m_Tail = pp;
- }
-
- m_Head = pp;
- m_wElements++;
- USER_EXIT_CRITICAL();
- }
-
-
- /*-------------------------------------------**
- ** Insert a buffer at the Tail of this list. **
- **-------------------------------------------*/
- void buffer_list::InsertTail( PoolPtr pp )
- {
- USER_ENTER_CRITICAL();
- pp->pPoolPrev = m_Tail;
- pp->pPoolNext = NULL;
-
- if ( m_Tail != NULL )
- {
- m_Tail->pPoolNext = pp;
- }
- else
- {
- m_Head = pp;
- }
-
- m_Tail = pp;
- m_wElements++;
- USER_EXIT_CRITICAL();
- }
-
-
-
- /*---------------------------------------------**
- ** Insert a buffer before an entry on the list.**
- ** NO checking is performed. IF the list does **
- ** not have the passed in buffer as a member **
- ** BAD THINGS WILL HAPPEN!! **
- ** **
- **---------------------------------------------*/
- void buffer_list::InsertBefore( PoolPtr pp, PoolPtr b4buffer )
- {
- USER_ENTER_CRITICAL();
- m_wElements++;
- if ( b4buffer->pPoolPrev == NULL )
- {
- InsertHead( pp );
- }
- else
- {
- pp->pPoolNext = b4buffer;
- pp->pPoolPrev = b4buffer->pPoolPrev;
- b4buffer->pPoolPrev = pp;
- pp->pPoolPrev->pPoolNext = pp;
- }
- USER_EXIT_CRITICAL();
- }
-
-
-
- /*---------------------------------------------**
- ** Insert a buffer after an entry on the list. **
- ** NO checking is performed. IF the list does **
- ** not have the passed in buffer as a member **
- ** BAD THINGS WILL HAPPEN!! **
- ** **
- **---------------------------------------------*/
- void buffer_list::InsertAfter( PoolPtr pp, PoolPtr after_buffer )
- {
- USER_ENTER_CRITICAL();
- m_wElements++;
- if ( after_buffer->pPoolNext == NULL )
- {
- InsertTail( pp );
- }
- else
- {
- pp->pPoolPrev = after_buffer;
- pp->pPoolNext = after_buffer->pPoolNext;
- after_buffer->pPoolNext = pp;
- pp->pPoolNext->pPoolPrev = pp;
- }
- USER_EXIT_CRITICAL();
- }
-
-
- /*--------------------------------------------**
- ** **
- ** Remove a buffer from the list. **
- ** NO checking is performed. IF the list does **
- ** not have the passed in buffer as a member **
- ** BAD THINGS WILL HAPPEN!! **
- ** **
- **--------------------------------------------*/
- void buffer_list::Remove( PoolPtr pp )
- {
- USER_ENTER_CRITICAL();
- if ( pp->pPoolNext == NULL )
- {
- m_Tail = pp->pPoolPrev = NULL;
- }
- else
- {
- pp->pPoolNext->pPoolPrev = pp->pPoolPrev;
- }
-
- if ( pp->pPoolPrev == NULL )
- {
- m_Head = pp->pPoolNext;
- }
- else
- {
- pp->pPoolPrev->pPoolNext = pp->pPoolNext;
- }
- m_wElements--;
- USER_EXIT_CRITICAL();
- pp->pPoolNext = NULL;
- pp->pPoolPrev = NULL;
- }
-
- PoolPtr LastHead;
-
- /*-----------------------------------------**
- ** Get the head of the list. **
- ** It return 0 if there are none availible **
- **-----------------------------------------*/
- PoolPtr buffer_list::RemoveHead()
- {
- USER_ENTER_CRITICAL();
- PoolPtr rv = m_Head;
- if ( m_Head != NULL )
- {
- LastHead=m_Head;
- m_wElements--;
- if ( m_Head == m_Tail )
- {
- m_Head = m_Tail = NULL;
- }
- else
- {
- m_Head = rv->pPoolNext;
- m_Head->pPoolPrev = NULL;
- }
- }
- USER_EXIT_CRITICAL();
- return rv;
- }
-
-
-
- /*-----------------------------------------**
- ** Get the end of the list. **
- ** It return 0 if there are none availible **
- **-----------------------------------------*/
- PoolPtr buffer_list::RemoveTail()
- {
- USER_ENTER_CRITICAL();
- m_wElements--;
- PoolPtr rv = m_Tail;
- if ( rv != NULL )
- {
- if ( m_Head == m_Tail )
- {
- m_Head = m_Tail = NULL;
- }
- else
- {
- m_Tail = rv->pPoolPrev;
- m_Tail->pPoolNext = NULL;
- }
- }
- USER_EXIT_CRITICAL();
- return rv;
- }
-
-
-
- void ShowBuffer( PoolPtr pb )
- {
- iprintf( "Buffer[%p] State =", pb );
-
- switch ( pb->bBuffer_state )
- {
- case BO_UNUSED :
- iprintf( " BO_UNUSED " ); break;
- case BO_SOFTWARE:
- iprintf( " BO_SOFTWARE" ); break;
- case BO_PRX :
- iprintf( " BO_PRX " ); break;
- case BO_PTXF :
- iprintf( " BO_PTXF " ); break;
- case BO_PTXS :
- iprintf( " BO_PTXS " ); break;
- default :
- iprintf( "Unknown %d", pb->bBuffer_state );
- }
- iprintf( " Size = %d\n", pb->usedsize );
- for ( WORD i = 0; i < pb->usedsize; i++ )
- {
- iprintf( "%02x ", ( int ) pb->pData[i] );
- if ( ( i % 16 ) == 15 )
- {
- iprintf( "\n" );
- }
- }
- iprintf( "\n" );
- }
-
-
-
-
-
-
- //Data is read in the tail
- //and read out the head.
- WORD fifo_buffer_storage::SpaceAvail()
- {
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
-
- WORD storage = ( m_MaxSegments - m_Segments_Stored ) * ETHER_BUFFER_SIZE;
- if ( m_Tail != NULL )
- {
- storage += ( ETHER_BUFFER_SIZE - m_Tail->usedsize );
- }
- return storage;
- }
-
-
- WORD fifo_buffer_storage::SpaceUsed()
- {
- return m_BytesStored;
- }
-
-
-
- int fifo_buffer_storage::ReadData( PBYTE pCopyTo, int max_bytes )
- {
- int bytes_copied = 0;
-
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
-
- if ( m_Head != NULL )
- {
- while ( ( m_Head ) && ( bytes_copied < max_bytes ) )
- {
- int bytes_avail;
- //How much is avail in the head segment?
- bytes_avail = m_Head->usedsize - ( m_Head->pBufQueuePointer - m_Head->pData );
- //Limit it to the amount we can copy
- if ( ( bytes_avail + bytes_copied ) > max_bytes )
- {
- memcpy( pCopyTo + bytes_copied,
- m_Head->pBufQueuePointer,
- max_bytes - bytes_copied );
- m_Head->pBufQueuePointer += ( max_bytes - bytes_copied );
- bytes_copied = max_bytes;
- }
- else
- {
- //Copy the whole buffer
- memcpy( pCopyTo + bytes_copied, m_Head->pBufQueuePointer, bytes_avail );
- bytes_copied += bytes_avail;
- PoolPtr pp = m_Head;
- m_Head = m_Head->pPoolNext;
- FreeBuffer( pp );
- if ( m_Head == NULL )
- {
- m_Tail = NULL;
- }
- m_Segments_Stored--;
- }
- }
- m_BytesStored -= bytes_copied;
- }
- return bytes_copied;
- }
-
-
-
- int fifo_buffer_storage::ReadDatawSum( PBYTE pCopyTo, int max_bytes, DWORD &csum )
- {
- int bytes_copied = 0;
-
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
- csum = 0;
-
- if ( m_Head != NULL )
- {
- while ( ( m_Head ) && ( bytes_copied < max_bytes ) )
- {
- int bytes_avail;
- //How much is avail in the head segment?
- bytes_avail = m_Head->usedsize - ( m_Head->pBufQueuePointer - m_Head->pData );
-
- if ( bytes_copied & 1 )
- {
- /* Odd checksum correction */
- *( pCopyTo + bytes_copied ) = *( m_Head->pBufQueuePointer );
- csum += *( m_Head->pBufQueuePointer );
- m_Head->pBufQueuePointer++;
- bytes_avail--;
- bytes_copied++;
- if ( bytes_avail == 0 )
- {
- PoolPtr pp = m_Head;
- m_Head = m_Head->pPoolNext;
- FreeBuffer( pp );
- if ( m_Head == NULL )
- {
- m_Tail = NULL;
- }
- m_Segments_Stored--;
- break;
- }
- if ( bytes_copied == max_bytes )
- {
- break;
- }
- }
-
- //Limit it to the amount we can copy
- if ( ( bytes_avail + bytes_copied ) > max_bytes )
- {
- csum += memcpysum( pCopyTo + bytes_copied,
- m_Head->pBufQueuePointer,
- max_bytes - bytes_copied );
- m_Head->pBufQueuePointer += ( max_bytes - bytes_copied );
- bytes_copied = max_bytes;
- }
- else
- {
- //Copy the whole buffer
- csum += memcpysum( pCopyTo + bytes_copied,
- m_Head->pBufQueuePointer,
- bytes_avail );
- bytes_copied += bytes_avail;
- PoolPtr pp = m_Head;
- m_Head = m_Head->pPoolNext;
- FreeBuffer( pp );
- if ( m_Head == NULL )
- {
- m_Tail = NULL;
- }
- m_Segments_Stored--;
- }
- }
- m_BytesStored -= bytes_copied;
- }
-
- return bytes_copied;
- }
-
-
-
-
- int fifo_buffer_storage::WriteData( PBYTE pCopyFrom, int num_bytes )
- {
- int bytes_copied = 0;
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
-
- if ( m_Tail == NULL )
- {
- m_Head = m_Tail = GetBuffer();
- if ( m_Head == NULL )
- {
- DBPRINT( DB_BUFFER, "Write Buffer Data Failed To alloc" );
- return 0;
- }
-
- m_Tail->pBufQueuePointer = m_Tail->pData;
- m_Tail->usedsize = 0;
- m_Segments_Stored++;
- m_Tail->pPoolNext = NULL;
- }
- else if ( ( m_Tail->usedsize == ETHER_BUFFER_SIZE ) &&
- ( m_Segments_Stored < m_MaxSegments ) )
- {
- m_Tail->pPoolNext = GetBuffer();
- if ( m_Tail->pPoolNext == NULL )
- {
- DBPRINT( DB_BUFFER, "Write Buffer Data Failed" );
- return 0;
- }
- m_Tail = m_Tail->pPoolNext;
- m_Tail->pBufQueuePointer = m_Tail->pData;
- m_Tail->usedsize = 0;
- m_Tail->pPoolNext = NULL;
- m_Segments_Stored++;
- }
-
- while ( ( bytes_copied < num_bytes ) )
- {
- int Can_Copy = ( ETHER_BUFFER_SIZE - m_Tail->usedsize );
- if ( ( Can_Copy + bytes_copied ) > num_bytes )
- {
- Can_Copy = num_bytes - bytes_copied;
- fmemcpy( m_Tail->pData + m_Tail->usedsize, pCopyFrom + bytes_copied, Can_Copy );
- m_Tail->usedsize += Can_Copy;
- bytes_copied += Can_Copy;
- }
- else
- {
- fmemcpy( m_Tail->pData + m_Tail->usedsize, pCopyFrom + bytes_copied, Can_Copy );
- m_Tail->usedsize += Can_Copy;
- bytes_copied += Can_Copy;
- if ( m_Segments_Stored < m_MaxSegments )
- {
- m_Tail->pPoolNext = GetBuffer();
- if ( m_Tail->pPoolNext == NULL )
- {
- DBPRINT( DB_BUFFER, "Wriite Buffer Faile " );
- return 0;
- }
- m_Tail = m_Tail->pPoolNext;
- m_Tail->pBufQueuePointer = m_Tail->pData;
- m_Tail->usedsize = 0;
- m_Tail->pPoolNext = NULL;
- m_Segments_Stored++;
- }
- else
- {
- break;
- } //Break out of while
- }//else a full buffer copy
- }//while
- m_BytesStored += bytes_copied;
- return bytes_copied;
- }
-
-
- fifo_buffer_storage::fifo_buffer_storage( BYTE max_buffers, BYTE use_fromisr )
- {
- Init( max_buffers, use_fromisr );
- }
-
-
- fifo_buffer_storage::~fifo_buffer_storage()
- {
- Reset( 0 );
- }
-
- void fifo_buffer_storage::Init( BYTE max_buffers, BYTE use_fromisr )
- {
- if ( use_fromisr )
- {
- /* We cheat and store a flag in the critical section */
- m_critical_section.OSCritTaskNum = 0xFF;
- }
- else
- {
- OSCritInit( &m_critical_section );
- }
- m_Head = m_Tail = NULL;
- m_Segments_Stored = 0;
- m_BytesStored = 0;
- m_MaxSegments = max_buffers;
- };
-
-
-
- void fifo_buffer_storage::SetMaxBuffers( BYTE max_buffers )
- {
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
- m_MaxSegments = max_buffers;
- }
-
-
-
- void fifo_buffer_storage::Reset( BYTE max_buffers )
- {
- BufferCriticalLock oscs( m_critical_section ); /*Locks the OS the destructor will unlock*/
-
- PoolPtr pp = m_Head;
- while ( pp )
- {
- m_Head = pp->pPoolNext;
- FreeBuffer( pp );
- pp = m_Head;
- }
- m_Head = m_Tail = NULL;
- m_Segments_Stored = 0;
- m_BytesStored = 0;
- m_MaxSegments = max_buffers;
- }
-
-
- BOOL fifo_buffer_storage::Empty()
- {
- return ( m_BytesStored == 0 );
- }
-
-
- BOOL fifo_buffer_storage::Full()
- {
- if ( m_MaxSegments - m_Segments_Stored )
- {
- return 0;
- }
- if ( ( m_Tail != NULL ) && ( ETHER_BUFFER_SIZE - m_Tail->usedsize ) )
- {
- return 0;
- }
- return 1;
- }
-
-
-
-