eEsifError esif_fpc_load( EsifFpcPtr fpcPtr, EsifDspPtr dspPtr ) { eEsifError rc = ESIF_OK; EsifFpcDomainPtr domainPtr; EsifFpcPrimitivePtr primitivePtr; EsifFpcAlgorithmPtr algoPtr; EsifFpcEventPtr eventPtr; unsigned long offset = 0; UInt8 *basePtr = (UInt8 *)fpcPtr; UInt32 numPrim = 0; UInt32 i; UInt32 j; if ((fpcPtr == NULL) || (dspPtr == NULL)) { ESIF_TRACE_ERROR("The fpc pointer or dsp pointer is NULL\n"); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } if (fpcPtr->number_of_domains < 1) { ESIF_TRACE_WARN("No domain error, number_of_domain = %d (less than 1)\n", fpcPtr->number_of_domains); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } dspPtr->domain_count = &fpcPtr->number_of_domains; /* Allocate Hash and List. Hash Size 31 Is Hard-Coded And Chosen By DSP Compiler */ dspPtr->ht_ptr = esif_ht_create(ESIF_DSP_HASHTABLE_SIZE); dspPtr->algo_ptr = esif_link_list_create(); dspPtr->domain_ptr = esif_link_list_create(); dspPtr->cap_ptr = esif_link_list_create(); dspPtr->evt_ptr = esif_link_list_create(); if (!dspPtr->ht_ptr || !dspPtr->algo_ptr || !dspPtr->domain_ptr || !dspPtr->cap_ptr || !dspPtr->evt_ptr) { ESIF_TRACE_ERROR("Fail to allocate linked list or hash table\n"); rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("<fpc @ %p> FPC name '%s' ver %x,%x desc '%s' size %u num_domains %d num_algorithms %d num_events %d", fpcPtr, fpcPtr->header.name, fpcPtr->header.ver_major, fpcPtr->header.ver_minor, fpcPtr->header.description, fpcPtr->size, fpcPtr->number_of_domains, fpcPtr->number_of_algorithms, fpcPtr->number_of_events); /* First Domain, Ok To Have Zero Primitive Of A Domain */ domainPtr = (EsifFpcDomainPtr)(fpcPtr + 1); for (i = 0; i < fpcPtr->number_of_domains; i++) { offset = (unsigned long)((UInt8 *)domainPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Domain[%d] name %s size %d num_of_primitives %d " "num_of_capabilites %u (0x%x)", offset, i, domainPtr->descriptor.name, domainPtr->size, domainPtr->number_of_primitives, domainPtr->capability_for_domain.number_of_capability_flags, domainPtr->capability_for_domain.capability_flags); /* Insert Domain Into Linked List */ rc = dspPtr->insert_domain(dspPtr, domainPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert domain #%d\n", i); goto exit; } /* Capability */ for (j = 0; j < domainPtr->capability_for_domain.number_of_capability_flags; j++) { offset = (unsigned long)(((UInt8 *)&domainPtr->capability_for_domain) - basePtr); ESIF_TRACE_DEBUG("<%04lu> Capability[%d] 0x%x", offset, j, domainPtr->capability_for_domain.capability_mask[j]); } /* First Primtive */ primitivePtr = (EsifFpcPrimitivePtr)(domainPtr + 1); for (j = 0; j < domainPtr->number_of_primitives; j++, numPrim++) { offset = (unsigned long)(((UInt8 *)primitivePtr) - basePtr); ESIF_TRACE_DEBUG("<%04lu> Primitive[%03d]: size %3d tuple_id <%03u %03u %03u> " "operation %u(%s) req_type %u(%s) res_type %u(%s) num_actions %u", offset, j, primitivePtr->size, primitivePtr->tuple.id, primitivePtr->tuple.domain, primitivePtr->tuple.instance, primitivePtr->operation, esif_primitive_opcode_str(primitivePtr->operation), primitivePtr->request_type, esif_data_type_str(primitivePtr->request_type), primitivePtr->result_type, esif_data_type_str(primitivePtr->result_type), primitivePtr->num_actions); /* Insert Primitive Into Hash */ rc = dspPtr->insert_primitive(dspPtr, primitivePtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert primitive (id = %d)\n", primitivePtr->tuple.id); goto exit; } /* Next Primitive */ primitivePtr = (EsifFpcPrimitivePtr)((UInt8 *)primitivePtr + primitivePtr->size); } /* Next Domain */ domainPtr = (EsifFpcDomainPtr)((UInt8 *)domainPtr + domainPtr->size); } /* First Algorithm (Laid After The Last Domain) */ algoPtr = (EsifFpcAlgorithmPtr)domainPtr; for (i = 0; i < fpcPtr->number_of_algorithms; i++) { offset = (unsigned long)((UInt8 *)algoPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Algorithm[%03d]: action_type %u(%s) temp_xform %u " "tempC1 %u percent_xform %u size %u", offset, i, algoPtr->action_type, esif_action_type_str(algoPtr->action_type), algoPtr->temp_xform, algoPtr->tempC1, algoPtr->percent_xform, algoPtr->size); /* Insert Algorithm Into Linked List */ rc = dspPtr->insert_algorithm(dspPtr, algoPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert algorithm - %s\n", esif_action_type_str(algoPtr->action_type)); goto exit; } /* Next Algorithm */ algoPtr = (EsifFpcAlgorithmPtr)(algoPtr + 1); } /* First Event (Laid After The Last Algorithm) */ eventPtr = (EsifFpcEventPtr)algoPtr; for (i = 0; i < fpcPtr->number_of_events; i++) { offset = (unsigned long)((UInt8 *)eventPtr - basePtr); ESIF_TRACE_DEBUG("<%04lu> Event [%03d] type %s(%d)\n", offset, i, esif_event_type_str(eventPtr->esif_event), eventPtr->esif_event); /* Insert Algorithm Into Linked List */ rc = dspPtr->insert_event(dspPtr, eventPtr); if (ESIF_OK != rc) { ESIF_TRACE_ERROR("Fail to insert event - %s\n", esif_event_type_str(eventPtr->esif_event)); goto exit; } /* Next Event */ eventPtr = (EsifFpcEventPtr)(eventPtr + 1); } exit: if (fpcPtr != NULL) { ESIF_TRACE_DEBUG("%u domains, %u primitives and %u algorithms %u events inserted! status %s", fpcPtr->number_of_domains, numPrim, fpcPtr->number_of_algorithms, fpcPtr->number_of_events, esif_rc_str(rc)); } return rc; }
/* Assumes hash table has already been created */ static enum esif_rc esif_cpc_to_dsp(struct esif_lp_dsp *dsp_ptr) { struct esif_lp_cpc *cpc_ptr = dsp_ptr->cpc_ptr; struct esif_cpc_primitive *primitive_ptr = NULL; struct esif_cpc_algorithm *algorithm_ptr; struct esif_cpc_event *event_ptr; struct domain *domain_ptr; enum esif_rc rc = ESIF_OK; u32 i; u8 *base_ptr; u64 offset; base_ptr = (u8 *)cpc_ptr; dsp_ptr->code_ptr = (esif_string)cpc_ptr->header.code; dsp_ptr->domain_count_ptr = (u8 *)&cpc_ptr->number_of_domains; dsp_ptr->ver_major_ptr = (u8 *)&cpc_ptr->header.ver_major; dsp_ptr->ver_minor_ptr = (u8 *)&cpc_ptr->header.ver_minor; dsp_ptr->capability_ptr = (esif_flags_t *) &cpc_ptr->header.cpc.capability; ESIF_TRACE_DYN_CPC( "%s: <cpc @ %p> CPC name '%s' size %d num_primitives %u, num_algorithms %u, num_domains %u\n", ESIF_FUNC, cpc_ptr, cpc_ptr->header.code, cpc_ptr->size, cpc_ptr->number_of_basic_primitives, cpc_ptr->number_of_algorithms, *dsp_ptr->domain_count_ptr); /* 1. Insert All Primitives Into Hash */ /* Locate First Primitive Laid After CPC Struct */ primitive_ptr = (struct esif_cpc_primitive *)((u8 *)cpc_ptr + sizeof(struct esif_lp_cpc)); for (i = 0; i < cpc_ptr->number_of_basic_primitives; i++) { offset = (u64)((u8 *)primitive_ptr - base_ptr); ESIF_TRACE_DYN_CPC( "<%06llu> Primitive[%03d]: size %03d tuple <%03u %03u %03u> operation %u(%s) num_actions %d\n", offset, i, primitive_ptr->size, primitive_ptr->tuple.id, primitive_ptr->tuple.domain, primitive_ptr->tuple.instance, primitive_ptr->operation, esif_primitive_opcode_str( (enum esif_primitive_opcode) primitive_ptr->operation), primitive_ptr->number_of_actions); /* Must Be ESIF Primitive Not CPC Primitive Format */ rc = dsp_ptr->insert_primitive(dsp_ptr, primitive_ptr); if (ESIF_OK != rc) goto exit; /* Primitives Have Varaible Length Due To Number Of Actions */ primitive_ptr = (struct esif_cpc_primitive *)((u8 *)primitive_ptr + primitive_ptr->size); } /* 2. Insert All Algorithms Into Linked List */ /* First Algorithm Laid After the Last Primitive */ algorithm_ptr = (struct esif_cpc_algorithm *)primitive_ptr; for (i = 0; i < cpc_ptr->number_of_algorithms; i++) { offset = (u64)((u8 *)algorithm_ptr - base_ptr); ESIF_TRACE_DYN_CPC("<%06llu> Algorithm[%3d]: action_type %u(%s) temp_xform %u tempC1 %u tempC2 %u size %u\n", offset, i, algorithm_ptr->action_type, esif_action_type_str( (enum esif_action_type)algorithm_ptr ->action_type), algorithm_ptr->temp_xform, algorithm_ptr->tempC1, algorithm_ptr->tempC2, algorithm_ptr->size); rc = dsp_ptr->insert_algorithm(dsp_ptr, algorithm_ptr); if (ESIF_OK != rc) goto exit; /* Next Algorithm. Algorithms Are Fix-Sized */ algorithm_ptr++; } /* Truncate any unsupported domain conunts */ if (*dsp_ptr->domain_count_ptr > ESIF_DOMAIN_MAX) *dsp_ptr->domain_count_ptr = ESIF_DOMAIN_MAX; /* Domains are contained in an array one entry per domain */ if (*dsp_ptr->domain_count_ptr > 0) { dsp_ptr->domains_ptr = (struct domain *)algorithm_ptr; ESIF_TRACE_DYN_CPC("%s: First DWORD %08x\n", ESIF_FUNC, *(u32 *)dsp_ptr->domains_ptr); } /* Domain */ domain_ptr = (struct domain *)algorithm_ptr; for (i = 0; i < cpc_ptr->number_of_domains; i++) { offset = (u64)((u8 *)domain_ptr - base_ptr); ESIF_TRACE_DYN_CPC("<%06llu> domain size %d name %s\n", offset, domain_ptr->size, domain_ptr->descriptor.name); domain_ptr = (struct domain *)((u8 *)domain_ptr + domain_ptr->size); } /* Event */ event_ptr = (struct esif_cpc_event *)domain_ptr; for (i = 0; i < cpc_ptr->number_of_events; i++) { offset = (u64)((u8 *)event_ptr - base_ptr); ESIF_TRACE_DYN_CPC( "<%06llu> name %s notify %x esif_event %s(%d) esif_event_group TBD(%d)\n", offset, event_ptr->name, event_ptr->event_key[i], esif_event_type_str(event_ptr->esif_event), event_ptr->esif_event, event_ptr->esif_group); /* Todo Handle Other Types Here */ if (ESIF_EVENT_GROUP_ACPI == event_ptr->esif_group) { rc = dsp_ptr->insert_event(dsp_ptr, event_ptr); if (ESIF_OK != rc) goto exit; } /* Next Event. Events Are Fix-Sized */ event_ptr++; } exit: ESIF_TRACE_DYN_CPC( "%s: %u primitives, %u algorithms and %u events inserted, status %s! %u domain found\n", ESIF_FUNC, cpc_ptr->number_of_basic_primitives, cpc_ptr->number_of_algorithms, cpc_ptr->number_of_events, esif_rc_str(rc), cpc_ptr->number_of_domains); return rc; }