// found in the LICENSE file. #include "intel-audio-dsp.h" namespace audio { namespace intel_hda { void IntelAudioDsp::DumpRegs() { LOG(INFO, "ADSP registers\n"); LOG(INFO, "ADSPCS 0x%08x\n", REG_RD(®s()->adspcs)); LOG(INFO, "ADSPIC 0x%08x\n", REG_RD(®s()->adspic)); LOG(INFO, "ADSPIS 0x%08x\n", REG_RD(®s()->adspis)); LOG(INFO, "ADSPIC2 0x%08x\n", REG_RD(®s()->adspic2)); LOG(INFO, "ADSPIS2 0x%08x\n", REG_RD(®s()->adspis2)); LOG(INFO, "HIPCT 0x%08x\n", REG_RD(®s()->hipct)); LOG(INFO, "HIPCTE 0x%08x\n", REG_RD(®s()->hipcte)); LOG(INFO, "HIPCI 0x%08x\n", REG_RD(®s()->hipci)); LOG(INFO, "HIPCIE 0x%08x\n", REG_RD(®s()->hipcie)); LOG(INFO, "HIPCCTL 0x%08x\n", REG_RD(®s()->hipcctl)); LOG(INFO, "Code Loader registers\n"); LOG(INFO, "CTL_STS 0x%08x\n", REG_RD(®s()->cldma.stream.ctl_sts.w)); LOG(INFO, "CBL 0x%08x\n", REG_RD(®s()->cldma.stream.cbl)); LOG(INFO, "LVI 0x%08x\n", REG_RD(®s()->cldma.stream.lvi)); LOG(INFO, "FIFOD 0x%08x\n", REG_RD(®s()->cldma.stream.fifod)); LOG(INFO, "FMT 0x%08x\n", REG_RD(®s()->cldma.stream.fmt)); LOG(INFO, "BDPL 0x%08x\n", REG_RD(®s()->cldma.stream.bdpl)); LOG(INFO, "BDPU 0x%08x\n", REG_RD(®s()->cldma.stream.bdpu)); LOG(INFO, "SPBFCH 0x%08x\n", REG_RD(®s()->cldma.spbfch)); LOG(INFO, "SPBFCTL 0x%08x\n", REG_RD(®s()->cldma.spbfctl)); LOG(INFO, "SPIB 0x%08x\n", REG_RD(®s()->cldma.spib)); LOG(INFO, "MAXFIFOS 0x%08x\n", REG_RD(®s()->cldma.maxfifos)); LOG(INFO, "Firmware registers\n"); LOG(INFO, "FW_STATUS 0x%08x\n", REG_RD(&fw_regs()->fw_status)); LOG(INFO, "ERROR_CODE 0x%08x\n", REG_RD(&fw_regs()->error_code)); LOG(INFO, "FW_PWR_STATUS 0x%08x\n", REG_RD(&fw_regs()->fw_pwr_status)); LOG(INFO, "ROM_INFO 0x%08x\n", REG_RD(&fw_regs()->rom_info)); } 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( reinterpret_cast(&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( reinterpret_cast(desc) + desc->length); if ((size_t)(reinterpret_cast(desc) - reinterpret_cast(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(config); auto cfg = reinterpret_cast(ptr + bytes); auto type = static_cast(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(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(cfg->data); LOG(INFO, " memory_reclaimed: %u\n", *memory); break; } case FirmwareConfigType::SLOW_CLOCK_FREQ_HZ: { auto freq = reinterpret_cast(cfg->data); LOG(INFO, " osc_freq: %u\n", *freq); break; } case FirmwareConfigType::FAST_CLOCK_FREQ_HZ: { auto freq = reinterpret_cast(cfg->data); LOG(INFO, " pll_freq: %u\n", *freq); break; } case FirmwareConfigType::DMA_BUFFER_CONFIG: { auto buf_cfg = reinterpret_cast(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(cfg->data); LOG(INFO, " alh_support_level: %u\n", *level); break; } case FirmwareConfigType::IPC_DL_MAILBOX_BYTES: { auto bytes = reinterpret_cast(cfg->data); LOG(INFO, " mailbox_in_size: %u\n", *bytes); break; } case FirmwareConfigType::IPC_UL_MAILBOX_BYTES: { auto bytes = reinterpret_cast(cfg->data); LOG(INFO, " mailbox_out_size: %u\n", *bytes); break; } case FirmwareConfigType::TRACE_LOG_BYTES: { auto bytes = reinterpret_cast(cfg->data); LOG(INFO, " trace_log_size: %u\n", *bytes); break; } case FirmwareConfigType::MAX_PPL_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " max_ppl_count: %u\n", *count); break; } case FirmwareConfigType::MAX_ASTATE_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " max_astate_count: %u\n", *count); break; } case FirmwareConfigType::MAX_MODULE_PIN_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " max_module_pin_count: %u\n", *count); break; } case FirmwareConfigType::MODULES_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " modules_count: %u\n", *count); break; } case FirmwareConfigType::MAX_MOD_INST_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " max_mod_inst_count: %u\n", *count); break; } case FirmwareConfigType::MAX_LL_TASKS_PER_PRI_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, "max_ll_tasks_per_pri_count: %u\n", *count); break; } case FirmwareConfigType::LL_PRI_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " ll_pri_count: %u\n", *count); break; } case FirmwareConfigType::MAX_DP_TASKS_COUNT: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " max_dp_tasks_count: %u\n", *count); break; } case FirmwareConfigType::MAX_LIBS_COUNT: { auto count = reinterpret_cast(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(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(config); auto cfg = reinterpret_cast(ptr + bytes); auto type = static_cast(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(cfg->data); LOG(INFO, " cavs_version: 0x%08x\n", *version); break; } case HardwareConfigType::DSP_CORES: { auto count = reinterpret_cast(cfg->data); LOG(INFO, " dsp_cores: %u\n", *count); break; } case HardwareConfigType::MEM_PAGE_BYTES: { auto bytes = reinterpret_cast(cfg->data); LOG(INFO, " mem_page_bytes: %u\n", *bytes); break; } case HardwareConfigType::TOTAL_PHYS_MEM_PAGES: { auto pages = reinterpret_cast(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(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(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