eEsifError EsifUpManagerRegisterParticipantsWithApp(EsifAppPtr aAppPtr) { eEsifError rc = ESIF_OK; UInt8 i = 0; if (NULL == aAppPtr) { ESIF_TRACE_ERROR("Esif app pointer is NULL\n"); return ESIF_E_PARAMETER_IS_NULL; } esif_ccb_read_lock(&g_uppMgr.fLock); /* Skip 0 ESIF treats this as a participant no one else does :) */ for (i = 1; i < MAX_PARTICIPANT_ENTRY; i++) { EsifUpPtr up_ptr = g_uppMgr.fEntries[i].fUpPtr; if ((NULL != up_ptr) && (g_uppMgr.fEntries[i].fState > ESIF_PM_PARTICIPANT_REMOVED)) { rc = EsifAppCreateParticipant(aAppPtr, up_ptr); if (ESIF_OK != rc) { break; } } } esif_ccb_read_unlock(&g_uppMgr.fLock); ESIF_TRACE_INFO("Register participants with App, status = %s\n", esif_rc_str(rc)); return rc; }
static eEsifError DestroyDomain( EsifAppPtr appPtr, AppParticipantDataMapPtr participantDataMapPtr, AppDomainDataMapPtr domainDataMapPtr ) { eEsifError rc = ESIF_OK; rc = appPtr->fInterface.fDomainDestroyFuncPtr( appPtr->fHandle, participantDataMapPtr->fAppParticipantHandle, domainDataMapPtr->fAppDomainHandle); if (ESIF_OK == rc) { ESIF_TRACE_DEBUG("DomainMap(%u) Esif 0x%p UnMapped From Handle 0x%p\n", domainDataMapPtr->fAppDomainId, domainDataMapPtr->fAppDomainDataPtr, domainDataMapPtr->fAppDomainHandle); } else { ESIF_TRACE_DEBUG("DomainMap(%u) Esif UnMapping Error %s(%d)\n", domainDataMapPtr->fAppDomainId, esif_rc_str(rc), rc); } memset(domainDataMapPtr, 0, sizeof(*domainDataMapPtr)); return rc; }
static eEsifError EsifApp_RegisterParticipantsWithApp( EsifAppPtr self ) { eEsifError rc = ESIF_OK; EsifUpPtr upPtr = NULL; UInt8 i = 0; ESIF_ASSERT(self != NULL); /* Skip 0 ESIF treats this as a participant no one else does :) */ /* TODO: Use iterator here. This function shouldn't know the number of participants */ for (i = 1; i < MAX_PARTICIPANT_ENTRY; i++) { upPtr = EsifUpPm_GetAvailableParticipantByInstance(i); if (NULL == upPtr) { continue; } rc = EsifAppCreateParticipant(self, upPtr); EsifUp_PutRef(upPtr); if (ESIF_OK != rc) { break; } } ESIF_TRACE_INFO("Register participants with App, status = %s\n", esif_rc_str(rc)); return rc; }
enum esif_rc esif_get_action_systemio( const struct esif_lp *lp_ptr, const struct esif_lp_primitive *primitive_ptr, const struct esif_lp_action *action_ptr, struct esif_data *req_data_ptr, struct esif_data *rsp_data_ptr ) { enum esif_rc rc = ESIF_OK; u32 val = 1234; UNREFERENCED_PARAMETER(lp_ptr); UNREFERENCED_PARAMETER(primitive_ptr); UNREFERENCED_PARAMETER(action_ptr); UNREFERENCED_PARAMETER(req_data_ptr); if (NULL == rsp_data_ptr) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } ESIF_TRACE_DYN_GET("val = %d\n", val); switch (rsp_data_ptr->type) { case ESIF_DATA_UINT8: rsp_data_ptr->data_len = sizeof(u8); if (rsp_data_ptr->buf_len >= sizeof(u8)) *((u8 *)rsp_data_ptr->buf_ptr) = (u8)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT16: rsp_data_ptr->data_len = sizeof(u16); if (rsp_data_ptr->buf_len >= sizeof(u16)) *((u16 *)rsp_data_ptr->buf_ptr) = (u16)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT32: rsp_data_ptr->data_len = sizeof(u32); if (rsp_data_ptr->buf_len >= sizeof(u32)) *((u32 *)rsp_data_ptr->buf_ptr) = (u32)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; default: ESIF_TRACE_DYN_GET("Data Type Not Implemented = %s\n", esif_data_type_str(rsp_data_ptr->type)); rc = ESIF_E_NOT_IMPLEMENTED; break; } exit: ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc); return rc; }
eEsifError EsifAppDestroyParticipant( const EsifAppPtr appPtr, const EsifUpPtr upPtr ) { eEsifError rc = ESIF_OK; AppParticipantDataMapPtr participant_data_map_ptr = NULL; if (NULL == appPtr || NULL == upPtr) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } participant_data_map_ptr = &appPtr->fParticipantData[upPtr->fInstance]; // If created as NULL no need for callback. if (NULL == participant_data_map_ptr || NULL == participant_data_map_ptr->fAppParticipantHandle) { goto exit; } rc = DestroyDomains(appPtr, participant_data_map_ptr); if (rc != ESIF_OK) { goto exit; } rc = appPtr->fInterface.fParticipantDestroyFuncPtr( appPtr->fHandle, participant_data_map_ptr->fAppParticipantHandle); if (ESIF_OK == rc) { ESIF_TRACE_DEBUG("ParticipantMap(%u) Esif 0x%p UnMapped From Handle 0x%p\n", participant_data_map_ptr->fUpPtr->fInstance, participant_data_map_ptr->fUpPtr, participant_data_map_ptr->fAppParticipantHandle); } else { ESIF_TRACE_DEBUG("ParticipantMap(%u) UnMapping Error %s(%d)\n", participant_data_map_ptr->fUpPtr->fInstance, esif_rc_str(rc), rc); } exit: if (participant_data_map_ptr != NULL) { if (participant_data_map_ptr->fUpPtr != NULL) { /* release reference on participant since we get reference on it in EsifAppCreateParticipant */ EsifUp_PutRef(participant_data_map_ptr->fUpPtr); } memset(participant_data_map_ptr, 0, sizeof(*participant_data_map_ptr)); } return rc; }
eEsifError EsifAppStart(EsifAppPtr appPtr) { ESIF_TRACE_ENTRY_INFO(); eEsifError rc = ESIF_OK; GetIfaceFuncPtr iface_func_ptr = NULL; esif_string iface_func_name = GET_APPLICATION_INTERFACE_FUNCTION; char libPath[ESIF_LIBPATH_LEN]; ESIF_TRACE_DEBUG("name=%s\n", appPtr->fLibNamePtr); esif_build_path(libPath, ESIF_LIBPATH_LEN, ESIF_PATHTYPE_DLL, appPtr->fLibNamePtr, ESIF_LIB_EXT); appPtr->fLibHandle = esif_ccb_library_load(libPath); if (NULL == appPtr->fLibHandle || NULL == appPtr->fLibHandle->handle) { rc = esif_ccb_library_error(appPtr->fLibHandle); ESIF_TRACE_DEBUG("esif_ccb_library_load() %s failed [%s (%d)]: %s\n", libPath, esif_rc_str(rc), rc, esif_ccb_library_errormsg(appPtr->fLibHandle)); goto exit; } ESIF_TRACE_DEBUG("esif_ccb_library_load() %s completed.\n", libPath); iface_func_ptr = (GetIfaceFuncPtr)esif_ccb_library_get_func(appPtr->fLibHandle, (char*)iface_func_name); if (NULL == iface_func_ptr) { rc = esif_ccb_library_error(appPtr->fLibHandle); ESIF_TRACE_DEBUG("esif_ccb_library_get_func() %s failed [%s (%d)]: %s\n", iface_func_name, esif_rc_str(rc), rc, esif_ccb_library_errormsg(appPtr->fLibHandle)); goto exit; } ESIF_TRACE_DEBUG("esif_ccb_library_get_func() %s completed.\n", iface_func_name); rc = AppCreate(appPtr, iface_func_ptr); if (ESIF_OK != rc) { ESIF_TRACE_DEBUG("AppCreate failed.\n"); goto exit; } ESIF_TRACE_DEBUG("AppCreate completed.\n"); rc = EsifApp_RegisterParticipantsWithApp(appPtr); if (ESIF_OK != rc) { ESIF_TRACE_DEBUG("EsifApp_RegisterParticipantsWithApp failed.\n"); goto exit; } ESIF_TRACE_DEBUG("EsifApp_RegisterParticipantsWithApp completed.\n"); exit: if (ESIF_OK != rc) { esif_ccb_library_unload(appPtr->fLibHandle); appPtr->fLibHandle = NULL; } ESIF_TRACE_EXIT_INFO_W_STATUS(rc); return rc; }
static eEsifError EsifActMgr_LoadAction( EsifActMgrEntryPtr entryPtr, GetIfaceFuncPtr *getIfacePtr ) { eEsifError rc = ESIF_OK; GetIfaceFuncPtr ifaceFuncPtr = NULL; EsifString ifaceFuncName = "GetActionInterface"; char libPath[ESIF_LIBPATH_LEN]; ESIF_ASSERT(entryPtr != NULL); ESIF_ASSERT(getIfacePtr != NULL); ESIF_TRACE_DEBUG("Name=%s\n", entryPtr->libName); esif_build_path(libPath, sizeof(libPath), ESIF_PATHTYPE_DLL, entryPtr->libName, ESIF_LIB_EXT); entryPtr->lib = esif_ccb_library_load(libPath); if (NULL == entryPtr->lib || NULL == entryPtr->lib->handle) { rc = esif_ccb_library_error(entryPtr->lib); ESIF_TRACE_ERROR("esif_ccb_library_load() %s failed [%s (%d)]: %s\n", libPath, esif_rc_str(rc), rc, esif_ccb_library_errormsg(entryPtr->lib)); goto exit; } ESIF_TRACE_DEBUG("esif_ccb_library_load() %s completed.\n", libPath); ifaceFuncPtr = (GetIfaceFuncPtr)esif_ccb_library_get_func(entryPtr->lib, (EsifString)ifaceFuncName); if (NULL == ifaceFuncPtr) { rc = esif_ccb_library_error(entryPtr->lib); ESIF_TRACE_ERROR("esif_ccb_library_get_func() %s failed [%s (%d)]: %s\n", libPath, esif_rc_str(rc), rc, esif_ccb_library_errormsg(entryPtr->lib)); goto exit; } ESIF_TRACE_DEBUG("esif_ccb_library_get_func() %s completed.\n", ifaceFuncName); *getIfacePtr = ifaceFuncPtr; exit: return rc; }
// Send DSP enum esif_rc esif_send_dsp( char *filename, u8 dstId ) { enum esif_rc rc = ESIF_OK; int edpSize = 512; int cmdSize = 0; struct esif_ipc *ipcPtr = NULL; struct esif_ipc_command *commandPtr = NULL; struct esif_command_send_dsp *dspCommandPtr = NULL; struct edp_dir edpDir; size_t bytesRead; char *edpName = 0; IOStreamPtr ioPtr = IOStream_Create(); EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; if (ioPtr == NULL) { ESIF_TRACE_ERROR("Fail to create IOStream\n"); rc = ESIF_E_NO_MEMORY; goto exit; } // // If we have a filename provided use the contents of the file as the CPC // note this is opaque it is up to the receiver to verify that this is in fact // a CPC. // if (NULL == filename) { ESIF_TRACE_ERROR("Filename is null\n"); rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } // Use name portion of filename for the DataVault key (C:\path\file.edp = file.edp) edpName = strrchr(filename, *ESIF_PATH_SEP); edpName = (edpName ? ++edpName : filename); nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, edpName, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } // Look for EDP file on disk first then DataVault (static or file) if (!esif_ccb_file_exists(filename) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { filename = edpName; IOStream_SetMemory(ioPtr, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, filename, (char *)"rb"); } /* FIND CPC within EDP file */ if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)\n", filename); rc = ESIF_E_IO_OPEN_FAILED; goto exit; } bytesRead = IOStream_Read(ioPtr, &edpDir, sizeof(struct edp_dir)); if (!esif_verify_edp(&edpDir, bytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edpDir.signature, edpDir.version); rc = ESIF_E_NOT_SUPPORTED; goto exit; } edpSize = edpDir.fpc_offset - edpDir.cpc_offset; IOStream_Seek(ioPtr, edpDir.cpc_offset, SEEK_SET); if (edpSize > MAX_EDP_SIZE) { ESIF_TRACE_ERROR("The edp size %d is larger than maximum edp size\n", edpSize); rc = -ESIF_E_UNSPECIFIED; goto exit; } cmdSize = edpSize + sizeof(*dspCommandPtr); ipcPtr = esif_ipc_alloc_command(&commandPtr, cmdSize); if (NULL == ipcPtr || NULL == commandPtr) { ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n"); rc = ESIF_E_NO_MEMORY; goto exit; } commandPtr->type = ESIF_COMMAND_TYPE_SEND_DSP; commandPtr->req_data_type = ESIF_DATA_STRUCTURE; commandPtr->req_data_offset = 0; commandPtr->req_data_len = cmdSize; commandPtr->rsp_data_type = ESIF_DATA_VOID; commandPtr->rsp_data_offset = 0; commandPtr->rsp_data_len = 0; dspCommandPtr = (struct esif_command_send_dsp *)(commandPtr + 1); dspCommandPtr->id = dstId; dspCommandPtr->data_len = edpSize; bytesRead = IOStream_Read(ioPtr, dspCommandPtr + 1, edpSize); ESIF_TRACE_DEBUG("loaded file %s bytes %d\n", filename, (int)bytesRead); ESIF_TRACE_INFO("CPC file %s(%d) sent to participant %d\n", filename, edpSize, dstId); ipc_execute(ipcPtr); if (ESIF_OK != ipcPtr->return_code) { ESIF_TRACE_ERROR("ipc error code = %s(%d)\n", esif_rc_str(ipcPtr->return_code), ipcPtr->return_code); rc = ipcPtr->return_code; goto exit; } rc = commandPtr->return_code; if ((rc != ESIF_OK) && (rc != ESIF_E_DSP_ALREADY_LOADED)) { ESIF_TRACE_ERROR("primitive error code = %s(%d)\n", esif_rc_str(commandPtr->return_code), commandPtr->return_code); goto exit; } exit: if (NULL != ipcPtr) { esif_ipc_free(ipcPtr); } if (NULL != ioPtr) { IOStream_Close(ioPtr); IOStream_Destroy(ioPtr); } EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); return rc; }
/* Will sync any existing lower framework participatnts */ enum esif_rc sync_lf_participants() { eEsifError rc = ESIF_OK; struct esif_command_get_participants *data_ptr = NULL; const UInt32 data_len = sizeof(struct esif_command_get_participants); struct esif_ipc_command *command_ptr = NULL; UInt8 i = 0; UInt32 count = 0; struct esif_ipc *ipc_ptr = NULL; ESIF_TRACE_ENTRY_INFO(); ipc_ptr = esif_ipc_alloc_command(&command_ptr, data_len); if (NULL == ipc_ptr || NULL == command_ptr) { ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n"); rc = ESIF_E_NO_MEMORY; goto exit; } command_ptr->type = ESIF_COMMAND_TYPE_GET_PARTICIPANTS; command_ptr->req_data_type = ESIF_DATA_VOID; command_ptr->req_data_offset = 0; command_ptr->req_data_len = 0; command_ptr->rsp_data_type = ESIF_DATA_STRUCTURE; command_ptr->rsp_data_offset = 0; command_ptr->rsp_data_len = data_len; rc = ipc_execute(ipc_ptr); if (ESIF_OK != rc) { goto exit; } if (ESIF_OK != ipc_ptr->return_code) { rc = ipc_ptr->return_code; ESIF_TRACE_WARN("ipc_ptr return_code failure - %s\n", esif_rc_str(rc)); goto exit; } if (ESIF_OK != command_ptr->return_code) { rc = command_ptr->return_code; ESIF_TRACE_WARN("command_ptr return_code failure - %s\n", esif_rc_str(rc)); goto exit; } /* Participant Data */ data_ptr = (struct esif_command_get_participants *)(command_ptr + 1); count = data_ptr->count; for (i = 0; i < count; i++) { struct esif_ipc_event_data_create_participant participantData; EsifData esifParticipantData = {ESIF_DATA_BINARY, &participantData, sizeof(participantData), sizeof(participantData)}; rc = get_participant_data(&participantData, i); if (ESIF_OK != rc) { rc = ESIF_OK; /* Ignore RC for get_participant_data */ continue; } EsifEventMgr_SignalEvent(0, EVENT_MGR_DOMAIN_D0, ESIF_EVENT_PARTICIPANT_CREATE, &esifParticipantData); } exit: ESIF_TRACE_INFO("rc = %s(%u)", esif_rc_str(rc), rc); if (NULL != ipc_ptr) { esif_ipc_free(ipc_ptr); } ESIF_TRACE_EXIT_INFO_W_STATUS(rc); return rc; }
/* Work Around */ static enum esif_rc get_participant_data( struct esif_ipc_event_data_create_participant *pi_ptr, UInt8 participantId ) { eEsifError rc = ESIF_OK; struct esif_command_get_part_detail *data_ptr = NULL; struct esif_ipc_command *command_ptr = NULL; struct esif_ipc *ipc_ptr = NULL; const u32 data_len = sizeof(struct esif_command_get_part_detail); ipc_ptr = esif_ipc_alloc_command(&command_ptr, data_len); if (NULL == ipc_ptr || NULL == command_ptr) { ESIF_TRACE_ERROR("Fail to allocate esif_ipc/esif_ipc_command\n"); rc = ESIF_E_NO_MEMORY; goto exit; } command_ptr->type = ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL; command_ptr->req_data_type = ESIF_DATA_UINT32; command_ptr->req_data_offset = 0; command_ptr->req_data_len = 4; command_ptr->rsp_data_type = ESIF_DATA_STRUCTURE; command_ptr->rsp_data_offset = 0; command_ptr->rsp_data_len = data_len; // ID For Command *(u32 *)(command_ptr + 1) = participantId; rc = ipc_execute(ipc_ptr); if (ESIF_OK != rc) { goto exit; } if (ESIF_OK != ipc_ptr->return_code) { rc = ipc_ptr->return_code; ESIF_TRACE_WARN("ipc_ptr return_code failure - %s\n", esif_rc_str(rc)); goto exit; } if (ESIF_OK != command_ptr->return_code) { rc = command_ptr->return_code; ESIF_TRACE_WARN("command_ptr return_code failure - %s\n", esif_rc_str(rc)); goto exit; } // our data data_ptr = (struct esif_command_get_part_detail *)(command_ptr + 1); if (0 == data_ptr->version) { ESIF_TRACE_ERROR("Participant version is 0\n"); goto exit; } pi_ptr->id = (u8)data_ptr->id; pi_ptr->version = data_ptr->version; esif_ccb_memcpy(pi_ptr->class_guid, data_ptr->class_guid, ESIF_GUID_LEN); pi_ptr->enumerator = data_ptr->enumerator; pi_ptr->flags = data_ptr->flags; esif_ccb_strcpy(pi_ptr->name, data_ptr->name, ESIF_NAME_LEN); esif_ccb_strcpy(pi_ptr->desc, data_ptr->desc, ESIF_DESC_LEN); esif_ccb_strcpy(pi_ptr->driver_name, data_ptr->driver_name, ESIF_NAME_LEN); esif_ccb_strcpy(pi_ptr->device_name, data_ptr->device_name, ESIF_NAME_LEN); esif_ccb_strcpy(pi_ptr->device_path, data_ptr->device_path, ESIF_NAME_LEN); /* ACPI */ esif_ccb_strcpy(pi_ptr->acpi_device, data_ptr->acpi_device, ESIF_NAME_LEN); esif_ccb_strcpy(pi_ptr->acpi_scope, data_ptr->acpi_scope, ESIF_SCOPE_LEN); esif_ccb_strcpy(pi_ptr->acpi_uid, data_ptr->acpi_uid, sizeof(pi_ptr->acpi_uid)); pi_ptr->acpi_type = data_ptr->acpi_type; /* PCI */ pi_ptr->pci_vendor = data_ptr->pci_vendor; pi_ptr->pci_device = data_ptr->pci_device; pi_ptr->pci_bus = data_ptr->pci_bus; pi_ptr->pci_bus_device = data_ptr->pci_bus_device; pi_ptr->pci_function = data_ptr->pci_function; pi_ptr->pci_revision = data_ptr->pci_revision; pi_ptr->pci_class = data_ptr->pci_class; pi_ptr->pci_sub_class = data_ptr->pci_sub_class; pi_ptr->pci_prog_if = data_ptr->pci_prog_if; exit: if (NULL != ipc_ptr) { esif_ipc_free(ipc_ptr); } return rc; }
/* Add DSP Entry */ static eEsifError esif_dsp_entry_create(struct esif_ccb_file *file_ptr) { eEsifError rc = ESIF_E_UNSPECIFIED; EsifDspPtr dspPtr = NULL; EsifFpcPtr fpcPtr = NULL; UInt32 fpcIsStatic = ESIF_FALSE; UInt8 i = 0; char path[MAX_PATH]={0}; UInt32 fpcSize = 0; UInt32 edpSize = 0; size_t numFpcBytesRead = 0; struct edp_dir edp_dir; EsifDataPtr nameSpace = 0; EsifDataPtr key = 0; EsifDataPtr value = 0; IOStreamPtr ioPtr = IOStream_Create(); if ((NULL == file_ptr) || (NULL == ioPtr)) { ESIF_TRACE_ERROR("The file pointer or IO stream is NULL\n"); goto exit; } nameSpace = EsifData_CreateAs(ESIF_DATA_STRING, ESIF_DSP_NAMESPACE, 0, ESIFAUTOLEN); key = EsifData_CreateAs(ESIF_DATA_STRING, file_ptr->filename, 0, ESIFAUTOLEN); value = EsifData_CreateAs(ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0); if (nameSpace == NULL || key == NULL || value == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("Filename: %s", file_ptr->filename); dspPtr = esif_dsp_create(); if (NULL == dspPtr) { ESIF_TRACE_ERROR("Fail to allocate dsp entry\n"); goto exit; } // Look for EDP file on disk first then in DataVault (static or file) esif_build_path(path, sizeof(path), ESIF_PATHTYPE_DSP, file_ptr->filename, NULL); if (!esif_ccb_file_exists(path) && EsifConfigGet(nameSpace, key, value) == ESIF_OK) { esif_ccb_strcpy(path, file_ptr->filename, MAX_PATH); IOStream_SetMemory(ioPtr, StoreReadOnly, (BytePtr)value->buf_ptr, value->data_len); } else { IOStream_SetFile(ioPtr, StoreReadOnly, path, "rb"); } ESIF_TRACE_DEBUG("Fullpath: %s", path); if (IOStream_Open(ioPtr) != 0) { ESIF_TRACE_ERROR("File not found (%s)", path); goto exit; } /* Read FPC From EDP File */ if (esif_ccb_strstr(&path[0], ".edp")) { /* EDP - Only Read The FPC Part */ edpSize = (UInt32)IOStream_GetSize(ioPtr); if (!edpSize) { goto exit; } numFpcBytesRead = IOStream_Read(ioPtr, &edp_dir, sizeof(edp_dir)); if (!esif_verify_edp(&edp_dir, numFpcBytesRead)) { ESIF_TRACE_ERROR("Invalid EDP Header: Signature=%4.4s Version=%d\n", (char *)&edp_dir.signature, edp_dir.version); goto exit; } if (edpSize > MAX_EDP_SIZE || edp_dir.fpc_offset > MAX_FPC_SIZE || edp_dir.fpc_offset > edpSize) { ESIF_TRACE_ERROR("The edp or fpc file size is larger than maximum\n"); goto exit; } fpcSize = edpSize - edp_dir.fpc_offset; IOStream_Seek(ioPtr, edp_dir.fpc_offset, SEEK_SET); ESIF_TRACE_DEBUG("File found (%s) size %u, FPC size %u from offset %u", path, edpSize, fpcSize, edp_dir.fpc_offset); } else { ESIF_TRACE_DEBUG("File %s does not have .fpc and .edp format!", path); } // use static DataVault buffer (if available), otherwise allocate space for our FPC file contents (which will not be freed) if (IOStream_GetType(ioPtr) == StreamMemory && value->buf_len == 0) { fpcPtr = (EsifFpcPtr)IOStream_GetMemoryBuffer(ioPtr); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("NULL buffer"); goto exit; } fpcPtr = (EsifFpcPtr) (((BytePtr) fpcPtr) + IOStream_GetOffset(ioPtr)); numFpcBytesRead = fpcSize; ESIF_TRACE_DEBUG("Static vault size %u buf_ptr=0x%p\n", (int)numFpcBytesRead, fpcPtr); fpcIsStatic = ESIF_TRUE; } else { fpcPtr = (EsifFpcPtr)esif_ccb_malloc(fpcSize); if (NULL == fpcPtr) { ESIF_TRACE_ERROR("malloc failed to allocate %u bytes\n", fpcSize); goto exit; } ESIF_TRACE_DEBUG("File malloc size %u", fpcSize); // read file contents numFpcBytesRead = IOStream_Read(ioPtr, fpcPtr, fpcSize); if (numFpcBytesRead < fpcSize) { ESIF_TRACE_ERROR("Read short received %u of %u bytes\n", (int)numFpcBytesRead, fpcSize); goto exit; } ESIF_TRACE_DEBUG("File read size %u", (int)numFpcBytesRead); } ESIF_TRACE_DEBUG("\nDecode Length: %u", fpcPtr->size); ESIF_TRACE_DEBUG("Code: %s", fpcPtr->header.code); ESIF_TRACE_DEBUG("Ver Major: %u", fpcPtr->header.ver_major); ESIF_TRACE_DEBUG("Ver Minor: %u", fpcPtr->header.ver_minor); ESIF_TRACE_DEBUG("Name: %s", fpcPtr->header.name); ESIF_TRACE_DEBUG("Description: %s", fpcPtr->header.description); ESIF_TRACE_DEBUG("Type: %s", fpcPtr->header.type); ESIF_TRACE_DEBUG("Bus Enumerator: %u", fpcPtr->header.bus_enum); ESIF_TRACE_DEBUG("ACPI Device: %s", fpcPtr->header.acpi_device); ESIF_TRACE_DEBUG("ACPI Scope: %s", fpcPtr->header.acpi_scope); ESIF_TRACE_DEBUG("ACPI Type: %s", fpcPtr->header.acpi_type); ESIF_TRACE_DEBUG("ACPI UID: %s", fpcPtr->header.acpi_UID); ESIF_TRACE_DEBUG("PCI Vendor ID: %s", fpcPtr->header.pci_vendor_id); ESIF_TRACE_DEBUG("PCI Device ID: %s", fpcPtr->header.pci_device_id); ESIF_TRACE_DEBUG("PCI Bus: %s", fpcPtr->header.pci_bus); ESIF_TRACE_DEBUG("PCI Device: %s", fpcPtr->header.pci_device); ESIF_TRACE_DEBUG("PCI Function: %s", fpcPtr->header.pci_function); dspPtr->code_ptr = (EsifString)fpcPtr->header.name; dspPtr->bus_enum = (UInt8 *)&fpcPtr->header.bus_enum; dspPtr->type = (EsifString)fpcPtr->header.type; dspPtr->ver_major_ptr = (UInt8 *)&fpcPtr->header.ver_major; dspPtr->ver_minor_ptr = (UInt8 *)&fpcPtr->header.ver_minor; dspPtr->acpi_device = (EsifString)fpcPtr->header.acpi_device; dspPtr->acpi_scope = (EsifString)fpcPtr->header.acpi_scope; dspPtr->acpi_type = (EsifString)fpcPtr->header.acpi_type; dspPtr->acpi_uid = (EsifString)fpcPtr->header.acpi_UID; dspPtr->vendor_id = (EsifString)fpcPtr->header.pci_vendor_id; dspPtr->device_id = (EsifString)fpcPtr->header.pci_device_id; dspPtr->pci_bus = (EsifString)&fpcPtr->header.pci_bus; dspPtr->pci_bus_device = (EsifString)&fpcPtr->header.pci_device; dspPtr->pci_function = (EsifString)&fpcPtr->header.pci_function; /* Assign Function Pointers */ dspPtr->get_code = get_code; dspPtr->get_ver_minor = get_ver_minor; dspPtr->get_ver_major = get_ver_major; dspPtr->get_temp_tc1 = get_temp_c1; dspPtr->get_percent_xform = get_percent_xform; dspPtr->insert_primitive = insert_primitive; dspPtr->insert_algorithm = insert_algorithm; dspPtr->insert_domain = insert_domain; dspPtr->insert_event = insert_event; dspPtr->get_primitive = get_primitive; dspPtr->get_action = get_action; dspPtr->get_algorithm = get_algorithm; dspPtr->get_domain = get_domain; dspPtr->get_event_by_type = get_event_by_type; dspPtr->get_event_by_guid = get_event_by_guid; dspPtr->init_fpc_iterator = init_fpc_iterator; dspPtr->get_next_fpc_domain = get_next_fpc_domain; dspPtr->get_domain_count = get_domain_count; rc = esif_fpc_load(fpcPtr, dspPtr); if (ESIF_OK == rc) { ESIF_TRACE_DEBUG("FPC %s load successfully", path); } else { ESIF_TRACE_DEBUG("Unable to load FPC %s, rc %s", path, esif_rc_str(rc)); goto exit; } /* Lock DSP Manager */ esif_ccb_write_lock(&g_dm.lock); /* Simple Table Lookup For Now. Scan Table And Find First Empty Slot */ /* Empty slot indicated by AVAILABLE state */ for (i = 0; i < MAX_DSP_MANAGER_ENTRY; i++) { if (NULL == g_dm.dme[i].dsp_ptr) { break; } } /* If No Available Slots Return */ if (i >= MAX_DSP_MANAGER_ENTRY) { esif_ccb_write_unlock(&g_dm.lock); ESIF_TRACE_ERROR("No free dsp manager entry is available for %s\n", file_ptr->filename); goto exit; } /* ** Take Slot */ g_dm.dme[i].dsp_ptr = dspPtr; g_dm.dme[i].file_ptr = file_ptr; g_dm.dme[i].fpc_ptr = (fpcIsStatic ? 0 : fpcPtr); g_dm.dme_count++; dspPtr = NULL; // Prevent deallocate on exit fpcPtr = NULL; // Prevent deallocate on exit esif_ccb_write_unlock(&g_dm.lock); rc = ESIF_OK; ESIF_TRACE_INFO("Create entry in dsp manager successfully for %s\n", file_ptr->filename); exit: IOStream_Destroy(ioPtr); EsifData_Destroy(nameSpace); EsifData_Destroy(key); EsifData_Destroy(value); esif_dsp_destroy(dspPtr); if (!fpcIsStatic) { esif_ccb_free(fpcPtr); } return rc; }
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; }
static eEsifError EsifGetActionDelegateCnfg( const EsifUpDomainPtr domainPtr, const EsifDataPtr requestPtr, EsifDataPtr responsePtr ) { extern int g_shell_enabled; // ESIF Shell Enabled Flag extern Bool g_ws_restricted;// Web Server Restricted Mode Flag eEsifError rc = ESIF_OK; EsifPrimitiveTuple dcfgTuple = { GET_CONFIG_ACCESS_CONTROL_SUR, 0, 255 }; EsifPrimitiveTuple gddvTuple = { GET_CONFIG_DATAVAULT_SUR, 0, 255 }; EsifData dcfgData = { ESIF_DATA_UINT32, NULL, ESIF_DATA_ALLOCATE, 0 }; EsifData gddvData = { ESIF_DATA_AUTO, NULL, ESIF_DATA_ALLOCATE, 0 }; ESIF_ASSERT(NULL != domainPtr); ESIF_ASSERT(NULL != requestPtr); UNREFERENCED_PARAMETER(responsePtr); // Not currently used by DPTF dcfgTuple.domain = domainPtr->domain; gddvTuple.domain = domainPtr->domain; // Execute DCFG to read Access Control List Bitmask from BIOS, if it exists rc = EsifUp_ExecutePrimitive(domainPtr->upPtr, &dcfgTuple, requestPtr, &dcfgData); if (rc == ESIF_OK && dcfgData.buf_ptr != NULL && dcfgData.buf_len >= sizeof(UInt32)) { DCfgOptions newmask = { .asU32 = *(UInt32 *)dcfgData.buf_ptr }; DCfg_Set(newmask); ESIF_TRACE_INFO("DCFG Loaded: 0x%08X\n", newmask.asU32); // Disable ESIF Shell if Access Control forbids it if (DCfg_Get().opt.ShellAccessControl) { g_shell_enabled = 0; } // Stop Web Server (if Started) if Restricted or Generic Access Control forbids it if (EsifWebIsStarted() && ((!g_ws_restricted && DCfg_Get().opt.GenericUIAccessControl)|| (g_ws_restricted && DCfg_Get().opt.RestrictedUIAccessControl)) ) { EsifWebStop(); } } // Execute GDDV to read DataVault from BIOS, if it exists rc = EsifUp_ExecutePrimitive(domainPtr->upPtr, &gddvTuple, requestPtr, &gddvData); if (rc != ESIF_OK) { // Always Return OK if no ESIF_LF or GDDV object in BIOS if (rc == ESIF_E_NO_LOWER_FRAMEWORK || rc == ESIF_E_ACPI_OBJECT_NOT_FOUND) { rc = ESIF_OK; } } else { char *dv_name = "__merge"; // Temporary DV Name DataVaultPtr DB = DataBank_GetNameSpace(g_DataBankMgr, dv_name); if (DB != NULL) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); } DB = DataBank_OpenNameSpace(g_DataBankMgr, dv_name); // Load Datavault into temporary namespace. DV may or may not be preceded by a variant if (DB) { u32 skipbytes = 0; void *buffer = NULL; // // This is in place to resolve a static code analysis issue. // This should never happen if EsifUp_ExecutePrimitive is successful above. // if (NULL == gddvData.buf_ptr) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("No data returned for BIOS datavault.\n"); goto exit; } skipbytes = (memcmp(gddvData.buf_ptr, "\xE5\x1F", 2) == 0 ? 0 : sizeof(union esif_data_variant)); buffer = esif_ccb_malloc(gddvData.data_len); if (NULL == buffer) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("Unable to allocate memory\n"); rc = ESIF_E_NO_MEMORY; goto exit; } esif_ccb_memcpy(buffer, (u8*)gddvData.buf_ptr + skipbytes, gddvData.data_len - skipbytes); IOStream_SetMemory(DB->stream, buffer, gddvData.data_len - skipbytes); if ((rc = DataVault_ReadVault(DB)) != ESIF_OK) { DataBank_CloseNameSpace(g_DataBankMgr, dv_name); ESIF_TRACE_DEBUG("Unable to Open DataVault: %s\n", esif_rc_str(rc)); rc = ESIF_OK; } else { EsifDataPtr data_nspace = NULL; EsifDataPtr data_key = NULL; EsifDataPtr data_targetdv = NULL; esif_flags_t options = 0; // NOPERSIST esif_string keyspec = "*"; // Merge All Keys esif_string targetdv = g_DataVaultDefault; DB->flags |= (ESIF_SERVICE_CONFIG_READONLY); // Merge Contents into Default DataVault data_nspace = EsifData_CreateAs(ESIF_DATA_STRING, dv_name, 0, ESIFAUTOLEN); data_targetdv = EsifData_CreateAs(ESIF_DATA_STRING, targetdv, 0, ESIFAUTOLEN); data_key = EsifData_CreateAs(ESIF_DATA_STRING, keyspec, 0, ESIFAUTOLEN); if (data_nspace == NULL || data_key == NULL || data_targetdv == NULL) { rc = ESIF_E_NO_MEMORY; } else { rc = EsifConfigCopy(data_nspace, data_targetdv, data_key, options, ESIF_FALSE, NULL); } ESIF_TRACE_INFO("GDDV Loaded: %d bytes, %d keys => %s.dv [%s]\n", (int)IOStream_GetSize(DB->stream), DataCache_GetCount(DB->cache), targetdv, esif_rc_str(rc)); EsifData_Destroy(data_nspace); EsifData_Destroy(data_key); EsifData_Destroy(data_targetdv); DataBank_CloseNameSpace(g_DataBankMgr, dv_name); } esif_ccb_free(buffer); } } exit: esif_ccb_free(dcfgData.buf_ptr); esif_ccb_free(gddvData.buf_ptr); return rc; }
static eEsifError EsifSetActionDelegateRset( const EsifUpDomainPtr domainPtr, const EsifDataPtr requestPtr) { eEsifError rc = ESIF_E_PRIMITIVE_ACTION_FAILURE; EsifPrimitiveTupleParameter parameters = { 0 }; EsifPrimitiveTuple tuple = { 0 }; Bool signal_event = ESIF_FALSE; char domain_str[8] = { 0 }; int j = 0; ESIF_ASSERT(domainPtr != NULL); ESIF_ASSERT(requestPtr != NULL); if (requestPtr->buf_ptr == NULL) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } if (requestPtr->data_len != sizeof(parameters)) { rc = ESIF_E_REQUEST_DATA_OUT_OF_BOUNDS; goto exit; } // Convert BINARY Parameters to Primitive Tuple esif_ccb_memcpy(¶meters, requestPtr->buf_ptr, sizeof(parameters)); ESIF_TRACE_DEBUG("CONFIG RESET: { %s (%hd), %s, %hd }\n", esif_primitive_str(parameters.id.integer.value), (u16)parameters.id.integer.value, esif_primitive_domain_str((u16)parameters.domain.integer.value, domain_str, sizeof(domain_str)), (u16)parameters.instance.integer.value ); // Look up Primitive Tuple in the DSP and verify it is a valid SET primtive EsifDspPtr dspPtr = EsifUp_GetDsp(domainPtr->upPtr); if (dspPtr == NULL) { rc = ESIF_E_NEED_DSP; goto exit; } tuple.id = (u16) parameters.id.integer.value; tuple.domain = (u16) parameters.domain.integer.value; tuple.instance = (u16) parameters.instance.integer.value; EsifFpcPrimitivePtr primitivePtr = dspPtr->get_primitive(dspPtr, &tuple); if (primitivePtr == NULL) { rc = ESIF_E_PRIMITIVE_NOT_FOUND_IN_DSP; goto exit; } if (primitivePtr->operation != ESIF_PRIMITIVE_OP_SET) { rc = ESIF_E_INVALID_REQUEST_TYPE; goto exit; } // Find first CONFIG Action and Delete its Key from its DataVault for (j = 0; j < (int)primitivePtr->num_actions; j++) { EsifFpcActionPtr fpcActionPtr = dspPtr->get_action(dspPtr, primitivePtr, (u8)j); DataItemPtr paramDataVault = EsifFpcAction_GetParam(fpcActionPtr, (const UInt8)0); DataItemPtr paramKeyName = EsifFpcAction_GetParam(fpcActionPtr, (const UInt8)1); EsifString expandedKeyName = NULL; if (fpcActionPtr->type != ESIF_ACTION_CONFIG) { continue; } if (paramDataVault == NULL || paramKeyName == NULL || paramDataVault->data_type != ESIF_DSP_PARAMETER_TYPE_STRING || paramKeyName->data_type != ESIF_DSP_PARAMETER_TYPE_STRING) { rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS; goto exit; } // Replace "%nm%" tokens in the key name or make a copy of the key name for static keys expandedKeyName = EsifUp_CreateTokenReplacedParamString(domainPtr->upPtr, primitivePtr, (StringPtr)paramKeyName->data); if (expandedKeyName == NULL) { expandedKeyName = esif_ccb_strdup((StringPtr)paramKeyName->data); if (expandedKeyName == NULL) { rc = ESIF_E_NO_MEMORY; goto exit; } } // Valid SET CONFIG Primitive found with valid DV/Key Name; Delete the associated Key from the DataVault EsifDataPtr data_nspace = EsifData_CreateAs(ESIF_DATA_STRING, (StringPtr)paramDataVault->data, 0, ESIFAUTOLEN); EsifDataPtr data_key = EsifData_CreateAs(ESIF_DATA_STRING, expandedKeyName, 0, ESIFAUTOLEN); // Do not signal an Event if Key does not exist in DataVault if (DataBank_KeyExists(g_DataBankMgr, (StringPtr)paramDataVault->data, expandedKeyName) == ESIF_FALSE) { rc = ESIF_OK; } else if (data_nspace == NULL || data_key == NULL) { rc = ESIF_E_NO_MEMORY; } else { // Delete Existing Key from DataVault rc = EsifConfigDelete(data_nspace, data_key); if (rc == ESIF_OK) { signal_event = ESIF_TRUE; } ESIF_TRACE_DEBUG("CONFIG RESET: config delete @%s %s [rc=%s (%d)]\n", (StringPtr)data_nspace->buf_ptr, (StringPtr)data_key->buf_ptr, esif_rc_str(rc), rc ); } // Signal any Event(s) associated with this SET Primitive if (signal_event) { EsifActConfigSignalChangeEvents(domainPtr->upPtr, tuple, NULL); } EsifData_Destroy(data_nspace); EsifData_Destroy(data_key); esif_ccb_free(expandedKeyName); break; } if (j >= (int)primitivePtr->num_actions) { rc = ESIF_E_UNSUPPORTED_ACTION_TYPE; } exit: return rc; }
/* Set */ enum esif_rc esif_set_action_mmio( const struct esif_lp *lp_ptr, const struct esif_lp_primitive *primitive_ptr, const struct esif_lp_action *action_ptr, struct esif_data *req_data_ptr ) { enum esif_rc rc = ESIF_OK; void __iomem *base_addr = NULL; u32 offset; u8 bit_from; u8 bit_to; int i = 0; /* Loop Counter */ u32 req_val = 0; /* Request MMIO Value */ u32 orig_val = 0; /* Original Value Of MMIO */ u32 bit_mask = 0; /* Bit Mask */ UNREFERENCED_PARAMETER(primitive_ptr); if ((NULL == lp_ptr) || (NULL == action_ptr) || (NULL == req_data_ptr)) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } base_addr = lp_ptr->pi_ptr->mem_base; if (NULL == base_addr) { rc = ESIF_E_NO_MMIO_SUPPORT; goto exit; } offset = action_ptr->get_p1_u32(action_ptr); bit_from = (u8)action_ptr->get_p3_u32(action_ptr); bit_to = (u8)action_ptr->get_p2_u32(action_ptr); #ifdef ESIF_ATTR_OS_WINDOWS if ((offset + MMIO_ACCESS_SIZE) > lp_ptr->pi_ptr->mem_size) { rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS; goto exit; } #endif switch (req_data_ptr->type) { case ESIF_DATA_UINT8: if (req_data_ptr->buf_len >= sizeof(u8)) req_val = *((u8 *)req_data_ptr->buf_ptr); else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT16: if (req_data_ptr->buf_len >= sizeof(u16)) req_val = *((u16 *)req_data_ptr->buf_ptr); else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT32: case ESIF_DATA_TIME: if (req_data_ptr->buf_len >= sizeof(u32)) req_val = *((u32 *)req_data_ptr->buf_ptr); else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; default: rc = ESIF_E_UNSUPPORTED_REQUEST_DATA_TYPE; break; } ESIF_TRACE_DYN_SET("Base %p offset 0x%x[%d:%d] = 0x%x\n", base_addr, offset, bit_to, bit_from, req_val); /* Read The Current Value Of The MMIO */ esif_ccb_write_lock(&g_esif_action_mmio_lock); esif_ccb_mmio_read(base_addr, offset, &orig_val); /* Mask Bits */ for (bit_mask = 0UL, i = bit_from; i <= bit_to; i++) bit_mask |= (1UL << i); /* Shift Bits */ orig_val &= ~(bit_mask); /* Get the New Value */ req_val = ((req_val << bit_from) & bit_mask) | orig_val; /* Write MMIO 32-Bit Always */ esif_ccb_mmio_write(base_addr, offset, req_val); esif_ccb_write_unlock(&g_esif_action_mmio_lock); exit: ESIF_TRACE_DYN_SET("RC: %s(%d)\n", esif_rc_str(rc), 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; }
/* Get */ enum esif_rc esif_get_action_mmio( const struct esif_lp *lp_ptr, const struct esif_lp_primitive *primitive_ptr, const struct esif_lp_action *action_ptr, struct esif_data *req_data_ptr, struct esif_data *rsp_data_ptr ) { enum esif_rc rc = ESIF_OK; void __iomem *base_addr = NULL; u32 offset; u8 bit_from; u8 bit_to; int i = 0; /* Loop Counter */ u32 val = 0; /* Temporary MMIO Value MMIO Always 32 Bit */ u32 bit_mask = 0; /* Bit Mask For MMIO Value */ UNREFERENCED_PARAMETER(primitive_ptr); UNREFERENCED_PARAMETER(req_data_ptr); if ((NULL == lp_ptr) || (NULL == action_ptr) || (NULL == rsp_data_ptr)) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } base_addr = lp_ptr->pi_ptr->mem_base; if (NULL == base_addr) { rc = ESIF_E_NO_MMIO_SUPPORT; goto exit; } offset = action_ptr->get_p1_u32(action_ptr); bit_from = (u8)action_ptr->get_p3_u32(action_ptr); bit_to = (u8)action_ptr->get_p2_u32(action_ptr); #ifdef ESIF_ATTR_OS_WINDOWS if ((offset + MMIO_ACCESS_SIZE) > lp_ptr->pi_ptr->mem_size) { rc = ESIF_E_PARAMETER_IS_OUT_OF_BOUNDS; goto exit; } #endif /* Read MMIO 32-Bit Always */ esif_ccb_read_lock(&g_esif_action_mmio_lock); esif_ccb_mmio_read(base_addr, offset, &val); esif_ccb_read_unlock(&g_esif_action_mmio_lock); /* Mask Bits */ for (bit_mask = 0, i = bit_from; i <= bit_to; i++) bit_mask |= (1 << i); val = val & bit_mask; val = val >> bit_from; ESIF_TRACE_DYN_GET("Base %p offset 0x%x[%d:%d] = 0x%x\n", base_addr, offset, bit_to, bit_from, val); switch (rsp_data_ptr->type) { case ESIF_DATA_UINT8: rsp_data_ptr->data_len = sizeof(u8); if (rsp_data_ptr->buf_len >= sizeof(u8)) *((u8 *)rsp_data_ptr->buf_ptr) = (u8)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT16: rsp_data_ptr->data_len = sizeof(u16); if (rsp_data_ptr->buf_len >= sizeof(u16)) *((u16 *)rsp_data_ptr->buf_ptr) = (u16)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; case ESIF_DATA_UINT32: case ESIF_DATA_TIME: rsp_data_ptr->data_len = sizeof(u32); if (rsp_data_ptr->buf_len >= sizeof(u32)) *((u32 *)rsp_data_ptr->buf_ptr) = (u32)val; else rc = ESIF_E_OVERFLOWED_RESULT_TYPE; break; default: rc = ESIF_E_UNSUPPORTED_RESULT_DATA_TYPE; break; } exit: ESIF_TRACE_DYN_GET("RC: %s(%d)\n", esif_rc_str(rc), rc); return rc; }
/* Loads a pluggable UPE action by library name */ eEsifError EsifActMgr_StartUpe( EsifString upeName, UInt8 upInstance ) { eEsifError rc = ESIF_OK; EsifActMgrEntryPtr entryPtr = NULL; GetIfaceFuncPtr getIfacePtr = NULL; EsifActIface iface = {0}; if (NULL == upeName) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } /* Check to see if the action is already running only one instance per action allowed */ esif_ccb_write_lock(&g_actMgr.mgrLock); entryPtr = EsifActMgr_GetActEntryByLibname_Locked(upeName); esif_ccb_write_unlock(&g_actMgr.mgrLock); if (entryPtr != NULL) { entryPtr = NULL; /* Keep from being destroy on exit for this failure type */ rc = ESIF_E_ACTION_ALREADY_STARTED; goto exit; } ESIF_TRACE_DEBUG("Adding new UPE action %s\n", upeName); rc = EsifActMgr_CreateEntry(&entryPtr); if (rc != ESIF_OK) { goto exit; } entryPtr->upInstance = upInstance; entryPtr->libName = (esif_string)esif_ccb_strdup(upeName); rc = EsifActMgr_LoadAction(entryPtr, &getIfacePtr); if (ESIF_OK != rc) { goto exit; } iface.hdr.fIfaceType = eIfaceTypeAction; iface.hdr.fIfaceVersion = ESIF_INTERFACE_VERSION; iface.hdr.fIfaceSize = sizeof(iface); rc = getIfacePtr(&iface); if (ESIF_OK != rc) { goto exit; } rc = EsifActMgr_CreateAction(entryPtr, &iface); if (ESIF_OK != rc) { goto exit; } EsifAct_MarkAsPlugin(entryPtr->actPtr); rc = EsifActMgr_AddEntry(entryPtr); if (rc != ESIF_OK) { goto exit; } ESIF_TRACE_DEBUG("Added action %s\n", upeName); exit: if (rc != ESIF_OK) { ESIF_TRACE_ERROR("Failure adding action %s\n", esif_rc_str(rc)); EsifActMgr_DestroyEntry(entryPtr); } return rc; }
eEsifError EsifAppCreateParticipant( const EsifAppPtr appPtr, const EsifUpPtr upPtr ) { eEsifError rc = ESIF_OK; void *participant_handle = NULL; AppParticipantDataPtr participant_data_ptr = NULL; if (NULL == appPtr || NULL == upPtr) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } /* Create participant metadata to marshall though interface */ participant_data_ptr = CreateParticipantData(upPtr, &upPtr->fMetadata); if (NULL == participant_data_ptr) { rc = ESIF_E_NO_MEMORY; goto exit; } /* Create particpant Handle */ rc = appPtr->fInterface.fParticipantAllocateHandleFuncPtr( appPtr->fHandle, &participant_handle); if ((rc != ESIF_OK) || (NULL == participant_handle)) { esif_ccb_free(participant_data_ptr); participant_data_ptr = NULL; if (NULL == participant_handle) { rc = ESIF_E_INVALID_HANDLE; } else { ESIF_TRACE_DEBUG("Participant(%u) Mapping Error %s(%d)\n", upPtr->fInstance, esif_rc_str(rc), rc); } goto exit; } { AppParticipantDataMapPtr participantDataMapPtr = &appPtr->fParticipantData[upPtr->fInstance]; participantDataMapPtr->fAppParticipantHandle = participant_handle; /* Application Participant */ participantDataMapPtr->fUpPtr = upPtr; /* ESIF Participant */ /* get reference on participant since we save a copy of pointer for later use*/ rc = EsifUp_GetRef(upPtr); if (ESIF_OK != rc) { goto exit; } ESIF_TRACE_DEBUG("Participant(%u) Esif 0x%p Mapped To Handle 0x%p\n", upPtr->fInstance, participantDataMapPtr->fUpPtr, participantDataMapPtr->fAppParticipantHandle); /* Call through the interface to create the participant instance in the app. */ rc = appPtr->fInterface.fParticipantCreateFuncPtr( appPtr->fHandle, participant_handle, participant_data_ptr, eParticipantStateEnabled); if (ESIF_OK != rc) { goto exit; } rc = CreateDomains(appPtr, upPtr, participantDataMapPtr); } exit: if (participant_data_ptr) { esif_ccb_free(participant_data_ptr); participant_data_ptr = NULL; } return rc; }
static eEsifError CreateDomain( UInt8 domainId, EsifAppPtr appPtr, AppParticipantDataMapPtr participantDataMapPtr, struct esif_fpc_domain *domainPtr ) { eEsifError rc = ESIF_OK; AppDomainDataPtr domain_data_ptr = NULL; void *domain_handle = NULL; ESIF_TRACE_DEBUG("Create Domain %s\n", domainPtr->descriptor.name); if (NULL == appPtr || NULL == domainPtr) { rc = ESIF_E_PARAMETER_IS_NULL; goto exit; } domain_data_ptr = CreateDomainData(domainPtr); if (NULL == domain_data_ptr) { rc = ESIF_E_NO_MEMORY; goto exit; } ESIF_TRACE_DEBUG("Have Domain Data %d\n", domainId); rc = appPtr->fInterface.fDomainAllocateHandleFuncPtr( appPtr->fHandle, participantDataMapPtr->fAppParticipantHandle, &domain_handle); if (ESIF_OK == rc && NULL == domain_handle) { rc = ESIF_E_INVALID_HANDLE; goto exit; } else if (ESIF_OK == rc && domainId < sizeof(g_qualifiers) / sizeof(esif_string)) { participantDataMapPtr->fDomainData[domainId].fAppDomainId = domainId; participantDataMapPtr->fDomainData[domainId].fAppDomainHandle = domain_handle; participantDataMapPtr->fDomainData[domainId].fAppDomainDataPtr = domain_data_ptr; participantDataMapPtr->fDomainData[domainId].fQualifier = g_qualifiers[domainId]; participantDataMapPtr->fDomainData[domainId].fQualifierId = *(u16 *)g_qualifiers[domainId]; ESIF_TRACE_DEBUG("DomainMap(%u): Name %s Esif(%s) %p Mapped To Handle 0x%p\n", domainId, (esif_string)domain_data_ptr->fName.buf_ptr, participantDataMapPtr->fDomainData[domainId].fQualifier, participantDataMapPtr->fDomainData[domainId].fAppDomainDataPtr, participantDataMapPtr->fDomainData[domainId].fAppDomainHandle); rc = appPtr->fInterface.fDomainCreateFuncPtr( appPtr->fHandle, participantDataMapPtr->fAppParticipantHandle, domain_handle, domain_data_ptr, eDomainStateEnabled); } else { ESIF_TRACE_DEBUG("DomainMap(%u): Domain Mapping Error %s(%d)\n", domainId, esif_rc_str(rc), rc); } exit: esif_ccb_free(domain_data_ptr); return rc; }
/* Dispatch */ struct esif_ipc *esif_execute_ipc_command( struct esif_ipc *ipc_ptr ) { struct esif_ipc_command *command_ptr = (struct esif_ipc_command *)(ipc_ptr + 1); u32 data_size = 0; command_ptr->return_code = ESIF_E_COMMAND_DATA_INVALID; if (ESIF_COMMAND_VERSION != command_ptr->version) goto exit; data_size = ipc_ptr->data_len - sizeof(*command_ptr); if(((command_ptr->req_data_offset + command_ptr->req_data_len) > data_size) || ((command_ptr->rsp_data_offset + command_ptr->rsp_data_len) > data_size)) goto exit; ESIF_TRACE_DYN_COMMAND("%s: COMMAND Received: ipc %p\n", ESIF_FUNC, ipc_ptr); ESIF_TRACE_DYN_DECODE(" Version: %d\n" " Type: %s(%d)\n" " Priority: %s(%d)\n" " Payload Length: %d\n" " Request Data Type: %s(%d)\n" " Request Data Offset: %d\n" " Request Data Length: %d\n" " Response Data Type: %s(%d)\n" " Response Data Offset: %d\n" " Response Data Length: %d\n", (int)command_ptr->version, esif_command_type_str(command_ptr->type), (int)command_ptr->type, esif_command_priority_str(command_ptr->priority), (int)command_ptr->priority, (int)command_ptr->payload_len, esif_data_type_str(command_ptr->req_data_type), (int)command_ptr->req_data_type, (int)command_ptr->req_data_offset, (int)command_ptr->req_data_len, esif_data_type_str(command_ptr->rsp_data_type), (int)command_ptr->rsp_data_type, (int)command_ptr->rsp_data_offset, (int)command_ptr->rsp_data_len); switch (command_ptr->type) { case ESIF_COMMAND_TYPE_SET_DEBUG_MODULES: esif_execute_ipc_command_set_debug_modules(command_ptr); break; case ESIF_COMMAND_TYPE_SET_DEBUG_MODULE_LEVEL: esif_execute_ipc_command_set_debug_module_level(command_ptr); break; case ESIF_COMMAND_TYPE_GET_DEBUG_MODULE_LEVEL: esif_execute_ipc_command_get_debug_module_level(command_ptr); break; case ESIF_COMMAND_TYPE_GET_KERNEL_INFO: esif_execute_ipc_command_get_kernel_info(command_ptr); break; case ESIF_COMMAND_TYPE_GET_MEMORY_STATS: esif_execute_ipc_command_get_memory_stats(command_ptr); break; case ESIF_COMMAND_TYPE_GET_PARTICIPANTS: esif_execute_ipc_command_get_participants(command_ptr); break; case ESIF_COMMAND_TYPE_GET_PARTICIPANT_DETAIL: esif_execute_ipc_command_get_participant_detail(command_ptr); break; default: ESIF_TRACE_DYN_COMMAND("%s: Unknown Command Type %d:\n", ESIF_FUNC, command_ptr->type); break; } ESIF_TRACE_DYN_COMMAND("%s: COMMAND return result: %s(%d)\n", ESIF_FUNC, esif_rc_str( command_ptr->return_code), command_ptr->return_code); exit: /* Send To User */ return ipc_ptr; }
/* Process IPC */ struct esif_ipc *esif_ipc_process( struct esif_ipc *ipc_ptr ) { struct esif_ipc *ipc_ret_ptr = ipc_ptr; struct esif_ipc_command *cmd_ptr = NULL; struct esif_ipc_primitive *prim_ptr = NULL; ESIF_TRACE_DYN_IPC("START ipc %p\n", ipc_ptr); if (NULL == ipc_ptr) goto exit; /* * If we got this far we are guaranteed to have a valid IPC * header now we need to check to see if we hav enough data * for the type specified if so process it if not return to * avoid what would surely result in undesired behavior. */ switch (ipc_ptr->type) { /* Command e.g. Get Participants, Etc. */ case ESIF_IPC_TYPE_COMMAND: ESIF_TRACE_DYN_IPC("COMMAND Received\n"); cmd_ptr = (struct esif_ipc_command *)(ipc_ptr + 1); if ((ipc_ptr->data_len < sizeof(*cmd_ptr)) || (ipc_ptr->data_len < (esif_ipc_command_get_data_len(cmd_ptr) + sizeof(*cmd_ptr)))) ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID; else esif_execute_ipc_command(cmd_ptr); break; /* Retrieve A Signaled Event Or Check Event Queue */ case ESIF_IPC_TYPE_EVENT: ESIF_TRACE_DYN_IPC("EVENT Received\n"); if (ipc_ptr->data_len < sizeof(struct esif_ipc_event)) ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID; else ipc_ret_ptr = esif_event_queue_pull(); break; /* Execute Primitive e.g. GET_TEMPERATURE */ case ESIF_IPC_TYPE_PRIMITIVE: ESIF_TRACE_DYN_IPC("PRIMITIVE Received\n"); prim_ptr = (struct esif_ipc_primitive *)(ipc_ptr + 1); if ((ipc_ptr->data_len < sizeof(*prim_ptr)) || (ipc_ptr->data_len < (esif_ipc_primitive_get_data_len(prim_ptr) + sizeof(*prim_ptr)))) ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID; else esif_execute_ipc_primitive(prim_ptr); break; /* NOOP For Testing */ case ESIF_IPC_TYPE_NOOP: ESIF_TRACE_DYN_IPC("NOOP Received\n"); ipc_ret_ptr = NULL; break; /* Unsupported or Unknown IPC Type Received */ default: ESIF_TRACE_DYN_IPC("Unknown IPC Type Received type=%u\n", ipc_ptr->type); ipc_ptr->return_code = ESIF_E_IPC_DATA_INVALID; break; } ESIF_TRACE_DYN_IPC("FINISH return result: %s(%u)\n", esif_rc_str(ipc_ptr->return_code), ipc_ptr->return_code); exit: return ipc_ret_ptr; }
/* Poll For Power and Send Event If Threshold Crossed */ static enum esif_rc esif_poll_power( struct esif_lp_domain *lpd_ptr ) { enum esif_rc rc = ESIF_OK; u32 energy_units = 0; u32 energy_units_used = 0; struct esif_primitive_tuple tuple = {GET_RAPL_ENERGY, lpd_ptr->id, 255}; struct esif_data req_data = {ESIF_DATA_VOID, NULL, 0, 0}; struct esif_data rsp_data = {ESIF_DATA_UINT32, &energy_units, sizeof(energy_units), 0}; rc = esif_execute_primitive(lpd_ptr->lp_ptr, &tuple, &req_data, &rsp_data, NULL); if (ESIF_OK != rc) goto exit; ESIF_TRACE_DYN_ENERGY( "GET_RAPL_ENERGY for %s energy_unit 0x%x rc %s(%d)\n", lpd_ptr->name_ptr, energy_units, esif_rc_str(rc), rc); /* Save the current and last RAPL energy counters */ lpd_ptr->rapl_energy_units_last = lpd_ptr->rapl_energy_units_current; lpd_ptr->rapl_energy_units_current = energy_units; /* Check For Wrap? */ if (lpd_ptr->rapl_energy_units_last > energy_units) { /* force I_AGAIN */ lpd_ptr->rapl_energy_units_last = 0; } else { energy_units_used = energy_units - lpd_ptr->rapl_energy_units_last; } /* TODO: Use a timestamp to make this as acurate as possible */ /* should be within a few usecs so good enough for now */ lpd_ptr->rapl_energy_units_per_sec = energy_units_used / (lpd_ptr->timer_period_msec / 1000); ESIF_TRACE_DYN_ENERGY( "id %s ENERGY units current %08X, last %08X, used %u, used/sec %d\n", lpd_ptr->name_ptr, lpd_ptr->rapl_energy_units_last, lpd_ptr->rapl_energy_units_current, energy_units_used, lpd_ptr->rapl_energy_units_per_sec); /* Take two samples to get the right rapl_power and send_event. */ if (lpd_ptr->rapl_energy_units_last == 0) goto exit; /* * Now Calculate Power */ if (lpd_ptr->rapl_energy_units_per_sec > 0) { u32 energy_joules = 0;/* default micro joules unit */ u32 power = 0; /* default power */ struct esif_lp_domain *lpd_d0_ptr = NULL; /* For Domain 0 */ /* * Don't HAVE Action Type Assume MSR since all processors * have this */ struct esif_cpc_algorithm *algo_ptr = lpd_ptr->lp_ptr->dsp_ptr->get_algorithm( lpd_ptr->lp_ptr->dsp_ptr, ESIF_ACTION_MSR); /* Power Unit Data Only Lives in Domain 0 (D0) */ lpd_d0_ptr = &lpd_ptr->lp_ptr->domains[0]; if (algo_ptr && ESIF_ALGORITHM_TYPE_POWER_UNIT_CORE == algo_ptr->power_xform) { if (lpd_d0_ptr->unit_energy) { energy_joules = 1000000 / (1 << lpd_d0_ptr->unit_energy); } else { /* 1000000uj / (2 ^ 14) = 61uj */ energy_joules = 61; } } if (algo_ptr && ESIF_ALGORITHM_TYPE_POWER_UNIT_ATOM == algo_ptr->power_xform) { if (lpd_d0_ptr->unit_energy) { energy_joules = (1 << lpd_d0_ptr->unit_energy); } else { /* 1uj * (2 ^ 5) = 32 uj */ energy_joules = 32; } } power = (lpd_ptr->rapl_energy_units_per_sec * energy_joules) / 1000; /* .001 of watt accuracy */ /* Normalized from DeciW */ esif_convert_power(ESIF_POWER_MILLIW, NORMALIZE_POWER_UNIT_TYPE, &power); ESIF_TRACE_DYN_RAPL("POWER %d %s(%d)\n", power, esif_power_unit_desc( NORMALIZE_POWER_UNIT_TYPE), NORMALIZE_POWER_UNIT_TYPE); lpd_ptr->rapl_power = power; /* * Now Check For Threshold */ ESIF_TRACE_DYN_RAPL( "THRESHOLD_CHECK hyst = %d aux0 = %d " "power = %d aux1 = %d units %s(%d)\n", lpd_ptr->power_hysteresis, lpd_ptr->power_aux0, power, lpd_ptr->power_aux1, esif_power_unit_desc( NORMALIZE_POWER_UNIT_TYPE), NORMALIZE_POWER_UNIT_TYPE); if (0 == lpd_ptr->power_aux0 && 0 == lpd_ptr->power_aux1) { /* Do Nothing */ } else { if (0 == lpd_ptr->power_aux0) { if (power > lpd_ptr->power_aux1) { lpd_ptr->lp_ptr->pi_ptr->send_event( lpd_ptr->lp_ptr->pi_ptr, ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED, lpd_ptr->id, NULL); } else if (power < lpd_ptr->power_aux0 || power > lpd_ptr->power_aux1) { lpd_ptr->lp_ptr->pi_ptr->send_event( lpd_ptr->lp_ptr->pi_ptr, ESIF_EVENT_DOMAIN_POWER_THRESHOLD_CROSSED, lpd_ptr->id, NULL); } } } } exit: return rc; }