885fd96380b8999b5d1a07159633cd4758afae73
1 /**
2 * @file rmservices.c
3 *
4 * @brief
5 * This is the Resource Manager services source.
6 *
7 * \par
8 * ============================================================================
9 * @n (C) Copyright 2012-2013, Texas Instruments, Inc.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the
21 * distribution.
22 *
23 * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * \par
40 */
42 /* Standard includes */
43 #include <string.h>
45 /* RM external API includes */
46 #include <ti/drv/rm/rm_services.h>
48 /* RM internal API includes */
49 #include <ti/drv/rm/include/rm_servicesloc.h>
50 #include <ti/drv/rm/include/rm_loc.h>
51 #include <ti/drv/rm/include/rm_policyloc.h>
53 /* RM OSAL layer */
54 #include <rm_osal.h>
56 /**********************************************************************
57 ********************** Application visible APIs **********************
58 **********************************************************************/
60 void Rm_serviceHandler (void *rmHandle, Rm_ServiceReqInfo *serviceRequest,
61 Rm_ServiceRespInfo *serviceResponse)
62 {
63 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
64 Rm_Transaction *transaction;
65 Rm_PolicyCheckCfg privCheckCfg;
66 Rm_ServiceStaticReq *lastStaticReq;
68 if (serviceRequest->reqType == Rm_reqType_STATIC) {
69 serviceResponse->serviceState = RM_SERVICE_PROCESSING;
71 if ((serviceRequest->serviceType == Rm_service_RESOURCE_ALLOCATE_INIT) ||
72 (serviceRequest->serviceType == Rm_service_RESOURCE_ALLOCATE_USE) ||
73 (serviceRequest->resourceBase != RM_RESOURCE_BASE_UNSPECIFIED)) {
74 /* Check request against startup policy */
75 memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
77 if (serviceRequest->serviceType == Rm_service_RESOURCE_ALLOCATE_INIT) {
78 privCheckCfg.type = Rm_policyCheck_INIT;
79 }
80 else {
81 privCheckCfg.type = Rm_policyCheck_USE;
82 }
83 privCheckCfg.policyDtb = rmInst->staticInfo.staticPolicy;
84 privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmInst->staticInfo.staticValidInstTree,
85 rmInst->instName);
86 privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(rmInst->staticInfo.staticPolicy,
87 serviceRequest->resourceName);
88 privCheckCfg.resourceBase = serviceRequest->resourceBase;
89 privCheckCfg.resourceLength = serviceRequest->resourceLength;
91 if (rmPolicyCheckPrivilege(&privCheckCfg, &serviceResponse->serviceState)) {
92 serviceResponse->serviceState = RM_SERVICE_APPROVED_AND_COMPLETED;
93 }
94 else if (serviceResponse->serviceState == RM_SERVICE_PROCESSING) {
95 /* Privilege check returned FALSE without error */
96 serviceResponse->serviceState = RM_SERVICE_DENIED_POLICY_DENIED_STATIC_ALLOCATION;
97 }
98 }
99 else {
100 serviceResponse->serviceState = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
101 }
103 /* Store request for validation after instance transports have been established */
104 if (serviceResponse->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) {
105 lastStaticReq = rmInst->staticInfo.staticReqList;
106 while(lastStaticReq) {
107 lastStaticReq = lastStaticReq->nextStaticReq;
108 }
109 lastStaticReq = (Rm_ServiceStaticReq *) Rm_osalMalloc (sizeof(Rm_ServiceStaticReq));
110 lastStaticReq->nextStaticReq = NULL;
111 lastStaticReq->staticReq = (Rm_ServiceReqInfo *) Rm_osalMalloc(sizeof(Rm_ServiceReqInfo));
112 memcpy((void *)lastStaticReq->staticReq, (void *)serviceRequest, sizeof(Rm_ServiceReqInfo));
114 /* Fill out response */
115 serviceResponse->resourceBase = serviceRequest->resourceBase;
116 serviceResponse->resourceLength = serviceRequest->resourceLength;
117 strncpy(serviceResponse->resourceName, serviceRequest->resourceName, RM_NAME_MAX_CHARS);
118 serviceResponse->serviceId = rmTransactionGetSequenceNum(rmInst);
119 }
120 }
121 else if (serviceRequest->reqType == Rm_reqType_DYNAMIC) {
122 if (serviceRequest->callback.serviceCallback == NULL) {
123 serviceResponse->serviceState = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;
124 return;
125 }
127 if (serviceRequest->serviceType >= Rm_service_LAST) {
128 serviceResponse->serviceState = RM_SERVICE_ERROR_INVALID_SERVICE_TYPE;
129 return;
130 }
132 transaction = rmTransactionQueueAdd(rmInst);
133 if (transaction) {
134 transaction->type = serviceRequest->serviceType;
135 strncpy(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
136 transaction->callback.serviceCallback = serviceRequest->callback.serviceCallback;
137 transaction->state = RM_SERVICE_PROCESSING;
138 if (serviceRequest->resourceName) {
139 strncpy(transaction->resourceInfo.name, serviceRequest->resourceName, RM_NAME_MAX_CHARS);
140 }
141 transaction->resourceInfo.base = serviceRequest->resourceBase;
142 transaction->resourceInfo.length = serviceRequest->resourceLength;
143 transaction->resourceInfo.alignment = serviceRequest->resourceAlignment;
144 if (serviceRequest->resourceNsName) {
145 strncpy(transaction->resourceInfo.nameServerName, serviceRequest->resourceNsName, RM_NAME_MAX_CHARS);
146 }
148 rmTransactionProcessor (rmInst, transaction);
149 serviceResponse->serviceState = transaction->state;
150 if (serviceResponse->serviceState == RM_SERVICE_PROCESSING) {
151 /* Service still being processed. Provide transaction ID
152 * back to component so it can sort service responses received
153 * via callback function */
154 serviceResponse->serviceId = transaction->localId;
155 }
156 else if (serviceResponse->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) {
157 if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
158 (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
159 (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)) {
160 strncpy(serviceResponse->resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
161 serviceResponse->resourceBase = transaction->resourceInfo.base;
162 serviceResponse->resourceLength = transaction->resourceInfo.length;
163 }
164 rmTransactionQueueDelete(rmInst, transaction->localId);
165 }
166 else {
167 rmTransactionQueueDelete(rmInst, transaction->localId);
168 }
169 }
170 else {
171 serviceResponse->serviceState = RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE;
172 }
173 }
174 return;
175 }
177 void Rm_serviceValidateStaticRequests(Rm_Handle rmHandle, Rm_ServiceCallback validateCallback)
178 {
179 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
180 Rm_ServiceReqInfo *staticRequest;
181 Rm_ServiceStaticReq *nextServiceReq;
182 Rm_Transaction *transaction;
183 Rm_ServiceRespInfo serviceResponse;
185 if (validateCallback.serviceCallback == NULL) {
186 serviceResponse->serviceState = RM_SERVICE_ERROR_CALLBACK_NOT_PROVIDED;
187 return;
188 }
190 /* Validate static requests against the global policyDtb */
191 while(rmInst->staticInfo.staticReqList) {
192 transaction = rmTransactionQueueAdd(rmInst);
193 if (transaction) {
194 staticRequest = rmInst->staticInfo.staticReqList->staticReq;
195 transaction->type = staticRequest->serviceType;
196 strncpy(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
197 transaction->callback.serviceCallback = validateCallback.serviceCallback;
198 transaction->state = RM_SERVICE_PROCESSING;
199 if (staticRequest->resourceName) {
200 strncpy(transaction->resourceInfo.name, staticRequest->resourceName, RM_NAME_MAX_CHARS);
201 }
202 transaction->resourceInfo.base = staticRequest->resourceBase;
203 transaction->resourceInfo.length = staticRequest->resourceLength;
204 transaction->resourceInfo.alignment = staticRequest->resourceAlignment;
205 if (staticRequest->resourceNsName) {
206 strncpy(transaction->resourceInfo.nameServerName, staticRequest->resourceNsName, RM_NAME_MAX_CHARS);
207 }
209 rmTransactionProcessor (rmInst, transaction);
210 memset((void *)&serviceResponse, 0, sizeof(Rm_ServiceRespInfo));
211 serviceResponse->serviceState = transaction->state;
212 if (serviceResponse->serviceState == RM_SERVICE_PROCESSING) {
213 /* Service still being processed. Provide transaction ID
214 * back to component so it can sort service responses received
215 * via callback function */
216 serviceResponse->serviceId = transaction->localId;
217 }
218 else if (serviceResponse->serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) {
219 if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
220 (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
221 (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)) {
222 strncpy(serviceResponse->resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
223 serviceResponse->resourceBase = transaction->resourceInfo.base;
224 serviceResponse->resourceLength = transaction->resourceInfo.length;
225 }
226 rmTransactionQueueDelete(rmInst, transaction->localId);
227 }
228 else {
229 rmTransactionQueueDelete(rmInst, transaction->localId);
230 }
231 /* Issue response via callback since function won't return until all static requests have
232 * been handled */
233 validateCallback->serviceCallback(&serviceResponse);
234 }
235 else {
236 serviceResponse->serviceState = RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE;
237 return;
238 }
239 /* Free memory associated with static requests sent for validation */
240 nextServiceReq = rmInst->staticInfo.staticReqList->nextStaticReq;
241 Rm_osalFree((void *)rmInst->staticInfo.staticReqList->staticReq, sizeof(Rm_ServiceReqInfo));
242 Rm_osalFree((void *)rmInst->staticInfo.staticReqList, sizeof(Rm_ServiceStaticReq));
243 rmInst->staticInfo.staticReqList = nextServiceReq;
244 }
245 }
247 Rm_ServiceHandle *Rm_serviceOpenHandle(Rm_Handle rmHandle, int32_t *result)
248 {
249 Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
250 Rm_ServiceHandle *newServiceHandle = NULL;
252 *result = RM_INIT_OK;
254 if (rmInst->serviceHandle == NULL) {
255 newServiceHandle = Rm_osalMalloc (sizeof(Rm_ServiceHandle));
256 if (newServiceHandle) {
257 newServiceHandle->rmHandle = rmHandle;
258 newServiceHandle->Rm_serviceHandler = Rm_serviceHandler;
259 rmInst->serviceHandle = newServiceHandle;
260 }
261 else {
262 *result = RM_INIT_ERROR_SERVICE_HANDLE_MEMORY_ALLOC_FAILED;
263 }
264 }
265 else {
266 *result = RM_INIT_ERROR_SERVICE_HANDLE_ALREADY_ALLOCATED;
267 }
268 return (newServiceHandle);
269 }
271 int32_t Rm_serviceCloseHandle(Rm_ServiceHandle *rmServiceHandle)
272 {
273 Rm_Inst *rmInst = (Rm_Inst *)rmServiceHandle->rmHandle;
274 int32_t retVal = RM_INIT_OK;
276 if (rmInst->serviceHandle) {
277 Rm_osalFree((void *)rmServiceHandle, sizeof(Rm_ServiceHandle));
278 rmInst->serviceHandle = NULL;
279 }
280 else {
281 retVal = RM_INIT_ERROR_SERVICE_HANDLE_ALREADY_CLOSED_FOR_INSTANCE;
282 }
283 return(retVal);
284 }