SDOCM00113029: Fix issue with limited size of EdmaMgr's internal heap. 3.31.00.00_eng
authorJacob Stiffler <j-stiffler@ti.com>
Tue, 30 Sep 2014 18:26:58 +0000 (14:26 -0400)
committerChris Ring <cring@ti.com>
Wed, 1 Oct 2014 19:34:41 +0000 (12:34 -0700)
While the memory requirements for regular EdmaMgr channels are constrained
relative to HW resources, large channels may require arbitrarily large memory for
the lookup tables used in the chained transfers. Therefore this memory must come
from outside EdmaMgr. The function EdmaMgr_getSizesLarge is introduced to provide
the application with the buffer requirements for a large channel based on a
supplied configuration.

Signed-off-by: Jacob Stiffler <j-stiffler@ti.com>
packages/ti/sdo/fc/edmamgr/edmamgr.c
packages/ti/sdo/fc/edmamgr/edmamgr.h

index 321ac28d4ef6a69c51f79cddf774b9c0a6c5b748..eadb2ae6a99ca6ad26934e8f737a89694f882375 100644 (file)
@@ -210,6 +210,36 @@ EdmaMgr_Handle EdmaMgr_alloc(int32_t max_linked_transfers)
     return ((EdmaMgr_Handle)&EdmaMgr_channels[i]);
 }
 
+
+
+/*********************************************************************************
+ * FUNCTION PURPOSE: Allocate EdmaMgr handle
+ *********************************************************************************
+  DESCRIPTION:      Get buffer requirements for a large channel.
+
+  Parameters :      Inputs: cfg    : Configuration for a large channel.
+
+                    Output: memTab : Memory requirements.
+
+                    Output: EdmaMgr_SUCCESS if successful;
+                            Error code otherwise
+ *********************************************************************************/
+int32_t EdmaMgr_getSizesLarge( EdmaMgr_ConfigLarge *cfg, IALG_MemRec memTab[])
+{
+  /* Validate configuration. */
+  if ( cfg->max_num_lines <= 0 )
+    return EdmaMgr_ERROR_INVCFG;
+
+  memTab[0].size      = cfg->max_num_lines * sizeof(uint32_t);
+  memTab[0].alignment = sizeof(uint32_t);
+  memTab[0].space     = IALG_DARAM0;
+  memTab[0].attrs     = IALG_PERSIST;
+  memTab[0].base      = NULL;
+
+  return EdmaMgr_SUCCESS;
+}
+
+
 /*********************************************************************************
  * FUNCTION PURPOSE: Allocate EdmaMgr handle for Large strides
  *********************************************************************************
@@ -228,19 +258,27 @@ EdmaMgr_Handle EdmaMgr_alloc(int32_t max_linked_transfers)
                     the first channel to read the next address in the table.
                     This will continue until the entire data is transfered.
 
-  Parameters :      Inputs: max_num_lines  : maximum number of lines in large
-                                             1D2D or 2D1D transfers required for
-                                             the channel.
+  Parameters :      Inputs: cfg            : Configuration for a large channel.
+
+                            memTab         : Buffer requirements along with
+                                             allocated buffers for a large
+                                             channel.
 
                     Output: Valid EdmaMgr handle on success;
                             NULL handle if there is an error.
  *********************************************************************************/
