AGESA_STATUS PcieAlibBuildAcpiTableV2 ( IN AMD_CONFIG_PARAMS *StdHeader, OUT VOID **AlibSsdtPtr ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; VOID *AlibSsdtBuffer; VOID *AlibSsdtTable; UINTN AlibSsdtlength; UINT32 AmlObjName; VOID *AmlObjPtr; IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Enter\n"); AgesaStatus = AGESA_SUCCESS; AlibSsdtTable = GnbFmAlibGetBaseTable (StdHeader); AlibSsdtlength = ((ACPI_TABLE_HEADER*) AlibSsdtTable)->TableLength; if (*AlibSsdtPtr == NULL) { AlibSsdtBuffer = GnbAllocateHeapBuffer ( AMD_ACPI_ALIB_BUFFER_HANDLE, AlibSsdtlength, StdHeader ); ASSERT (AlibSsdtBuffer != NULL); if (AlibSsdtBuffer == NULL) { return AGESA_ERROR; } *AlibSsdtPtr = AlibSsdtBuffer; } else { AlibSsdtBuffer = *AlibSsdtPtr; } // Check length of port data ASSERT (sizeof (_ALIB_PORT_DATA) <= 20); // Check length of global data ASSERT (sizeof (_ALIB_GLOBAL_DATA) <= 32); // Copy template to buffer LibAmdMemCopy (AlibSsdtBuffer, AlibSsdtTable, AlibSsdtlength, StdHeader); // Update table OEM fields. LibAmdMemCopy ( (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemId, (VOID *) &GnbBuildOptions.OemIdString, sizeof (GnbBuildOptions.OemIdString), StdHeader); LibAmdMemCopy ( (VOID *) &((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->OemTableId, (VOID *) &GnbBuildOptions.OemTableIdString, sizeof (GnbBuildOptions.OemTableIdString), StdHeader); // // Update register base base // PcieAlibUpdateGnbData (AlibSsdtBuffer, StdHeader); // // Update transfer block // AmlObjName = STRING_TO_UINT32 ('A', 'D', 'A', 'T'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); if (AmlObjPtr != NULL) { AmlObjPtr = (UINT8 *) AmlObjPtr + 10; } // Dispatch function from table Status = GnbLibDispatchFeaturesV2 (&AlibDispatchTableV2[0], AmlObjPtr, StdHeader); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (AgesaStatus != AGESA_SUCCESS) { //Shrink table length to size of the header ((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->TableLength = sizeof (ACPI_TABLE_HEADER); } ChecksumAcpiTable ((ACPI_TABLE_HEADER*) AlibSsdtBuffer, StdHeader); IDS_HDT_CONSOLE (GNB_TRACE, "PcieAlibBuildAcpiTableV2 Exit [0x%x]\n", AgesaStatus); return AgesaStatus; }
/** * * This function generates a complete CDIT table into a memory buffer. * After completion, this table must be set by the system BIOS into its * internal ACPI namespace, and linked into the RSDT/XSDT * * @param[in, out] StdHeader Standard Head Pointer * @param[in] PlatformConfig Config handle for platform specific information * @param[out] CditPtr Point to Cdit Struct including buffer address and length * * @retval UINT32 AGESA_STATUS */ AGESA_STATUS GetAcpiCditMain ( IN OUT AMD_CONFIG_PARAMS *StdHeader, IN PLATFORM_CONFIGURATION *PlatformConfig, OUT VOID **CditPtr ) { UINT8 MaxHops; UINT8 DomainNum; UINT8 i; UINT8 j; UINT8 *BufferPtr; UINT8 *SocketTopologyDataPtr; UINT8 *SocketTopologyPtr; ACPI_TABLE_HEADER *CpuCditHeaderStructPtr; AGESA_STATUS Flag; ALLOCATE_HEAP_PARAMS AllocStruct; MaxHops = 0; SocketTopologyPtr = NULL; Flag = AGESA_ERROR; // find out the pointer to the BufferHandle which contains // Node Topology information AcpiCditHBufferFind (StdHeader, &SocketTopologyPtr); if (SocketTopologyPtr == NULL) { return (Flag); } DomainNum = *SocketTopologyPtr; IDS_HDT_CONSOLE (CPU_TRACE, " CDIT is created\n"); // create a buffer by calling IBV callout routine AllocStruct.RequestedBufferSize = (DomainNum * DomainNum) + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + sizeof (ACPI_TABLE_HEADER); AllocStruct.BufferHandle = AMD_ACPI_CDIT_BUFFER_HANDLE; AllocStruct.Persist = HEAP_SYSTEM_MEM; if (HeapAllocateBuffer (&AllocStruct, StdHeader) != AGESA_SUCCESS) { return (Flag); } *CditPtr = AllocStruct.BufferPtr; //CDIT header LibAmdMemCopy (*CditPtr, (VOID *) &CpuCditHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); CpuCditHeaderStructPtr = (ACPI_TABLE_HEADER *) *CditPtr; CpuCditHeaderStructPtr->TableLength = (UINT32) AllocStruct.RequestedBufferSize; // Update table OEM fields. LibAmdMemCopy ((VOID *) &CpuCditHeaderStructPtr->OemId, (VOID *) &OptionCditConfiguration.OemIdString, sizeof (OptionCditConfiguration.OemIdString), StdHeader); LibAmdMemCopy ((VOID *) &CpuCditHeaderStructPtr->OemTableId, (VOID *) &OptionCditConfiguration.OemTableIdString, sizeof (OptionCditConfiguration.OemTableIdString), StdHeader); BufferPtr = *CditPtr; Flag = AGESA_SUCCESS; // CDIT body // get MaxHops SocketTopologyDataPtr = SocketTopologyPtr + sizeof (DomainNum); for (i = 0; i < DomainNum; i++) { for (j = 0; j < DomainNum; j++) { if (*SocketTopologyDataPtr > MaxHops) { MaxHops = *SocketTopologyDataPtr; } SocketTopologyDataPtr++; } } // the Max hop entries have a value of 13 // and all other entries have 10. SocketTopologyDataPtr = SocketTopologyPtr + sizeof (DomainNum); for (i = 0; i < DomainNum; i++) { for (j = 0; j < DomainNum; j++) { if (*SocketTopologyDataPtr++ == MaxHops) { *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + (i * DomainNum) + j) = 13; } else { *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + AMD_ACPI_CDIT_NUM_DOMAINS_LENGTH + (i * DomainNum) + j) = 10; } } } BufferPtr += sizeof (ACPI_TABLE_HEADER); *((UINT32 *) BufferPtr) = (UINT32) DomainNum; //Update CDIT header Checksum ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *CditPtr, StdHeader); return (Flag); }
AGESA_STATUS PcieAlibBuildAcpiTable ( IN AMD_CONFIG_PARAMS *StdHeader, OUT VOID **AlibSsdtPtr ) { AGESA_STATUS Status; UINT32 AmlObjName; PCIe_PLATFORM_CONFIG *Pcie; PP_FUSE_ARRAY *PpFuseArray; VOID *AlibSsdtBuffer; VOID *AmlObjPtr; UINT8 SclkVidArray[4]; UINT8 BootUpVid; UINT8 BootUpVidIndex; UINT8 Gen1VidIndex; UINTN Index; UINTN AlibSsdtlength; Status = AGESA_SUCCESS; AlibSsdtlength = ((ACPI_TABLE_HEADER*) &AlibSsdt[0])->TableLength; if (*AlibSsdtPtr == NULL) { AlibSsdtBuffer = GnbAllocateHeapBuffer ( AMD_ACPI_ALIB_BUFFER_HANDLE, AlibSsdtlength, StdHeader ); ASSERT (AlibSsdtBuffer != NULL); if (AlibSsdtBuffer == NULL) { return AGESA_ERROR; } *AlibSsdtPtr = AlibSsdtBuffer; } else { AlibSsdtBuffer = *AlibSsdtPtr; } // Copy template to buffer LibAmdMemCopy (AlibSsdtBuffer, &AlibSsdt[0], AlibSsdtlength, StdHeader); // Set PCI MMIO configuration // AmlObjName = '10DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '1'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); if (AmlObjPtr != NULL) { UINT64 MsrReg; LibAmdMsrRead (MSR_MMIO_Cfg_Base, &MsrReg, StdHeader); if ((MsrReg & BIT0) != 0 && (MsrReg & 0xFFFFFFFF00000000) == 0) { *(UINT32*)((UINT8*)AmlObjPtr + 5) = (UINT32)(MsrReg & 0xFFFFF00000); } else { Status = AGESA_ERROR; } } else { Status = AGESA_ERROR; } // Set voltage configuration PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, StdHeader); if (PpFuseArray != NULL) { // AmlObjName = '30DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '3'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { *(UINT8*)((UINT8*)AmlObjPtr + 5) = PpFuseArray->PcieGen2Vid; } else { Status = AGESA_ERROR; } } else { Status = AGESA_ERROR; } GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &SclkVidArray[0], StdHeader ); Gen1VidIndex = 0; BootUpVidIndex = 0; BootUpVid = 0xff; for (Index = 0; Index < 4; Index++) { if (SclkVidArray[Index] > SclkVidArray[Gen1VidIndex]) { Gen1VidIndex = (UINT8) Index; } if (SclkVidArray[Index] != 0 && SclkVidArray[Index] < BootUpVid) { BootUpVid = SclkVidArray[Index]; BootUpVidIndex = (UINT8) Index; } } // AmlObjName = '40DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '4'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { *(UINT8*)((UINT8*)AmlObjPtr + 5) = Gen1VidIndex; } else { Status = AGESA_ERROR; } // AmlObjName = '50DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '5'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { *(UINT8*)((UINT8*)AmlObjPtr + 5) = BootUpVidIndex; } else { Status = AGESA_ERROR; } // Set PCIe configuration if (PcieLocateConfigurationData (StdHeader, &Pcie) == AGESA_SUCCESS) { // AmlObjName = '20DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '2'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { *(UINT8*)((UINT8*)AmlObjPtr + 5) = Pcie->PsppPolicy; } else { Status = AGESA_ERROR; } // AmlObjName = '60DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '6'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, PcieAlibSetPortMaxSpeedCallback, (UINT8*)((UINT8*)AmlObjPtr + 7), Pcie ); } else { Status = AGESA_ERROR; } // AmlObjName = '80DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '8'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, PcieAlibSetPortOverrideSpeedCallback, (UINT8*)((UINT8*)AmlObjPtr + 7), Pcie ); } else { Status = AGESA_ERROR; } // AmlObjName = '70DA'; AmlObjName = Int32FromChar ('A', 'D', '0', '7'); AmlObjPtr = GnbLibFind (AlibSsdtBuffer, AlibSsdtlength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { PcieConfigRunProcForAllEngines ( DESCRIPTOR_ALLOCATED | DESCRIPTOR_PCIE_ENGINE, PcieAlibSetPortInfoCallback, (UINT8*)((UINT8*)AmlObjPtr + 4), Pcie ); } else { Status = AGESA_ERROR; } } else { ASSERT (FALSE); Status = AGESA_ERROR; } if (Status == AGESA_SUCCESS) { Status = PcieFmAlibBuildAcpiTable (AlibSsdtBuffer, StdHeader); } if (Status != AGESA_SUCCESS) { //Shrink table length to size of the header ((ACPI_TABLE_HEADER*) AlibSsdtBuffer)->TableLength = sizeof (ACPI_TABLE_HEADER); } ChecksumAcpiTable ((ACPI_TABLE_HEADER*) AlibSsdtBuffer, StdHeader); return Status; }
/** * * This function generates a complete SLIT table into a memory buffer. * After completion, this table must be set by the system BIOS into its * internal ACPI namespace, and linked into the RSDT/XSDT * * @param[in, out] StdHeader Standard Head Pointer * @param[in] PlatformConfig Config handle for platform specific information * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length * * @retval UINT32 AGESA_STATUS */ AGESA_STATUS GetAcpiSlitMain ( IN OUT AMD_CONFIG_PARAMS *StdHeader, IN PLATFORM_CONFIGURATION *PlatformConfig, IN OUT VOID **SlitPtr ) { UINT8 MaxHops; UINT8 SocketNum; UINT8 i; UINT8 j; UINT8 *BufferPtr; UINT8 *SocketTopologyDataPtr; UINT8 *SocketTopologyPtr; ACPI_TABLE_HEADER *CpuSlitHeaderStructPtr; AGESA_STATUS Flag; ALLOCATE_HEAP_PARAMS AllocStruct; MaxHops = 0; SocketTopologyPtr = NULL; Flag = AGESA_ERROR; // find out the pointer to the BufferHandle which contains // Node Topology information AcpiSlitHBufferFind (StdHeader, &SocketTopologyPtr); if (SocketTopologyPtr == 0) { return (Flag); } SocketNum = *SocketTopologyPtr; IDS_HDT_CONSOLE (CPU_TRACE, " SLIT is created\n"); // create a buffer by calling IBV callout routine AllocStruct.RequestedBufferSize = (SocketNum * SocketNum) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + sizeof (ACPI_TABLE_HEADER); AllocStruct.BufferHandle = AMD_ACPI_SLIT_BUFFER_HANDLE; AllocStruct.Persist = HEAP_SYSTEM_MEM; if (HeapAllocateBuffer (&AllocStruct, StdHeader) != AGESA_SUCCESS) { return (Flag); } *SlitPtr = AllocStruct.BufferPtr; //SLIT header LibAmdMemCopy (*SlitPtr, (VOID *) &CpuSlitHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader); CpuSlitHeaderStructPtr = (ACPI_TABLE_HEADER *) *SlitPtr; CpuSlitHeaderStructPtr->TableLength = (UINT32) AllocStruct.RequestedBufferSize; BufferPtr = *SlitPtr; Flag = AGESA_SUCCESS; // SLIT body // check if is PfMode (Prober Filer Mode) if (!IsFeatureEnabled (HtAssist, PlatformConfig, StdHeader)) { // probe filter is disabled // get MaxHops SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); for (i = 0; i < SocketNum; i++) { for (j = 0; j < SocketNum; j++) { if (*SocketTopologyDataPtr > MaxHops) { MaxHops = *SocketTopologyDataPtr; } SocketTopologyDataPtr++; } } // the Max hop entries have a value of 13 // and all other entries have 10. SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); for (i = 0; i < SocketNum; i++) { for (j = 0; j < SocketNum; j++) { if (*SocketTopologyDataPtr++ == MaxHops) { *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 13; } else { *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 10; } } } } else { // probe filter is enabled // formula : num_hops * 6 + 10 SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum); for (i = 0; i < SocketNum; i++) { for (j = 0; j < SocketNum; j++) { *(BufferPtr + sizeof (ACPI_TABLE_HEADER) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = ((*SocketTopologyDataPtr++) * 6) + 10; } } } BufferPtr += sizeof (ACPI_TABLE_HEADER); *((UINT64 *) BufferPtr) = (UINT64) SocketNum; //Update SLIT header Checksum ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SlitPtr, StdHeader); return (Flag); }