/** @file
HD Audio NHLT Library implementation.
Copyright (c) 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
Returns pointer to Endpoint ENDPOINT_DESCRIPTOR structure.
@param[in] *NhltTable Endpoint for which Format address is retrieved
@param[in] FormatIndex Index of Format to be retrieved
@retval Pointer to ENDPOINT_DESCRIPTOR structure with given index
**/
ENDPOINT_DESCRIPTOR *
GetNhltEndpoint (
IN CONST NHLT_ACPI_TABLE *NhltTable,
IN CONST UINT8 EndpointIndex
)
{
UINT8 Index;
ENDPOINT_DESCRIPTOR *Endpoint;
Endpoint = (ENDPOINT_DESCRIPTOR*) (NhltTable->EndpointDescriptors);
if (EndpointIndex > NhltTable->EndpointCount) {
return NULL;
}
for (Index = 0; Index < EndpointIndex; Index++) {
Endpoint = (ENDPOINT_DESCRIPTOR*) ((UINT8*) (Endpoint) + Endpoint->EndpointDescriptorLength);
}
return Endpoint;
}
/**
Returns pointer to Endpoint Specific Configuration SPECIFIC_CONFIG structure.
@param[in] *Endpoint Endpoint for which config address is retrieved
@retval Pointer to SPECIFIC_CONFIG structure with endpoint's capabilities
**/
SPECIFIC_CONFIG *
GetNhltEndpointDeviceCapabilities (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint
)
{
return (SPECIFIC_CONFIG*) (&Endpoint->EndpointConfig);
}
/**
Returns pointer to all Formats Configuration FORMATS_CONFIG structure.
@param[in] *Endpoint Endpoint for which Formats address is retrieved
@retval Pointer to FORMATS_CONFIG structure
**/
FORMATS_CONFIG *
GetNhltEndpointFormatsConfig (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint
)
{
FORMATS_CONFIG *FormatsConfig;
FormatsConfig = (FORMATS_CONFIG*) ((UINT8*) (&Endpoint->EndpointConfig)
+ sizeof (Endpoint->EndpointConfig.CapabilitiesSize)
+ Endpoint->EndpointConfig.CapabilitiesSize);
return FormatsConfig;
}
/**
Returns pointer to Format Configuration FORMAT_CONFIG structure.
@param[in] *Endpoint Endpoint for which Format address is retrieved
@param[in] FormatIndex Index of Format to be retrieved
@retval Pointer to FORMAT_CONFIG structure with given index
**/
FORMAT_CONFIG *
GetNhltEndpointFormat (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint,
IN CONST UINT8 FormatIndex
)
{
UINT8 Index;
UINT32 Length;
FORMATS_CONFIG *FormatsConfig;
FORMAT_CONFIG *Format;
Length = 0;
FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
Format = FormatsConfig->FormatsConfiguration;
if (FormatIndex > FormatsConfig->FormatsCount) {
return NULL;
}
for (Index = 0; Index < FormatIndex; Index++) {
Length = sizeof (Format->Format) + Format->FormatConfiguration.CapabilitiesSize
+ sizeof (Format->FormatConfiguration.CapabilitiesSize);
Format = (FORMAT_CONFIG*) ((UINT8*) (Format) + Length);
}
return Format;
}
/**
Returns pointer to all Device Information DEVICES_INFO structure.
@param[in] *Endpoint Endpoint for which DevicesInfo address is retrieved
@retval Pointer to DEVICES_INFO structure
**/
DEVICES_INFO *
GetNhltEndpointDevicesInfo (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint
)
{
DEVICES_INFO *DevicesInfo;
FORMATS_CONFIG *FormatsConfig;
FORMAT_CONFIG *Format;
FormatsConfig = GetNhltEndpointFormatsConfig (Endpoint);
Format = GetNhltEndpointFormat (Endpoint, FormatsConfig->FormatsCount);
DevicesInfo = (DEVICES_INFO*) ((UINT8*) Format);
return DevicesInfo;
}
/**
Returns pointer to Device Information DEVICES_INFO structure.
@param[in] *Endpoint Endpoint for which Device Info address is retrieved
@param[in] DeviceInfoIndex Index of Device Info to be retrieved
@retval Pointer to DEVICE_INFO structure with given index
**/
DEVICE_INFO *
GetNhltEndpointDeviceInfo (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint,
IN CONST UINT8 DeviceInfoIndex
)
{
DEVICES_INFO *DevicesInfo;
DEVICE_INFO *DeviceInfo;
DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
DeviceInfo = DevicesInfo->DeviceInformation;
if (DevicesInfo == NULL || DeviceInfoIndex >= DevicesInfo->DeviceInfoCount) {
return NULL;
}
DeviceInfo = (DEVICE_INFO*) ((UINT8*) (DeviceInfo) + sizeof (*DeviceInfo) * DeviceInfoIndex);
return DeviceInfo;
}
/**
Returns pointer to OED Configuration SPECIFIC_CONFIG structure.
@param[in] *NhltTable NHLT table for which OED address is retrieved
@retval Pointer to SPECIFIC_CONFIG structure with NHLT capabilities
**/
SPECIFIC_CONFIG *
GetNhltOedConfig (
IN CONST NHLT_ACPI_TABLE *NhltTable
)
{
ENDPOINT_DESCRIPTOR *Endpoint;
SPECIFIC_CONFIG *OedConfig;
Endpoint = GetNhltEndpoint (NhltTable, (NhltTable->EndpointCount));
OedConfig = (SPECIFIC_CONFIG*) ((UINT8*) (Endpoint));
return OedConfig;
}
/**
Prints Format configuration.
@param[in] *Format Format to be printed
@retval None
**/
VOID
NhltFormatDump (
IN CONST FORMAT_CONFIG *Format
)
{
UINT32 Index;
DEBUG ((DEBUG_INFO, "------------------------------- FORMAT -------------------------------\n"));
DEBUG ((DEBUG_INFO, " Format->Format.Format.wFormatTag = 0x%x\n", Format->Format.Format.wFormatTag));
DEBUG ((DEBUG_INFO, " Format->Format.Format.nChannels = %d\n", Format->Format.Format.nChannels));
DEBUG ((DEBUG_INFO, " Format->Format.Format.nSamplesPerSec = %d\n", Format->Format.Format.nSamplesPerSec));
DEBUG ((DEBUG_INFO, " Format->Format.Format.nAvgBytesPerSec = %d\n", Format->Format.Format.nAvgBytesPerSec));
DEBUG ((DEBUG_INFO, " Format->Format.Format.nBlockAlign = %d\n", Format->Format.Format.nBlockAlign));
DEBUG ((DEBUG_INFO, " Format->Format.Format.wBitsPerSample = %d\n", Format->Format.Format.wBitsPerSample));
DEBUG ((DEBUG_INFO, " Format->Format.Format.cbSize = %d\n", Format->Format.Format.cbSize));
DEBUG ((DEBUG_INFO, " Format->Format.Samples = %d\n", Format->Format.Samples));
DEBUG ((DEBUG_INFO, " Format->Format.dwChannelMask = 0x%x\n", Format->Format.dwChannelMask));
DEBUG ((DEBUG_INFO, " Format->Format.SubFormat = %g\n", Format->Format.SubFormat));
DEBUG ((DEBUG_INFO, " Format->FormatConfiguration.CapabilitiesSize = %d B\n", Format->FormatConfiguration.CapabilitiesSize));
DEBUG ((DEBUG_VERBOSE, " Format->FormatConfiguration.Capabilities:"));
for (Index = 0; Index < ( Format->FormatConfiguration.CapabilitiesSize ) ; Index++) {
if (Index % 16 == 0) {
DEBUG ((DEBUG_VERBOSE, "\n"));
}
DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Format->FormatConfiguration.Capabilities[Index]));
}
DEBUG ((DEBUG_VERBOSE, "\n"));
}
/**
Prints Device Information.
@param[in] *DeviceInfo DeviceInfo to be printed
@retval None
**/
VOID
NhltDeviceInfoDump (
IN CONST DEVICE_INFO *DeviceInfo
)
{
DEBUG ((DEBUG_INFO, "----------------------------- DEVICE INFO ----------------------------\n"));
DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceId = %a\n", DeviceInfo->DeviceId));
DEBUG ((DEBUG_INFO, " DeviceInfo->DeviceInstanceId = 0x%x\n", DeviceInfo->DeviceInstanceId));
DEBUG ((DEBUG_INFO, " DeviceInfo->DevicePortId = 0x%x\n", DeviceInfo->DevicePortId));
}
/**
Prints Endpoint configuration.
@param[in] *Endpoint Endpoint to be printed
@retval None
**/
VOID
NhltEndpointDump (
IN CONST ENDPOINT_DESCRIPTOR *Endpoint
)
{
UINT8 Index;
FORMATS_CONFIG *FormatsConfigs;
FORMAT_CONFIG *Format;
DEVICES_INFO *DevicesInfo;
DEVICE_INFO *DeviceInfo;
DEBUG ((DEBUG_INFO, "------------------------------ ENDPOINT ------------------------------\n"));
DEBUG ((DEBUG_INFO, " Endpoint->DeviceDescriptorLength = %d B\n", Endpoint->EndpointDescriptorLength));
DEBUG ((DEBUG_INFO, " Endpoint->LinkType = 0x%x\n", Endpoint->LinkType));
DEBUG ((DEBUG_INFO, " Endpoint->InstanceId = 0x%x\n", Endpoint->InstanceId));
DEBUG ((DEBUG_INFO, " Endpoint->HwVendorId = 0x%x\n", Endpoint->HwVendorId));
DEBUG ((DEBUG_INFO, " Endpoint->HwDeviceId = 0x%x\n", Endpoint->HwDeviceId));
DEBUG ((DEBUG_INFO, " Endpoint->HwRevisionId = 0x%x\n", Endpoint->HwRevisionId));
DEBUG ((DEBUG_INFO, " Endpoint->HwSubsystemId = 0x%x\n", Endpoint->HwSubsystemId));
DEBUG ((DEBUG_INFO, " Endpoint->DeviceType = 0x%x\n", Endpoint->DeviceType));
DEBUG ((DEBUG_INFO, " Endpoint->Direction = 0x%x\n", Endpoint->Direction));
DEBUG ((DEBUG_INFO, " Endpoint->VirtualBusId = 0x%x\n", Endpoint->VirtualBusId));
DEBUG ((DEBUG_INFO, " Endpoint->EndpointConfig.CapabilitiesSize = %d B\n", Endpoint->EndpointConfig.CapabilitiesSize));
DEBUG ((DEBUG_VERBOSE, " Endpoint->EndpointConfig.Capabilities:"));
for (Index = 0; Index < (Endpoint->EndpointConfig.CapabilitiesSize ) ; Index++) {
if (Index % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
DEBUG ((DEBUG_VERBOSE, "0x%02x, ", Endpoint->EndpointConfig.Capabilities[Index]));
}
FormatsConfigs = GetNhltEndpointFormatsConfig (Endpoint);
DEBUG ((DEBUG_INFO, "\n"));
DEBUG ((DEBUG_INFO, " Endpoint->FormatsConfig.FormatsCount = %d\n", FormatsConfigs->FormatsCount));
for (Index = 0; Index < FormatsConfigs->FormatsCount; Index++) {
Format = GetNhltEndpointFormat (Endpoint, Index);
if (Format != NULL) {
NhltFormatDump (Format);
}
}
DevicesInfo = GetNhltEndpointDevicesInfo (Endpoint);
if (DevicesInfo != NULL) {
DEBUG ((DEBUG_INFO, "\n"));
DEBUG ((DEBUG_INFO, " Endpoint->DevicesInfo.DeviceInfoCount = %d\n", DevicesInfo->DeviceInfoCount));
for (Index = 0; Index < DevicesInfo->DeviceInfoCount; Index++) {
DeviceInfo = GetNhltEndpointDeviceInfo (Endpoint, Index);
if (DeviceInfo != NULL) {
NhltDeviceInfoDump (DeviceInfo);
}
}
}
DEBUG ((DEBUG_VERBOSE, "\n"));
}
/**
Prints OED (Offload Engine Driver) configuration.
@param[in] *OedConfig OED to be printed
@retval None
**/
VOID
NhltOedConfigDump (
IN CONST SPECIFIC_CONFIG *OedConfig
)
{
UINT8 Index;
DEBUG ((DEBUG_INFO, "-------------------------- OED CONFIGURATION -------------------------\n"));
DEBUG ((DEBUG_INFO, " OedConfig->CapabilitiesSize = %d B\n", OedConfig->CapabilitiesSize));
DEBUG ((DEBUG_VERBOSE, " OedConfig->Capabilities:"));
for (Index = 0; Index < (OedConfig->CapabilitiesSize) ; Index++) {
if (Index % 16 == 0) DEBUG ((DEBUG_VERBOSE, "\n"));
DEBUG ((DEBUG_VERBOSE, "0x%02x, ", OedConfig->Capabilities[Index]));
}
DEBUG ((DEBUG_VERBOSE, "\n"));
}
/**
Prints NHLT (Non HDA-Link Table) to be exposed via ACPI (aka. OED (Offload Engine Driver) Configuration Table).
@param[in] *NhltTable The NHLT table to print
@retval None
**/
VOID
NhltAcpiTableDump (
IN NHLT_ACPI_TABLE *NhltTable
)
{
DEBUG_CODE_BEGIN ();
UINT8 Index;
DEBUG ((DEBUG_INFO, "\n"));
DEBUG ((DEBUG_INFO, "--- NHLT ACPI Table Dump [OED (Offload Engine Driver) Configuration] ---\n"));
DEBUG ((DEBUG_INFO, "sizeof NHLT_ACPI_TABLE = %d B\n", sizeof (NHLT_ACPI_TABLE)));
DEBUG ((DEBUG_INFO, "sizeof EFI_ACPI_DESCRIPTION_HEADER = %d B\n", sizeof (EFI_ACPI_DESCRIPTION_HEADER)));
DEBUG ((DEBUG_INFO, "sizeof ENDPOINT_DESCRIPTOR = %d B\n", sizeof (ENDPOINT_DESCRIPTOR)));
DEBUG ((DEBUG_INFO, "sizeof SPECIFIC_CONFIG = %d B\n", sizeof (SPECIFIC_CONFIG)));
DEBUG ((DEBUG_INFO, "sizeof FORMATS_CONFIG = %d B\n", sizeof (FORMATS_CONFIG)));
DEBUG ((DEBUG_INFO, "sizeof FORMAT_CONFIG = %d B\n", sizeof (FORMAT_CONFIG)));
DEBUG ((DEBUG_INFO, "sizeof WAVEFORMATEXTENSIBLE = %d B\n", sizeof (WAVEFORMATEXTENSIBLE)));
DEBUG ((DEBUG_INFO, "sizeof DEVICES_INFO = %d B\n", sizeof (DEVICES_INFO)));
DEBUG ((DEBUG_INFO, "sizeof DEVICE_INFO = %d B\n", sizeof (DEVICE_INFO)));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Signature = 0x%08x\n", NhltTable->Header.Signature));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Length = 0x%08x\n", NhltTable->Header.Length));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Revision = 0x%02x\n", NhltTable->Header.Revision));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.Checksum = 0x%02x\n", NhltTable->Header.Checksum));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemId = %a\n", NhltTable->Header.OemId));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemTableId = 0x%lx\n", NhltTable->Header.OemTableId));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.OemRevision = 0x%08x\n", NhltTable->Header.OemRevision));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorId = 0x%08x\n", NhltTable->Header.CreatorId));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE Header.CreatorRevision = 0x%08x\n", NhltTable->Header.CreatorRevision));
DEBUG ((DEBUG_INFO, "\n"));
DEBUG ((DEBUG_INFO, " NHLT_ACPI_TABLE EndpointCount = %d\n", NhltTable->EndpointCount));
for (Index = 0; Index < NhltTable->EndpointCount; Index++) {
NhltEndpointDump (GetNhltEndpoint (NhltTable, Index));
}
NhltOedConfigDump (GetNhltOedConfig (NhltTable));
DEBUG ((DEBUG_INFO, "----------------------------------------------------------------------\n"));
DEBUG_CODE_END ();
}