]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm_services.c
Added pre-main capabilities, cleaned up services and NameServer modules
[keystone-rtos/rm-lld.git] / src / rm_services.c
index b334f096da247041f6155fb26244f41919705fc8..b1ff067cf5d08203e8b13aafc857c81c545ba4ec 100644 (file)
@@ -46,7 +46,9 @@
 #include <ti/drv/rm/rm_services.h>
 
 /* RM internal API includes */
+#include <ti/drv/rm/include/rm_servicesloc.h>
 #include <ti/drv/rm/include/rm_loc.h>
+#include <ti/drv/rm/include/rm_policyloc.h>
 
 /* RM OSAL layer */
 #include <rm_osal.h>
@@ -61,14 +63,8 @@ void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
     Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
     Rm_Transaction *transaction;
 
-    /* Make sure serviceType is valid and that a callback function has been provided */
-    if ((serviceRequest->type < Rm_service_FIRST) || 
-        (serviceRequest->type > Rm_service_LAST))
-    {
-        serviceResponse->serviceState = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;
-        return;
-    }
-    else if (serviceRequest->callback.serviceCallback == NULL)
+    /* Make sure that a callback function has been provided */
+    if (serviceRequest->callback.serviceCallback == NULL)
     {
         /* The RM Client and Client Delegate use blocking transports to consult with a 
          * high-level RM agent prior to providing a response to the component.  It is 
@@ -91,14 +87,14 @@ void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
     {
         /* Transfer request information into the transaction */
         transaction->type = serviceRequest->type;
-        strcpy(transaction->sourceInstName, rmInst->name);
+        strcpy(transaction->serviceSrcInstName, rmInst->instName);
         transaction->callback.serviceCallback = serviceRequest->callback.serviceCallback;
         transaction->state = RM_SERVICE_PROCESSING;
         strcpy(&(transaction->resourceInfo.name)[0], serviceRequest->resourceName);
         transaction->resourceInfo.base = serviceRequest->resourceBase;
-        transaction->resourceInfo.range = serviceRequest->resourceRange;
+        transaction->resourceInfo.length = serviceRequest->resourceLength;
         transaction->resourceInfo.alignment = serviceRequest->resourceAlignment;
-        strcpy(&(transaction->resourceInfo.nsName)[0], serviceRequest->resourceNsName);
+        strcpy(transaction->resourceInfo.nameServerName, serviceRequest->resourceNsName);
 
         /* Pass the new transaction to the transaction processor */
         Rm_transactionProcessor (rmInst, transaction);
@@ -112,27 +108,27 @@ void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
              * via the provided callback function */
             serviceResponse->serviceId = transaction->localId;
         }
-        else if (serviceResponse->serviceState == RM_SERVICE_APPROVED)
+        else if (serviceResponse->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED)
         {
             /* Service was approved and service was an allocate request the resource
              * data is passed back to the component */
-            if ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
-                (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
-                (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME))
+            if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+                (transaction->type == Rm_service_RESOURCE_GET_BY_NAME))
             {
+                strcpy(serviceResponse->resourceName, transaction->resourceInfo.name);
                 serviceResponse->resourceBase = transaction->resourceInfo.base;
-                serviceResponse->resourceRange = transaction->resourceInfo.range;
+                serviceResponse->resourceLength = transaction->resourceInfo.length;
             }
 
             /* Delete the transaction since a response was received immediately */
             Rm_transactionQueueDelete(rmInst, transaction->localId);
         }
-        else if ((serviceResponse->serviceState >= RM_SERVICE_DENIED_BEGIN) &&
-                 (serviceResponse->serviceState <= RM_SERVICE_DENIED_END))
+        else
         {
             /* The serviceState field will contain information regarding why the 
-             * service was denied.  Just delete the transaction since a response was
-             * received immediately */
+             * service was denied or what error the service encountered.  Just delete
+             * the transaction since a response was received immediately */
             Rm_transactionQueueDelete(rmInst, transaction->localId);
         }
     }
@@ -140,56 +136,80 @@ void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
     return;
 }
 
-/* This function is executed when a RM instance receives a response to one of its requests
- * and the information in the request must be provided to the original requesting component */
-void Rm_serviceResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
-{
-    Rm_ServiceRespInfo serviceResponse;
-
-    /* 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;
-
-    /* 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) ||
-         (transaction->type == Rm_service_RESOURCE_BLOCK_ALLOCATE) ||
-         (transaction->type == Rm_service_RESOURCE_ALLOCATE_BY_NAME)))
-    {
-        serviceResponse.resourceBase = transaction->resourceInfo.base;
-        serviceResponse.resourceRange = transaction->resourceInfo.range;
-    }
-
-    /* Issue the callback to the requesting component with the response information */
-    transaction->callback.serviceCallback(&serviceResponse);
-
-    /* Delete the transaction from the transaction queue */
-    Rm_transactionQueueDelete(rmInst, transaction->localId);
-    return;
-}
-
 /**********************************************************************
  ********************** Application visible APIs **********************
  **********************************************************************/
 
