📄 dp_hardware_dispatcher.c
字号:
/*********************************************************************************
*********************************************************************************
**
** Name : dp_hardware_dispatcher.c
** Title : Display pipeline API DMA engine interface
** Author : T. Whalley
** Created : June 2001
**
** Copyright : 2001 by Imagination Technologies Limited. All rights reserved
** : No part of this software, either material or conceptual
** : may be copied or distributed, transmitted, transcribed,
** : stored in a retrieval system or translated into any
** : human or computer language in any form by any means,
** : electronic, mechanical, manual or other-wise, or
** : disclosed to third parties without the express written
** : permission of Imagination Technologies Limited, Unit 8,
** : HomePark Industrial Estate, King's Langley, Hertfordshire,
** : WD4 8LZ, U.K.
**
** Description : Contains all functions for sorting and preparing data for the
** DMA engine and for retrieving data from hardware.
**
** Platform : Platform independent (modify 'types.h' accordingly)
**
*********************************************************************************
*********************************************************************************/
#include "services_headers.h"
#include "dp_types.h"
#include "dp_init_marathon.h"
#include "dp_hardware.h"
#include "dp_hardware_dispatcher.h"
#if defined DP_SIMULATION_MODE
#include <windows.h>
#include <stdio.h>
#endif
#ifdef PDUMP
typedef struct _MEM_INFO_ *PMEM_INFO;
//uncomment if needed #define PDPPDUMP
#endif
DP_UINT_32 DP_DispatcherBufferStorage [ 2 * DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES * (sizeof (DP_QueuedMemoryWrite) / sizeof ( DP_UINT_32)) ];
DP_QueuedMemoryWrite * DP_DispatcherBuffers;
DP_UINT_16 DP_ui16DispatcherBufferSize [ 2 ];
DP_DMABufferStates DP_eBufferStates [ 2 ];
DP_UINT_8 DP_ui8DispatcherBufferOffset [ 2 ];
DP_PUINT_32 DP_pSharedMemory;
#if defined DP_SIMULATION_MODE
#define DP_SIMULATION_NO_OF_REGISTERS 0x2000
DP_UINT_32 DP_aui32SimulationMemory [ DP_SIMULATION_NO_OF_REGISTERS ];
/* This simulates the hardware's ability to detect a write to a register. */
DP_BOOL DP_bNewValuePending = DP_FALSE;
#endif
/***********************************************************************************************
*
* Function Name : DP_CommandSequence
* Inputs : eOperation - An instance of the 'DP_CommandSequenceOperations'
* enumerated type, used to indicate to the function
* the type of command sequence operation being
* carried out. The following values are supported :
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND
* Specifies that a single field is to be written
* to, using the DMA engine. The command (passed by
* this functions other two parameters) is
* submitted when the function is called.
*
* DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE
* Specifies that a new list of commands is to be,
* started, and should not be transmitted until
* the list is marked complete. This command
* the other two parameters passed.
*
* DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND
* Specifies that a command should be added to a
* list previously created using the 'new sequence'
* command.
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE
* Specifies that a prepared list (using the
* 'new sequence' and 'add command' settings should
* be submitted to the DMA engine.
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE
* Specifies that a prepated list should be written
* directly to the hardware, bypassing the DMA
* engine (this mode of writing does not wait for
* the VSYNC signal).
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC
* Specifies that a prepared list should be written
* directly to the hardware, bypassing the DMA
* engine, but waiting for the next VSYNC signal to
* begin prior to writing. The function simply
* polls for the VSYNC signal and hence can tie up
* the calling process for a significant period.
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT
* Specifies that a single field is to be written to
* , but bypassing the DMA engine and writing
* directly to hardware. The command (passed by
* this function's other two parameters) is
* submitted when the function is called (this mode
* of writing does not wait for the VSYNC signal).
*
* DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC
* Specifies that a single field is to be written to
* , but bypassing the DMA engine and writing
* directly to hardware, after waiting for the next
* VSYNC signal. The function simply polls for the
* VSYNC signal and hence can tie up the calling
* process for a significant period.
*
* pasField - A pointer to the 'DP_pFieldTarget' structure
* which contains the details of the field to be
* written to.
*
* ui32Value - The value to be written to the target field.
*
* Outputs : None.
* Returns : DP_UINT_16 - Returns one of the defined display pipeline error
* codes according to the success of the function,
* within the bounds of limited error checking :
* > The function checks that each target field exists
* returning, DP_ERR_EXCEEDS_CAPABILITIES, if it does
* not (regardless of error checking mode).
* > The function checks that the passed target value
* will not exceed the bounds of the specified field
* (only when error checking is enabled).
*
* Globals Used : None.
* Description : This function is used to generate, add to and ultimately submit to the DMA
* Engine a series of field writes. By using this function, it can be ensured
* that all memory writes which up a single operation are all submitted to the
* DMA Engine as part of the same buffer.
*
***********************************************************************************************/
DP_UINT_16 DP_CommandSequence ( DP_CommandSequenceOperations eOperation,
DP_pFieldTarget pasField,
DP_UINT_32 ui32Value )
{
static DP_UINT_8 ui8LengthOfCommandSequence = 0;
DP_UINT_16 ui16ReturnValue = DP_STANDARD_CODE_NO_ERROR;
DP_QueuedFieldWrite sInstruction;
DP_UINT_16 ui16SizeOfBuffer = 0;
DP_UINT_16 ui16i;
/* Used as a scratch pad for preparing lists of memory writes for immediate actioning (i.e.: */
/* not using the DMA Engine). By using the same structures to prepare the lists as ARE used by */
/* the DMA Engine, all the same preparation interrogation functions can be used. */
static DP_QueuedMemoryWrite DP_TemporaryDispatchBuffer [ DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES ];
/* Used as a scratch pad for preparation of memory writes for non-immediate actioning. These */
/* memory writes are subsequently submitted to the DMA Engine via the DP_QueueNewDMABuffer */
/* function. */
static DP_QueuedFieldWrite DP_asCommandSequence [ DP_MAXIMUM_COMMAND_SEQUENCE_LENGTH ];
#if defined DP_DO_NOT_USE_DMA_ENGINE
switch ( eOperation )
{
case DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE:
case DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND:
/* These are nothing to do with sending the actual sequence, anyway - these */
/* remain unchanged whether or not we are using the DMA Engine */
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE:
/* This command needs changing to avoid using the DMA Engine */
eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE;
//eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC;
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND:
/* This command needs changing to avoid using the DMA Engine */
eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT;
//eOperation = DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC;
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE:
case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC:
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT:
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC:
/* These commands all instruct the sequence to be sent without the DMA Engine */
/* anyway, so they remain unchanged whether or not we are using the DMA Engine */
break;
}
#endif
ui16ReturnValue = DP_STANDARD_CODE_NO_ERROR;
switch ( eOperation )
{
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND:
/* Higher level API functions rely on being told if a field doesn't exist, */
/* regardless of whether error checking is enabled or not. For this reason, we must */
/* check 'up front' whether the field is null. */
if (( pasField != DP_NULL ) &&
( pasField->ui32TargetAddressOffset != DP_NO_REG ))
{
#if defined DP_ERROR_CHECKING
/* Confirm that the value to add won't cause a field overflow (i.e.: is the */
/* field larger than the space available for it ? */
if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart ))
{
#endif
sInstruction.pasFieldToWrite = (DP_FieldTarget *) pasField;
sInstruction.ui32ValueToWrite = ui32Value;
DP_QueueNewDMABuffer ( &sInstruction, (DP_UINT_8) 1 );
#if defined DP_ERROR_CHECKING
}
else
ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
#endif
}
else
ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_NEW_SEQUENCE:
ui8LengthOfCommandSequence = 0;
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_ADD_COMMAND:
/* Higher level API functions rely on being told if a field doesn't exist, */
/* regardless of whether error checking is enabled or not. For this reason, we must */
/* check 'up front' whether the field is null. */
if (( pasField != DP_NULL ) &&
( pasField->ui32TargetAddressOffset != DP_NO_REG ))
{
#if defined DP_ERROR_CHECKING
/* Confirm that the value to add won't cause a field overflow (i.e.: is the */
/* field larger than the space available for it ? */
if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart ))
{
#endif
DP_asCommandSequence [ ui8LengthOfCommandSequence ].pasFieldToWrite = (DP_FieldTarget *) pasField;
DP_asCommandSequence [ ui8LengthOfCommandSequence ].ui32ValueToWrite = ui32Value;
ui8LengthOfCommandSequence ++;
#if defined DP_ERROR_CHECKING
}
else
ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
#endif
}
else
ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_SEQUENCE:
if ( ui8LengthOfCommandSequence > 0 )
{
DP_QueueNewDMABuffer ( &DP_asCommandSequence [0], ui8LengthOfCommandSequence );
ui8LengthOfCommandSequence = 0;
}
break;
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_INSTANT:
case DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC:
/* Higher level API functions rely on being told if a field doesn't exist, */
/* regardless of whether error checking is enabled or not. For this reason, we must */
/* check 'up front' whether the field is null. */
if (( pasField != DP_NULL ) &&
( pasField->ui32TargetAddressOffset != DP_NO_REG ))
{
#if defined DP_ERROR_CHECKING
/* Confirm that the value to add won't cause a field overflow (i.e.: is the */
/* field larger than the space available for it ? */
if (( ui32Value >> pasField->ui8SourceBitfieldStart ) <= ( pasField->ui32TargetBitfieldMask >> pasField->ui8TargetBitfieldStart ))
{
#endif
ui8LengthOfCommandSequence = 1;
DP_asCommandSequence [0].pasFieldToWrite = (DP_FieldTarget *) pasField;
DP_asCommandSequence [0].ui32ValueToWrite = ui32Value;
#if defined DP_ERROR_CHECKING
}
else
{
ui16ReturnValue = DP_ERR_OUT_OF_RANGE;
break;
}
#endif
}
else
{
ui16ReturnValue = DP_ERR_EXCEEDS_CAPABILITIES;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -