| // found in the LICENSE file. |
| |
| #include "intel-audio-dsp.h" |
| |
| namespace audio { |
| namespace intel_hda { |
| |
| void IntelAudioDsp::DumpNhlt(const nhlt_table_t* table, size_t length) { |
| if (length < sizeof(*table)) { |
| LOG(ERROR, "NHLT too small (%zu bytes)\n", length); |
| return; |
| } |
| |
| if (memcmp(table->header.signature, ACPI_NHLT_SIGNATURE, ACPI_NAME_SIZE)) { |
| LOG(ERROR, "Invalid NHLT signature (expected '%s', got '%s')\n", |
| ACPI_NHLT_SIGNATURE, table->header.signature); |
| return; |
| } |
| |
| uint8_t count = table->endpoint_desc_count; |
| const nhlt_descriptor_t* desc = table->endpoints; |
| LOG(INFO, "Got %u NHLT endpoints:\n", count); |
| while (count--) { |
| LOG(INFO, "Endpoint @ %p\n", desc); |
| LOG(INFO, " link_type: %u\n", desc->link_type); |
| LOG(INFO, " instance_id: %u\n", desc->instance_id); |
| LOG(INFO, " vendor_id: 0x%x\n", desc->vendor_id); |
| LOG(INFO, " device_id: 0x%x\n", desc->device_id); |
| LOG(INFO, " revision_id: %u\n", desc->revision_id); |
| LOG(INFO, " subsystem_id: %u\n", desc->subsystem_id); |
| LOG(INFO, " device_type: %u\n", desc->device_type); |
| LOG(INFO, " direction: %u\n", desc->direction); |
| LOG(INFO, " virtual_bus_id: %u\n", desc->virtual_bus_id); |
| LOG(INFO, " specific config @ %p size 0x%x\n", &desc->config, |
| desc->config.capabilities_size); |
| |
| auto formats = reinterpret_cast<const formats_config_t*>( |
| reinterpret_cast<const uint8_t*>(&desc->config) + |
| sizeof(desc->config.capabilities_size) + |
| desc->config.capabilities_size |
| ); |
| LOG(INFO, " formats_config @ %p count %u\n", formats, formats->format_config_count); |
| |
| desc = reinterpret_cast<const nhlt_descriptor_t*>( |
| reinterpret_cast<const uint8_t*>(desc) + desc->length); |
| if ((size_t)(reinterpret_cast<const uint8_t*>(desc) - |
| reinterpret_cast<const uint8_t*>(table)) > length) { |
| LOG(ERROR, "descriptor at %p out of bounds\n", desc); |
| break; |
| } |
| } |
| } |
| |
| void IntelAudioDsp::DumpFirmwareConfig(const TLVHeader* config, size_t length) { |
| LOG(INFO, "===== Firmware Config =====\n"); |
| size_t bytes = 0; |
| while (bytes < length) { |
| if (length - bytes <= sizeof(*config)) { |
| LOG(ERROR, "Got short firmware config TLV header\n"); |
| return; |
| } |
| |
| auto ptr = reinterpret_cast<const uint8_t*>(config); |
| auto cfg = reinterpret_cast<const TLVHeader*>(ptr + bytes); |
| auto type = static_cast<FirmwareConfigType>(cfg->type); |
| |
| if ((cfg->length + sizeof(*cfg)) > (bytes - length)) { |
| LOG(ERROR, "Got short firmware config TLV entry\n"); |
| return; |
| } |
| |
| // Values dumped below are all uint32_t |
| static constexpr size_t PAYLOAD_LENGTH = sizeof(uint32_t); |
| if (cfg->length < PAYLOAD_LENGTH) { |
| LOG(ERROR, "Got short firmware config payload length (got %u expected %zu)\n", |
| cfg->length, PAYLOAD_LENGTH); |
| continue; |
| } |
| |
| switch (type) { |
| case FirmwareConfigType::FW_VERSION: { |
| auto version = reinterpret_cast<const uint16_t*>(cfg->data); |
| LOG(INFO, " fw_version: %hu.%hu hotfix %hu (build %hu)\n", |
| version[0], version[1], version[2], version[3]); |
| break; |
| } |
| case FirmwareConfigType::MEMORY_RECLAIMED: { |
| auto memory = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " memory_reclaimed: %u\n", *memory); |
| break; |
| } |
| case FirmwareConfigType::SLOW_CLOCK_FREQ_HZ: { |
| auto freq = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " osc_freq: %u\n", *freq); |
| break; |
| } |
| case FirmwareConfigType::FAST_CLOCK_FREQ_HZ: { |
| auto freq = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " pll_freq: %u\n", *freq); |
| break; |
| } |
| case FirmwareConfigType::DMA_BUFFER_CONFIG: { |
| auto buf_cfg = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " dma_buf_count: %u\n", cfg->length / 8); |
| for (uint32_t i = 0; i < cfg->length / 8; i++) { |
| LOG(INFO, " dma_min_size[%02u]: %u\n", i, buf_cfg[i * 2]); |
| LOG(INFO, " dma_max_size[%02u]: %u\n", i, buf_cfg[(i * 2) + 1]); |
| } |
| break; |
| } |
| case FirmwareConfigType::ALH_SUPPORT_LEVEL: { |
| auto level = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " alh_support_level: %u\n", *level); |
| break; |
| } |
| case FirmwareConfigType::IPC_DL_MAILBOX_BYTES: { |
| auto bytes = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " mailbox_in_size: %u\n", *bytes); |
| break; |
| } |
| case FirmwareConfigType::IPC_UL_MAILBOX_BYTES: { |
| auto bytes = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " mailbox_out_size: %u\n", *bytes); |
| break; |
| } |
| case FirmwareConfigType::TRACE_LOG_BYTES: { |
| auto bytes = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " trace_log_size: %u\n", *bytes); |
| break; |
| } |
| case FirmwareConfigType::MAX_PPL_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_ppl_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_ASTATE_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_astate_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_MODULE_PIN_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_module_pin_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MODULES_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " modules_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_MOD_INST_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_mod_inst_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_LL_TASKS_PER_PRI_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, "max_ll_tasks_per_pri_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::LL_PRI_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " ll_pri_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_DP_TASKS_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_dp_tasks_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::MAX_LIBS_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " max_libs_count: %u\n", *count); |
| break; |
| } |
| case FirmwareConfigType::SCHEDULER_CONFIG: { |
| // Skip dumping this one |
| break; |
| } |
| case FirmwareConfigType::XTAL_FREQ_HZ: { |
| auto freq = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " xtal_freq_hz: %u\n", *freq); |
| break; |
| } |
| default: |
| LOG(ERROR, "Unknown firmware config type %u\n", cfg->type); |
| break; |
| } |
| bytes += sizeof(*cfg) + cfg->length; |
| } |
| } |
| |
| void IntelAudioDsp::DumpHardwareConfig(const TLVHeader* config, size_t length) { |
| LOG(INFO, "===== Hardware Config =====\n"); |
| size_t bytes = 0; |
| while (bytes < length) { |
| if (length - bytes <= sizeof(*config)) { |
| LOG(ERROR, "Got short hardware config TLV header\n"); |
| return; |
| } |
| |
| auto ptr = reinterpret_cast<const uint8_t*>(config); |
| auto cfg = reinterpret_cast<const TLVHeader*>(ptr + bytes); |
| auto type = static_cast<HardwareConfigType>(cfg->type); |
| |
| if ((cfg->length + sizeof(*cfg)) > (bytes - length)) { |
| LOG(ERROR, "Got short hardware config TLV entry\n"); |
| return; |
| } |
| |
| // Values dumped below are all uint32_t |
| static constexpr size_t PAYLOAD_LENGTH = sizeof(uint32_t); |
| if (cfg->length < PAYLOAD_LENGTH) { |
| LOG(ERROR, "Got short hardware config payload length (got %u expected %zu)\n", |
| cfg->length, PAYLOAD_LENGTH); |
| continue; |
| } |
| |
| switch (type) { |
| case HardwareConfigType::CAVS_VERSION: { |
| auto version = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " cavs_version: 0x%08x\n", *version); |
| break; |
| } |
| case HardwareConfigType::DSP_CORES: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " dsp_cores: %u\n", *count); |
| break; |
| } |
| case HardwareConfigType::MEM_PAGE_BYTES: { |
| auto bytes = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " mem_page_bytes: %u\n", *bytes); |
| break; |
| } |
| case HardwareConfigType::TOTAL_PHYS_MEM_PAGES: { |
| auto pages = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, "total_phys_mem_pages: %u\n", *pages); |
| break; |
| } |
| case HardwareConfigType::I2S_CAPS: { |
| // Skip dumping this one |
| break; |
| } |
| case HardwareConfigType::GPDMA_CAPS: { |
| // Skip dumping this one |
| break; |
| } |
| case HardwareConfigType::GATEWAY_COUNT: { |
| auto count = reinterpret_cast<const uint32_t*>(cfg->data); |
| LOG(INFO, " gateway_count: %u\n", *count); |
| break; |
| } |
| case HardwareConfigType::HP_EBB_COUNT: { |
| // Skip dumping this one |
| break; |
| } |
| case HardwareConfigType::LP_EBB_COUNT: { |
| // Skip dumping this one |
| break; |
| } |
| case HardwareConfigType::EBB_SIZE_BYTES: { |
| // Skip dumping this one |
| break; |
| } |
| default: |
| LOG(ERROR, "Unknown hardware config type %u\n", cfg->type); |
| break; |
| } |
| bytes += sizeof(*cfg) + cfg->length; |
| } |
| } |
| |
| void IntelAudioDsp::DumpModulesInfo(const ModuleEntry* info, uint32_t count) { |
| LOG(INFO, "num modules: %u\n", count); |
| for (uint32_t i = 0; i < count; i++) { |
| LOG(INFO, "[%02u]:\n", i); |
| LOG(INFO, " module_id: %u\n", info[i].module_id); |
| LOG(INFO, " state_flags: 0x%04x\n", info[i].state_flags); |
| char name[9] = { 0 }; |
| strncpy(name, reinterpret_cast<const char*>(info[i].name), sizeof(name)-1); |
| LOG(INFO, " name: %s\n", name); |
| LOG(INFO, " uuid: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n", |
| info[i].uuid[0], |
| info[i].uuid[1] & 0xFFFF, info[i].uuid[1] >> 16, |
| info[i].uuid[2] & 0xFF, |
| (info[i].uuid[2] >> 8) & 0xFF, |
| (info[i].uuid[2] >> 16) & 0xFF, |
| (info[i].uuid[2] >> 24) & 0xFF, |
| info[i].uuid[3] & 0xFF, |
| (info[i].uuid[3] >> 8) & 0xFF, |
| (info[i].uuid[3] >> 16) & 0xFF, |
| (info[i].uuid[3] >> 24) & 0xFF); |
| } |
| } |
| |
| void IntelAudioDsp::DumpPipelineListInfo(const PipelineListInfo* info) { |
| LOG(INFO, "num pipelines: %u\n", info->ppl_count); |
| for (uint32_t i = 0; i < info->ppl_count; i++) { |
| LOG(INFO, "[%02u]: id %u\n", i, info->ppl_id[i]); |
| } |
| } |
| |
| void IntelAudioDsp::DumpPipelineProps(const PipelineProps* props) { |
| LOG(INFO, " id: %u\n", props->id); |
| LOG(INFO, " priority: %u\n", props->priority); |
| LOG(INFO, " state: %u\n", props->state); |
| LOG(INFO, " total_memory_bytes: %u\n", props->total_memory_bytes); |
| LOG(INFO, " used_memory_bytes: %u\n", props->used_memory_bytes); |
| LOG(INFO, " context_pages: %u\n", props->context_pages); |
| LOG(INFO, "module_instance_count: %u\n", props->module_instances.module_instance_count); |
| for (uint32_t i = 0; i < props->module_instances.module_instance_count; i++) { |
| LOG(INFO, " module_instance[%1u]: id 0x%08x\n", |
| i, props->module_instances.module_instance_id[i]); |
| } |
| } |
| |
| } // namespace intel_hda |
| } // namespace audio |