1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402 |
- /** @file
- Update the _PRT and _PRW method for pci devices
- Copyright (c) 2013-2016 Intel Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "AcpiPlatform.h"
- PCI_DEVICE_INFO *mQNCPciInfo = NULL;
- /**
- Init Pci Device Structure
- @param mConfigData - Pointer of Pci Device information Structure
- **/
- VOID
- InitPciDeviceInfoStructure (
- PCI_DEVICE_SETTING *mConfigData
- )
- {
- //
- // Return 0 given that function unsupported.
- // Would need to parse ACPI tables and build mQNCPciInfo above
- // with found _PRT & _PRW methods for PCI devices.
- //
- mConfigData->PciDeviceInfoNumber = 0;
- }
- /**
- return Integer value.
- @param Data - AML data buffer
- @param Integer - integer value.
- @return Data size processed.
- **/
- UINTN
- SdtGetInteger (
- IN UINT8 *Data,
- OUT UINT64 *Integer
- )
- {
- *Integer = 0;
- switch (*Data) {
- case AML_ZERO_OP:
- return 1;
- case AML_ONE_OP:
- *Integer = 1;
- return 1;
- case AML_ONES_OP:
- *Integer = (UINTN)-1;
- return 1;
- case AML_BYTE_PREFIX:
- CopyMem (Integer, Data + 1, sizeof(UINT8));
- return 1 + sizeof(UINT8);
- case AML_WORD_PREFIX:
- CopyMem (Integer, Data + 1, sizeof(UINT16));
- return 1 + sizeof(UINT16);
- case AML_DWORD_PREFIX:
- CopyMem (Integer, Data + 1, sizeof(UINT32));
- return 1 + sizeof(UINT32);
- case AML_QWORD_PREFIX:
- CopyMem (Integer, Data + 1, sizeof(UINT64));
- return 1 + sizeof(UINT64);
- default:
- // Something wrong
- ASSERT (FALSE);
- return 1;
- }
- }
- /**
- Check if this handle has expected opcode.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param Handle ACPI handle
- @param OpCode Expected OpCode
- @param SubOpCode Expected SubOpCode
- @retval TRUE This handle has expected opcode
- @retval FALSE This handle does not have expected opcode
- **/
- BOOLEAN
- SdtIsThisTypeObject (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE Handle,
- IN UINT8 OpCode,
- IN UINT8 SubOpCode
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- Status = AcpiSdt->GetOption (Handle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- if (OpCode == AML_EXT_OP) {
- if (Data[1] == SubOpCode) {
- return TRUE;
- }
- } else {
- if (Data[0] == OpCode) {
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- Check if this handle has expected name and name value.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param Handle ACPI handle
- @param Name Expected name
- @param Value Expected name value
- @retval TRUE This handle has expected name and name value.
- @retval FALSE This handle does not have expected name and name value.
- **/
- BOOLEAN
- SdtIsNameIntegerValueEqual (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE Handle,
- IN CHAR8 *Name,
- IN UINT64 Value
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- UINT64 Integer;
- Status = AcpiSdt->GetOption (Handle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
- if (CompareMem (Data, Name, 4) != 0) {
- return FALSE;
- }
- //
- // Name match check object
- //
- Status = AcpiSdt->GetOption (Handle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- Integer = 0;
- SdtGetInteger (Data, &Integer);
- if (Integer != Value) {
- return FALSE;
- }
- // All match
- return TRUE;
- }
- /**
- Check if this handle's children has expected name and name value.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param ParentHandle ACPI parent handle
- @param Name Expected name
- @param Value Expected name value
- @retval TRUE This handle's children has expected name and name value.
- @retval FALSE This handle's children does not have expected name and name value.
- **/
- BOOLEAN
- SdtCheckNameIntegerValue (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE ParentHandle,
- IN CHAR8 *Name,
- IN UINT64 Value
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_ACPI_HANDLE Handle;
- EFI_STATUS Status;
- Handle = NULL;
- while (TRUE) {
- PreviousHandle = Handle;
- Status = AcpiSdt->GetChild (ParentHandle, &Handle);
- ASSERT_EFI_ERROR (Status);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- //
- // Done
- //
- if (Handle == NULL) {
- return FALSE;
- }
- //
- // Check this name
- //
- if (SdtIsThisTypeObject (AcpiSdt, Handle, AML_NAME_OP, 0)) {
- if (SdtIsNameIntegerValueEqual (AcpiSdt, Handle, Name, Value)) {
- return TRUE;
- }
- }
- }
- //
- // Should not run here
- //
- }
- /**
- Convert the pci address from VPD (bus,dev,fun) into the address that acpi table
- can recognize.
- @param PciAddress Pci address from VPD
- @retval return the address that acpi table can recognize
- **/
- UINT32
- SdtConvertToAcpiPciAdress (
- IN UINT32 PciAddress
- )
- {
- UINT32 ReturnAddress;
- ReturnAddress = ((PciAddress & 0x0000FF00) << 8) | (PciAddress & 0x000000FF);
- if ((PciAddress & 0x000000FF) == 0x000000FF)
- ReturnAddress |= 0x0000FFFF;
- return ReturnAddress;
- }
- /**
- return AML NameString size.
- @param Buffer - AML name string
- @return AML name string size
- **/
- UINTN
- SdtGetNameStringSize (
- IN UINT8 *Buffer
- )
- {
- UINTN SegCount;
- UINTN Length;
- Length = 0;
- //
- // Parse root or prefix
- //
- if (*Buffer == AML_ROOT_CHAR) {
- //
- // RootChar
- //
- Buffer ++;
- Length ++;
- } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
- //
- // ParentPrefixChar
- //
- Buffer ++;
- Length ++;
- while (*Buffer == AML_PARENT_PREFIX_CHAR) {
- Buffer ++;
- Length ++;
- }
- }
- //
- // Parse name segment
- //
- if (*Buffer == AML_DUAL_NAME_PREFIX) {
- //
- // DualName
- //
- Buffer ++;
- Length ++;
- SegCount = 2;
- } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
- //
- // MultiName
- //
- Buffer ++;
- Length ++;
- SegCount = *Buffer;
- Buffer ++;
- Length ++;
- } else if (*Buffer == 0) {
- //
- // NULL Name
- //
- SegCount = 0;
- Length ++;
- } else {
- //
- // NameSeg
- //
- SegCount = 1;
- }
- Buffer += 4 * SegCount;
- Length += 4 * SegCount;
- return Length;
- }
- /**
- The routine to check if this device is PCI root bridge.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param DeviceHandle ACPI device handle
- @param Context Context info - not used here
- @retval TRUE This is PCI root bridge
- @retval FALSE This is not PCI root bridge
- **/
- BOOLEAN
- SdtFindRootBridgeHandle (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE CheckHandle,
- IN VOID *Context
- )
- {
- BOOLEAN Result;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- EFI_STATUS Status;
- if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP))
- return FALSE;
- Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_HID", (UINT64)0x080AD041); // PNP0A08
- if (!Result) {
- Result = SdtCheckNameIntegerValue (AcpiSdt, CheckHandle, "_CID", (UINT64)0x030AD041); // PNP0A03
- if (!Result) {
- return Result;
- }
- }
- //
- // Found
- //
- Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
- return Result;
- }
- /**
- The routine to check if this device is wanted.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param DeviceHandle ACPI device handle
- @param Context Context info - not used here
- @retval TRUE This is PCI device wanted
- @retval FALSE This is not PCI device wanted
- **/
- BOOLEAN
- SdtFindPciDeviceHandle (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE CheckHandle,
- IN VOID *Context
- )
- {
- BOOLEAN Result;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- EFI_STATUS Status;
- if (!SdtIsThisTypeObject (AcpiSdt, CheckHandle, AML_EXT_OP, AML_EXT_DEVICE_OP))
- return FALSE;
- Result = SdtCheckNameIntegerValue (AcpiSdt,CheckHandle, "_ADR", (UINT64)*(UINT32 *)Context);
- if (!Result) {
- return Result;
- }
- //
- // Found
- //
- Status = AcpiSdt->GetOption (CheckHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
- return Result;
- }
- /**
- Go through the parent handle and find the handle which pass CheckHandleInfo.
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param ParentHandle ACPI parent handle
- @param CheckHandleInfo The callback routine to check if this handle meet the requirement
- @param Context The context of CheckHandleInfo
- @return the handle which is first one can pass CheckHandleInfo.
- **/
- EFI_ACPI_HANDLE
- SdtGetHandleByScanAllChilds (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE ParentHandle,
- IN CHECK_HANDLE_INFO CheckHandleInfo,
- IN VOID *Context
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_ACPI_HANDLE Handle;
- EFI_STATUS Status;
- EFI_ACPI_HANDLE ReturnHandle;
- //
- // Use deep first algo to enumerate all ACPI object
- //
- Handle = NULL;
- while (TRUE) {
- PreviousHandle = Handle;
- Status = AcpiSdt->GetChild (ParentHandle, &Handle);
- ASSERT_EFI_ERROR (Status);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- //
- // Done
- //
- if (Handle == NULL) {
- return NULL;
- }
- //
- // Check this handle
- //
- if (CheckHandleInfo (AcpiSdt, Handle, Context)) {
- return Handle;
- }
- //
- // Enumerate
- //
- ReturnHandle = SdtGetHandleByScanAllChilds (AcpiSdt, Handle, CheckHandleInfo, Context);
- if (ReturnHandle != NULL) {
- return ReturnHandle;
- }
- }
- //
- // Should not run here
- //
- }
- /**
- Check whether the INTx package is matched
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param INTxPkgHandle ACPI INTx package handle
- @param PciAddress Acpi pci address
- @param INTx Index of INTx pin
- @param IsAPIC Tell whether the returned INTx package is for APIC or not
- @retval TRUE the INTx package is matched
- @retval FALSE the INTx package is not matched
- **/
- BOOLEAN
- SdtCheckINTxPkgIsMatch (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE INTxPkgHandle,
- IN UINT32 PciAddress,
- IN UINT8 INTx,
- IN BOOLEAN *IsAPIC
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_STATUS Status;
- EFI_ACPI_HANDLE MemberHandle;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- UINT64 CurrentPciAddress;
- UINT64 CurrentINTx;
- UINTN ChildSize;
- //
- // Check the pci address
- //
- MemberHandle = NULL;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- CurrentPciAddress = 0;
- SdtGetInteger (Data, &CurrentPciAddress);
- if (CurrentPciAddress != PciAddress) {
- Status = AcpiSdt->Close (MemberHandle);
- ASSERT_EFI_ERROR (Status);
- return FALSE;
- }
- //
- // Check the pci interrupt pin
- //
- PreviousHandle = MemberHandle;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- CurrentINTx = 0;
- ChildSize = SdtGetInteger (Data, &CurrentINTx);
- Status = AcpiSdt->Close (MemberHandle);
- ASSERT_EFI_ERROR (Status);
- if (CurrentINTx != INTx)
- return FALSE;
- Data += ChildSize;
- if (*Data == AML_BYTE_PREFIX)
- Data += 1;
- //
- // Check the pci interrupt source
- //
- if (*Data != 0)
- *IsAPIC = FALSE;
- else
- *IsAPIC = TRUE;
- return TRUE;
- }
- /**
- Get the wanted INTx package inside the parent package
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param ParentPkgHandle ACPI parent package handle
- @param PciAddress Acpi pci address
- @param INTx Index of INTx pin
- @param INTxPkgHandle ACPI INTx package handle
- @param IsAPIC Tell whether the returned INTx package is for APIC or not
- **/
- VOID
- SdtGetINTxPkgHandle (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE ParentPkgHandle,
- IN UINT32 PciAddress,
- IN UINT8 INTx,
- IN EFI_ACPI_HANDLE *INTxPkgHandle,
- IN BOOLEAN *IsAPIC
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_STATUS Status;
- EFI_ACPI_HANDLE ChildPkgHandle;
- ChildPkgHandle = NULL;
- while (TRUE) {
- PreviousHandle = ChildPkgHandle;
- Status = AcpiSdt->GetChild (ParentPkgHandle, &ChildPkgHandle);
- ASSERT_EFI_ERROR (Status);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- if (ChildPkgHandle == NULL) {
- break;
- }
- if (SdtCheckINTxPkgIsMatch(AcpiSdt, ChildPkgHandle, PciAddress, INTx, IsAPIC)) {
- *INTxPkgHandle = ChildPkgHandle;
- return;
- }
- }
- return;
- }
- /**
- Update the INTx package with the correct pirq value
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param INTxPkgHandle ACPI INTx package handle
- @param PirqValue Correct pirq value
- @param IsAPIC Tell whether the INTx package is for APIC or not
- **/
- VOID
- SdtUpdateINTxPkg (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE INTxPkgHandle,
- IN UINT8 PirqValue,
- IN BOOLEAN IsAPIC
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_STATUS Status;
- EFI_ACPI_HANDLE MemberHandle;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- UINT64 TempValue;
- UINTN ChildSize;
- //
- // Check the pci address
- //
- MemberHandle = NULL;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- //
- // Check the pci interrupt pin
- //
- PreviousHandle = MemberHandle;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- ChildSize = SdtGetInteger (Data, &TempValue);
- Status = AcpiSdt->Close (MemberHandle);
- ASSERT_EFI_ERROR (Status);
- Data += ChildSize;
- //
- // update the pci interrupt source or source index
- //
- if (!IsAPIC) {
- ChildSize = SdtGetNameStringSize (Data);
- Data += (ChildSize - 1);
- PirqValue += 0x40; // change to ascii char
- if (*Data != PirqValue)
- *Data = PirqValue;
- } else {
- ChildSize = SdtGetInteger (Data, &TempValue);
- Data += ChildSize;
- Data += 1;
- if (*Data != PirqValue)
- *Data = PirqValue;
- }
- }
- /**
- Check every child package inside this interested parent package for update PRT
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param ParentPkgHandle ACPI parent package handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- VOID
- SdtCheckParentPackage (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE ParentPkgHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_ACPI_HANDLE INTAPkgHandle;
- EFI_ACPI_HANDLE INTBPkgHandle;
- EFI_ACPI_HANDLE INTCPkgHandle;
- EFI_ACPI_HANDLE INTDPkgHandle;
- UINT32 PciAddress = 0;
- BOOLEAN IsAllFunctions = FALSE;
- UINT8 IsAPIC = 0;
- EFI_STATUS Status;
- INTAPkgHandle = INTBPkgHandle = INTCPkgHandle = INTDPkgHandle = NULL;
- PciAddress = SdtConvertToAcpiPciAdress(PciDeviceInfo->DeviceAddress);
- if ((PciAddress & 0xFFFF) == 0xFFFF) {
- IsAllFunctions = TRUE;
- } else {
- IsAllFunctions = FALSE;
- PciAddress = (PciAddress | 0xFFFF);
- }
- SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 0, &INTAPkgHandle, (BOOLEAN *)&IsAPIC);
- SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 1, &INTBPkgHandle, (BOOLEAN *)&IsAPIC);
- SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 2, &INTCPkgHandle, (BOOLEAN *)&IsAPIC);
- SdtGetINTxPkgHandle (AcpiSdt, ParentPkgHandle, PciAddress, 3, &INTDPkgHandle, (BOOLEAN *)&IsAPIC);
- //
- // Check INTA
- //
- if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle != NULL)) {
- //
- // Find INTA package and there is valid INTA update item, update it
- //
- SdtUpdateINTxPkg (AcpiSdt, INTAPkgHandle, (PciDeviceInfo->INTA[IsAPIC]), IsAPIC);
- } else if ((PciDeviceInfo->INTA[IsAPIC] != 0xFF) && (INTAPkgHandle == NULL)) {
- //
- // There is valid INTA update item, but no INA package exist, should add it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould add INTA item for this device(0x%x)\n\n", PciAddress));
- } else if ((PciDeviceInfo->INTA[IsAPIC] == 0xFF) && (INTAPkgHandle != NULL) && IsAllFunctions) {
- //
- // For all functions senario, if there is invalid INTA update item, but INTA package does exist, should delete it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould remove INTA item for this device(0x%x)\n\n", PciAddress));
- }
- //
- // Check INTB
- //
- if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle != NULL)) {
- //
- // Find INTB package and there is valid INTB update item, update it
- //
- SdtUpdateINTxPkg (AcpiSdt, INTBPkgHandle, (PciDeviceInfo->INTB[IsAPIC]), IsAPIC);
- } else if ((PciDeviceInfo->INTB[IsAPIC] != 0xFF) && (INTBPkgHandle == NULL)) {
- //
- // There is valid INTB update item, but no INTB package exist, should add it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould add INTB item for this device(0x%x)\n\n", PciAddress));
- } else if ((PciDeviceInfo->INTB[IsAPIC] == 0xFF) && (INTBPkgHandle != NULL) && IsAllFunctions) {
- //
- // For all functions senario, if there is invalid INTB update item, but INTB package does exist, should delete it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould remove INTB item for this device(0x%x)\n\n", PciAddress));
- }
- //
- // Check INTC
- //
- if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle != NULL)) {
- //
- // Find INTC package and there is valid INTC update item, update it
- //
- SdtUpdateINTxPkg (AcpiSdt, INTCPkgHandle, (PciDeviceInfo->INTC[IsAPIC]), IsAPIC);
- } else if ((PciDeviceInfo->INTC[IsAPIC] != 0xFF) && (INTCPkgHandle == NULL)) {
- //
- // There is valid INTC update item, but no INTC package exist, should add it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould add INTC item for this device(0x%x)\n\n", PciAddress));
- } else if ((PciDeviceInfo->INTC[IsAPIC] == 0xFF) && (INTCPkgHandle != NULL) && IsAllFunctions) {
- //
- // For all functions senario, if there is invalid INTC update item, but INTC package does exist, should delete it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould remove INTC item for this device(0x%x)\n\n", PciAddress));
- }
- //
- // Check INTD
- //
- if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle != NULL)) {
- //
- // Find INTD package and there is valid INTD update item, update it
- //
- SdtUpdateINTxPkg (AcpiSdt, INTDPkgHandle, (PciDeviceInfo->INTD[IsAPIC]), IsAPIC);
- } else if ((PciDeviceInfo->INTD[IsAPIC] != 0xFF) && (INTDPkgHandle == NULL)) {
- //
- // There is valid INTD update item, but no INTD package exist, should add it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould add INTD item for this device(0x%x)\n\n", PciAddress));
- } else if ((PciDeviceInfo->INTD[IsAPIC] == 0xFF) && (INTDPkgHandle != NULL) && IsAllFunctions) {
- //
- // For all functions senario, if there is invalid INTD update item, but INTD package does exist, should delete it
- //
- DEBUG ((EFI_D_ERROR, "\n\nShould remove INTD item for this device(0x%x)\n\n", PciAddress));
- }
- if (INTAPkgHandle != NULL) {
- Status = AcpiSdt->Close (INTAPkgHandle);
- ASSERT_EFI_ERROR (Status);
- }
- if (INTBPkgHandle != NULL) {
- Status = AcpiSdt->Close (INTBPkgHandle);
- ASSERT_EFI_ERROR (Status);
- }
- if (INTCPkgHandle != NULL) {
- Status = AcpiSdt->Close (INTCPkgHandle);
- ASSERT_EFI_ERROR (Status);
- }
- if (INTDPkgHandle != NULL) {
- Status = AcpiSdt->Close (INTDPkgHandle);
- ASSERT_EFI_ERROR (Status);
- }
- return;
- }
- /**
- Check every return package for update PRT
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param ParentHandle ACPI pci device handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- VOID
- SdtCheckReturnPackage (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE MethodHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_ACPI_HANDLE ReturnHandle;
- EFI_ACPI_HANDLE PackageHandle;
- EFI_ACPI_HANDLE NamePkgHandle;
- EFI_STATUS Status;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- CHAR8 NameStr[128];
- ReturnHandle = NULL;
- while (TRUE) {
- PreviousHandle = ReturnHandle;
- Status = AcpiSdt->GetChild (MethodHandle, &ReturnHandle);
- ASSERT_EFI_ERROR (Status);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- if (ReturnHandle == NULL) {
- break;
- }
- Status = AcpiSdt->GetOption (ReturnHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- if (*Data == AML_RETURN_OP) {
- //
- // Find the return method handle, then look for the returned package data
- //
- Status = AcpiSdt->GetOption (ReturnHandle, 1, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- if (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING) {
- ZeroMem (NameStr, 128);
- AsciiStrCpyS (NameStr, 128, "\\_SB.");
- DataSize = SdtGetNameStringSize (Data);
- AsciiStrnCatS (NameStr, 128, (CHAR8 *)Data, DataSize);
- NamePkgHandle = NULL;
- Status = AcpiSdt->FindPath (mDsdtHandle, NameStr, &NamePkgHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (NamePkgHandle != NULL);
- Status = AcpiSdt->GetOption (NamePkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- ASSERT (*Data == AML_NAME_OP);
- Status = AcpiSdt->GetOption (NamePkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
- }
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
- //
- // Get the parent package handle
- //
- PackageHandle = NULL;
- Status = AcpiSdt->Open (Data, &PackageHandle);
- ASSERT_EFI_ERROR (Status);
- //
- // Check the parent package for update pci routing
- //
- SdtCheckParentPackage (AcpiSdt, PackageHandle, PciDeviceInfo);
- Status = AcpiSdt->Close (PackageHandle);
- ASSERT_EFI_ERROR (Status);
- Status = AcpiSdt->Close (ReturnHandle);
- ASSERT_EFI_ERROR (Status);
- break;
- }
- //
- // Not ReturnOp, search it as parent
- //
- SdtCheckReturnPackage (AcpiSdt, ReturnHandle, PciDeviceInfo);
- }
- //
- // Done
- //
- return;
- }
- /**
- update interrupt info inside the PRT method for the given pci device handle
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param PciHandle ACPI pci device handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- EFI_STATUS
- SdtUpdatePrtMethod (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE PciHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_HANDLE PrtMethodHandle;
- //
- // Find the PRT method under this pci device
- //
- PrtMethodHandle = NULL;
- Status = AcpiSdt->FindPath (PciHandle, "_PRT", &PrtMethodHandle);
- if (EFI_ERROR (Status)) {
- return EFI_INVALID_PARAMETER;
- }
- if (PrtMethodHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- SdtCheckReturnPackage(AcpiSdt, PrtMethodHandle, PciDeviceInfo);
- Status = AcpiSdt->Close (PrtMethodHandle);
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- /**
- Update the package inside name op with correct wakeup resources
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param InPkgHandle ACPI inside package handle
- @param GPEPin Correct gpe pin
- @param SxNum Correct system state the device can wake up from
- **/
- VOID
- SdtUpdatePackageInName (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE INTxPkgHandle,
- IN UINT8 GPEPin,
- IN UINT8 SxNum
- )
- {
- EFI_ACPI_HANDLE PreviousHandle;
- EFI_STATUS Status;
- EFI_ACPI_HANDLE MemberHandle;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- //
- // Check the gpe pin
- //
- MemberHandle = NULL;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- //
- // Skip byte prefix
- //
- Data += 1;
- if (*Data != GPEPin) {
- *Data = GPEPin;
- }
- //
- // Check the sx number
- //
- PreviousHandle = MemberHandle;
- Status = AcpiSdt->GetChild (INTxPkgHandle, &MemberHandle);
- ASSERT_EFI_ERROR (Status);
- ASSERT (MemberHandle != NULL);
- if (PreviousHandle != NULL) {
- Status = AcpiSdt->Close (PreviousHandle);
- ASSERT_EFI_ERROR (Status);
- }
- Status = AcpiSdt->GetOption (MemberHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- //
- // Skip byte prefix
- //
- Data += 1;
- if (*Data != SxNum) {
- *Data = SxNum;
- }
- Status = AcpiSdt->Close (MemberHandle);
- ASSERT_EFI_ERROR (Status);
- }
- /**
- Check the name package belonged to PRW
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param PrwPkgHandle ACPI PRW package handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- VOID
- SdtCheckNamePackage (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE PrwPkgHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_ACPI_HANDLE InPkgHandle;
- EFI_STATUS Status;
- EFI_ACPI_DATA_TYPE DataType;
- UINT8 *Data;
- UINTN DataSize;
- Status = AcpiSdt->GetOption (PrwPkgHandle, 0, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE);
- ASSERT (*Data == AML_NAME_OP);
- Status = AcpiSdt->GetOption (PrwPkgHandle, 2, &DataType, (CONST VOID **)&Data, &DataSize);
- ASSERT_EFI_ERROR (Status);
- ASSERT (DataType == EFI_ACPI_DATA_TYPE_CHILD);
- //
- // Get the inside package handle
- //
- InPkgHandle = NULL;
- Status = AcpiSdt->Open (Data, &InPkgHandle);
- ASSERT_EFI_ERROR (Status);
- //
- // update the package in name op for wakeup info
- //
- if ((PciDeviceInfo->GPEPin != 0xFF) && (PciDeviceInfo->SxNum != 0xFF))
- SdtUpdatePackageInName (AcpiSdt, InPkgHandle, PciDeviceInfo->GPEPin, PciDeviceInfo->SxNum);
- Status = AcpiSdt->Close (InPkgHandle);
- ASSERT_EFI_ERROR (Status);
- return;
- }
- /**
- update wakeup info inside the PRW method for the given pci device handle
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param PciHandle ACPI pci device handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- EFI_STATUS
- SdtUpdatePrwPackage (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE PciHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_HANDLE PrwPkgHandle;
- //
- // Find the PRT method under this pci device
- //
- PrwPkgHandle = NULL;
- Status = AcpiSdt->FindPath (PciHandle, "_PRW", &PrwPkgHandle);
- if (EFI_ERROR (Status)) {
- return EFI_INVALID_PARAMETER;
- }
- if (PrwPkgHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- SdtCheckNamePackage(AcpiSdt, PrwPkgHandle, PciDeviceInfo);
- Status = AcpiSdt->Close (PrwPkgHandle);
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- /**
- update pci routing information in acpi table based on pcd settings
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param PciRootHandle ACPI root bridge handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- EFI_STATUS
- SdtUpdatePciRouting (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE PciRootHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_HANDLE PciBridgeHandle;
- UINT32 PciAddress;
- PciBridgeHandle = NULL;
- if (PciDeviceInfo->BridgeAddress == 0x00000000) {
- //
- // Its bridge is the host root bridge
- //
- PciBridgeHandle = PciRootHandle;
- } else {
- //
- // Its bridge is just a pci device under the host bridge
- //
- //
- // Conver the bridge address into one that acpi table can recognize
- //
- PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress);
- //
- // Scan the whole table to find the pci device
- //
- PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress);
- if (PciBridgeHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- }
- Status = SdtUpdatePrtMethod(AcpiSdt, PciBridgeHandle, PciDeviceInfo);
- if (PciDeviceInfo->BridgeAddress != 0x00000000) {
- Status = AcpiSdt->Close (PciBridgeHandle);
- ASSERT_EFI_ERROR (Status);
- }
- return Status;
- }
- /**
- update power resource wake up information in acpi table based on pcd settings
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param PciRootHandle ACPI root bridge handle
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- **/
- EFI_STATUS
- SdtUpdatePowerWake (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE PciRootHandle,
- IN PCI_DEVICE_INFO *PciDeviceInfo
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_HANDLE PciBridgeHandle;
- EFI_ACPI_HANDLE PciDeviceHandle;
- UINT32 PciAddress;
- PciBridgeHandle = NULL;
- if (PciDeviceInfo->BridgeAddress == 0x00000000) {
- //
- // Its bridge is the host root bridge
- //
- PciBridgeHandle = PciRootHandle;
- } else {
- //
- // Its bridge is just a pci device under the host bridge
- //
- //
- // Conver the bridge address into one that acpi table can recognize
- //
- PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->BridgeAddress);
- //
- // Scan the whole table to find the pci device
- //
- PciBridgeHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciRootHandle, SdtFindPciDeviceHandle, &PciAddress);
- if (PciBridgeHandle == NULL) {
- Status = AcpiSdt->Close (PciRootHandle);
- ASSERT_EFI_ERROR (Status);
- return EFI_INVALID_PARAMETER;
- }
- }
- PciDeviceHandle = NULL;
- //
- // Conver the device address into one that acpi table can recognize
- //
- PciAddress = SdtConvertToAcpiPciAdress (PciDeviceInfo->DeviceAddress);
- //
- // Scan the whole table to find the pci device
- //
- PciDeviceHandle = SdtGetHandleByScanAllChilds(AcpiSdt, PciBridgeHandle, SdtFindPciDeviceHandle, &PciAddress);
- if (PciDeviceHandle == NULL) {
- if (PciDeviceInfo->BridgeAddress != 0x00000000) {
- Status = AcpiSdt->Close (PciBridgeHandle);
- ASSERT_EFI_ERROR (Status);
- }
- return EFI_INVALID_PARAMETER;
- }
- Status = SdtUpdatePrwPackage(AcpiSdt, PciDeviceHandle, PciDeviceInfo);
- Status = AcpiSdt->Close (PciDeviceHandle);
- ASSERT_EFI_ERROR (Status);
- if (PciDeviceInfo->BridgeAddress != 0x00000000) {
- Status = AcpiSdt->Close (PciBridgeHandle);
- ASSERT_EFI_ERROR (Status);
- }
- return Status;
- }
- /**
- Get the root bridge handle by scanning the acpi table
- @param AcpiSdt Pointer to Acpi SDT protocol
- @param DsdtHandle ACPI root handle
- @retval EFI_ACPI_HANDLE the handle of the root bridge
- **/
- EFI_ACPI_HANDLE
- SdtGetRootBridgeHandle (
- IN EFI_ACPI_SDT_PROTOCOL *AcpiSdt,
- IN EFI_ACPI_HANDLE DsdtHandle
- )
- {
- EFI_ACPI_HANDLE PciRootHandle;
- //
- // Scan the whole table to find the root bridge
- //
- PciRootHandle = NULL;
- PciRootHandle = SdtGetHandleByScanAllChilds(AcpiSdt, DsdtHandle, SdtFindRootBridgeHandle, NULL);
- ASSERT (PciRootHandle != NULL);
- return PciRootHandle;
- }
- /**
- Check input Pci device info is changed from the default values
- @param PciDeviceInfo Pointer to PCI_DEVICE_INFO
- @param UpdatePRT Pointer to BOOLEAN
- @param UpdatePRW Pointer to BOOLEAN
- **/
- VOID
- SdtCheckPciDeviceInfoChanged (
- IN PCI_DEVICE_INFO *PciDeviceInfo,
- IN BOOLEAN *UpdatePRT,
- IN BOOLEAN *UpdatePRW
- )
- {
- UINTN Index = 0;
- if (mQNCPciInfo == NULL) {
- *UpdatePRT = FALSE;
- *UpdatePRW = FALSE;
- return;
- }
- *UpdatePRT = TRUE;
- *UpdatePRW = TRUE;
- for (Index = 0;Index < CURRENT_PCI_DEVICE_NUM; Index++) {
- if ((mQNCPciInfo[Index].BridgeAddress == PciDeviceInfo->BridgeAddress)
- && (mQNCPciInfo[Index].DeviceAddress == PciDeviceInfo->DeviceAddress)) {
- //
- // Find one matched entry
- //
- if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 10) == 0) {
- *UpdatePRT = FALSE;
- *UpdatePRW = FALSE;
- //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and no change\n", Index));
- } else {
- if (CompareMem (&(mQNCPciInfo[Index].INTA[0]), &PciDeviceInfo->INTA[0], 8) == 0)
- *UpdatePRT = FALSE;
- if (CompareMem (&(mQNCPciInfo[Index].GPEPin), &PciDeviceInfo->GPEPin, 2) == 0)
- *UpdatePRW = FALSE;
- if (*(UINT64 *)(&PciDeviceInfo->INTA[0]) == 0xFFFFFFFFFFFFFFFFULL)
- *UpdatePRT = FALSE;
- if (*(UINT16 *)(&PciDeviceInfo->GPEPin) == 0xFFFF)
- *UpdatePRW = FALSE;
- //DEBUG ((EFI_D_ERROR, "Find one matched entry[%d] and but need update PRT:0x%x PRW:0x%x\n", Index, *UpdatePRT, *UpdatePRW));
- }
- break;
- }
- }
- //if (Index == 42) {
- // DEBUG ((EFI_D_ERROR, "Find No matched entry\n"));
- //}
- return;
- }
|