diff --git a/src/rm.c b/src/rm.c
index 607eab17b6ed8d8788bbbcd02cf1abd76bd12e61..cfa937e2e484e7d095aa58c78b8470d51bc550bd 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
* @file rm.c
*
* @brief
- * This is the Resource Manager Low Level Driver file.
+ * This is the Resource Manager source.
*
* \par
* ============================================================================
- * @n (C) Copyright 2012, Texas Instruments, Inc.
+ * @n (C) Copyright 2012-2013, Texas Instruments, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* \par
*/
-/* c99 include */
+/* Standard includes */
#include <stdint.h>
-#include <stdlib.h>
+#include <string.h>
-/* RM includes */
+/* RM external includes */
#include <ti/drv/rm/rm.h>
-#include <ti/drv/rm/rm_public_lld.h>
-#include <ti/drv/rm/resource_table_defs.h>
-#include <ti/drv/rm/include/rm_pvt.h>
+#include <ti/drv/rm/rmver.h>
+#include <ti/drv/rm/rm_services.h>
+#include <ti/drv/rm/rm_transport.h>
+
+/* RM internal includes */
+#include <ti/drv/rm/include/rm_internal.h>
+#include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_allocatorloc.h>
+#include <ti/drv/rm/include/rm_transportloc.h>
+#include <ti/drv/rm/include/rm_nameserverloc.h>
+#include <ti/drv/rm/include/rm_servicesloc.h>
+
+/* RM LIBFDT includes */
+#include <ti/drv/rm/util/libfdt/libfdt.h>
/* RM OSAL layer */
#include <rm_osal.h>
-/* CSL includes */
-#include <ti/csl/csl_qm_queue.h>
-
/**********************************************************************
************************** Globals ***********************************
**********************************************************************/
-/* Place QMSS PDSP permissions array */
-#pragma DATA_SECTION (rmQmssPdspFirmwarePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssPdspFirmwarePerms, 128)
-Rm_Perms rmQmssPdspFirmwarePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_FIRMWARE_PDSPS, Rm_Perms)];
-
-/* Place QMSS queue permissions array */
-#pragma DATA_SECTION (rmQmssQueuePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQueuePerms, 128)
-Rm_Perms rmQmssQueuePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QUEUES, Rm_Perms)];
-
-/* Place QMSS memory region permissions array */
-#pragma DATA_SECTION (rmQmssMemRegionPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssMemRegionPerms, 128)
-Rm_Perms rmQmssMemRegionPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_MEM_REGIONS, Rm_Perms)];
-
-/* Place QMSS Linking RAM permissions array */
-#pragma DATA_SECTION (rmQmssLinkingRamPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssLinkingRamPerms, 128)
-Rm_qmssLinkingRamPerms rmQmssLinkingRamPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_LINKING_RAM_RANGES, Rm_qmssLinkingRamPerms)];
-
-/* Place QMSS accumulator channel permissions array */
-#pragma DATA_SECTION (rmQmssAccumChPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssAccumChPerms, 128)
-Rm_Perms rmQmssAccumChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_ACCUM_CH, Rm_Perms)];
-
-/* Place QMSS QOS cluster permissions array */
-#pragma DATA_SECTION (rmQmssQosClusterPerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQosClusterPerms, 128)
-Rm_Perms rmQmssQosClusterPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QOS_CLUSTER, Rm_Perms)];
-
-/* Place QMSS QOS queue permissions array */
-#pragma DATA_SECTION (rmQmssQosQueuePerms, ".rm");
-#pragma DATA_ALIGN (rmQmssQosQueuePerms, 128)
-Rm_Perms rmQmssQosQueuePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_QOS_QUEUES, Rm_Perms)];
-
-/* Place CPPI SRIO TX channel permissions array */
-#pragma DATA_SECTION (rmCppiSrioTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioTxChPerms, 128)
-Rm_Perms rmCppiSrioTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_TX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF TX channel permissions array */
-#pragma DATA_SECTION (rmCppiAifTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifTxChPerms, 128)
-Rm_Perms rmCppiAifTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcATxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcATxChPerms, 128)
-Rm_Perms rmCppiFftcATxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcBTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBTxChPerms, 128)
-Rm_Perms rmCppiFftcBTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS TX channel permissions array */
-#pragma DATA_SECTION (rmCppiPassTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassTxChPerms, 128)
-Rm_Perms rmCppiPassTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_TX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS TX channel permissions array */
-#pragma DATA_SECTION (rmCppiQmssTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssTxChPerms, 128)
-Rm_Perms rmCppiQmssTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_TX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C TX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcCTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCTxChPerms, 128)
-Rm_Perms rmCppiFftcCTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_TX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP TX channel permissions array */
-#pragma DATA_SECTION (rmCppiBcpTxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpTxChPerms, 128)
-Rm_Perms rmCppiBcpTxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_TX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI SRIO RX channel permissions array */
-#pragma DATA_SECTION (rmCppiSrioRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioRxChPerms, 128)
-Rm_Perms rmCppiSrioRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_RX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF RX channel permissions array */
-#pragma DATA_SECTION (rmCppiAifRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifRxChPerms, 128)
-Rm_Perms rmCppiAifRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcARxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcARxChPerms, 128)
-Rm_Perms rmCppiFftcARxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcBRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBRxChPerms, 128)
-Rm_Perms rmCppiFftcBRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS RX channel permissions array */
-#pragma DATA_SECTION (rmCppiPassRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassRxChPerms, 128)
-Rm_Perms rmCppiPassRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_RX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS RX channel permissions array */
-#pragma DATA_SECTION (rmCppiQmssRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssRxChPerms, 128)
-Rm_Perms rmCppiQmssRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_RX_CH, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C RX channel permissions array */
-#pragma DATA_SECTION (rmCppiFftcCRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCRxChPerms, 128)
-Rm_Perms rmCppiFftcCRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_RX_CH, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP RX channel permissions array */
-#pragma DATA_SECTION (rmCppiBcpRxChPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpRxChPerms, 128)
-Rm_Perms rmCppiBcpRxChPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_RX_CH, Rm_Perms)];
-#endif
-
-/* Place CPPI SRIO flow permissions array */
-#pragma DATA_SECTION (rmCppiSrioFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiSrioFlowPerms, 128)
-Rm_Perms rmCppiSrioFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_SRIO_FLOW, Rm_Perms)];
-
-#ifdef QMSS_MAX_AIF_QUEUE
-/* Place CPPI AIF flow permissions array */
-#pragma DATA_SECTION (rmCppiAifFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiAifFlowPerms, 128)
-Rm_Perms rmCppiAifFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_AIF_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
-/* Place CPPI FFTC A flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcAFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcAFlowPerms, 128)
-Rm_Perms rmCppiFftcAFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_A_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
-/* Place CPPI FFTC B flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcBFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcBFlowPerms, 128)
-Rm_Perms rmCppiFftcBFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_B_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
-/* Place CPPI PASS flow permissions array */
-#pragma DATA_SECTION (rmCppiPassFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiPassFlowPerms, 128)
-Rm_Perms rmCppiPassFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_PASS_FLOW, Rm_Perms)];
-#endif
-
-/* Place CPPI QMSS flow permissions array */
-#pragma DATA_SECTION (rmCppiQmssFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiQmssFlowPerms, 128)
-Rm_Perms rmCppiQmssFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_QMSS_FLOW, Rm_Perms)];
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
-/* Place CPPI FFTC C flow permissions array */
-#pragma DATA_SECTION (rmCppiFftcCFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiFftcCFlowPerms, 128)
-Rm_Perms rmCppiFftcCFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_FFTC_C_FLOW, Rm_Perms)];
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
-/* Place CPPI BCP flow permissions array */
-#pragma DATA_SECTION (rmCppiBcpFlowPerms, ".rm");
-#pragma DATA_ALIGN (rmCppiBcpFlowPerms, 128)
-Rm_Perms rmCppiBcpFlowPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_CPPI_BCP_FLOW, Rm_Perms)];
-#endif
-
-/* Place PA lookup table permissions array */
-#pragma DATA_SECTION (rmPaLutPerms, ".rm");
-#pragma DATA_ALIGN (rmPaLutPerms, 128)
-Rm_Perms rmPaLutPerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_PA_LUT, Rm_Perms)];
-
-/* Rm_init/Rm_start synchronization object. Initialized to 0. */
-#pragma DATA_SECTION (rmGSyncObj, ".rm");
-#pragma DATA_ALIGN (rmGSyncObj, 128)
-Rm_Sync_Obj rmGSyncObj =
+/* Global Variable which describes the RM Version Information */
+const char rmVersionStr[] = RM_VERSION_STR ":" __DATE__ ":" __TIME__;
+
+/**********************************************************************
+ ************************ Local Functions *****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Initializes a RM inst's transaction sequence number
+ ***********************************************************************
+ * DESCRIPTION: The RM instance transaction sequence number can never
+ * have a value of 0 to avoid conflicts with transactions
+ * that have a remoteOriginatingId of 0 (transaction ID
+ * will be used as the remoteOriginatingId for
+ * transactions that are responses to requests).
+ */
+static uint32_t transactionInitSequenceNum(void)
{
- {
- RM_PERMISSION_TABLE_NOT_VALID,
- }
-};
+ return (1);
+}
-/* Create, populate, and place RM global permissions object */
-#pragma DATA_SECTION (rmGPermsObj, ".rm");
-#pragma DATA_ALIGN (rmGPermsObj, 128)
-Rm_GlobalPermissionsObj rmGPermsObj =
+/* FUNCTION PURPOSE: Provides a sequence number for new transactions
+ ***********************************************************************
+ * DESCRIPTION: Returns a sequence number for a new transaction
+ * specific to a RM instance. Handles rollover of
+ * sequence number.
+ */
+static uint32_t transactionGetSequenceNum(Rm_Inst *rmInst)
{
- {
- /* qmssPdspFirmwarePerms */
- &rmQmssPdspFirmwarePerms[0],
- /* Pointer: qmssQueuePerms */
- &rmQmssQueuePerms[0],
- /* Pointer: qmssMemRegionPerms */
- &rmQmssMemRegionPerms[0],
- /* qmssLinkRamControlPerms */
- {
- 0u,
- 0u,
- },
- /* Pointer: qmssLinkRamPerms */
- &rmQmssLinkingRamPerms[0],
- /* Pointer: qmssAccumChPerms */
- &rmQmssAccumChPerms[0],
- /* qmssQosPdspTimerPerms */
- {
- 0u,
- 0u,
- },
- /* Pointer: qmssQosClusterPerms */
- &rmQmssQosClusterPerms[0],
- /* Pointer: qmssQosQueuePerms */
- &rmQmssQosQueuePerms[0],
- /* Pointer array: cppiTxChPerms - Must be in same order as DMA objects */
- {
- { &rmCppiSrioTxChPerms[0],
-#ifdef QMSS_MAX_AIF_QUEUE
- &rmCppiAifTxChPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- &rmCppiFftcATxChPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- &rmCppiFftcBTxChPerms[0],
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- &rmCppiPassTxChPerms[0],
-#endif
- &rmCppiQmssTxChPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- &rmCppiFftcCTxChPerms[0],
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- &rmCppiBcpTxChPerms[0]
-#endif
- }
- },
- /* Pointer array: cppiRxChPerms - Must be in same order as DMA objects */
- {
- { &rmCppiSrioRxChPerms[0],
-#ifdef QMSS_MAX_AIF_QUEUE
- &rmCppiAifRxChPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- &rmCppiFftcARxChPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- &rmCppiFftcBRxChPerms[0],
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- &rmCppiPassRxChPerms[0],
-#endif
- &rmCppiQmssRxChPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- &rmCppiFftcCRxChPerms[0],
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- &rmCppiBcpRxChPerms[0]
-#endif
- }
- },
- /* Pointer array: cppiFlowPerms - Must be in same order as DMA objects */
- {
- { &rmCppiSrioFlowPerms[0],
-#ifdef QMSS_MAX_AIF_QUEUE
- &rmCppiAifFlowPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- &rmCppiFftcAFlowPerms[0],
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- &rmCppiFftcBFlowPerms[0],
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- &rmCppiPassFlowPerms[0],
-#endif
- &rmCppiQmssFlowPerms[0],
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- &rmCppiFftcCFlowPerms[0],
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- &rmCppiBcpFlowPerms[0]
-#endif
- }
- },
- /* paFirmwarePerms */
- {
- 0u,
- 0u,
- },
- /* Pointer: paLutPerms */
- &rmPaLutPerms[0],
+ rmInst->transactionSeqNum++;
+ if (!rmInst->transactionSeqNum) {
+ rmInst->transactionSeqNum++;
+ }
+ return (rmInst->transactionSeqNum);
+}
+
+/* FUNCTION PURPOSE: Creates a resource request packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ * resource request packet that has been prepared
+ * for sending to another RM instance. The packet
+ * is allocated via the rmAllocPkt API using the
+ * appTransport handle provided by the application
+ */
+void createResourceReqPkt(Rm_Packet *rmPkt, char *localInstName, Rm_Transaction *transaction)
+{
+ Rm_ResourceRequestPkt *resourceReqPkt = NULL;
+
+ rmPkt->pktType = Rm_pktType_RESOURCE_REQUEST;
+ resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data;
+ resourceReqPkt->requestId = transaction->localId;
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_USE;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_STATUS;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_FREE) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;
}
-};
+ else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_NAMED;
+ }
+ strncpy(resourceReqPkt->pktSrcInstName, localInstName, RM_NAME_MAX_CHARS);
+ strncpy(resourceReqPkt->serviceSrcInstName, transaction->serviceSrcInstName, RM_NAME_MAX_CHARS);
+ memcpy ((void *)&(resourceReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),
+ sizeof(Rm_ResourceInfo));
+}
-/** @brief Global Variable (should be local per DSP) containing LLD RM permission checkers */
-Rm_LldPermCallouts rmPermissionCheckers =
+/* FUNCTION PURPOSE: Creates a resource response packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ * resource response packet that has been prepared
+ * for sending to another RM instance. The packet
+ * is allocated via the rmAllocPkt API using the
+ * appTransport handle provided by the application
+ */
+void createResourceResponsePkt(Rm_Packet *rmPkt, Rm_Transaction *transaction)
{
- Rm_initPermissionChecker,
- Rm_usePermissionChecker,
-};
+ Rm_ResourceResponsePkt *resourceRespPkt = NULL;
+
+ rmPkt->pktType = Rm_pktType_RESOURCE_RESPONSE;
+ resourceRespPkt = (Rm_ResourceResponsePkt *)rmPkt->data;
+ resourceRespPkt->responseId = transaction->remoteOriginatingId;
+ resourceRespPkt->requestState = transaction->state;
+ memcpy ((void *)&(resourceRespPkt->resourceInfo), (void *)&(transaction->resourceInfo),
+ sizeof(Rm_ResourceInfo));
+}
-/** @brief Global Variable which describes the RM LLD Version Information */
-const char rmLldVersionStr[] = RM_LLD_VERSION_STR ":" __DATE__ ":" __TIME__;
+/* FUNCTION PURPOSE: Creates a NameServer request packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ * NameServer request packet that has been prepared
+ * for sending to another RM instance. The packet
+ * is allocated via the rmAllocPkt API using the
+ * appTransport handle provided by the application
+ */
+void createNsRequestPkt(Rm_Packet *rmPkt, char *localInstName, Rm_Transaction *transaction)
+{
+ Rm_NsRequestPkt *nsReqPkt = NULL;
+
+ rmPkt->pktType = Rm_pktType_NAMESERVER_REQUEST;
+ nsReqPkt = (Rm_NsRequestPkt *)rmPkt->data;
+ nsReqPkt->requestId = transaction->localId;
+ if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
+ nsReqPkt->nsRequestType = Rm_nsReqPktType_MAP_RESOURCE;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
+ nsReqPkt->nsRequestType = Rm_nsReqPktType_UNMAP_RESOURCE;
+ }
+ strncpy(nsReqPkt->pktSrcInstName, localInstName, RM_NAME_MAX_CHARS);
+ strncpy(nsReqPkt->serviceSrcInstName, transaction->serviceSrcInstName, RM_NAME_MAX_CHARS);
+ memcpy ((void *)&(nsReqPkt->resourceInfo), (void *)&(transaction->resourceInfo),
+ sizeof(Rm_ResourceInfo));
+}
-/**********************************************************************
- ********************** Internal Functions *********************************
- **********************************************************************/
+/* FUNCTION PURPOSE: Creates a NameServer response packet
+ ***********************************************************************
+ * DESCRIPTION: Returns a RM packet handle that points to a RM
+ * NameServer response packet that has been prepared
+ * for sending to another RM instance. The packet
+ * is allocated via the rmAllocPkt API using the
+ * appTransport handle provided by the application
+ */
+void createNsResponsePkt(Rm_Packet *rmPkt, Rm_Transaction *transaction)
+{
+ Rm_NsResponsePkt *nsRespPkt = NULL;
-/**
- * @b Description
- * @n
- * Initialize the permission tables. All resources are intialized to deny all initialization
- * and usage permissions.
- *
+ rmPkt->pktType = Rm_pktType_NAMESERVER_RESPONSE;
+ nsRespPkt = (Rm_NsResponsePkt *)rmPkt->data;
+ nsRespPkt->responseId = transaction->remoteOriginatingId;
+ nsRespPkt->requestState = transaction->state;
+}
+
+/* FUNCTION PURPOSE: Issues a service response to application
+ ***********************************************************************
+ * DESCRIPTION: Provides a service response back to the application
+ * using the service callback function provided to
+ * the RM instance at the time of the service request.
*/
-void Rm_permissionTableInit(void)
+static void serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- uint16_t resourceIndex;
- Rm_Perms *resArrayPtr;
- uint16_t dmaNum;
- uint16_t dmaTxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_TX_CH,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_TX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_TX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_TX_CH,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_TX_CH,
-#endif
- RM_CPPI_QMSS_TX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_TX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_TX_CH
-#endif
- };
- uint16_t dmaRxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_RX_CH,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_RX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_RX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_RX_CH,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_RX_CH,
-#endif
- RM_CPPI_QMSS_RX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_RX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_RX_CH
-#endif
- };
- uint16_t dmaFlow[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_FLOW,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_FLOW,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_FLOW,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_FLOW,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_FLOW,
-#endif
- RM_CPPI_QMSS_FLOW,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_FLOW,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_FLOW
-#endif
- };
-
- /* QMSS Linking RAM Control */
- rmGPermsObj.obj.qmssLinkRamControlPerms.initPerms = 0;
- rmGPermsObj.obj.qmssLinkRamControlPerms.usePerms = 0;
-
- /* QMSS QOS PDSP Timer */
- rmGPermsObj.obj.qmssQosPdspTimerPerms.initPerms = 0;
- rmGPermsObj.obj.qmssQosPdspTimerPerms.usePerms = 0;
-
- /* PA Firmware */
- rmGPermsObj.obj.paFirmwarePerms.initPerms = 0;
- rmGPermsObj.obj.paFirmwarePerms.usePerms = 0;
-
- /* Writeback the values that were initialized in the global object itself */
- Rm_osalEndMemAccess ((void *) &rmGPermsObj, sizeof (Rm_GlobalPermissionsObj));
-
- /* QMSS PDSP Firmware */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_FIRMWARE_PDSPS; resourceIndex++)
+ Rm_ServiceRespInfo serviceResponse;
+
+ serviceResponse.rmHandle = (Rm_Handle)rmInst;
+ /* The responseTransaction will contain the resultant state details of
+ * the requestTransaction's service request */
+ serviceResponse.serviceState = transaction->state;
+ /* Pass back the ID that was provided to the component when it requested
+ * the service */
+ serviceResponse.serviceId = transaction->localId;
+ /* Owner count will only be set within RM under certain circumstances. Most of time
+ * it will be RM_RESOURCE_NUM_OWNERS_INVALID */
+ serviceResponse.resourceNumOwners = transaction->resourceInfo.ownerCount;
+
+ /* Service was approved and service was an allocate request. The resource
+ * data is passed back to the component */
+ if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&
+ ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+ (transaction->type == Rm_service_RESOURCE_FREE) ||
+ (transaction->type == Rm_service_RESOURCE_STATUS) ||
+ (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
{
- rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceIndex].usePerms = 0;
+ strncpy(serviceResponse.resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ serviceResponse.resourceBase = transaction->resourceInfo.base;
+ serviceResponse.resourceLength = transaction->resourceInfo.length;
}
- /* Writeback the qmssPdspFirmwarePerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssPdspFirmwarePerms, sizeof (Rm_Perms)*RM_QMSS_FIRMWARE_PDSPS);
- /* QMSS queues */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_QUEUES; resourceIndex++)
- {
- rmGPermsObj.obj.qmssQueuePerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssQueuePerms[resourceIndex].usePerms = 0;
+ if (transaction->u.callback.serviceCallback) {
+ /* Issue the callback to the requesting component with the response information */
+ transaction->u.callback.serviceCallback(&serviceResponse);
+ /* Delete the transaction from the transaction queue */
+ rmTransactionQueueDelete(rmInst, transaction->localId);
}
- /* Writeback the qmssQueuePerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQueuePerms, sizeof (Rm_Perms)*RM_QMSS_QUEUES);
-
- /* QMSS memory regions */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_MEM_REGIONS; resourceIndex++)
- {
- rmGPermsObj.obj.qmssMemRegionPerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssMemRegionPerms[resourceIndex].usePerms = 0;
+ else {
+ rmServiceInternalCallback((Rm_Handle)rmInst);
}
- /* Writeback the qmssMemRegionPerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssMemRegionPerms, sizeof (Rm_Perms)*RM_QMSS_MEM_REGIONS);
+
+ return;
+}
- /* QMSS Linking RAM */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_LINKING_RAM_RANGES; resourceIndex++)
- {
- rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].startIndex = RM_QMSS_LINKING_RAM_RANGE_INIT;
- rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].endIndex = RM_QMSS_LINKING_RAM_RANGE_INIT;
- rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].rangePerms.initPerms = 0;
- rmGPermsObj.obj.qmssLinkRamPerms[resourceIndex].rangePerms.usePerms = 0;
+/* FUNCTION PURPOSE: Sends RM response packets
+ ***********************************************************************
+ * DESCRIPTION: Sends RM response packets to RM instance's that sent
+ * RM request packets to the RM instance. The response
+ * is sent via the RM transport API which is plugged
+ * with an application created transport path.
+ */
+static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transport *dstTransport = transaction->u.respTrans;
+ Rm_Packet *rmPkt = NULL;
+ Rm_PacketHandle pktHandle = NULL;
+
+ rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle,
+ sizeof(Rm_Packet), &pktHandle);
+ if (!rmPkt || !pktHandle) {
+ transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+ goto errorExit;
}
- /* Writeback the qmssLinkRamPerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssLinkRamPerms, sizeof (Rm_Perms)*RM_QMSS_LINKING_RAM_RANGES);
- /* QMSS accumulator channels */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_ACCUM_CH; resourceIndex++)
- {
- rmGPermsObj.obj.qmssAccumChPerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssAccumChPerms[resourceIndex].usePerms = 0;
+ switch (transaction->type) {
+ case Rm_service_RESOURCE_ALLOCATE_INIT:
+ case Rm_service_RESOURCE_ALLOCATE_USE:
+ case Rm_service_RESOURCE_STATUS:
+ case Rm_service_RESOURCE_FREE:
+ case Rm_service_RESOURCE_GET_BY_NAME:
+ createResourceResponsePkt(rmPkt, transaction);
+ break;
+ case Rm_service_RESOURCE_MAP_TO_NAME:
+ case Rm_service_RESOURCE_UNMAP_NAME:
+ createNsResponsePkt(rmPkt, transaction);
+ break;
}
- /* Writeback the qmssAccumChPerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssAccumChPerms, sizeof (Rm_Perms)*RM_QMSS_ACCUM_CH);
-
- /* QMSS QOS Clusters */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_QOS_CLUSTER; resourceIndex++)
- {
- rmGPermsObj.obj.qmssQosClusterPerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssQosClusterPerms[resourceIndex].usePerms = 0;
+ if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+ transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+ goto errorExit;
}
- /* Writeback the qmssQosClusterPerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQosClusterPerms, sizeof (Rm_Perms)*RM_QMSS_QOS_CLUSTER);
+
+ /* Response packet sent: Delete transaction from queue */
+ rmTransactionQueueDelete(rmInst, transaction->localId);
- /* QMSS QOS Queues */
- for (resourceIndex = 0; resourceIndex < RM_QMSS_QOS_QUEUES; resourceIndex++)
- {
- rmGPermsObj.obj.qmssQosQueuePerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.qmssQosQueuePerms[resourceIndex].usePerms = 0;
- }
- /* Writeback the qmssQosQueuePerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.qmssQosQueuePerms, sizeof (Rm_Perms)*RM_QMSS_QOS_QUEUES);
+errorExit:
+ /* Do not delete transaction on transport error. Transport error transactions should be visible
+ * from Rm_printInstanceStatus() */
+ return;
+}
- /* CPPI DMA transmit channels */
- for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
- {
- resArrayPtr = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[dmaNum];
-
- for (resourceIndex = 0; resourceIndex < dmaTxCh[dmaNum]; resourceIndex++)
- {
- resArrayPtr[resourceIndex].initPerms = 0;
- resArrayPtr[resourceIndex].usePerms = 0;
- }
+/* FUNCTION PURPOSE: Sends RM request packets
+ ***********************************************************************
+ * DESCRIPTION: Sends RM request packets to RM instance's that are
+ * capable of forwarding or validating service requests.
+ * The request is sent via the RM transport API which is
+ * plugged with an application created transport path.
+ */
+static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transport *dstTransport = NULL;
+ Rm_Packet *rmPkt = NULL;
+ Rm_PacketHandle pktHandle = NULL;
- /* Writeback each of the transmit channel arrays */
- Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaTxCh[dmaNum]);
- }
+ if (rmInst->instType == Rm_instType_CLIENT) {
+ dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_CLIENT_DELEGATE);
- /* CPPI DMA receive channels */
- for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
- {
- resArrayPtr = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[dmaNum];
-
- for (resourceIndex = 0; resourceIndex < dmaRxCh[dmaNum]; resourceIndex++)
- {
- resArrayPtr[resourceIndex].initPerms = 0;
- resArrayPtr[resourceIndex].usePerms = 0;
+ if (!dstTransport) {
+ dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_SERVER);
}
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ dstTransport = rmTransportFindRemoteInstType(rmInst->transports, Rm_instType_SERVER);
+ }
- /* Writeback each of the receive channel arrays */
- Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaRxCh[dmaNum]);
- }
-
- /* CPPI DMA flows */
- for (dmaNum = 0; dmaNum < RM_CPPI_MAX_DMAS; dmaNum++)
- {
- resArrayPtr = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[dmaNum];
-
- for (resourceIndex = 0; resourceIndex < dmaFlow[dmaNum]; resourceIndex++)
- {
- resArrayPtr[resourceIndex].initPerms = 0;
- resArrayPtr[resourceIndex].usePerms = 0;
+ /* Just queue transaction if transport hasn't been registered. Do not return error */
+ if (dstTransport) {
+ rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle,
+ sizeof(Rm_Packet), &pktHandle);
+ if (!rmPkt || !pktHandle) {
+ transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+ goto errorExit;
}
- /* Writeback each of the flow arrays */
- Rm_osalEndMemAccess ((void *) resArrayPtr, sizeof (Rm_Perms)*dmaFlow[dmaNum]);
- }
-
- /* PA Lookup tables */
- for (resourceIndex = 0; resourceIndex < RM_PA_LUT; resourceIndex++)
- {
- rmGPermsObj.obj.paLutPerms[resourceIndex].initPerms = 0;
- rmGPermsObj.obj.paLutPerms[resourceIndex].usePerms = 0;
+ switch (transaction->type) {
+ case Rm_service_RESOURCE_ALLOCATE_INIT:
+ case Rm_service_RESOURCE_ALLOCATE_USE:
+ case Rm_service_RESOURCE_STATUS:
+ case Rm_service_RESOURCE_FREE:
+ case Rm_service_RESOURCE_GET_BY_NAME:
+ createResourceReqPkt(rmPkt, rmInst->instName, transaction);
+ break;
+ case Rm_service_RESOURCE_MAP_TO_NAME:
+ case Rm_service_RESOURCE_UNMAP_NAME:
+ createNsRequestPkt(rmPkt, rmInst->instName, transaction);
+ break;
+ }
+
+ if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+ transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+ goto errorExit;
+ }
+ transaction->hasBeenForwarded = RM_TRUE;
+ /* Transaction not deleted. Waiting for response from RM CD or Server */
}
- /* Writeback the paLutPerms array */
- Rm_osalEndMemAccess ((void *) rmGPermsObj.obj.paLutPerms, sizeof (Rm_Perms)*RM_PA_LUT);
-
+errorExit:
+ /* Do not delete transaction on transport error. Transport error transactions should be visible
+ * from Rm_printInstanceStatus() */
+ return;
}
-/**
- * @b Description
- * @n
- * Sets a list of entries in a permissions array to the specified permissions
- *
- * @param[in] resourceEntry
- * The resource entry from the application defined resource table containing
- * a range of resources and the permissions to assign to them.
- *
- * @param[in] rmPermsArray
- * The permissions array for the resource specified in the resourceEntry.
- *
- * @param[in] len
- * Full length of permissions array for writeback after the permissions have been
- * transferred.
+/* FUNCTION PURPOSE: Handles static allocation requests
+ ***********************************************************************
+ * DESCRIPTION: Validates allocation requests received on CDs and
+ * Clients prior to the instance's registering
+ * with a Server. The allocation request is validated
+ * against a static policy.
*/
-void Rm_setTablePermissions (const Rm_Resource *resourceEntry, Rm_Perms *rmPermsArray, uint32_t len)
+static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transaction)
{
- uint32_t index;
-
- /* Scan through the resource range filling in the specified permission */
- for (index = resourceEntry->resourceStart; index < resourceEntry->resourceEnd + 1; index++)
- {
- rmPermsArray[index].initPerms = resourceEntry->resourceInitFlags;
- rmPermsArray[index].usePerms = resourceEntry->resourceUseFlags;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ void *staticPolicy = rmPolicyGetPolicy(rmHandle);
+ Rm_PolicyCheckCfg privCheckCfg;
+ int32_t result;
+
+ if (staticPolicy) {
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ /* Check request against static policy */
+ memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ privCheckCfg.type = Rm_policyCheck_INIT;
+ }
+ else {
+ privCheckCfg.type = Rm_policyCheck_USE;
+ }
+ privCheckCfg.policyDtb = staticPolicy;
+ privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmHandle, rmInst->instName);
+ privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(staticPolicy,
+ transaction->resourceInfo.name);
+ privCheckCfg.resourceBase = transaction->resourceInfo.base;
+ privCheckCfg.resourceLength = transaction->resourceInfo.length;
+
+ if (rmPolicyCheckPrivilege(&privCheckCfg, &result)) {
+ transaction->state = RM_SERVICE_APPROVED_STATIC;
+ }
+ else if (result == RM_OK) {
+ /* Privilege check returned false without error */
+ transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
+ }
+ else {
+ /* Privilege check returned false with error */
+ transaction->state = result;
+ }
+ }
+ else {
+ transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
+ }
}
-
- Rm_osalEndMemAccess ((void *)rmPermsArray, sizeof (Rm_Perms)* len);
+ else {
+ transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
+ }
}
-/**
- * @b Description
- * @n
- * Takes an application specified resource table as input and transfers all
- * resource permissions specified within into the internal resource
- * permission tables. Upon completion of permission transfer a global
- * synchronization object is written to sync with slave cores.
- *
- * @param[in] rmResourceTable
- * Application defined resource table containing all resources that should
- * have permissions set for the DSPs
- *
- * @retval
- * Success - RM_OK
- * @retval
- * Failure - RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED
+/* FUNCTION PURPOSE: Requests resources from Server for CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to allocate resources
+ * from the Server for local management by the CD. The
+ * transaction which causes this request is put in the
+ * pending state in order to wait for the response from the
+ * Server
*/
-Rm_Result Rm_populatePermissionTable(const Rm_Resource *rmResourceTable)
+static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- const Rm_Resource *resourceEntry;
- uint16_t linkRamIndex;
+ Rm_Transaction *newTrans = NULL;
+ void * policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ int32_t resourceOffsetInPolicy;
+ uint32_t allocSize = 0;
+ int32_t retVal;
+
+ resourceOffsetInPolicy = rmPolicyGetResourceOffset(policy, transaction->resourceInfo.name);
+ if (resourceOffsetInPolicy > 0) {
+ if (allocSize = rmPolicyGetResourceAllocSize(policy, resourceOffsetInPolicy)) {
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = transaction->type;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+ /* Make sure request length will satisfy transaction length */
+ newTrans->resourceInfo.length = allocSize;
+ while (newTrans->resourceInfo.length < transaction->resourceInfo.length) {
+ newTrans->resourceInfo.length += allocSize;
+ }
+ newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
- /* Verify resource table can be read by verifying magic number is contained
- * in first entry of the resource table */
- resourceEntry = rmResourceTable;
-
- /* Invalidate the resource */
- Rm_osalBeginMemAccess ((void *) resourceEntry, sizeof (Rm_Resource));
- if (resourceEntry->resourceId != RM_RESOURCE_MAGIC_NUMBER)
- {
- return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
+ retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ else {
+ /* Forward request to Server for completion if policy has
+ * no allocation size for resource */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ else {
+ /* Resource could not be found in policy */
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
}
+ return (retVal);
+}
- /* Magic number is visible start parsing the resource table and transferring
- * permissions to the internal permissions tables */
+/* FUNCTION PURPOSE: Frees local resources to Server from CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to free locally
+ * managed resources that are now localized back to
+ * the Server.
+ */
+static int32_t cdFreeResourcesToServer(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ int32_t baseToFree = transaction->resourceInfo.base;
+ uint32_t lenToFree = transaction->resourceInfo.length;
+ Rm_Transaction *newTrans = NULL;
+ /* This function should only be called after a free was approved */
+ int32_t retVal = RM_SERVICE_APPROVED;
+
+ /* Did free result in a localized free node that can be given back to Server? If
+ * so create transaction to Server to free localized resource node */
+ if (rmAllocatorGetNodeLocalization((Rm_Handle)rmInst, transaction->resourceInfo.name,
+ &baseToFree, &lenToFree)) {
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = transaction->type;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ newTrans->resourceInfo.base = baseToFree;
+ newTrans->resourceInfo.length = lenToFree;
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
+
+ retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ /* Error: Need to re-allocate what was freed */
+ retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ return (retVal);
+}
- /* Parse resource table until last entry field is encountered */
- while (resourceEntry->resourceId != RM_RESOURCE_FINAL_ENTRY)
- {
- /* Invalidate the resource */
- Rm_osalBeginMemAccess ((void *) resourceEntry, sizeof (Rm_Resource));
-
- /* Populate a permission table based on the resourceId */
- switch (resourceEntry->resourceId)
- {
- case RM_RESOURCE_MAGIC_NUMBER:
- break;
+/* FUNCTION PURPOSE: Arbitrates allocation service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations in order to
+ * handle a received allocation request. Allocation
+ * requests are always forwarded to the Server on Client
+ * CD instances. If a request is made with a NameServer
+ * name the resource base and length parameters are
+ * retrieved from the NameServer prior to the allocation
+ * attempt.
+ */
+static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_AllocatorOpInfo opInfo;
+ Rm_NameServerObjCfg nameServerObjCfg;
+ int32_t retVal = transaction->state;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
- case RM_RESOURCE_QMSS_FIRMWARE_PDSP:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_FIRMWARE_PDSPS, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssPdspFirmwarePerms, RM_QMSS_FIRMWARE_PDSPS);
- break;
-
- case RM_RESOURCE_QMSS_QUEUE:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QUEUES, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQueuePerms, RM_QMSS_QUEUES);
- break;
-
- case RM_RESOURCE_QMSS_MEMORY_REGION:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_MEM_REGIONS, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssMemRegionPerms, RM_QMSS_MEM_REGIONS);
- break;
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to allocate from local resources that were provided by Server */
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ }
+ else {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ int32_t oldAlign = transaction->resourceInfo.alignment;
- case RM_RESOURCE_QMSS_LINKING_RAM_CONTROL:
- rmGPermsObj.obj.qmssLinkRamControlPerms.initPerms = resourceEntry->resourceInitFlags;
- rmGPermsObj.obj.qmssLinkRamControlPerms.usePerms = resourceEntry->resourceUseFlags;
- break;
+ /* Attempt to allocate from local resources that were provided by Server */
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
- case RM_RESOURCE_QMSS_LINKING_RAM:
- /* Expect Linking RAM ranges to be presented in order */
-
- /* Find next available unused Linking RAM permissions entry */
- for (linkRamIndex = 0; linkRamIndex < RM_QMSS_LINKING_RAM_RANGES; linkRamIndex++)
- {
- if ((rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].startIndex == RM_QMSS_LINKING_RAM_RANGE_INIT) &&
- (rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].endIndex == RM_QMSS_LINKING_RAM_RANGE_INIT))
- {
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_LINKING_RAM_RANGE_INIT,
- RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- /* Populate the entry with the Linking RAM resource data */
- rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].startIndex = resourceEntry->resourceStart;
- rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].endIndex = resourceEntry->resourceEnd;
- rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].rangePerms.initPerms = resourceEntry->resourceInitFlags;
- rmGPermsObj.obj.qmssLinkRamPerms[linkRamIndex].rangePerms.usePerms = resourceEntry->resourceUseFlags;
-
- Rm_osalEndMemAccess ((void *)&rmGPermsObj.obj.qmssLinkRamPerms[0], sizeof (Rm_Perms)* RM_QMSS_LINKING_RAM_RANGES);
+ if (retVal == RM_SERVICE_PROCESSING) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ else if (retVal == RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET) {
+ if (transaction->pendingTransactionId) {
+ /* Request to Server for resources to complete transaction locally
+ * performed once already. Forward transaction to Server for completion */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ else {
+ /* Restore base and alignment since they were replaced in pre-allocate routine */
+ transaction->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+ transaction->resourceInfo.alignment = oldAlign;
- /* Leave search loop */
- break;
+ retVal = cdRequestServerResources(rmInst, transaction);
}
}
- break;
-
- case RM_RESOURCE_QMSS_ACCUMULATOR_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_ACCUM_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssAccumChPerms, RM_QMSS_ACCUM_CH);
- break;
-
- case RM_RESOURCE_QMSS_QOS_PDSP_TIMER:
- rmGPermsObj.obj.qmssQosPdspTimerPerms.initPerms = resourceEntry->resourceInitFlags;
- rmGPermsObj.obj.qmssQosPdspTimerPerms.usePerms = resourceEntry->resourceUseFlags;
- break;
-
- case RM_RESOURCE_QMSS_QOS_CLUSTER:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QOS_CLUSTER, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQosClusterPerms, RM_QMSS_QOS_CLUSTER);
- break;
-
- case RM_RESOURCE_QMSS_QOS_QUEUE:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_QMSS_QOS_QUEUES, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.qmssQosQueuePerms, RM_QMSS_QOS_QUEUES);
- break;
-
- case RM_RESOURCE_CPPI_SRIO_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_SRIO_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_SRIO_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_SRIO_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_SRIO_DMA_ID], RM_CPPI_SRIO_FLOW);
- break;
-
-#ifdef QMSS_MAX_AIF_QUEUE
- case RM_RESOURCE_CPPI_AIF_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_AIF_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_AIF_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_AIF_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_AIF_DMA_ID], RM_CPPI_AIF_FLOW);
- break;
-#endif
-
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- case RM_RESOURCE_CPPI_FFTC_A_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_A_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_A_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_A_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_A_DMA_ID], RM_CPPI_FFTC_A_FLOW);
- break;
-#endif
-
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- case RM_RESOURCE_CPPI_FFTC_B_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_B_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_B_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_B_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_B_DMA_ID], RM_CPPI_FFTC_B_FLOW);
- break;
-#endif
-
-#ifdef QMSS_MAX_PASS_QUEUE
- case RM_RESOURCE_CPPI_PASS_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_PASS_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_PASS_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_PASS_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_PASS_DMA_ID], RM_CPPI_PASS_FLOW);
- break;
-#endif
-
- case RM_RESOURCE_CPPI_QMSS_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_QMSS_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_QMSS_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_QMSS_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_QMSS_DMA_ID], RM_CPPI_QMSS_FLOW);
- break;
-
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- case RM_RESOURCE_CPPI_FFTC_C_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_C_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_FFTC_C_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_FFTC_C_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_FFTC_C_DMA_ID], RM_CPPI_FFTC_C_FLOW);
- break;
-#endif
-
-#ifdef QMSS_MAX_BCP_QUEUE
- case RM_RESOURCE_CPPI_BCP_TX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_TX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_TX_CH);
- break;
-
- case RM_RESOURCE_CPPI_BCP_RX_CH:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_RX_CH, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_RX_CH);
- break;
-
- case RM_RESOURCE_CPPI_BCP_FLOW:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_CPPI_BCP_FLOW, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[RM_CPPI_BCP_DMA_ID], RM_CPPI_BCP_FLOW);
- break;
-#endif
-
- case RM_RESOURCE_PA_FIRMWARE:
- rmGPermsObj.obj.paFirmwarePerms.initPerms = resourceEntry->resourceInitFlags;
- rmGPermsObj.obj.paFirmwarePerms.usePerms = resourceEntry->resourceUseFlags;
- break;
-
- case RM_RESOURCE_PA_LUT_ENTRY:
- RM_RANGE_CHECK (resourceEntry->resourceStart, resourceEntry->resourceEnd, RM_PA_LUT, RM_ERROR_PERMISSION_TABLE_ENTRY_FAILURE);
- Rm_setTablePermissions (resourceEntry, rmGPermsObj.obj.paLutPerms, RM_PA_LUT);
- break;
-
- default:
- return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
-
+ }
+ else {
+ retVal = cdRequestServerResources(rmInst, transaction);
+ }
+ }
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER)||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ /* Populated NameServer name has precedence over base */
+ if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ }
+ else {
+ goto errorExit;
+ }
}
- resourceEntry++;
- };
-
- /* Write synchronization object so that slave cores know permissions table is
- * populated and valid */
- rmGSyncObj.obj.globalSyncObj = RM_PERMISSION_TABLE_VALID;
+ if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
- /* Writeback Sync Object */
- Rm_osalEndMemAccess ((void *) &rmGSyncObj, sizeof (Rm_Sync_Obj));
-
- return RM_OK;
+ if (retVal == RM_SERVICE_PROCESSING) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
+ }
+errorExit:
+ transaction->state = retVal;
}
-/**
- * @b Description
- * @n
- * This function is called on slave DSPs after the master DSP has populated
- * the internal permission tables. This function invalidates all internal
- * global permission tables so that no further invalidates are required
- * when LLDs perform resource permission checks
- *
+/* FUNCTION PURPOSE: Handles resource status service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations to retrieve the
+ * current status (currently just owner reference count)
+ * for the resource specified in the transaction
*/
-void Rm_updatePermissionTables(void)
+static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- uint16_t dmaIndex;
- const uint16_t dmaTxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_TX_CH,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_TX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_TX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_TX_CH,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_TX_CH,
-#endif
- RM_CPPI_QMSS_TX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_TX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_TX_CH
-#endif
- };
- const uint16_t dmaRxCh[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_RX_CH,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_RX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_RX_CH,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_RX_CH,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_RX_CH,
-#endif
- RM_CPPI_QMSS_RX_CH,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_RX_CH,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_RX_CH
-#endif
- };
- const uint16_t dmaFlow[RM_CPPI_MAX_DMAS] = {RM_CPPI_SRIO_FLOW,
-#ifdef QMSS_MAX_AIF_QUEUE
- RM_CPPI_AIF_FLOW,
-#endif
-#ifdef QMSS_MAX_FFTC_A_QUEUE
- RM_CPPI_FFTC_A_FLOW,
-#endif
-#ifdef QMSS_MAX_FFTC_B_QUEUE
- RM_CPPI_FFTC_B_FLOW,
-#endif
-#ifdef QMSS_MAX_PASS_QUEUE
- RM_CPPI_PASS_FLOW,
-#endif
- RM_CPPI_QMSS_FLOW,
-#ifdef QMSS_MAX_FFTC_C_QUEUE
- RM_CPPI_FFTC_C_FLOW,
-#endif
-#ifdef QMSS_MAX_BCP_QUEUE
- RM_CPPI_BCP_FLOW
-#endif
- };
-
- /* Invalidate all permission tables so no further invalidates are required
- * on slave cores */
+ Rm_AllocatorOpInfo opInfo;
+ Rm_NameServerObjCfg nameServerObjCfg;
+ int32_t retVal = transaction->state;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.operation = Rm_allocatorOp_GET_STATUS;
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
+
+ if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+ ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+ (transaction->resourceInfo.length == 0))) {
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ goto errorExit;
+ }
- /* Global permissions object */
- Rm_osalBeginMemAccess ((void *) &rmGPermsObj, sizeof (Rm_GlobalPermissionsObj));
-
- /* QMSS Permission Tables */
-
- /* QMSS PDSPs */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssPdspFirmwarePerms, sizeof (Rm_Perms) * RM_QMSS_FIRMWARE_PDSPS);
- /* QMSS Queues */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQueuePerms, sizeof (Rm_Perms) * RM_QMSS_QUEUES);
- /* QMSS Memory Regions */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssMemRegionPerms, sizeof (Rm_Perms) * RM_QMSS_MEM_REGIONS);
- /* QMSS Linking RAM */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssLinkRamPerms, sizeof (Rm_qmssLinkingRamPerms) * RM_QMSS_LINKING_RAM_RANGES);
- /* QMSS Accumulator Channels */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssAccumChPerms, sizeof (Rm_Perms) * RM_QMSS_ACCUM_CH);
- /* QMSS QOS Clusters */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQosClusterPerms, sizeof (Rm_Perms) * RM_QMSS_QOS_CLUSTER);
- /* QMSS QOS Queues */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.qmssQosQueuePerms, sizeof (Rm_Perms) * RM_QMSS_QOS_QUEUES);
-
- /* CPPI Permission Tables */
-
- /* CPPI DMA Transmit Channels */
- for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
- {
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaTxCh[dmaIndex]);
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to get status from local resources that were provided by Server */
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local allocator resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
}
- /* CPPI DMA Receive Channels */
- for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
- {
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaRxCh[dmaIndex]);
+ else if ((rmInst->instType == Rm_instType_SERVER)||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ /* Populated NameServer name has precedence over base and length values */
+ if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ }
+ else {
+ goto errorExit;
+ }
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
}
- /* CPPI DMA Receive Flows */
- for (dmaIndex = 0; dmaIndex < RM_CPPI_MAX_DMAS; dmaIndex++)
- {
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[dmaIndex], sizeof (Rm_Perms)*dmaFlow[dmaIndex]);
+errorExit:
+ transaction->state = retVal;
+}
+
+/* FUNCTION PURPOSE: Arbitrates free service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations in order to
+ * handle a received free request. Free
+ * requests are always forwarded to the Server on Client
+ * CD instances. If a request is made with a NameServer
+ * name the resource base and length parameters are
+ * retrieved from the NameServer prior to the free
+ * attempt.
+ */
+static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_AllocatorOpInfo opInfo;
+ Rm_NameServerObjCfg nameServerObjCfg;
+ int32_t retVal = transaction->state;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.operation = Rm_allocatorOp_FREE;
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
+
+ if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+ ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+ (transaction->resourceInfo.length == 0))) {
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ goto errorExit;
}
- /* PA permission tables */
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to free from local resources that were provided by Server */
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
- /* PA Firmware invalidated as part of global permissions object invalidate */
- /* PA LUTs */
- Rm_osalBeginMemAccess ((void *)rmGPermsObj.obj.paLutPerms, sizeof (Rm_Perms) * RM_PA_LUT);
+ if (retVal == RM_SERVICE_APPROVED) {
+ /* Check if free allows local resources to be freed back to Server */
+ retVal = cdFreeResourcesToServer(rmInst, transaction);
+ }
+ else if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local allocator resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ /* Populated NameServer name has precedence over base */
+ if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ }
+ else {
+ goto errorExit;
+ }
+ }
+
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
+errorExit:
+ transaction->state = retVal;
}
-/**
- * @b Description
- * @n
- * This function extracts the initialization permission for a DSP from a resource
- * permission element.
- *
- * @param[in] resourcePermissions
- * A permissions structure element to extract the per DSP initialization permission
- *
- * @retval
- * Success - RM_INIT_PERMISSION_APPROVED
- * @retval
- * Failure - RM_INIT_PERMISSION_DENIED
+/* FUNCTION PURPOSE: Client transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Client process:
+ * - Performs static allocations if no transport
+ * to CD or Server has been registered
+ * - Forwards all service requests to CD or Server
+ * once transport has been registered
*/
-Rm_Result Rm_getInitPermissions (Rm_Perms *resourcePermissions)
+static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- /* Check the init permissions for the calling DSP */
- if (!(RM_GET_PERMISSIONS(resourcePermissions->initPerms)))
- {
- return RM_INIT_PERMISSION_DENIED;
+ Rm_Transaction *transQ = rmInst->transactionQueue;
+
+ if (!rmInst->registeredWithDelegateOrServer) {
+ staticAllocationHandler((Rm_Handle)rmInst, transaction);
}
-
- return RM_INIT_PERMISSION_APPROVED;
+ else {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ /* Forward all new transactions to CD or Server */
+ transactionForwarder(rmInst, transaction);
+ }
+ else {
+ /* Transaction validated. Return result. */
+ serviceResponder(rmInst, transaction);
+ }
+
+ /* Forward any queued static requests that weren't forwarded */
+ while(transQ) {
+ if ((transQ->state == RM_SERVICE_APPROVED_STATIC) &&
+ (!transQ->hasBeenForwarded)) {
+ transactionForwarder(rmInst, transQ);
+ }
+ transQ = transQ->nextTransaction;
+ }
+ }
+ /* Let call stack return transaction result app via Rm_serviceHandler */
}
-/**
- * @b Description
- * @n
- * This function extracts the usage permission for a DSP from a resource
- * permission element.
- *
- * @param[in] resourcePermissions
- * A permissions structure element to extract the per DSP usage permission
- *
- * @retval
- * Success - RM_INIT_PERMISSION_APPROVED
- * @retval
- * Failure - RM_INIT_PERMISSION_DENIED
+/* FUNCTION PURPOSE: Client Delegate transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client Delegate process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Client Delegate process:
+ * - Performs static allocations if no transport
+ * to Server has been registered
+ * - Forwards all NameServer related service requests
+ * to Server once transport has been registered
+ * - Attempts to complete resource service requests
+ * received from registered Clients
*/
-Rm_Result Rm_getUsePermissions (Rm_Perms *resourcePermissions)
-{
- /* Check the use permissions for the calling DSP */
- if (!(RM_GET_PERMISSIONS(resourcePermissions->usePerms)))
- {
- return RM_USE_PERMISSION_DENIED;
+static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transaction *newTrans = NULL;
+ Rm_Allocator *allocator = NULL;
+ Rm_Transaction *transQ = rmInst->transactionQueue;
+
+ if (!rmInst->registeredWithDelegateOrServer) {
+ if ((transaction->state == RM_SERVICE_PROCESSING) &&
+ (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
+ /* Attempt static allocation of requests originating from CD inst */
+ staticAllocationHandler((Rm_Handle)rmInst, transaction);
+ }
+ /* Everything else left in transaction queue for forwarding once transport to
+ * Server is registered */
+ }
+ else {
+ if (transaction->pendingTransactionId) {
+ Rm_Transaction *pendingTrans = rmTransactionQueueFind(rmInst, transaction->pendingTransactionId);
+
+ /* Transaction is response from Server for transaction sent to get
+ * information in order to complete pending transaction */
+ if (transaction->state == RM_SERVICE_APPROVED) {
+ if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+ /* Transfer resource data tied to name to pending transaction */
+ strncpy(pendingTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ pendingTrans->resourceInfo.base = transaction->resourceInfo.base;
+ pendingTrans->resourceInfo.length = transaction->resourceInfo.length;
+ /* Delete NS name from pending transaction so Server isn't queried again */
+ memset(pendingTrans->resourceInfo.nameServerName, 0, RM_NAME_MAX_CHARS);
+ /* Now that resource values have been retrieved clear pending transaction ID so
+ * CD doesn't think a resource request was sent to Server already for more local resources */
+ pendingTrans->pendingTransactionId = 0;
+
+ /* Return original transaction to processing state to attempt completion. */
+ pendingTrans->state = RM_SERVICE_PROCESSING;
+ }
+ else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ /* Add resources provided by Server to those managed by CD */
+ if (allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ Rm_ResourceNode *treeNode = NULL;
+
+ treeNode = rmResourceNodeNew(transaction->resourceInfo.base, transaction->resourceInfo.length);
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, treeNode);
+ }
+ else {
+ Rm_ResourceRange resRange;
+
+ memset((void *)&resRange, 0, sizeof(resRange));
+ resRange.base = transaction->resourceInfo.base;
+ resRange.length = transaction->resourceInfo.length;
+
+ rmAllocatorCreate((Rm_Handle)rmInst, transaction->resourceInfo.name, &resRange);
+ }
+
+ /* Return original transaction to processing state to attempt completion */
+ pendingTrans->state = RM_SERVICE_PROCESSING;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_FREE) {
+ /* Local resource freed on Server. Need to remove from local allocator. */
+ rmAllocatorDeleteNode((Rm_Handle)rmInst, transaction->resourceInfo.name,
+ transaction->resourceInfo.base, transaction->resourceInfo.length);
+
+ /* Delete the allocator if there are no nodes left in the tree */
+ allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name);
+ if (RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry) == NULL) {
+ rmAllocatorDelete((Rm_Handle)rmInst, transaction->resourceInfo.name);
+ }
+
+ /* Allow original free to complete */
+ pendingTrans->state = RM_SERVICE_APPROVED;
+ }
+ }
+ else {
+ if (transaction->type == Rm_service_RESOURCE_FREE) {
+ /* Error occurred when trying to free local resource on Server. Reinsert local
+ * resources freed by original request */
+ Rm_AllocatorOpInfo opInfo;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &pendingTrans->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, pendingTrans->serviceSrcInstName);
+ /* Can't regain the original type of allocate. Default to init */
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) != RM_SERVICE_APPROVED) {
+ transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
+ }
+ }
+ /* Transfer error or denial to pending transaction */
+ pendingTrans->state = transaction->state;
+ }
+ rmTransactionQueueDelete(rmInst, transaction->localId);
+ /* Switch to pending transaction */
+ transaction = pendingTrans;
+ }
+
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+ (transaction->type == Rm_service_RESOURCE_STATUS) ||
+ (transaction->type == Rm_service_RESOURCE_FREE)) {
+ if ((transaction->state == RM_SERVICE_PROCESSING) &&
+ (strlen(transaction->resourceInfo.nameServerName) > 0)) {
+ /* Create and forward new transaction to Server to
+ * retrieve resource data mapped to name */
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = Rm_service_RESOURCE_GET_BY_NAME;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.nameServerName, transaction->resourceInfo.nameServerName,
+ RM_NAME_MAX_CHARS);
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
+
+ transaction->state = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ transaction->state = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ }
+
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ allocationHandler(rmInst, transaction);
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ statusHandler(rmInst, transaction);
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_FREE) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ freeHandler(rmInst, transaction);
+ }
+ }
+ /* Forward all NameServer-based transactions */
+
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ /* CD could not complete transaction. Forward to Server */
+ transactionForwarder(rmInst, transaction);
+ }
+ else if (transaction->state != RM_SERVICE_PENDING_SERVER_RESPONSE) {
+ /* Transaction completed by CD or completed response received from Server. Return result */
+ if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+ /* Transaction did not originate on this instance */
+ transactionResponder(rmInst, transaction);
+ }
+ else {
+ /* Transaction originated on this instance */
+ serviceResponder(rmInst, transaction);
+ }
+ }
+
+ /* Attempt allocation of any queued static requests:
+ * RM_SERVICE_APPROVED_STATIC - Originated locally
+ * RM_SERVICE_PROCESSING - Received from any registered Clients */
+ while(transQ) {
+ if (((transQ->state == RM_SERVICE_PROCESSING) ||
+ (transQ->state == RM_SERVICE_APPROVED_STATIC)) &&
+ (!transQ->hasBeenForwarded)) {
+ transactionForwarder(rmInst, transQ);
+ }
+ transQ = transQ->nextTransaction;
+ }
}
-
- return RM_USE_PERMISSION_APPROVED;
}
-/**
- * @b Description
- * @n
- * This function searches the list of linking RAM address ranges to find one that has
- * the requested linking RAM address within it. If found the function returns the permissions
- * for this range. Otherwise it returns denied.
- *
- * @param[in] isInitCheck
- * True - Permissions check is for initialization
- * False - Permissions check is for usage
- *
- * @param[in] linkRamPermArray
- * Internal array of linking RAM ranges and their permissions
- *
- * @param[in] linkRamResData
- * Linking RAM addresses to check for initialization or usage permissions
- *
- * @retval
- * Success - RM_INIT_PERMISSION_APPROVED
- * @retval
- * Failure - RM_INIT_PERMISSION_DENIED
+/* FUNCTION PURPOSE: Server transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Server process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Server process:
+ * - Validates all service requests received from
+ * the service handle and registered CDs and
+ * Clients
*/
-Rm_Result Rm_getLinkRamPermissions (Bool isInitCheck, Rm_qmssLinkingRamPerms *linkRamPermArray, Rm_ResourceInfo *linkRamResData)
+static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- Rm_Result retVal;
- uint16_t linkRamIndex;
+ Rm_NameServerObjCfg nameServerObjCfg;
- /* Initialize the return value based on type of check boolean */
- if (isInitCheck)
- {
- retVal = RM_INIT_PERMISSION_DENIED;
- }
- else
- {
- retVal = RM_USE_PERMISSION_DENIED;
- }
-
- for (linkRamIndex = 0; linkRamIndex < RM_QMSS_LINKING_RAM_RANGES; linkRamIndex++)
- {
- if ((linkRamResData->res_info.linkRamData.linkRamStartIndex >= linkRamPermArray[linkRamIndex].startIndex) &&
- (linkRamResData->res_info.linkRamData.linkRamEndIndex <= linkRamPermArray[linkRamIndex].endIndex))
- {
- /* Check the use permissions for the calling DSP */
- if (isInitCheck)
- {
- if (RM_GET_PERMISSIONS(linkRamPermArray[linkRamIndex].rangePerms.initPerms))
- {
- retVal = RM_USE_PERMISSION_APPROVED;
+ switch (transaction->type) {
+ case Rm_service_RESOURCE_STATUS:
+ statusHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_ALLOCATE_INIT:
+ case Rm_service_RESOURCE_ALLOCATE_USE:
+ allocationHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_FREE:
+ freeHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_MAP_TO_NAME:
+ case Rm_service_RESOURCE_GET_BY_NAME:
+ case Rm_service_RESOURCE_UNMAP_NAME:
+ if (rmInst->u.server.nameServer) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
+ nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
+ nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
+ nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
+ transaction->state = rmNameServerAddObject(&nameServerObjCfg);
}
- }
- else
- {
- if (RM_GET_PERMISSIONS(linkRamPermArray[linkRamIndex].rangePerms.usePerms))
- {
- retVal = RM_USE_PERMISSION_APPROVED;
+ else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+ if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
+ RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ transaction->state = RM_SERVICE_APPROVED;
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
+ transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
+ }
+
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeWb(rmInst->u.server.nameServer);
}
}
+ else {
+ transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
+ }
break;
+ }
+
+ /* Source of shared server transaction will always be local. */
+ if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+ if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+ /* Source of transaction was not Server, return transaction via responder */
+ transactionResponder(rmInst, transaction);
+ }
+ }
+ /* Otherwise let call stack return transaction result app via Rm_serviceHandler */
+}
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+/* FUNCTION PURPOSE: Adds a transaction
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to a newly created transaction.
+ * The transaction is created based on a new service
+ * request received via the service API or the
+ * transport API (service forwarded from another instance)
+ */
+Rm_Transaction *rmTransactionQueueAdd(Rm_Inst *rmInst)
+{
+ Rm_Transaction *transactionQueue = rmInst->transactionQueue;
+ Rm_Transaction *newTransaction = NULL;
+
+ newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));
+ if (newTransaction) {
+ memset((void *)newTransaction, 0, sizeof(Rm_Transaction));
+
+ newTransaction->localId = transactionGetSequenceNum(rmInst);
+ newTransaction->nextTransaction = NULL;
+ if (transactionQueue) {
+ while (transactionQueue->nextTransaction) {
+ transactionQueue = transactionQueue->nextTransaction;
+ }
+ transactionQueue->nextTransaction = newTransaction;
+ }
+ else {
+ rmInst->transactionQueue = newTransaction;
+ }
+ }
+ return (newTransaction);
+}
+
+/* FUNCTION PURPOSE: Finds a transaction
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to a transaction resident
+ * in the transaction queue that matches the provided
+ * transaction ID.
+ */
+Rm_Transaction *rmTransactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)
+{
+ Rm_Transaction *transaction = rmInst->transactionQueue;
+
+ while (transaction) {
+ if (transaction->localId == transactionId) {
+ break;
+ }
+ transaction = transaction->nextTransaction;
+ }
+
+ return (transaction);
+}
+
+/* FUNCTION PURPOSE: Deletes a transaction
+ ***********************************************************************
+ * DESCRIPTION: Deletes the transaction with the provided transaction
+ * ID from the instance's transaction queue.
+ */
+int32_t rmTransactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)
+{
+ Rm_Transaction *transaction = rmInst->transactionQueue;
+ Rm_Transaction *prevTransaction = NULL;
+ int32_t retVal = RM_OK;
+
+ while (transaction) {
+ if (transaction->localId == transactionId) {
+ break;
}
+
+ prevTransaction = transaction;
+ transaction = transaction->nextTransaction;
}
+ if (transaction) {
+ if (prevTransaction == NULL) {
+ /* Transaction at start of queue. Map second transaction to start of queue
+ * as long as more than one transactions. */
+ rmInst->transactionQueue = transaction->nextTransaction;
+ }
+ else {
+ /* Transaction in middle or end of queue. */
+ prevTransaction->nextTransaction = transaction->nextTransaction;
+ }
+ Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));
+ }
+ else {
+ retVal = RM_ERROR_SERVICE_TRANS_DOES_NOT_EXIST;
+ }
return (retVal);
}
+/* FUNCTION PURPOSE: Routes a transaction for processing
+ ***********************************************************************
+ * DESCRIPTION: Routes a received transaction to the appropriate
+ * instance processing routine
+ */
+void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ if (rmInst->instType == Rm_instType_CLIENT) {
+ clientProcess(rmInst, transaction);
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ cdProcess(rmInst, transaction);
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ serverProcess(rmInst, transaction);
+ }
+}
+
/**********************************************************************
- **********APIs visible to other LLDs internally via call table *******************
+ ********************** Application visible APIs **********************
**********************************************************************/
-/**
- * @b Description
- * @n
- * This function is used by LLDs to check initialization permissions for a resource
- *
- * @param[in] resourceData
- * Structure containing resource information such as resource type and the
- * resource value to be checked
- *
- * @retval
- * Success - RM_INIT_PERMISSION_APPROVED
- * @retval
- * Failure - RM_INIT_PERMISSION_DENIED
+/* FUNCTION PURPOSE: Display status of managed resources
+ ***********************************************************************
+ * DESCRIPTION: Prints the status (allocate/free status, as well as
+ * owners) for all resources managed by the RM
+ * instance network. Also, prints the NameServer name
+ * entries. The number of resource range owners is
+ * returned as well. This function is only available on
+ * Server and CD instances.
*/
-Rm_Result Rm_initPermissionChecker (Rm_ResourceInfo *resourceData)
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
{
- switch (resourceData->resourceType)
- {
- case Rm_resource_QMSS_FIRMWARE_PDSP:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceData->res_info.pdspNum]));
-
- case Rm_resource_QMSS_QUEUE:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQueuePerms[resourceData->res_info.queNum]));
-
- case Rm_resource_QMSS_MEMORY_REGION:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssMemRegionPerms[resourceData->res_info.memRegion]));
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocator = NULL;
+ Rm_Owner *owners;
+ Rm_ResourceTree *treeRoot;
+ Rm_ResourceNode *treeNode;
+ int32_t totalResOwners = 0;
+ void *key;
+
+ RM_SS_INST_INV_ENTER_CS(key);
+ RM_SC_INST_INV_ENTER_CS(key);
+
+ if (rmInst->instType != Rm_instType_CLIENT) {
+ Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+ if (rmInst->instType == Rm_instType_SERVER) {
+ Rm_osalLog("Type: Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ Rm_osalLog("Type: Client Delegate\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalLog("Type: Shared Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ Rm_osalLog("Type: Shared Client\n");
+ }
- case Rm_resource_QMSS_LINKING_RAM_CONTROL:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssLinkRamControlPerms));
-
- case Rm_resource_QMSS_LINKING_RAM:
- return (Rm_getLinkRamPermissions (TRUE, &rmGPermsObj.obj.qmssLinkRamPerms[0], resourceData));
-
- case Rm_resource_QMSS_ACCUM_CH:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssAccumChPerms[resourceData->res_info.accumCh]));
+ Rm_osalLog("\nResource Status:\n\n");
+ }
- case Rm_resource_QMSS_QOS_TIMER:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosPdspTimerPerms));
+ if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ /* Transfer control to shared server instance */
+ rmInst = rmInst->u.sharedClient.sharedServerHandle;
+ }
- case Rm_resource_QMSS_QOS_CLUSTER:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosClusterPerms[resourceData->res_info.qosCluster]));
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER) ||
+ (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
+ allocator = rmAllocatorGetAllocatorList(rmHandle);
+
+ if (!allocator) {
+ Rm_osalLog("No resources managed by instance at the moment\n\n");
+ }
+
+ while (allocator) {
+ RM_SS_OBJ_INV(allocator, Rm_Allocator);
+ if (printResources) {
+ Rm_osalLog("Resource: %s\n", allocator->resourceName);
+ }
- case Rm_resource_QMSS_QOS_QUEUE:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.qmssQosQueuePerms[resourceData->res_info.qosQueue]));
-
- case Rm_resource_CPPI_TX_CH:
- {
- Rm_Perms *txChPermsArray = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getInitPermissions(&txChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+ treeRoot = allocator->allocatorRootEntry;
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeInv(treeRoot);
}
-
- case Rm_resource_CPPI_RX_CH:
- {
- Rm_Perms *rxChPermsArray = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getInitPermissions(&rxChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+ RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {
+ if (printResources) {
+ if ((treeNode->base >= 65536) ||
+ ((treeNode->base + treeNode->length - 1) >= 65536)) {
+ /* Print in hex if number is very large */
+ Rm_osalLog(" 0x%08x - 0x%08x ", treeNode->base,
+ treeNode->base + treeNode->length - 1);
+ }
+ else {
+ Rm_osalLog(" %10d - %10d ", treeNode->base,
+ treeNode->base + treeNode->length - 1);
+ }
+ }
+
+ if (treeNode->allocationCount == 0) {
+ if (printResources) {
+ Rm_osalLog("FREE\n");
+ }
+ }
+ else {
+ owners = treeNode->ownerList;
+ while (owners) {
+ RM_SS_OBJ_INV(owners, Rm_Owner);
+ if (printResources) {
+ Rm_osalLog("%s ", owners->instNameNode->name);
+ }
+ totalResOwners++;
+ owners = owners->nextOwner;
+ }
+ if (printResources) {
+ Rm_osalLog("\n");
+ }
+ }
+ }
+ allocator = allocator->nextAllocator;
+ }
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ if (printResources) {
+ rmNameServerPrintObjects((Rm_Handle)rmInst);
}
-
- case Rm_resource_CPPI_RX_FLOW:
- {
- Rm_Perms *flowPermsArray = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getInitPermissions(&flowPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+ }
+ }
+ else {
+ totalResOwners = RM_ERROR_INVALID_RES_STATUS_INSTANCE;
+ }
+
+ RM_SS_INST_WB_EXIT_CS(key);
+ return(totalResOwners);
+}
+
+/* FUNCTION PURPOSE: Display status of a RM instance
+ ***********************************************************************
+ * DESCRIPTION: Prints the current status of various RM instance
+ * properties such as the state of all transactions
+ * in the transaction queue and registered transports
+ */
+void Rm_instanceStatus(Rm_Handle rmHandle)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Transport *transportList = NULL;
+ Rm_Transaction *transactionQ = NULL;
+ void *key;
+
+ RM_SS_INST_INV_ENTER_CS(key);
+ RM_SC_INST_INV_ENTER_CS(key);
+
+ Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+ if (rmInst->instType == Rm_instType_SERVER) {
+ Rm_osalLog("Type: Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ Rm_osalLog("Type: Client Delegate\n");
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT) {
+ Rm_osalLog("Type: Client\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalLog("Type: Shared Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ Rm_osalLog("Type: Shared Client\n");
+
+ Rm_osalLog("\nShared Server Properties:\n");
+ /* Transfer to Shared Server instance to print out transport and
+ * transaction status */
+ rmInst = rmInst->u.sharedClient.sharedServerHandle;
+ Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+ }
+
+ transportList = rmInst->transports;
+ if (transportList) {
+ Rm_osalLog("\nRegistered Transports:\n");
+ while (transportList) {
+ RM_SS_OBJ_INV(transportList, Rm_Transport);
+ if (transportList->remoteInstType == Rm_instType_SERVER) {
+ Rm_osalLog(" Remote instType: Server\n");
}
-
- case Rm_resource_PA_FIRMWARE:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.paFirmwarePerms));
-
- case Rm_resource_PA_LUT:
- return (Rm_getInitPermissions(&rmGPermsObj.obj.paLutPerms[resourceData->res_info.lutEntry]));
-
- default:
- return (RM_INIT_PERMISSION_DENIED);
+ else if (transportList->remoteInstType == Rm_instType_CLIENT_DELEGATE) {
+ Rm_osalLog(" Remote instType: Client Delegate\n");
+ }
+ else {
+ Rm_osalLog(" Remote instType: Client\n");
+ }
+ Rm_osalLog(" appTransportHandle: 0x%08x\n", transportList->appTransportHandle);
+ Rm_osalLog("\n");
+ transportList = transportList->nextTransport;
+ }
}
+
+ transactionQ = rmInst->transactionQueue;
+ if (transactionQ) {
+ Rm_osalLog("\nQueued Service Transactions:\n");
+ while (transactionQ) {
+ RM_SS_OBJ_INV(transactionQ, Rm_Transaction);
+ Rm_osalLog(" Service type: %d\n", transactionQ->type);
+ Rm_osalLog(" Service ID: %d\n", transactionQ->localId);
+ Rm_osalLog(" Service srcInstName %s\n", transactionQ->serviceSrcInstName);
+ Rm_osalLog(" Service state: %d\n", transactionQ->state);
+ Rm_osalLog(" Resource name: %s\n", transactionQ->resourceInfo.name);
+ Rm_osalLog(" Resource base: %d\n", transactionQ->resourceInfo.base);
+ Rm_osalLog(" Resource length: %d\n", transactionQ->resourceInfo.length);
+ Rm_osalLog(" Resource alignment: %d\n", transactionQ->resourceInfo.alignment);
+ Rm_osalLog(" Resource NS name: %s\n", transactionQ->resourceInfo.nameServerName);
+ Rm_osalLog("\n");
+ transactionQ = transactionQ->nextTransaction;
+ }
+ }
+ RM_SS_INST_WB_EXIT_CS(key);
}
-/**
- * @b Description
- * @n
- * This function is used by LLDs to check usage permissions for a resource
- *
- * @param[in] resourceData
- * Structure containing resource information such as resource type and the
- * resource value to be checked
- *
- * @retval
- * Success - RM_INIT_PERMISSION_APPROVED
- * @retval
- * Failure - RM_INIT_PERMISSION_DENIED
+/* FUNCTION PURPOSE: RM instance creation and initialization
+ ***********************************************************************
+ * DESCRIPTION: Returns a new RM instance created and initialized
+ * using the parameters provided via the initCfg
+ * structure.
*/
-Rm_Result Rm_usePermissionChecker (Rm_ResourceInfo *resourceData)
+Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
{
- switch (resourceData->resourceType)
- {
- case Rm_resource_QMSS_FIRMWARE_PDSP:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssPdspFirmwarePerms[resourceData->res_info.pdspNum]));
-
- case Rm_resource_QMSS_QUEUE:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQueuePerms[resourceData->res_info.queNum]));
-
- case Rm_resource_QMSS_MEMORY_REGION:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssMemRegionPerms[resourceData->res_info.memRegion]));
+ Rm_Inst *rmInst = NULL;
+ Rm_Inst *sharedServerInst = NULL;
+ uint32_t policySize;
+ void *globalResourceDtb = NULL;
+ void *linuxResourceDtb = NULL;
+ int addLinux = RM_FALSE;
+ void *key;
+
+ *result = RM_OK;
+
+ if ((initCfg->instName == NULL) ||
+ ((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {
+ *result = RM_ERROR_INVALID_INST_NAME;
+ goto errorExit;
+ }
- case Rm_resource_QMSS_LINKING_RAM_CONTROL:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssLinkRamControlPerms));
-
- case Rm_resource_QMSS_LINKING_RAM:
- return (Rm_getLinkRamPermissions(FALSE, &rmGPermsObj.obj.qmssLinkRamPerms[0], resourceData));
-
- case Rm_resource_QMSS_ACCUM_CH:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssAccumChPerms[resourceData->res_info.accumCh]));
+ if (initCfg->instType >= Rm_instType_LAST) {
+ *result = RM_ERROR_INVALID_INST_TYPE;
+ goto errorExit;
+ }
- case Rm_resource_QMSS_QOS_TIMER:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosPdspTimerPerms));
+ /* Create and initialize instance */
+ rmInst = Rm_osalMalloc(sizeof(*rmInst));
+ memset ((void *)rmInst, 0, sizeof(*rmInst));
+ rmInst->isLocked = RM_FALSE;
+ rmInst->registeredWithDelegateOrServer = RM_FALSE;
+ rmInst->transactionSeqNum = transactionInitSequenceNum();
+
+ rmInst->instType = initCfg->instType;
+ strncpy (rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ if (!initCfg->instCfg.serverCfg.globalResourceList ||
+ !initCfg->instCfg.serverCfg.globalPolicy) {
+ *result = RM_ERROR_INVALID_SERVER_CONFIGURATION;
+ goto errorExit;
+ }
- case Rm_resource_QMSS_QOS_CLUSTER:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosClusterPerms[resourceData->res_info.qosCluster]));
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ /* Shared Server makes copy of policy in shared memory for Shared Clients
+ * on other cores */
+ policySize = fdt_totalsize(initCfg->instCfg.serverCfg.globalPolicy);
+ /* Align policy size to cache boundary */
+ if (policySize % RM_MAX_CACHE_ALIGN) {
+ policySize += (RM_MAX_CACHE_ALIGN - (policySize % RM_MAX_CACHE_ALIGN));
+ }
+ rmInst->u.server.policySize = policySize;
+ rmInst->u.server.globalPolicy = Rm_osalMalloc(rmInst->u.server.policySize);
+ memcpy(rmInst->u.server.globalPolicy, initCfg->instCfg.serverCfg.globalPolicy, rmInst->u.server.policySize);
+ }
+ else {
+ rmInst->u.server.globalPolicy = initCfg->instCfg.serverCfg.globalPolicy;
+ }
- case Rm_resource_QMSS_QOS_QUEUE:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.qmssQosQueuePerms[resourceData->res_info.qosQueue]));
-
- case Rm_resource_CPPI_TX_CH:
- {
- Rm_Perms *txChPermsArray = rmGPermsObj.obj.cppiTxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getUsePermissions(&txChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+ if (initCfg->instCfg.serverCfg.linuxDtb) {
+ linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;
+ addLinux = RM_TRUE;
+ }
+
+ /* Create valid instance list from policy. Must be done prior to parsing
+ * GRL so that Linux resources can be reserved correctly */
+ rmInst->u.server.globalValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+ if (*result == RM_OK) {
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+ }
+
+ if (*result != RM_OK) {
+ if (rmInst->u.server.globalValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
}
-
- case Rm_resource_CPPI_RX_CH:
- {
- Rm_Perms *rxChPermsArray = rmGPermsObj.obj.cppiRxChPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getUsePermissions(&rxChPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+ goto errorExit;
+ }
+ else {
+ rmNameServerInit((Rm_Handle)rmInst);
+
+ globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
+
+ if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {
+ *result = rmPolicyValidatePolicyResourceNames((Rm_Handle)rmInst);
}
-
- case Rm_resource_CPPI_RX_FLOW:
- {
- Rm_Perms *flowPermsArray = rmGPermsObj.obj.cppiFlowPerms.dmaPermPtrs[resourceData->res_info.cpDmaData.dmaNum];
- return (Rm_getUsePermissions(&flowPermsArray[resourceData->res_info.cpDmaData.cppiChNumOrFlowId]));
+
+ if (*result != RM_OK) {
+ rmAllocatorDeleteResources((Rm_Handle)rmInst);
+ rmNameServerDelete((Rm_Handle)rmInst);
+ goto errorExit;
}
-
- case Rm_resource_PA_FIRMWARE:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.paFirmwarePerms));
-
- case Rm_resource_PA_LUT:
- return (Rm_getUsePermissions(&rmGPermsObj.obj.paLutPerms[resourceData->res_info.lutEntry]));
-
- default:
- return (RM_USE_PERMISSION_DENIED);
+ }
}
-}
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (!initCfg->instCfg.cdCfg.cdPolicy) {
+ *result = RM_ERROR_INVALID_CD_CONFIGURATION;
+ goto errorExit;
+ }
+
+ rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
+ rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+ if (*result == RM_OK) {
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+ }
-/* */
+ if (*result != RM_OK) {
+ if (rmInst->u.cd.cdValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+ }
+ goto errorExit;
+ }
-/**********************************************************************
- *********************** Application visible APIs ***************************
- **********************************************************************/
+ rmInst->u.cd.allocators = NULL;
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT) {
+ if (initCfg->instCfg.clientCfg.staticPolicy) {
+ rmInst->u.client.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy;
+ rmInst->u.client.staticValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+ if (*result == RM_OK) {
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+ }
+
+ if (*result != RM_OK) {
+ if (rmInst->u.client.staticValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+ }
+ goto errorExit;
+ }
+ }
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ if (initCfg->instCfg.sharedClientCfg.sharedServerHandle) {
+ rmInst->u.sharedClient.sharedServerHandle = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
+ /* Invalidate the Shared server instance structure on this core to get the latest
+ * instance data. */
+ key = Rm_osalCsEnter();
+ Rm_osalBeginMemAccess((void *)rmInst->u.sharedClient.sharedServerHandle, sizeof(Rm_Inst));
+ sharedServerInst = rmInst->u.sharedClient.sharedServerHandle;
+ if (sharedServerInst->instType != Rm_instType_SHARED_SERVER) {
+ *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+ Rm_osalCsExit(key);
+ goto errorExit;
+ }
+ else {
+ /* Invalidate the policy */
+ Rm_osalBeginMemAccess((void *)sharedServerInst->u.server.globalPolicy,
+ sharedServerInst->u.server.policySize);
+ }
+ Rm_osalCsExit(key);
+ }
+ else {
+ *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+ goto errorExit;
+ }
+ }
-/** @addtogroup RM_LLD_FUNCTION
-@{
-*/
+ if (initCfg->instType == Rm_instType_SHARED_SERVER) {
+ /* Writeback the instance and policy for other cores */
+ Rm_osalEndMemAccess ((void *)rmInst, sizeof(Rm_Inst));
+ Rm_osalEndMemAccess ((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+ }
+ else if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+ /* Create the instance's task blocking mechanism */
+ rmInst->blockHandle = Rm_osalTaskBlockCreate();
+ }
-/**
- * @b Description
- * @n
- * This function initializes the Resource Manager low level driver
- * This function is called once in the system to setup the Resource Manager
- * low level driver by mapping the application defined resource table to internal
- * permission tables. After mapping is complete a global synchronization object
- * is written to sync with slave cores
- *
- * @param[in] rmResourceTable
- * Resource table defined by application. Used to populate internal permission
- * tables.
- *
- * @post
- * RM LLD global permissions are set.
- *
- * @retval
- * Success - RM_OK
- * @retval
- * Failure - RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED
+ return ((Rm_Handle) rmInst);
+errorExit:
+ if (rmInst) {
+ Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+ }
+ return (NULL);
+}
+
+/* FUNCTION PURPOSE: Deletes an RM instance
+ ***********************************************************************
+ * DESCRIPTION: Frees all memory associated with an RM instance
+ * as long as all transports have been unregistered
+ * and the service handle has been closed
*/
-Rm_Result Rm_init (const Rm_Resource *rmResourceTable)
+int32_t Rm_delete(Rm_Handle rmHandle, int ignorePendingServices)
{
- void *key;
- Rm_Result ret_val = RM_ERROR;
-
- /* Check permission structure sizes to make sure they're evenly
- * divisible into a cache line. This generates no object code when
- * optimizer is on. If failes, assert will occur at compile time */
- RM_COMPILE_TIME_SIZE_CHECK((RM_MAX_CACHE_ALIGN/sizeof(Rm_Perms)) * sizeof(Rm_Perms) == RM_MAX_CACHE_ALIGN);
- RM_COMPILE_TIME_SIZE_CHECK((RM_MAX_CACHE_ALIGN/sizeof(Rm_qmssLinkingRamPerms)) * \
- sizeof(Rm_qmssLinkingRamPerms) == RM_MAX_CACHE_ALIGN);
-
- /* Begin Critical Section before accessing shared resources. */
- key = Rm_osalCsEnter ();
-
- /* Initialize the permissions table */
- Rm_permissionTableInit();
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ void *key;
- if (!rmResourceTable)
- {
- /* End Critical Section */
- Rm_osalCsExit (key);
- return RM_ERROR_PERMISSION_TABLE_POPULATION_FAILED;
+ key = Rm_osalCsEnter();
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalBeginMemAccess((void *)rmInst, sizeof(Rm_Inst));
}
- ret_val = Rm_populatePermissionTable(rmResourceTable);
+ if (rmInst->serviceHandle) {
+ return (RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
+ }
+ else if (rmInst->transports) {
+ return (RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
+ }
+ else if (rmInst->transactionQueue && !ignorePendingServices) {
+ return (RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
+ }
- /* End Critical Section */
- Rm_osalCsExit (key);
- return ret_val;
-}
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ rmAllocatorDeleteResources(rmHandle);
+ rmNameServerDelete(rmHandle);
+ rmInst->u.server.allocators = NULL;
-/**
- * @b Description
- * @n
- * This function waits for the Resource Manager master to populate the
- * global permissions table based on a global sync object. Once the
- * global sync object has been written by the master core this function
- * will invalidate all permissions tables. Since the permissions table are
- * static, and will not change through the system up-time, a single
- * invalidation at the start will suffice.
- *
- * This function can be called on all core besides that which called
- * Rm_init. Calling this function on said cores will act as a blocking
- * synchronization point.
- *
- * @retval
- * Success - RM_OK
- * @retval
- * Failure - RM_FAILURE
- */
-Rm_Result Rm_start (void)
-{
- /* Loop until the global sync object signals the permissions table has been
- * populated and valid */
- do
- {
- /* Invalidate the global sync object */
- Rm_osalBeginMemAccess ((void *) &rmGSyncObj, sizeof (Rm_Sync_Obj));
- } while (rmGSyncObj.obj.globalSyncObj != RM_PERMISSION_TABLE_VALID);
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalFree((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+ }
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ rmAllocatorDeleteResources(rmHandle);
+ rmInst->u.cd.allocators = NULL;
+ }
- /* Master core finished populating the permission tables. Must invalidate
- * all tables to see latest permissions */
- Rm_updatePermissionTables();
+ if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+ /* Delete valid instance tree */
+ rmPolicyFreeValidInstTree(rmHandle);
- return RM_OK;
-}
+ /* Delete any transactions */
+ while(rmInst->transactionQueue) {
+ rmTransactionQueueDelete(rmInst, rmInst->transactionQueue->localId);
+ }
-/**
- * @b Description
- * @n
- * This function returns an RM handle to the application to provide
- * to LLDs that want to use the RM.
- *
- * @retval
- * Success - RM Handle. Used an an input parameter for LLD startCfg functions.
- * @retval
- * Failure - NULL
- */
-Rm_Handle Rm_getHandle(void)
-{
- return ((void *) &rmPermissionCheckers);
+ if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+ /* Delete the instance's task blocking mechanism */
+ Rm_osalTaskBlockDelete(rmInst->blockHandle);
+ }
+ else {
+ Rm_osalEndMemAccess((void *)rmInst, sizeof(Rm_Inst));
+ }
+ }
+
+ Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+
+ Rm_osalCsExit(key);
+ return (RM_OK);
}
-/**
- * @b Description
- * @n
- * The function is used to get the version information of the RM LLD.
- *
- * @retval
- * Version Information.
+/* FUNCTION PURPOSE: Returns RM version information
+ ***********************************************************************
*/
-uint32_t Rm_getVersion (void)
+uint32_t Rm_getVersion(void)
{
- return RM_LLD_VERSION_ID;
+ return RM_VERSION_ID;
}
-/**
- * @b Description
- * @n
- * The function is used to get the version string for the RM LLD.
- *
- * @retval
- * Version String.
+/* FUNCTION PURPOSE: Returns RM version string
+ ***********************************************************************
*/
-const char* Rm_getVersionStr (void)
+const char* Rm_getVersionStr(void)
{
- return rmLldVersionStr;
+ return rmVersionStr;
}
-/**
-@}
-*/