-EdmaMgr_Handle EdmaMgr_allocLarge(int32_t max_num_lines)
+EdmaMgr_Handle EdmaMgr_allocLarge( EdmaMgr_ConfigLarge *cfg, IALG_MemRec memTab[])
 {
     EdmaMgr_Handle   h1, h2;
     EdmaMgr_Channel  *chan1, *chan2;
     uint32_t         tcc1, tcc2;
 
+    if ( cfg->max_num_lines * sizeof(uint32_t) > memTab[0].size )
+      return ((EdmaMgr_Handle)NULL);
+
+    if ( memTab[0].base == NULL )
+      return ((EdmaMgr_Handle)NULL);
+
     /*
      *  Allocate a basic EdmaMgr channel.
      *
@@ -264,15 +302,8 @@ EdmaMgr_Handle EdmaMgr_allocLarge(int32_t max_num_lines)
     chan1 = (EdmaMgr_Channel *)h1;
     chan2 = (EdmaMgr_Channel *)h2;
 
-    /* Allocate memory for the address lookup table. */
-    chan1->addrTable.size      = max_num_lines*sizeof(uint32_t);
-    chan1->addrTable.alignment = sizeof(uint32_t);
-
-    if( !EdmaMgr_heap_alloc( &chan1->addrTable, 1) ) {
-        EdmaMgr_free(chan1);
-        EdmaMgr_free(chan2);
-        return ((EdmaMgr_Handle)NULL);
-    }
+    /* Copy over memory for the address lookup table. */
+    memcpy( &chan1->addrTable, &memTab[0], sizeof(IALG_MemRec));
 
     /* Obtain each channel's TCC so that chaining can be configured, */
     tcc1 = chan1->edmaHandle->assignedTccIndices[0];
index b6e3fe31a68858e528667144e51a5921aabcc6ad..f6776fd5b01d2f2f8b34d693fab57d4c7d11018c 100644 (file)
@@ -60,6 +60,7 @@
 #include <string.h>
 
 #include <ti/sdo/fc/ecpy/ecpy.h>
+#include <ti/xdais/ialg.h>
 #include <ti/xdais/ires.h>
 #include <ti/sdo/fc/ires/edma3chan/ires_edma3Chan.h>
 #include <ti/sdo/fc/edma3/edma3_config.h>
@@ -140,21 +141,62 @@ EdmaMgr_Handle EdmaMgr_alloc
 );
 
 
+#define EdmaMgr_MAX_NUM_MEMRECS_LARGE  1  /**< Maximum number of buffers
+                                           *   required to allocate a large
+                                           *   channel.
+                                           */
+/**
+ *  @brief  Configuration for a large channel.
+ */
+typedef struct _EdmaMgr_ConfigLarge {
+
+  /**< Maximum number of lines which may be transfered by the channel. */
+  int32_t       max_num_lines;
+
+} EdmaMgr_ConfigLarge;
+
+
+/**
+ *  @brief  Get buffer requirements for a large channel.
+ *
+ *  @param[in]    cfg     Configuration for a large channel.
+ *
+ *  @param[out]   memTab  Buffer requirements for a large channel.
+ *
+ *  @retval       EdmaMgr_SUCCESS         @copydoc EdmaMgr_SUCCESS
+ *  @retval       EdmaMgr_ERROR_INVCFG    @copydoc EdmaMgr_ERROR_INVCFG
+ *
+ *  @remark  These buffers must be provided to EdmaMgr_allocLarge() along with
+ *           the corresponding EdmaMgr_ConfigLarge structure.
+ */
+int32_t EdmaMgr_getSizesLarge
+(
+  EdmaMgr_ConfigLarge   *cfg,
+  IALG_MemRec            memTab[]
+);
+
+
 /**
  *  @brief      Allocate an EdmaMgr channel for "Large" 1D2D or 2D1D transfers
  *              which have a pitch outside the range [-32768,32768].
  *
- *  @param[in]  max_num_lines    Maximum number of lines to be transfered.
+ *  @param[in]  cfg         Configuration for a large channel.
+ *
+ *  @param[in]  memTab      Buffer requirements along with allocated buffers for
+ *                          a large channel.
  *
  *  @retval     NULL        Failure to allocate the channel
  *  @retval     non-NULL    Success
  *
  *  @pre        EdmaMgr_init() must have first been called.
+ *  @pre        EdmaMgr_getSizesLarge() must have been called and buffers
+ *              allocated satisfying the requirements in memTab.
  *
  */
 EdmaMgr_Handle EdmaMgr_allocLarge
 (
-  int32_t max_num_lines
+  EdmaMgr_ConfigLarge  *cfg,
+  IALG_MemRec          memTab[]
 );