12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385 |
- /** @file
- @copyright
- Copyright 1999 - 2021 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Guid/SocketPciResourceData.h>
- #include <Guid/SocketIioVariable.h>
- #include "PciHostBridge.h"
- #include "PciRootBridge.h"
- #include <CpuAndRevisionDefines.h>
- #include <Library/UefiRuntimeServicesTableLib.h>
- #include <Protocol/IioUds.h>
- #include "PciRebalance.h"
- /******************************************************************************
- * Local definitions.
- ******************************************************************************/
- extern CHAR16 *mAcpiAddressSpaceTypeStr[];
- extern CHAR16 *mPciResourceTypeStr[];
- extern EFI_IIO_UDS_PROTOCOL *mIioUds;
- /******************************************************************************
- * Variables.
- ******************************************************************************/
- /**
- * The table below is a cache with pointers to protocol instances created at
- * Host Bridge initialization. It also provides mapping of protocol instance
- * to the PCI stack.
- */
- PCI_ROOT_BRIDGE_INSTANCE *mPciRootBridgeTable[MAX_SOCKET][MAX_LOGIC_IIO_STACK] = {0};
- PCI_ROOT_BRIDGE_INSTANCE *mPciRootBridgeTableReserved[MAX_SOCKET][IIO_RESERVED_1] = {0};
- /******************************************************************************
- * Functions.
- ******************************************************************************/
- /**
- Find socket and stack index for given PCI Root Bridge protocol pointer.
- @param[out] PciResConfigPtr - Buffer for the resource configuration variable.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_NOT_FOUND The variable was not found.
- @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
- @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
- **/
- EFI_STATUS
- PciRootBridge2SocketStack (
- IN PCI_ROOT_BRIDGE_INSTANCE *RootBridgePtr,
- OUT UINT8 *SocketPtr,
- OUT UINT8 *StackPtr
- )
- {
- UINT8 Socket;
- UINT8 Stack;
- if (RootBridgePtr != NULL) {
- for (Socket = 0; Socket < NELEMENTS(mPciRootBridgeTable); Socket++) {
- for (Stack = 0; Stack < NELEMENTS(mPciRootBridgeTable[Socket]); Stack++) {
- if (mPciRootBridgeTable[Socket][Stack] == RootBridgePtr) {
- if (SocketPtr != NULL) {
- *SocketPtr = Socket;
- }
- if (StackPtr != NULL) {
- *StackPtr = Stack;
- }
- return EFI_SUCCESS;
- }
- }
- }
- }
- return EFI_NOT_FOUND;
- }
- /**
- Determine the last stack for a given socket
- @param Socket the socket for which the last socket is desired
- @return the number of the last socket
- */
- UINT8
- LastStackOfSocket (
- UINT8 Socket
- )
- {
- UINT8 LastStack;
- BOOLEAN FoundEnabledStack;
- UINT8 Stack;
- ASSERT (Socket < ARRAY_SIZE(mIioUds->IioUdsPtr->PlatformData.IIO_resource));
- ASSERT (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid);
- FoundEnabledStack = FALSE;
- LastStack = 0;
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)) {
- LastStack = Stack;
- FoundEnabledStack = TRUE;
- }
- }
- ASSERT (FoundEnabledStack);
- return LastStack;
- }
- /**
- Determine the last stack for a given socket with resources
- @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per stack
- @param Socket - Index of the Socket
- @param ResourceType - Type of resource that requires alignment
- @param LastStack - Pointer that will store the value of the last stack with resources allocated to it
- @param ResourceSize - Pointer that will store the sum of the requested resource type
- @return The last stack with resources allocated to it and the
- total amount of resoures requested of the type
- requested.
- */
- VOID
- LastStackWithResources (
- IN CPU_RESOURCE *SocketResources,
- IN UINT8 Socket,
- IN PCI_RESOURCE_TYPE ResourceType,
- OUT UINT8 *LastStack,
- OUT UINT64 *ResourceSize
- )
- {
- UINT8 Stack;
- *LastStack = 0;
- *ResourceSize = 0;
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- switch (ResourceType) {
- case TypeIo:
- if (SocketResources->StackRes[Stack].NumIoPortsDesired != 0) {
- *ResourceSize += SocketResources->StackRes[Stack].NumIoPortsDesired + 1;
- *LastStack = Stack;
- }
- break;
- case TypeMem32:
- if (SocketResources->StackRes[Stack].MmiolLength != 0) {
- *ResourceSize += SocketResources->StackRes[Stack].MmiolLength + 1;
- *LastStack = Stack;
- }
- break;
- case TypeMem64:
- if (SocketResources->StackRes[Stack].MmiohLength != 0) {
- *ResourceSize += SocketResources->StackRes[Stack].MmiohLength + 1;
- *LastStack = Stack;
- }
- break;
- default:
- break;
- }
- }
- }
- /**
- Visit all stacks in this socket and recalculate the resource ranges per stack based on resource
- needs from PCI/PCIe device/functions.
- @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per stack
- @param Socket - Index of the Socket
- @param ResourceType - type of resource that requires alignment
- @retval EFI_SUCCESS - Succeed.
- @retval EFI_OUT_OF_RESOURCES - Not enough resources to be adjusted within the socket.
- **/
- EFI_STATUS
- AdjustResources (
- CPU_RESOURCE *SocketResources,
- UINT8 Socket,
- UINT8 ResourceType
- )
- {
- UINT8 Stack;
- UINT64 NewLength;
- CONST UINT8 LastStack = LastStackOfSocket (Socket);
- UINT64 PreviousLimit;
- BOOLEAN FirstStack = TRUE;
- switch (ResourceType) {
- case TypeIo:
- // Return if IoResourceNeeds is not zero which indicates a socket adjustment is needed
- if(SocketResources->IoResourceNeeds != 0){
- return EFI_OUT_OF_RESOURCES;
- }
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))){
- continue;
- }
- //
- // For the first enabled stack, use the base I/O address for the socket, otherwise
- // calculate the new base based off the last enabled stack
- //
- if (FirstStack) {
- // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
- // Start with valid resources for current socket
- SocketResources->StackRes[Stack].IoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
- FirstStack = FALSE;
- } else {
- // Check to see if the previous stack is disabled by checking for equal base and limit
- if (SocketResources->StackRes[Stack-1].IoBase == SocketResources->StackRes[Stack-1].IoLimit) {
- if (PreviousLimit % 2 == 1) {
- PreviousLimit += 1;
- }
- SocketResources->StackRes[Stack].IoBase = (UINT16) PreviousLimit;
- } else {
- SocketResources->StackRes[Stack].IoBase = (UINT16) PreviousLimit + 1;
- }
- }
- NewLength = SocketResources->StackRes[Stack].NumIoPortsDesired;
- //
- //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
- //make adjustments if NewLength is zero
- //
- if (Stack == LastStack) {
- if (NewLength != 0) {
- if (SocketResources->IoResourcesLeft != 0) {
- NewLength += SocketResources->IoResourcesLeft + 1;
- }
- } else {
- NewLength = SocketResources->IoResourcesLeft;
- }
- }
- SocketResources->StackRes[Stack].NeedIoUpdate = TRUE;
- SocketResources->StackRes[Stack].IoLimit = (UINT16)(SocketResources->StackRes[Stack].IoBase + NewLength);
- PreviousLimit = SocketResources->StackRes[Stack].IoLimit;
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoBase =%x newLength = %x\n",Socket,Stack,SocketResources->StackRes[Stack].IoBase,NewLength));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoLimit =%x\n",Socket,Stack,SocketResources->StackRes[Stack].IoLimit));
- }
- break;
- case TypeMem32:
- //
- // Return if MmiolResourceNeeds is not zero which indicates a socket adjustment is needed
- //
- if (SocketResources->MmiolResourceNeeds != 0) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Visit all Stacks in this Socket and recalculate the New Mem32 Ranges per Stack
- //
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++){
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- //
- // For the first enabled stack, use the base low mmio address for the socket, otherwize
- // calculate the new base based off the last enabled stack
- //
- if (FirstStack) {
- // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
- // Start with valid resources for current socket
- SocketResources->StackRes[Stack].MmiolBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
- FirstStack = FALSE;
- } else {
- // Check to see if the previous stack is disabled by checking for equal base and limit
- if (SocketResources->StackRes[Stack-1].MmiolBase == SocketResources->StackRes[Stack-1].MmiolLimit) {
- if (PreviousLimit % 2 == 1) {
- PreviousLimit += 1;
- }
- SocketResources->StackRes[Stack].MmiolBase = (UINT32) PreviousLimit;
- } else {
- SocketResources->StackRes[Stack].MmiolBase = (UINT32) PreviousLimit + 1;
- }
- }
- //
- // Verify if this Stack is the one that requires an update and calculate the new Limit
- // otherwise assign the new limit based on the Chunk and Extra Chunk calculation and assign the Newlength
- //
- NewLength = SocketResources->StackRes[Stack].MmiolLength;
- //
- //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
- //make adjustments if NewLength is zero
- //
- if (Stack == LastStack) {
- if (NewLength != 0) {
- if (SocketResources->MmiolResourcesLeft){
- NewLength += SocketResources->MmiolResourcesLeft + 1;
- }
- } else {
- NewLength = SocketResources->MmiolResourcesLeft;
- }
- }
- SocketResources->StackRes[Stack].MmiolUpdate = 1;
- SocketResources->StackRes[Stack].MmiolLimit = (UINT32)(SocketResources->StackRes[Stack].MmiolBase + NewLength);
- PreviousLimit = SocketResources->StackRes[Stack].MmiolLimit;
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolBase =%x newLength = %x\n",Socket,Stack,SocketResources->StackRes[Stack].MmiolBase,NewLength));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolLimit =%x\n",Socket,Stack,SocketResources->StackRes[Stack].MmiolLimit));
- }
- break;
- case TypeMem64:
- // Return if MmiohResourceNeeds is not zero which indicates a socket adjustment is needed
- if (SocketResources->MmiohResourceNeeds != 0){
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // Visit all Stacks in this Socket and recalculate the New Mem64 Ranges per Stack
- //
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if(!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))){
- continue;
- }
- //
- // For the first enabled stack, use the base high mmio address for the socket, otherwise
- // calculate the new base based off the last enabled stack
- //
- if (FirstStack) {
- // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
- // Start with valid resources for current socket
- SocketResources->StackRes[Stack].MmiohBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
- FirstStack = FALSE;
- } else {
- // Check to see if the previous stack is disabled by checking for equal base and limit
- if (SocketResources->StackRes[Stack-1].MmiohBase == SocketResources->StackRes[Stack-1].MmiohLimit) {
- if (PreviousLimit % 2 == 1) {
- PreviousLimit += 1;
- }
- SocketResources->StackRes[Stack].MmiohBase = PreviousLimit;
- } else {
- SocketResources->StackRes[Stack].MmiohBase = PreviousLimit + 1;
- }
- }
- //
- // Verify if this Stack is the one that requires an update and calculate the new Limit
- // otherwise assign the new limit based on the Chunk and Extra Chunk calculation and assign the Newlength
- //
- NewLength = SocketResources->StackRes[Stack].MmiohLength;
- //
- //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
- //make adjustments if NewLength is zero
- //
- if (Stack == LastStack) {
- if (NewLength != 0) {
- if (SocketResources->MmiohResourcesLeft) {
- NewLength += SocketResources->MmiohResourcesLeft + 1;
- }
- } else {
- NewLength = SocketResources->MmiohResourcesLeft;
- }
- }
- SocketResources->StackRes[Stack].MmiohUpdate = 1;
- SocketResources->StackRes[Stack].MmiohLimit = (SocketResources->StackRes[Stack].MmiohBase + NewLength);
- PreviousLimit = SocketResources->StackRes[Stack].MmiohLimit;
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohBase =%lx newLength = %lx\n",Socket,Stack,SocketResources->StackRes[Stack].MmiohBase,NewLength));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohLimit =%lx\n",Socket,Stack,SocketResources->StackRes[Stack].MmiohLimit));
- } // for Stack
- break;
- default:
- DEBUG((DEBUG_ERROR, "[PCI] ERROR: Resource Type Unknown = %x\n", ResourceType));
- break;
- }// switch
- return EFI_SUCCESS;
- }
- /**
- Adjust resource ratio assignment among sockets to fit the resource needs from PCI devices.
- @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per socket
- @param ResourceType - type of resource that requires alignment
- @param ValidSockets - Number of Valid Sockets, need it to calculate how resources need to be splitted
- @retval EFI_SUCCESS - Succeed.
- @retval EFI_OUT_OF_RESOURCES - Not enough resources to be adjusted within the socket.
- **/
- EFI_STATUS
- AdjustSocketResources (
- CPU_RESOURCE *SocketResources,
- UINT8 ResourceType,
- UINT8 ValidSockets
- )
- {
- EFI_STATUS Status;
- switch(ResourceType){
- case TypeIo:
- Status = AdjustSocketIo (SocketResources, ResourceType, ValidSockets);
- break;
- case TypeMem32:
- Status = AdjustSocketMmioL (SocketResources, ResourceType, ValidSockets);
- break;
- case TypeMem64:
- Status = AdjustSocketMmioH (SocketResources, ResourceType, ValidSockets);
- break;
- default:
- DEBUG((DEBUG_ERROR, "[PCI] ERROR: Resource Type Unknown = %x\n", ResourceType));
- Status = EFI_INVALID_PARAMETER;
- break;
- } // switch
- return Status;
- }
- /**
- Compare current system resource map with rebalance request NVRAM variable to see if stored settings were applied.
- @param[in] SocketPciResourceData - Pointer to stored CPU resource map
- @retval TRUE - SYSTEM_PCI_BASE_LIMITS has been rejected and was not applied or not initialized
- @retval FALSE - SYSTEM_PCI_BASE_LIMITS has been applied and still has relevant data
- **/
- BOOLEAN
- IsResourceMapRejected (
- SYSTEM_PCI_BASE_LIMITS *SocketPciResourceData
- )
- {
- UINT8 Socket;
- UINT8 Stack;
- BOOLEAN Rejected = FALSE;
- PCI_BASE_LIMITS *StackLimits;
- PCI_BASE_LIMITS *UboxStackLimits;
- PCI_BASE_LIMITS *SocketLimits;
- STACK_RES *IioUdsUboxStackLimits;
- STACK_RES *IioUdsStackLimits;
- IIO_RESOURCE_INSTANCE *IioUdsSocketLimits;
- if (SocketPciResourceData == NULL) {
- return TRUE;
- }
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid) {
- IioUdsSocketLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket];
- SocketLimits = &SocketPciResourceData->Socket[Socket].SocketLimits;
- IioUdsUboxStackLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UBOX_STACK];
- UboxStackLimits = &SocketPciResourceData->Socket[Socket].StackLimits[UBOX_STACK];
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)) {
- IioUdsStackLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack];
- StackLimits = &SocketPciResourceData->Socket[Socket].StackLimits[Stack];
- //
- // Per stack
- //
- if (Socket == 0 && Stack == 0) {
- // First base starts at zero, mIioUds struct reserves 4K of Io for legacy purposes
- if (StackLimits->Io.Base != 0) {
- Rejected = TRUE;
- }
- } else {
- if (IioUdsStackLimits->PciResourceIoBase != StackLimits->Io.Base && StackLimits->Io.Base != 0) {
- Rejected = TRUE;
- }
- }
- if (IioUdsStackLimits->PciResourceIoLimit != StackLimits->Io.Limit && StackLimits->Io.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d.%d] Current I/O: 0x%04X..0x%04X\n", Socket, Stack,
- IioUdsStackLimits->PciResourceIoBase, IioUdsStackLimits->PciResourceIoLimit);
- PCIDEBUG ("[%d.%d] Saved I/O: 0x%04X..0x%04X %a\n", Socket, Stack,
- StackLimits->Io.Base, StackLimits->Io.Limit,
- (StackLimits->Io.Limit != 0 && Rejected) ? "rejected" : "");
- if (IioUdsStackLimits->Mmio32Base != StackLimits->LowMmio.Base && StackLimits->LowMmio.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsStackLimits->Mmio32Limit != StackLimits->LowMmio.Limit && StackLimits->LowMmio.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d.%d] Current MMIOL: 0x%08X..0x%08X\n", Socket, Stack,
- IioUdsStackLimits->Mmio32Base, IioUdsStackLimits->Mmio32Limit);
- PCIDEBUG ("[%d.%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket, Stack,
- StackLimits->LowMmio.Base, StackLimits->LowMmio.Limit,
- (StackLimits->LowMmio.Limit != 0 && Rejected) ? "rejected" : "");
- if (IioUdsStackLimits->Mmio64Base != StackLimits->HighMmio.Base && StackLimits->HighMmio.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsStackLimits->Mmio64Limit != StackLimits->HighMmio.Limit && StackLimits->HighMmio.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d.%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket, Stack,
- IioUdsStackLimits->Mmio64Base, IioUdsStackLimits->Mmio64Limit);
- PCIDEBUG ("[%d.%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket, Stack,
- StackLimits->HighMmio.Base, StackLimits->HighMmio.Limit,
- (StackLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
- }
- }
- //
- // Per socket
- //
- if (IioUdsSocketLimits->PciResourceIoBase != SocketLimits->Io.Base && SocketLimits->Io.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsSocketLimits->PciResourceIoLimit != SocketLimits->Io.Limit && SocketLimits->Io.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG("[%d] Current I/O: 0x%04X..0x%04X\n", Socket,
- IioUdsSocketLimits->PciResourceIoBase, IioUdsSocketLimits->PciResourceIoLimit);
- PCIDEBUG("[%d] Saved I/O: 0x%04X..0x%04X %a\n", Socket,
- SocketLimits->Io.Base, SocketLimits->Io.Limit,
- (SocketLimits->Io.Limit != 0 && Rejected) ? "rejected" : "");
- if (IioUdsSocketLimits->Mmio32Base != SocketLimits->LowMmio.Base && SocketLimits->LowMmio.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsSocketLimits->Mmio32Limit != SocketLimits->LowMmio.Limit && SocketLimits->LowMmio.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d] Current MMIOL: 0x%08X..0x%08X\n", Socket,
- IioUdsSocketLimits->Mmio32Base, IioUdsSocketLimits->Mmio32Limit);
- PCIDEBUG ("[%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket,
- SocketLimits->LowMmio.Base, SocketLimits->LowMmio.Limit,
- (SocketLimits->LowMmio.Limit != 0 && Rejected) ? "rejected" : "");
- if (IioUdsSocketLimits->Mmio64Base != SocketLimits->HighMmio.Base && SocketLimits->HighMmio.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsSocketLimits->Mmio64Limit != SocketLimits->HighMmio.Limit && SocketLimits->HighMmio.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket,
- IioUdsSocketLimits->Mmio64Base, IioUdsSocketLimits->Mmio64Limit);
- PCIDEBUG ("[%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket,
- SocketLimits->HighMmio.Base, SocketLimits->HighMmio.Limit,
- (SocketLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
- if (IioUdsUboxStackLimits->Mmio64Base != UboxStackLimits->HighMmio.Base && UboxStackLimits->HighMmio.Base != 0) {
- Rejected = TRUE;
- }
- if (IioUdsUboxStackLimits->Mmio64Limit != UboxStackLimits->HighMmio.Limit && UboxStackLimits->HighMmio.Limit != 0) {
- Rejected = TRUE;
- }
- PCIDEBUG ("[%d] Current UBOX: 0x%08X..0x%08X\n", Socket,
- IioUdsUboxStackLimits->Mmio64Base, IioUdsUboxStackLimits->Mmio64Limit);
- PCIDEBUG ("[%d] Saved UBOX: 0x%08X..0x%08X %a\n", Socket,
- UboxStackLimits->HighMmio.Base, UboxStackLimits->HighMmio.Limit,
- (UboxStackLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
- }
- }
- DEBUG ((DEBUG_INFO, "[PCI] Resource rebalance rejected ? %a\n", Rejected ? "TRUE" : "FALSE"));
- return Rejected;
- }
- /**
- Verify whether system resource map changed comparing to the state when rebalance request was created.
- @param[in] PciResConfigPtr - Buffer with the rebalance request.
- @return If current map is different than the one used when rebalance was created true is returned,
- otherwise false.
- **/
- BOOLEAN
- IsSystemMapChanged (
- IN SYSTEM_PCI_BASE_LIMITS *PciResConfigPtr
- )
- {
- UINT8 Socket;
- if (PciResConfigPtr->MmioHBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base ||
- PciResConfigPtr->MmioHGranularity != *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity) {
- DEBUG ((DEBUG_ERROR, "[PCI] %s: MMIOH Base %012llX [%llX] != %012llX [%llX] - system map changed\n",
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
- PciResConfigPtr->MmioHBase, PciResConfigPtr->MmioHGranularity,
- mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base,
- *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity));
- return TRUE;
- }
- if (PciResConfigPtr->MmioLBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base ||
- PciResConfigPtr->MmioLLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit ||
- PciResConfigPtr->MmioLGranularity != mIioUds->IioUdsPtr->PlatformData.MmiolGranularity) {
- DEBUG ((DEBUG_ERROR, "[PCI] %s: MMIOL %08X..%08X [%X] != %08X..%08X [%X] - system map changed\n",
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
- PciResConfigPtr->MmioLBase, PciResConfigPtr->MmioLLimit, PciResConfigPtr->MmioLGranularity,
- mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base,
- mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit,
- mIioUds->IioUdsPtr->PlatformData.MmiolGranularity));
- return TRUE;
- }
- if (PciResConfigPtr->IoBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase ||
- PciResConfigPtr->IoLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit ||
- PciResConfigPtr->IoGranularity != mIioUds->IioUdsPtr->PlatformData.IoGranularity) {
- DEBUG ((DEBUG_ERROR, "[PCI] %s: I/O %04X..%04X [%X] != %04X..%04X [%X] - system map changed\n",
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
- PciResConfigPtr->IoBase, PciResConfigPtr->IoLimit, PciResConfigPtr->IoGranularity,
- mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase,
- mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit,
- mIioUds->IioUdsPtr->PlatformData.IoGranularity));
- return TRUE;
- }
- for (Socket = 0; Socket < NELEMENTS (PciResConfigPtr->Socket); Socket++) {
- if (PciResConfigPtr->StackPresentBitmap[Socket] !=
- mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap) {
- DEBUG ((DEBUG_ERROR, "[PCI] %s: Stack bitmap mismach (%04X != %04X) in socket %d - system map changed\n",
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, PciResConfigPtr->StackPresentBitmap[Socket],
- mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap, Socket));
- return TRUE;
- }
- }
- return FALSE;
- } // IsSystemMapChanged()
- /**
- Adjust resource ratio assignment among CPU sockets to fit the resource needs from PCI devices.
- Update Setup variable if there are changes from the existing ratio requests for this boot.
- @param[in] HostBridgeInstance - The Host Bridge Instance where the resource adjustment happens.
- @param[out] Result - Output parameter. Indicates whether changes have been made.
- **/
- VOID
- AdjustResourceAmongRootBridges (
- IN PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance,
- OUT SOCKET_RESOURCE_ADJUSTMENT_RESULT *Result
- )
- {
- PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
- LIST_ENTRY *List;
- CPU_RESOURCE SocketResources[MAX_SOCKET];
- UINT64 SocketIoLength;
- UINT64 SocketMem32Length;
- UINT64 SocketMem64Length;
- UINT64 SocketIoBase;
- UINT64 SocketMem32Base;
- UINT64 SocketMem64Base;
- UINT64 RsvLenAtBegin;
- UINT64 RsvLenAtEnd;
- UINT64 StackLength;
- UINT64 NewLength;
- UINT64 Alignment;
- UINT64 Remainder;
- UINT8 Socket;
- UINT8 ValidSockets;
- BOOLEAN ChangedType[TypeMax];
- BOOLEAN ChangedTypeOOR[TypeMax]; // Change type for out of resources
- UINT8 TypeIndex;
- UINT8 ChangedBitMap;
- EFI_STATUS Status;
- UINTN VarSize;
- SYSTEM_PCI_BASE_LIMITS SocketPciResourceData;
- UINT8 Stack;
- UINT8 LastStack;
- UINT16 IoGranularity;
- UINT32 MmiolGranularity;
- UINT64 MmiohGranularity;
- BOOLEAN OutOfResources;
- UINT32 UboxMmioSize;
- BOOLEAN IsVirtualRootBridge;
- PCI_BASE_LIMITS *CurStackLimits;
- PCI_BASE_LIMITS *UboxStackLimits;
- PCI_BASE_LIMITS *CurSocketLimits;
- UINT32 PlatGlobalMmiolBase;
- UINT32 VtdBarSize;
- *Result = SocketResourceRatioNotChanged;
- SetMem (ChangedType, TypeMax, FALSE);
- SetMem (ChangedTypeOOR, TypeMax, FALSE);
- ChangedBitMap = 0;
- OutOfResources = FALSE;
- IsVirtualRootBridge = FALSE;
- IoGranularity = mIioUds->IioUdsPtr->PlatformData.IoGranularity;
- MmiolGranularity = mIioUds->IioUdsPtr->PlatformData.MmiolGranularity;
- MmiohGranularity = (UINT64) mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.lo;
- MmiohGranularity |= ((UINT64)mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.hi) << 32;
- ZeroMem (&SocketResources[0], sizeof(SocketResources));
- //
- // Read the system resource cfg from NVRAM. If the variable does not exist just create new one.
- // If variable exists, check if it was applied by KTI. If not we got two options possible:
- // (1) it is not valid because system resource map changed, or
- // (2) it is not valid because of unknown reason.
- // The first case is detected and new request shall be created for rebalance.
- // In the second case just continue boot to avoid reboot loop.
- //
- VarSize = sizeof(SocketPciResourceData);
- ZeroMem (&SocketPciResourceData, sizeof(SocketPciResourceData));
- Status = gRT->GetVariable (SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, &gEfiSocketPciResourceDataGuid,
- NULL, &VarSize, &SocketPciResourceData);
- if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND && Status != EFI_BUFFER_TOO_SMALL) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- if (Status == EFI_BUFFER_TOO_SMALL) {
- VarSize += 1; // Make it not equal to sizeof(SocketPciResourceData)
- }
- if (VarSize != sizeof(SocketPciResourceData)) {
- PCIDEBUG ("Got variable '%s' of unexpected size %d (expect %d)\n",
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, VarSize, sizeof(SocketPciResourceData));
- }
- if (Status != EFI_NOT_FOUND) {
- //
- // Variable exists, let's check if it was applied by KTI.
- //
- if (IsResourceMapRejected (&SocketPciResourceData)) {
- //
- // Rejected so check if system resources map was changed.
- //
- if (!IsSystemMapChanged (&SocketPciResourceData) && VarSize == sizeof(SocketPciResourceData)) {
- DEBUG ((DEBUG_ERROR, "[PCI] ERROR: Resource rebalance rejected by KTI - continue without rebalance\n"));
- return;
- }
- ZeroMem (&SocketPciResourceData, sizeof(SocketPciResourceData));
- }
- }
- UboxMmioSize = mIioUds->IioUdsPtr->PlatformData.UboxMmioSize;
- PlatGlobalMmiolBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
- ValidSockets = 0;
- for (List = HostBridgeInstance->RootBridges.ForwardLink, Socket = 0; Socket < MAX_SOCKET; Socket ++) {
- if (!mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid) {
- continue;
- }
- ValidSockets++;
- //
- // Calculate the length of resources available per socket
- //
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit) {
- SocketIoBase = 0;
- SocketIoLength = 0;
- } else {
- SocketIoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
- SocketIoLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
- }
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit) {
- SocketMem32Base = 0;
- SocketMem32Length = 0;
- } else {
- SocketMem32Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
- SocketMem32Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
- // Reserve 8M for ubox mmio
- SocketMem32Length = SocketMem32Length - UboxMmioSize;
- }
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit) {
- SocketMem64Base = 0;
- SocketMem64Length = 0;
- } else{
- SocketMem64Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
- SocketMem64Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
- }
- // Get all the resources that are in this socket
- SocketResources[Socket].IoResourcesLeft = (UINT16)SocketIoLength;
- SocketResources[Socket].MmiolResourcesLeft = (UINT32)SocketMem32Length;
- SocketResources[Socket].MmiohResourcesLeft = (UINT64)SocketMem64Length;
- LastStack = LastStackOfSocket (Socket);
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
- //
- // Check IO Resource
- //
- Alignment = RootBridgeInstance->ResAllocNode[TypeIo].Alignment + 1;
- NewLength = RootBridgeInstance->ResAllocNode[TypeIo].Length;
- if (IsVirtualRootBridge) {
- NewLength += NewLength;
- }
- // IoTrap allocates 256 byte range from GCD for common pool usage
- // For device to fit move to the next available alignment
- if ((Socket == 0) && (Stack == 0)) {
- NewLength += Alignment;
- }
- if (NewLength != 0) {
- //
- // At least 2KB align per KTI requirement. Add the length requested with given alignment.
- // If the sum is not 2KB aligned add on the remainder that would make it align.
- // Bump up to 4KB for root bridge requirements
- // Have to make sure Alignment is handled for direct address allocation
- //
- Remainder = SocketIoBase & (Alignment - 1);
- if (Remainder != 0) {
- NewLength += Alignment - Remainder;
- }
- if (NewLength % (IoGranularity * 2)) {
- Remainder = (IoGranularity * 2) - (NewLength % (IoGranularity * 2));
- NewLength += Remainder;
- }
- //
- // Store length as length - 1 for handling
- //
- NewLength -= 1;
- // Zero StackLength if its disable or negative
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit) {
- StackLength = 0;
- } else {
- StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase;
- }
- SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = (UINT16)NewLength;
- // Check if new length can fit in the socket or stack
- if (SocketResources[Socket].IoResourcesLeft > (UINT16)NewLength) {
- SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength + 1;
- } else if (SocketResources[Socket].IoResourcesLeft == (UINT16)NewLength) {
- SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength;
- } else {
- // If there are resources left consume them
- if (SocketResources[Socket].IoResourcesLeft != 0) {
- NewLength = NewLength - SocketResources[Socket].IoResourcesLeft - 1;
- SocketResources[Socket].IoResourcesLeft = 0;
- }
- SocketResources[Socket].IoResourceNeeds += (UINT16)NewLength + 1;
- OutOfResources = TRUE;
- ChangedTypeOOR[TypeIo] = TRUE;
- }
- SocketResources[Socket].StackRes[Stack].IoAlignment = Alignment;
- if (NewLength > StackLength) {
- SocketResources[Socket].StackRes[Stack].NeedIoUpdate = TRUE;
- //IoResourcesLeft is UINT16 type, not 2's-complement value.
- if (SocketResources[Socket].IoResourcesLeft > SocketIoLength) {
- DEBUG ((DEBUG_ERROR, "[PCI] Out of Resources for Socket = %x Stack = %x Type = %x\n",
- Socket, Stack, TypeIo));
- SocketResources[Socket].IoResourcesLeft = 0;
- }
- ChangedType[TypeIo] = TRUE;
- }
- SocketIoBase += SocketResources[Socket].StackRes[Stack].NumIoPortsDesired + 1;
- DEBUG ((DEBUG_INFO, "SocketResources[%x].IoResourceLeft = %x\n",
- Socket, SocketResources[Socket].IoResourcesLeft));
- DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoAlignment = %x\n",
- Socket, Stack, SocketResources[Socket].StackRes[Stack].IoAlignment));
- } else {
- SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = 0;
- }
- //
- // Check Mmem32 resource. This Host bridge does not support separated MEM / PMEM requests,
- // so only count MEM requests here.
- //
- Alignment = RootBridgeInstance->ResAllocNode[TypeMem32].Alignment + 1;
- NewLength = RootBridgeInstance->ResAllocNode[TypeMem32].Length;
- //
- // Account for reserved regions at begin and end of the stack MMIO32 region.
- //
- RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Base -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
- RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit;
- NewLength += RsvLenAtBegin + RsvLenAtEnd;
- if (Alignment < RsvLenAtBegin) {
- Alignment = RsvLenAtBegin;
- }
- if (Alignment < RsvLenAtEnd) {
- Alignment = RsvLenAtEnd;
- }
- //
- // Always account for VT-d reserved resource ranges.
- // TODO: Remove when VTd BAR is included in RsvLenAtEnd.
- //
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress != 0) {
- VtdBarSize = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress + 1;
- NewLength += VtdBarSize;
- if (Alignment < VtdBarSize) {
- Alignment = VtdBarSize;
- }
- }
- if (IsVirtualRootBridge) {
- NewLength += NewLength;
- }
- // PCH Allocates reserved MMIO for Sx SMI handler use
- // For device to fit move to the next available alignment
- if ((Socket == 0) && (Stack == 0)) {
- NewLength += Alignment;
- }
- //
- // Check if new length is big enough to support PEI MMIO resource assigment for the stacks
- //
- if (NewLength < mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32MinSize) {
- NewLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32MinSize;
- }
- if (NewLength != 0) {
- //
- // At least 4MB align per KTI requirement. Add the length requested with given alignment.
- // If the sum is not 4MB aligned add on the remainder that would make it align.
- // Have to make sure Alignment is handled for direct address allocation
- //
- Remainder = SocketMem32Base & (Alignment - 1);
- if (Remainder != 0) {
- NewLength += Alignment - Remainder;
- }
- if (NewLength % MmiolGranularity) {
- Remainder = MmiolGranularity - (NewLength % MmiolGranularity);
- NewLength += Remainder;
- }
- if (Stack == LastStack) {
- //
- // Ubox address must be 8MB aligned for the base address on most processors; skip check
- // if uboxMmioSize is 0 (avoid divide by zero exception).
- // At this point the requested resource has already been calculated to be satisfied.
- // Add granularity padding if necessary to satisfy Ubox requirement.
- //
- if (UboxMmioSize != 0 && (SocketMem32Base + NewLength) % UboxMmioSize) {
- Remainder = UboxMmioSize - (NewLength % UboxMmioSize);
- NewLength += Remainder;
- }
- }
- //
- // Store length as length - 1 for handling
- //
- NewLength -= 1;
- // Zero StackLength if its disable or negative
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit) {
- StackLength = 0;
- } else {
- StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
- }
- SocketResources[Socket].StackRes[Stack].MmiolLength = (UINT32)NewLength;
- // Check if new length can fit in the socket or stack
- if (SocketResources[Socket].MmiolResourcesLeft > (UINT32)NewLength) {
- SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength + 1;
- } else if (SocketResources[Socket].MmiolResourcesLeft == (UINT32)NewLength) {
- SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength;
- } else {
- // If there are resources left consume them
- if (SocketResources[Socket].MmiolResourcesLeft) {
- NewLength = NewLength - SocketResources[Socket].MmiolResourcesLeft - 1;
- SocketResources[Socket].MmiolResourcesLeft = 0;
- }
- SocketResources[Socket].MmiolResourceNeeds += (UINT32)NewLength + 1;
- OutOfResources = TRUE;
- ChangedTypeOOR[TypeMem32] = TRUE;
- }
- SocketResources[Socket].StackRes[Stack].MmiolAlignment = Alignment;
- if (NewLength > StackLength) {
- SocketResources[Socket].StackRes[Stack].MmiolUpdate = 1;
- //MmiolResourcesLeft is UINT32 type, not 2's-complement value.
- if (SocketResources[Socket].MmiolResourcesLeft > SocketMem32Length) {
- DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
- Socket, Stack, TypeMem32));
- SocketResources[Socket].MmiolResourcesLeft = 0;
- }
- ChangedType[TypeMem32] = TRUE;
- }
- SocketMem32Base += SocketResources[Socket].StackRes[Stack].MmiolLength + 1;
- DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiolResourceLeft = %x\n",
- Socket, SocketResources[Socket].MmiolResourcesLeft));
- DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolAlignment = %x\n",
- Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiolAlignment));
- } else {
- SocketResources[Socket].StackRes[Stack].MmiolLength = 0;
- }
- //
- // Check Mem64 resource. This Host bridge does not support separated MEM / PMEM requests, so only count MEM requests here.
- //
- Alignment = RootBridgeInstance->ResAllocNode[TypeMem64].Alignment + 1;
- NewLength = RootBridgeInstance->ResAllocNode[TypeMem64].Length;
- //
- // Account for reserved regions at begin and end of the stack MMIO32 region.
- //
- RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Base -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
- RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Limit;
- NewLength += RsvLenAtBegin + RsvLenAtEnd;
- if (Alignment < RsvLenAtBegin) {
- Alignment = RsvLenAtBegin;
- }
- if (Alignment < RsvLenAtEnd) {
- Alignment = RsvLenAtEnd;
- }
- if (IsVirtualRootBridge) {
- NewLength += NewLength;
- }
- if (NewLength != 0) {
- //
- // At least 1GB align per KTI requirement. Add the length requested with given alignment.
- // If the sum is not 1GB aligned add on the remainder that would make it align.
- // Have to make sure Alignment is handled for direct address allocation
- //
- Remainder = SocketMem64Base & (Alignment - 1);
- if (Remainder != 0) {
- NewLength += Alignment - Remainder;
- }
- if (NewLength % MmiohGranularity) {
- Remainder = MmiohGranularity - (NewLength % MmiohGranularity);
- NewLength += Remainder;
- }
- NewLength = ALIGN_VALUE (NewLength, Alignment);
- //
- // Store length as length - 1 for handling
- //
- NewLength -= 1;
- // Zero StackLength if it's disable or negative
- if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base >=
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit) {
- StackLength = 0;
- } else {
- StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
- mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
- }
- SocketResources[Socket].StackRes[Stack].MmiohLength = NewLength;
- // Check if new length can fit in the socket or stack
- if (SocketResources[Socket].MmiohResourcesLeft > NewLength) {
- SocketResources[Socket].MmiohResourcesLeft -= NewLength + 1;
- } else if (SocketResources[Socket].MmiohResourcesLeft == NewLength) {
- SocketResources[Socket].MmiohResourcesLeft -= NewLength;
- } else {
- // If there are resources left consume them
- if (SocketResources[Socket].MmiohResourcesLeft != 0) {
- NewLength = NewLength - SocketResources[Socket].MmiohResourcesLeft - 1;
- SocketResources[Socket].MmiohResourcesLeft = 0;
- }
- SocketResources[Socket].MmiohResourceNeeds += NewLength + 1;
- OutOfResources = TRUE;
- ChangedTypeOOR[TypeMem64] = TRUE;
- }
- SocketResources[Socket].StackRes[Stack].MmiohAlignment = Alignment;
- if (NewLength > StackLength) {
- SocketResources[Socket].StackRes[Stack].MmiohUpdate = 1;
- //MmiohResourcesLeft is UINT64 type, not 2's-complement value.
- if (SocketResources[Socket].MmiohResourcesLeft > SocketMem64Length) {
- DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
- Socket, Stack, TypeMem64));
- SocketResources[Socket].MmiohResourcesLeft = 0;
- }
- ChangedType[TypeMem64] = TRUE;
- }
- SocketMem64Base += SocketResources[Socket].StackRes[Stack].MmiohLength + 1;
- DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiohResourceLeft = %lx\n",
- Socket, SocketResources[Socket].MmiohResourcesLeft));
- DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohAlignment = %lx\n",
- Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiohAlignment));
- } else {
- SocketResources[Socket].StackRes[Stack].MmiohLength = 0;
- }
- List = List->ForwardLink;
- } // for Stack
- // Check and update all resource types in socket that needs adjustment
- for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
- if (ChangedType[TypeIndex]) {
- DEBUG ((DEBUG_INFO, "[%d] Adjust stack %s resources...\n", Socket, mPciResourceTypeStr[TypeIndex]));
- Status = AdjustResources (&SocketResources[Socket], Socket, TypeIndex);
- ChangedType[TypeIndex] = FALSE;
- if (Status == EFI_SUCCESS) {
- ChangedBitMap |= (1 << TypeIndex);
- } else {
- ChangedBitMap &= ~(1 << TypeIndex);
- }
- }
- }
- //
- // Account for Ubox resources to accurately calculate new alignments for the next socket
- //
- SocketMem32Base += UboxMmioSize;
- } // for Socket ..
- ASSERT (List == &HostBridgeInstance->RootBridges);
- //
- // If a socket is out of resources, try to adjusting sockets for more room.
- //
- if (OutOfResources && (MAX_SOCKET > 1) && (ValidSockets > 1)) {
- for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
- if (ChangedTypeOOR[TypeIndex]) {
- DEBUG ((DEBUG_INFO, "Adjust socket %s resources...\n", mPciResourceTypeStr[TypeIndex]));
- Status = AdjustSocketResources (SocketResources, TypeIndex, ValidSockets);
- if (Status == EFI_SUCCESS) {
- ChangedBitMap |= (1 << TypeIndex);
- } else {
- ChangedBitMap &= ~(1 << TypeIndex);
- }
- }
- }
- } else if (OutOfResources) {
- if (ChangedTypeOOR[TypeMem64]) {
- //
- // Allow mmioh to be adjusted to access max available physical address range.
- //
- Status = AdjustSocketResources (SocketResources, TypeMem64, ValidSockets);
- if (Status == EFI_SUCCESS) {
- ChangedBitMap |= (1 << TypeIndex);
- } else {
- ChangedBitMap &= ~(1 << TypeIndex);
- }
- }
- if (ChangedTypeOOR[TypeIo] || ChangedTypeOOR[TypeMem32]) {
- DEBUG ((DEBUG_ERROR, "Clearing %s request\n", mPciResourceTypeStr[TypeIo]));
- DEBUG ((DEBUG_ERROR, "Clearing %s request\n", mPciResourceTypeStr[TypeMem32]));
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- SocketResources[Socket].StackRes[Stack].NeedIoUpdate = 0;
- SocketResources[Socket].StackRes[Stack].MmiolUpdate = 0;
- }
- }
- }
- }
- //
- // Update changed resource type.
- // OemGetResourceMapUpdate() will only update changed resource type so it is alright if data is zero.
- //
- if (ChangedBitMap != 0) {
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- SocketPciResourceData.StackPresentBitmap[Socket] = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap;
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- CurStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[Stack];
- //
- // Disable stacks that have no resources and are assigned none.
- // Reaching this far means the stack is valid and should be disabled if base equals limit and
- // length is zero.
- // Assigned address will be none zero at this point because CSTACK takes the first 4K in legacy
- // IO space.
- //
- if ((SocketResources[Socket].StackRes[Stack].NeedIoUpdate) &&
- (SocketResources[Socket].StackRes[Stack].IoLimit -
- SocketResources[Socket].StackRes[Stack].IoBase == 0)) {
- SocketResources[Socket].StackRes[Stack].IoBase = (UINT16)(-1);
- SocketResources[Socket].StackRes[Stack].IoLimit = 0;
- }
- if ((SocketResources[Socket].StackRes[Stack].MmiolUpdate) &&
- (SocketResources[Socket].StackRes[Stack].MmiolLimit -
- SocketResources[Socket].StackRes[Stack].MmiolBase == 0)) {
- SocketResources[Socket].StackRes[Stack].MmiolBase = (UINT32)(-1);
- SocketResources[Socket].StackRes[Stack].MmiolLimit = 0;
- }
- if ((SocketResources[Socket].StackRes[Stack].MmiohUpdate) &&
- (SocketResources[Socket].StackRes[Stack].MmiohLimit -
- SocketResources[Socket].StackRes[Stack].MmiohBase == 0)) {
- SocketResources[Socket].StackRes[Stack].MmiohBase = (UINT64)(-1);
- SocketResources[Socket].StackRes[Stack].MmiohLimit = 0;
- }
- // Zero base if 4K because mIioUds struct reserves 4K of Io for legacy purposes
- // Remove if mIioUds first base starts at zero
- if (SocketResources[Socket].StackRes[Stack].IoBase == 0x1000){
- SocketResources[Socket].StackRes[Stack].IoBase = 0;
- }
- if (SocketResources[Socket].StackRes[Stack].NeedIoUpdate) {
- CurStackLimits->Io.Base = SocketResources[Socket].StackRes[Stack].IoBase;
- CurStackLimits->Io.Limit = SocketResources[Socket].StackRes[Stack].IoLimit;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiolUpdate) {
- if ((Socket == 0) && (Stack == 0)) {
- CurStackLimits->LowMmio.Base = PlatGlobalMmiolBase;
- } else {
- CurStackLimits->LowMmio.Base = SocketResources[Socket].StackRes[Stack].MmiolBase;
- }
- CurStackLimits->LowMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiohUpdate) {
- CurStackLimits->HighMmio.Base = SocketResources[Socket].StackRes[Stack].MmiohBase;
- CurStackLimits->HighMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
- }
- DEBUG((DEBUG_INFO, "\nSocketResources[%x].StackRes[%x].IoBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoLimit));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolLimit));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohBase =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohLimit =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohLimit));
- } // for Stack
- // Initialize to disabled
- SocketResources[Socket].IoBase = (UINT16)(-1);
- SocketResources[Socket].IoLimit = 0;
- SocketResources[Socket].MmiolBase = (UINT32)(-1);
- SocketResources[Socket].MmiolLimit = 0;
- SocketResources[Socket].MmiohBase = (UINT64)(-1);
- SocketResources[Socket].MmiohLimit = 0;
- // Search backwards to find the beginning valid stack
- for (Stack = MAX_IIO_STACK - 1; Stack < MAX_IIO_STACK ; Stack--) {
- CurSocketLimits = &SocketPciResourceData.Socket[Socket].SocketLimits;
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- if (SocketResources[Socket].StackRes[Stack].IoBase != (UINT16)(-1)) {
- SocketResources[Socket].IoBase = SocketResources[Socket].StackRes[Stack].IoBase;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiolBase != (UINT32)(-1)) {
- SocketResources[Socket].MmiolBase = SocketResources[Socket].StackRes[Stack].MmiolBase;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiohBase != (UINT64)(-1)) {
- SocketResources[Socket].MmiohBase = SocketResources[Socket].StackRes[Stack].MmiohBase;
- }
- } // for Stack
- // Search to find the last valid limit
- for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
- if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
- continue;
- }
- if (SocketResources[Socket].StackRes[Stack].IoLimit != 0) {
- SocketResources[Socket].IoLimit = SocketResources[Socket].StackRes[Stack].IoLimit;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiolLimit) {
- SocketResources[Socket].MmiolLimit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
- }
- if (SocketResources[Socket].StackRes[Stack].MmiohLimit) {
- SocketResources[Socket].MmiohLimit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
- }
- } // for Stack
- // Update socket level resource range
- if (SocketResources[Socket].StackRes[0].NeedIoUpdate) {
- CurSocketLimits->Io.Base = SocketResources[Socket].IoBase;
- CurSocketLimits->Io.Limit = SocketResources[Socket].IoLimit;
- }
- if (SocketResources[Socket].StackRes[0].MmiolUpdate) {
- //
- // Apply stolen 8M for ubox mmio per socket
- //
- if (UboxMmioSize != 0) {
- UboxStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK];
- UboxStackLimits->LowMmio.Base = SocketResources[Socket].MmiolLimit + 1;
- SocketResources[Socket].MmiolLimit = (UINT32)UboxStackLimits->LowMmio.Base + UboxMmioSize - 1;
- UboxStackLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
- }
- CurSocketLimits->LowMmio.Base = SocketResources[Socket].MmiolBase;
- CurSocketLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
- }
- if (SocketResources[Socket].StackRes[0].MmiohUpdate) {
- CurSocketLimits->HighMmio.Base = SocketResources[Socket].MmiohBase;
- CurSocketLimits->HighMmio.Limit = SocketResources[Socket].MmiohLimit;
- }
- DEBUG((DEBUG_INFO, "\nSocketResources[%x].UboxBase = %x\n",
- Socket, SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK].LowMmio.Base));
- DEBUG((DEBUG_INFO, "SocketResources[%x].UboxLimit = %x\n",
- Socket, SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK].LowMmio.Limit));
- DEBUG((DEBUG_INFO, "\nSocketResources[%x].IoBase =%x\n",Socket,SocketResources[Socket].IoBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].IoLimit =%x\n",Socket,SocketResources[Socket].IoLimit));
- DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolBase =%x\n",Socket,SocketResources[Socket].MmiolBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolLimit =%x\n",Socket,SocketResources[Socket].MmiolLimit));
- DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohBase =%lx\n",Socket,SocketResources[Socket].MmiohBase));
- DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohLimit =%lx\n",Socket,SocketResources[Socket].MmiohLimit));
- } // for Socket
- SocketPciResourceData.MmioHBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base;
- SocketPciResourceData.MmioHGranularity = *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity;
- SocketPciResourceData.MmioLBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
- SocketPciResourceData.MmioLLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit;
- SocketPciResourceData.MmioLGranularity = mIioUds->IioUdsPtr->PlatformData.MmiolGranularity;
- SocketPciResourceData.IoBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase;
- SocketPciResourceData.IoLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit;
- SocketPciResourceData.IoGranularity = mIioUds->IioUdsPtr->PlatformData.IoGranularity;
- PCIDEBUG("Writing resource rebalance request '%s':\n", SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME);
- PCIDEBUG("System I/O : %04X..%04X [%X]\n", SocketPciResourceData.IoBase, SocketPciResourceData.IoLimit, SocketPciResourceData.IoGranularity);
- PCIDEBUG("System MMIOL: %08X..%08X [%X]\n", SocketPciResourceData.MmioLBase, SocketPciResourceData.MmioLLimit, SocketPciResourceData.MmioLGranularity);
- PCIDEBUG("System MMIOH: %012llX [%llX]\n", SocketPciResourceData.MmioHBase, SocketPciResourceData.MmioHGranularity);
- for (Socket = 0; Socket < NELEMENTS (SocketPciResourceData.Socket); Socket++) {
- PCIDEBUG("[%d] StackPresent: 0x%04X\n", Socket, SocketPciResourceData.StackPresentBitmap[Socket]);
- PCIDEBUG("[%d] I/O : %04X..%04X\n", Socket,
- SocketPciResourceData.Socket[Socket].SocketLimits.Io.Base,
- SocketPciResourceData.Socket[Socket].SocketLimits.Io.Limit);
- PCIDEBUG("[%d] MMIOL: %08X..%08X\n", Socket,
- SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Base,
- SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Limit);
- PCIDEBUG("[%d] MMIOH: %012llX..%012llX\n", Socket,
- SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Base,
- SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Limit);
- for (Stack = 0; Stack < NELEMENTS (SocketPciResourceData.Socket[Socket].StackLimits); Stack++) {
- PCIDEBUG("[%d.%d] I/O : %04X..%04X\n", Socket, Stack,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Base,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Limit);
- PCIDEBUG("[%d.%d] MMIOL: %08X..%08X\n", Socket, Stack,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Base,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Limit);
- PCIDEBUG("[%d.%d] MMIOH: %012llX..%012llX\n", Socket, Stack,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Base,
- SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Limit);
- }
- }
- *Result = SocketResourceRatioChanged;
- Status = gRT->SetVariable(
- SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
- &gEfiSocketPciResourceDataGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- sizeof(SocketPciResourceData),
- &SocketPciResourceData
- );
- ASSERT_EFI_ERROR(Status);
- }
- return;
- }
|