-void Rm_preMainAllocService(Rm_PreMainAllocInfo *preMainAllocInfo,
-                            Rm_ServiceRespInfo *serviceResponse)
+void Rm_servicePreMainRequest(Rm_PreMainReqCfg *reqCfg, Rm_ServiceRespInfo *preMainResp)
 {
+    Rm_PreMainInst       *preMainInst = (Rm_PreMainInst *)reqCfg->rmPreMainHandle;
+    Rm_PolicyCheckCfg     privCheckCfg;
+    Rm_ServicePreMainReq *lastServiceReq;
 
+    preMainResp->serviceState = RM_SERVICE_PROCESSING;
+    preMainResp->serviceId = 0;
+
+    if ((reqCfg->request->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+        (reqCfg->request->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+        (reqCfg->request->resourceBase == RM_RESOURCE_BASE_UNSPECIFIED)) {
+        /* Check request against startup policy */
+        memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+
+        if (reqCfg->request->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+            privCheckCfg.type = Rm_policyCheck_INIT;
+        }
+        else {
+            privCheckCfg.type = Rm_policyCheck_USE;
+        }
+        privCheckCfg.policyDtb = preMainInst->startupDtb;
+        privCheckCfg.validInstNode = Rm_policyGetValidInstNode(preMainInst->validInstTree, 
+                                                                preMainInst->instName);
+        privCheckCfg.resourceOffset = Rm_policyGetResourceOffset(preMainInst->startupDtb,
+                                                                  reqCfg->request->resourceName);
+        privCheckCfg.resourceBase = reqCfg->request->resourceBase;
+        privCheckCfg.resourceLength = reqCfg->request->resourceLength;
+
+        if (Rm_policyCheckPrivilege(&privCheckCfg, &preMainResp->serviceState)) {
+            preMainResp->serviceState = RM_SERVICE_APPROVED_AND_COMPLETED;
+        }
+        else if (preMainResp->serviceState == RM_SERVICE_PROCESSING) {
+            /* Privilege check returned FALSE without error */
+            preMainResp->serviceState = RM_SERVICE_DENIED_POLICY_DENIED_PREMAIN_ALLOCATION;
+        }
+    }
+    else {
+        preMainResp->serviceState = RM_SERVICE_DENIED_INVALID_PREMAIN_REQUEST;
+    }
+
+    /* Store the request for validation after post-main instance
+     * transports have been established */
+    if (preMainResp->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) {
+        /* Store the request for validation after all instances have been setup post-main */
+        lastServiceReq = preMainInst->preMainReqList;
+        while(lastServiceReq) {
+            lastServiceReq = lastServiceReq->nextPreMainReq;
+        }
+        lastServiceReq = (Rm_ServicePreMainReq *) Rm_osalMalloc (sizeof(Rm_ServicePreMainReq));
+        lastServiceReq->nextPreMainReq = NULL;
+        lastServiceReq->preMainReq = (Rm_ServiceReqInfo *) Rm_osalMalloc(sizeof(Rm_ServiceReqInfo));
+        memcpy((void *)lastServiceReq->preMainReq, (void *)reqCfg->request, sizeof(Rm_ServiceReqInfo));
+
+        /* Fill out response */
+        preMainResp->resourceBase = reqCfg->request->resourceBase;
+        preMainResp->resourceLength = reqCfg->request->resourceLength;
+        strcpy(preMainResp->resourceName, reqCfg->request->resourceName);
+        preMainResp->serviceId = ++preMainInst->requestCount;
+    }
 }
 
-Rm_ServicePort *Rm_getServicePort(Rm_Handle rmHandle)
+Rm_ServicePort *Rm_serviceGetPort(Rm_Handle rmHandle)
 {
     Rm_ServicePort *newServicePort = NULL;
     
     /* Create a new service handle for the specified RM instance */
     
     /* Get memory for a new service port from local memory */
-    newServicePort = Rm_osalMalloc (sizeof(Rm_ServicePort), false);
+    newServicePort = Rm_osalMalloc (sizeof(Rm_ServicePort));
 
     /* Return NULL immediately if malloc returned NULL */
     if (newServicePort == NULL)