/******************************************************************************* * This function calls the initialisation routine in the descriptor exported by * a runtime service. Once a descriptor has been validated, its start & end * owning entity numbers and the call type are combined to form a unique oen. * The unique oen is used as an index into the 'rt_svc_descs_indices' array. * The index of the runtime service descriptor is stored at this index. ******************************************************************************/ void runtime_svc_init(void) { int rc = 0; unsigned int index, start_idx, end_idx; /* Assert the number of descriptors detected are less than maximum indices */ assert((RT_SVC_DESCS_END >= RT_SVC_DESCS_START) && (RT_SVC_DECS_NUM < MAX_RT_SVCS)); /* If no runtime services are implemented then simply bail out */ if (RT_SVC_DECS_NUM == 0) return; /* Initialise internal variables to invalid state */ memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices)); rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START; for (index = 0; index < RT_SVC_DECS_NUM; index++) { rt_svc_desc_t *service = &rt_svc_descs[index]; /* * An invalid descriptor is an error condition since it is * difficult to predict the system behaviour in the absence * of this service. */ rc = validate_rt_svc_desc(service); if (rc) { ERROR("Invalid runtime service descriptor %p\n", (void *) service); panic(); } /* * The runtime service may have separate rt_svc_desc_t * for its fast smc and yielding smc. Since the service itself * need to be initialized only once, only one of them will have * an initialisation routine defined. Call the initialisation * routine for this runtime service, if it is defined. */ if (service->init) { rc = service->init(); if (rc) { ERROR("Error initializing runtime service %s\n", service->name); continue; } } /* * Fill the indices corresponding to the start and end * owning entity numbers with the index of the * descriptor which will handle the SMCs for this owning * entity range. */ start_idx = get_unique_oen(rt_svc_descs[index].start_oen, service->call_type); assert(start_idx < MAX_RT_SVCS); end_idx = get_unique_oen(rt_svc_descs[index].end_oen, service->call_type); assert(end_idx < MAX_RT_SVCS); for (; start_idx <= end_idx; start_idx++) rt_svc_descs_indices[start_idx] = index; } }
/******************************************************************************* * This function calls the initialisation routine in the descriptor exported by * a runtime service. Once a descriptor has been validated, its start & end * owning entity numbers and the call type are combined to form a unique oen. * The unique oen is used as an index into the 'rt_svc_descs_indices' array. * The index of the runtime service descriptor is stored at this index. ******************************************************************************/ void runtime_svc_init(void) { int32_t rc = 0; uint32_t index, start_idx, end_idx; uint64_t rt_svc_descs_num; /* If no runtime services are implemented then simply bail out */ rt_svc_descs_num = RT_SVC_DESCS_END - RT_SVC_DESCS_START; rt_svc_descs_num /= sizeof(rt_svc_desc_t); if (rt_svc_descs_num == 0) return; /* Initialise internal variables to invalid state */ memset(rt_svc_descs_indices, -1, sizeof(rt_svc_descs_indices)); rt_svc_descs = (rt_svc_desc_t *) RT_SVC_DESCS_START; for (index = 0; index < rt_svc_descs_num; index++) { /* * An invalid descriptor is an error condition since it is * difficult to predict the system behaviour in the absence * of this service. */ rc = validate_rt_svc_desc(&rt_svc_descs[index]); if (rc) { ERROR("Invalid runtime service descriptor 0x%lx (%s)\n", (uintptr_t) &rt_svc_descs[index], rt_svc_descs[index].name); goto error; } /* * The runtime service may have seperate rt_svc_desc_t * for its fast smc and standard smc. Since the service itself * need to be initialized only once, only one of them will have * an initialisation routine defined. Call the initialisation * routine for this runtime service, if it is defined. */ if (rt_svc_descs[index].init) { rc = rt_svc_descs[index].init(); if (rc) { ERROR("Error initializing runtime service %s\n", rt_svc_descs[index].name); continue; } } /* * Fill the indices corresponding to the start and end * owning entity numbers with the index of the * descriptor which will handle the SMCs for this owning * entity range. */ start_idx = get_unique_oen(rt_svc_descs[index].start_oen, rt_svc_descs[index].call_type); end_idx = get_unique_oen(rt_svc_descs[index].end_oen, rt_svc_descs[index].call_type); for (; start_idx <= end_idx; start_idx++) rt_svc_descs_indices[start_idx] = index; } return; error: panic(); }