PciRebalance.c 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. /** @file
  2. @copyright
  3. Copyright 1999 - 2021 Intel Corporation. <BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Guid/SocketPciResourceData.h>
  7. #include <Guid/SocketIioVariable.h>
  8. #include "PciHostBridge.h"
  9. #include "PciRootBridge.h"
  10. #include <CpuAndRevisionDefines.h>
  11. #include <Library/UefiRuntimeServicesTableLib.h>
  12. #include <Protocol/IioUds.h>
  13. #include "PciRebalance.h"
  14. /******************************************************************************
  15. * Local definitions.
  16. ******************************************************************************/
  17. extern CHAR16 *mAcpiAddressSpaceTypeStr[];
  18. extern CHAR16 *mPciResourceTypeStr[];
  19. extern EFI_IIO_UDS_PROTOCOL *mIioUds;
  20. /******************************************************************************
  21. * Variables.
  22. ******************************************************************************/
  23. /**
  24. * The table below is a cache with pointers to protocol instances created at
  25. * Host Bridge initialization. It also provides mapping of protocol instance
  26. * to the PCI stack.
  27. */
  28. PCI_ROOT_BRIDGE_INSTANCE *mPciRootBridgeTable[MAX_SOCKET][MAX_LOGIC_IIO_STACK] = {0};
  29. PCI_ROOT_BRIDGE_INSTANCE *mPciRootBridgeTableReserved[MAX_SOCKET][IIO_RESERVED_1] = {0};
  30. /******************************************************************************
  31. * Functions.
  32. ******************************************************************************/
  33. /**
  34. Find socket and stack index for given PCI Root Bridge protocol pointer.
  35. @param[out] PciResConfigPtr - Buffer for the resource configuration variable.
  36. @retval EFI_SUCCESS The function completed successfully.
  37. @retval EFI_NOT_FOUND The variable was not found.
  38. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
  39. @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
  40. **/
  41. EFI_STATUS
  42. PciRootBridge2SocketStack (
  43. IN PCI_ROOT_BRIDGE_INSTANCE *RootBridgePtr,
  44. OUT UINT8 *SocketPtr,
  45. OUT UINT8 *StackPtr
  46. )
  47. {
  48. UINT8 Socket;
  49. UINT8 Stack;
  50. if (RootBridgePtr != NULL) {
  51. for (Socket = 0; Socket < NELEMENTS(mPciRootBridgeTable); Socket++) {
  52. for (Stack = 0; Stack < NELEMENTS(mPciRootBridgeTable[Socket]); Stack++) {
  53. if (mPciRootBridgeTable[Socket][Stack] == RootBridgePtr) {
  54. if (SocketPtr != NULL) {
  55. *SocketPtr = Socket;
  56. }
  57. if (StackPtr != NULL) {
  58. *StackPtr = Stack;
  59. }
  60. return EFI_SUCCESS;
  61. }
  62. }
  63. }
  64. }
  65. return EFI_NOT_FOUND;
  66. }
  67. /**
  68. Determine the last stack for a given socket
  69. @param Socket the socket for which the last socket is desired
  70. @return the number of the last socket
  71. */
  72. UINT8
  73. LastStackOfSocket (
  74. UINT8 Socket
  75. )
  76. {
  77. UINT8 LastStack;
  78. BOOLEAN FoundEnabledStack;
  79. UINT8 Stack;
  80. ASSERT (Socket < ARRAY_SIZE(mIioUds->IioUdsPtr->PlatformData.IIO_resource));
  81. ASSERT (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid);
  82. FoundEnabledStack = FALSE;
  83. LastStack = 0;
  84. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  85. if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)) {
  86. LastStack = Stack;
  87. FoundEnabledStack = TRUE;
  88. }
  89. }
  90. ASSERT (FoundEnabledStack);
  91. return LastStack;
  92. }
  93. /**
  94. Determine the last stack for a given socket with resources
  95. @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per stack
  96. @param Socket - Index of the Socket
  97. @param ResourceType - Type of resource that requires alignment
  98. @param LastStack - Pointer that will store the value of the last stack with resources allocated to it
  99. @param ResourceSize - Pointer that will store the sum of the requested resource type
  100. @return The last stack with resources allocated to it and the
  101. total amount of resoures requested of the type
  102. requested.
  103. */
  104. VOID
  105. LastStackWithResources (
  106. IN CPU_RESOURCE *SocketResources,
  107. IN UINT8 Socket,
  108. IN PCI_RESOURCE_TYPE ResourceType,
  109. OUT UINT8 *LastStack,
  110. OUT UINT64 *ResourceSize
  111. )
  112. {
  113. UINT8 Stack;
  114. *LastStack = 0;
  115. *ResourceSize = 0;
  116. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  117. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  118. continue;
  119. }
  120. switch (ResourceType) {
  121. case TypeIo:
  122. if (SocketResources->StackRes[Stack].NumIoPortsDesired != 0) {
  123. *ResourceSize += SocketResources->StackRes[Stack].NumIoPortsDesired + 1;
  124. *LastStack = Stack;
  125. }
  126. break;
  127. case TypeMem32:
  128. if (SocketResources->StackRes[Stack].MmiolLength != 0) {
  129. *ResourceSize += SocketResources->StackRes[Stack].MmiolLength + 1;
  130. *LastStack = Stack;
  131. }
  132. break;
  133. case TypeMem64:
  134. if (SocketResources->StackRes[Stack].MmiohLength != 0) {
  135. *ResourceSize += SocketResources->StackRes[Stack].MmiohLength + 1;
  136. *LastStack = Stack;
  137. }
  138. break;
  139. default:
  140. break;
  141. }
  142. }
  143. }
  144. /**
  145. Visit all stacks in this socket and recalculate the resource ranges per stack based on resource
  146. needs from PCI/PCIe device/functions.
  147. @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per stack
  148. @param Socket - Index of the Socket
  149. @param ResourceType - type of resource that requires alignment
  150. @retval EFI_SUCCESS - Succeed.
  151. @retval EFI_OUT_OF_RESOURCES - Not enough resources to be adjusted within the socket.
  152. **/
  153. EFI_STATUS
  154. AdjustResources (
  155. CPU_RESOURCE *SocketResources,
  156. UINT8 Socket,
  157. UINT8 ResourceType
  158. )
  159. {
  160. UINT8 Stack;
  161. UINT64 NewLength;
  162. CONST UINT8 LastStack = LastStackOfSocket (Socket);
  163. UINT64 PreviousLimit;
  164. BOOLEAN FirstStack = TRUE;
  165. switch (ResourceType) {
  166. case TypeIo:
  167. // Return if IoResourceNeeds is not zero which indicates a socket adjustment is needed
  168. if(SocketResources->IoResourceNeeds != 0){
  169. return EFI_OUT_OF_RESOURCES;
  170. }
  171. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  172. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))){
  173. continue;
  174. }
  175. //
  176. // For the first enabled stack, use the base I/O address for the socket, otherwise
  177. // calculate the new base based off the last enabled stack
  178. //
  179. if (FirstStack) {
  180. // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
  181. // Start with valid resources for current socket
  182. SocketResources->StackRes[Stack].IoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
  183. FirstStack = FALSE;
  184. } else {
  185. // Check to see if the previous stack is disabled by checking for equal base and limit
  186. if (SocketResources->StackRes[Stack-1].IoBase == SocketResources->StackRes[Stack-1].IoLimit) {
  187. if (PreviousLimit % 2 == 1) {
  188. PreviousLimit += 1;
  189. }
  190. SocketResources->StackRes[Stack].IoBase = (UINT16) PreviousLimit;
  191. } else {
  192. SocketResources->StackRes[Stack].IoBase = (UINT16) PreviousLimit + 1;
  193. }
  194. }
  195. NewLength = SocketResources->StackRes[Stack].NumIoPortsDesired;
  196. //
  197. //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
  198. //make adjustments if NewLength is zero
  199. //
  200. if (Stack == LastStack) {
  201. if (NewLength != 0) {
  202. if (SocketResources->IoResourcesLeft != 0) {
  203. NewLength += SocketResources->IoResourcesLeft + 1;
  204. }
  205. } else {
  206. NewLength = SocketResources->IoResourcesLeft;
  207. }
  208. }
  209. SocketResources->StackRes[Stack].NeedIoUpdate = TRUE;
  210. SocketResources->StackRes[Stack].IoLimit = (UINT16)(SocketResources->StackRes[Stack].IoBase + NewLength);
  211. PreviousLimit = SocketResources->StackRes[Stack].IoLimit;
  212. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoBase =%x newLength = %x\n",Socket,Stack,SocketResources->StackRes[Stack].IoBase,NewLength));
  213. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoLimit =%x\n",Socket,Stack,SocketResources->StackRes[Stack].IoLimit));
  214. }
  215. break;
  216. case TypeMem32:
  217. //
  218. // Return if MmiolResourceNeeds is not zero which indicates a socket adjustment is needed
  219. //
  220. if (SocketResources->MmiolResourceNeeds != 0) {
  221. return EFI_OUT_OF_RESOURCES;
  222. }
  223. //
  224. // Visit all Stacks in this Socket and recalculate the New Mem32 Ranges per Stack
  225. //
  226. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++){
  227. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  228. continue;
  229. }
  230. //
  231. // For the first enabled stack, use the base low mmio address for the socket, otherwize
  232. // calculate the new base based off the last enabled stack
  233. //
  234. if (FirstStack) {
  235. // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
  236. // Start with valid resources for current socket
  237. SocketResources->StackRes[Stack].MmiolBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
  238. FirstStack = FALSE;
  239. } else {
  240. // Check to see if the previous stack is disabled by checking for equal base and limit
  241. if (SocketResources->StackRes[Stack-1].MmiolBase == SocketResources->StackRes[Stack-1].MmiolLimit) {
  242. if (PreviousLimit % 2 == 1) {
  243. PreviousLimit += 1;
  244. }
  245. SocketResources->StackRes[Stack].MmiolBase = (UINT32) PreviousLimit;
  246. } else {
  247. SocketResources->StackRes[Stack].MmiolBase = (UINT32) PreviousLimit + 1;
  248. }
  249. }
  250. //
  251. // Verify if this Stack is the one that requires an update and calculate the new Limit
  252. // otherwise assign the new limit based on the Chunk and Extra Chunk calculation and assign the Newlength
  253. //
  254. NewLength = SocketResources->StackRes[Stack].MmiolLength;
  255. //
  256. //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
  257. //make adjustments if NewLength is zero
  258. //
  259. if (Stack == LastStack) {
  260. if (NewLength != 0) {
  261. if (SocketResources->MmiolResourcesLeft){
  262. NewLength += SocketResources->MmiolResourcesLeft + 1;
  263. }
  264. } else {
  265. NewLength = SocketResources->MmiolResourcesLeft;
  266. }
  267. }
  268. SocketResources->StackRes[Stack].MmiolUpdate = 1;
  269. SocketResources->StackRes[Stack].MmiolLimit = (UINT32)(SocketResources->StackRes[Stack].MmiolBase + NewLength);
  270. PreviousLimit = SocketResources->StackRes[Stack].MmiolLimit;
  271. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolBase =%x newLength = %x\n",Socket,Stack,SocketResources->StackRes[Stack].MmiolBase,NewLength));
  272. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolLimit =%x\n",Socket,Stack,SocketResources->StackRes[Stack].MmiolLimit));
  273. }
  274. break;
  275. case TypeMem64:
  276. // Return if MmiohResourceNeeds is not zero which indicates a socket adjustment is needed
  277. if (SocketResources->MmiohResourceNeeds != 0){
  278. return EFI_OUT_OF_RESOURCES;
  279. }
  280. //
  281. // Visit all Stacks in this Socket and recalculate the New Mem64 Ranges per Stack
  282. //
  283. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  284. if(!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))){
  285. continue;
  286. }
  287. //
  288. // For the first enabled stack, use the base high mmio address for the socket, otherwise
  289. // calculate the new base based off the last enabled stack
  290. //
  291. if (FirstStack) {
  292. // stackPresentBitmap doesn't cover if a valid stack was disable due to resource adjustments.
  293. // Start with valid resources for current socket
  294. SocketResources->StackRes[Stack].MmiohBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
  295. FirstStack = FALSE;
  296. } else {
  297. // Check to see if the previous stack is disabled by checking for equal base and limit
  298. if (SocketResources->StackRes[Stack-1].MmiohBase == SocketResources->StackRes[Stack-1].MmiohLimit) {
  299. if (PreviousLimit % 2 == 1) {
  300. PreviousLimit += 1;
  301. }
  302. SocketResources->StackRes[Stack].MmiohBase = PreviousLimit;
  303. } else {
  304. SocketResources->StackRes[Stack].MmiohBase = PreviousLimit + 1;
  305. }
  306. }
  307. //
  308. // Verify if this Stack is the one that requires an update and calculate the new Limit
  309. // otherwise assign the new limit based on the Chunk and Extra Chunk calculation and assign the Newlength
  310. //
  311. NewLength = SocketResources->StackRes[Stack].MmiohLength;
  312. //
  313. //assign the left space to the last IIO stack. Reserved for across socket resource adjustment.
  314. //make adjustments if NewLength is zero
  315. //
  316. if (Stack == LastStack) {
  317. if (NewLength != 0) {
  318. if (SocketResources->MmiohResourcesLeft) {
  319. NewLength += SocketResources->MmiohResourcesLeft + 1;
  320. }
  321. } else {
  322. NewLength = SocketResources->MmiohResourcesLeft;
  323. }
  324. }
  325. SocketResources->StackRes[Stack].MmiohUpdate = 1;
  326. SocketResources->StackRes[Stack].MmiohLimit = (SocketResources->StackRes[Stack].MmiohBase + NewLength);
  327. PreviousLimit = SocketResources->StackRes[Stack].MmiohLimit;
  328. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohBase =%lx newLength = %lx\n",Socket,Stack,SocketResources->StackRes[Stack].MmiohBase,NewLength));
  329. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohLimit =%lx\n",Socket,Stack,SocketResources->StackRes[Stack].MmiohLimit));
  330. } // for Stack
  331. break;
  332. default:
  333. DEBUG((DEBUG_ERROR, "[PCI] ERROR: Resource Type Unknown = %x\n", ResourceType));
  334. break;
  335. }// switch
  336. return EFI_SUCCESS;
  337. }
  338. /**
  339. Adjust resource ratio assignment among sockets to fit the resource needs from PCI devices.
  340. @param SocketResources - CPU_RESOURCE structure pointer that stores all resources need per socket
  341. @param ResourceType - type of resource that requires alignment
  342. @param ValidSockets - Number of Valid Sockets, need it to calculate how resources need to be splitted
  343. @retval EFI_SUCCESS - Succeed.
  344. @retval EFI_OUT_OF_RESOURCES - Not enough resources to be adjusted within the socket.
  345. **/
  346. EFI_STATUS
  347. AdjustSocketResources (
  348. CPU_RESOURCE *SocketResources,
  349. UINT8 ResourceType,
  350. UINT8 ValidSockets
  351. )
  352. {
  353. EFI_STATUS Status;
  354. switch(ResourceType){
  355. case TypeIo:
  356. Status = AdjustSocketIo (SocketResources, ResourceType, ValidSockets);
  357. break;
  358. case TypeMem32:
  359. Status = AdjustSocketMmioL (SocketResources, ResourceType, ValidSockets);
  360. break;
  361. case TypeMem64:
  362. Status = AdjustSocketMmioH (SocketResources, ResourceType, ValidSockets);
  363. break;
  364. default:
  365. DEBUG((DEBUG_ERROR, "[PCI] ERROR: Resource Type Unknown = %x\n", ResourceType));
  366. Status = EFI_INVALID_PARAMETER;
  367. break;
  368. } // switch
  369. return Status;
  370. }
  371. /**
  372. Compare current system resource map with rebalance request NVRAM variable to see if stored settings were applied.
  373. @param[in] SocketPciResourceData - Pointer to stored CPU resource map
  374. @retval TRUE - SYSTEM_PCI_BASE_LIMITS has been rejected and was not applied or not initialized
  375. @retval FALSE - SYSTEM_PCI_BASE_LIMITS has been applied and still has relevant data
  376. **/
  377. BOOLEAN
  378. IsResourceMapRejected (
  379. SYSTEM_PCI_BASE_LIMITS *SocketPciResourceData
  380. )
  381. {
  382. UINT8 Socket;
  383. UINT8 Stack;
  384. BOOLEAN Rejected = FALSE;
  385. PCI_BASE_LIMITS *StackLimits;
  386. PCI_BASE_LIMITS *UboxStackLimits;
  387. PCI_BASE_LIMITS *SocketLimits;
  388. STACK_RES *IioUdsUboxStackLimits;
  389. STACK_RES *IioUdsStackLimits;
  390. IIO_RESOURCE_INSTANCE *IioUdsSocketLimits;
  391. if (SocketPciResourceData == NULL) {
  392. return TRUE;
  393. }
  394. for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
  395. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid) {
  396. IioUdsSocketLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket];
  397. SocketLimits = &SocketPciResourceData->Socket[Socket].SocketLimits;
  398. IioUdsUboxStackLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[UBOX_STACK];
  399. UboxStackLimits = &SocketPciResourceData->Socket[Socket].StackLimits[UBOX_STACK];
  400. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  401. if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)) {
  402. IioUdsStackLimits = &mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack];
  403. StackLimits = &SocketPciResourceData->Socket[Socket].StackLimits[Stack];
  404. //
  405. // Per stack
  406. //
  407. if (Socket == 0 && Stack == 0) {
  408. // First base starts at zero, mIioUds struct reserves 4K of Io for legacy purposes
  409. if (StackLimits->Io.Base != 0) {
  410. Rejected = TRUE;
  411. }
  412. } else {
  413. if (IioUdsStackLimits->PciResourceIoBase != StackLimits->Io.Base && StackLimits->Io.Base != 0) {
  414. Rejected = TRUE;
  415. }
  416. }
  417. if (IioUdsStackLimits->PciResourceIoLimit != StackLimits->Io.Limit && StackLimits->Io.Limit != 0) {
  418. Rejected = TRUE;
  419. }
  420. PCIDEBUG ("[%d.%d] Current I/O: 0x%04X..0x%04X\n", Socket, Stack,
  421. IioUdsStackLimits->PciResourceIoBase, IioUdsStackLimits->PciResourceIoLimit);
  422. PCIDEBUG ("[%d.%d] Saved I/O: 0x%04X..0x%04X %a\n", Socket, Stack,
  423. StackLimits->Io.Base, StackLimits->Io.Limit,
  424. (StackLimits->Io.Limit != 0 && Rejected) ? "rejected" : "");
  425. if (IioUdsStackLimits->Mmio32Base != StackLimits->LowMmio.Base && StackLimits->LowMmio.Base != 0) {
  426. Rejected = TRUE;
  427. }
  428. if (IioUdsStackLimits->Mmio32Limit != StackLimits->LowMmio.Limit && StackLimits->LowMmio.Limit != 0) {
  429. Rejected = TRUE;
  430. }
  431. PCIDEBUG ("[%d.%d] Current MMIOL: 0x%08X..0x%08X\n", Socket, Stack,
  432. IioUdsStackLimits->Mmio32Base, IioUdsStackLimits->Mmio32Limit);
  433. PCIDEBUG ("[%d.%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket, Stack,
  434. StackLimits->LowMmio.Base, StackLimits->LowMmio.Limit,
  435. (StackLimits->LowMmio.Limit != 0 && Rejected) ? "rejected" : "");
  436. if (IioUdsStackLimits->Mmio64Base != StackLimits->HighMmio.Base && StackLimits->HighMmio.Base != 0) {
  437. Rejected = TRUE;
  438. }
  439. if (IioUdsStackLimits->Mmio64Limit != StackLimits->HighMmio.Limit && StackLimits->HighMmio.Limit != 0) {
  440. Rejected = TRUE;
  441. }
  442. PCIDEBUG ("[%d.%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket, Stack,
  443. IioUdsStackLimits->Mmio64Base, IioUdsStackLimits->Mmio64Limit);
  444. PCIDEBUG ("[%d.%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket, Stack,
  445. StackLimits->HighMmio.Base, StackLimits->HighMmio.Limit,
  446. (StackLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
  447. }
  448. }
  449. //
  450. // Per socket
  451. //
  452. if (IioUdsSocketLimits->PciResourceIoBase != SocketLimits->Io.Base && SocketLimits->Io.Base != 0) {
  453. Rejected = TRUE;
  454. }
  455. if (IioUdsSocketLimits->PciResourceIoLimit != SocketLimits->Io.Limit && SocketLimits->Io.Limit != 0) {
  456. Rejected = TRUE;
  457. }
  458. PCIDEBUG("[%d] Current I/O: 0x%04X..0x%04X\n", Socket,
  459. IioUdsSocketLimits->PciResourceIoBase, IioUdsSocketLimits->PciResourceIoLimit);
  460. PCIDEBUG("[%d] Saved I/O: 0x%04X..0x%04X %a\n", Socket,
  461. SocketLimits->Io.Base, SocketLimits->Io.Limit,
  462. (SocketLimits->Io.Limit != 0 && Rejected) ? "rejected" : "");
  463. if (IioUdsSocketLimits->Mmio32Base != SocketLimits->LowMmio.Base && SocketLimits->LowMmio.Base != 0) {
  464. Rejected = TRUE;
  465. }
  466. if (IioUdsSocketLimits->Mmio32Limit != SocketLimits->LowMmio.Limit && SocketLimits->LowMmio.Limit != 0) {
  467. Rejected = TRUE;
  468. }
  469. PCIDEBUG ("[%d] Current MMIOL: 0x%08X..0x%08X\n", Socket,
  470. IioUdsSocketLimits->Mmio32Base, IioUdsSocketLimits->Mmio32Limit);
  471. PCIDEBUG ("[%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket,
  472. SocketLimits->LowMmio.Base, SocketLimits->LowMmio.Limit,
  473. (SocketLimits->LowMmio.Limit != 0 && Rejected) ? "rejected" : "");
  474. if (IioUdsSocketLimits->Mmio64Base != SocketLimits->HighMmio.Base && SocketLimits->HighMmio.Base != 0) {
  475. Rejected = TRUE;
  476. }
  477. if (IioUdsSocketLimits->Mmio64Limit != SocketLimits->HighMmio.Limit && SocketLimits->HighMmio.Limit != 0) {
  478. Rejected = TRUE;
  479. }
  480. PCIDEBUG ("[%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket,
  481. IioUdsSocketLimits->Mmio64Base, IioUdsSocketLimits->Mmio64Limit);
  482. PCIDEBUG ("[%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket,
  483. SocketLimits->HighMmio.Base, SocketLimits->HighMmio.Limit,
  484. (SocketLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
  485. if (IioUdsUboxStackLimits->Mmio64Base != UboxStackLimits->HighMmio.Base && UboxStackLimits->HighMmio.Base != 0) {
  486. Rejected = TRUE;
  487. }
  488. if (IioUdsUboxStackLimits->Mmio64Limit != UboxStackLimits->HighMmio.Limit && UboxStackLimits->HighMmio.Limit != 0) {
  489. Rejected = TRUE;
  490. }
  491. PCIDEBUG ("[%d] Current UBOX: 0x%08X..0x%08X\n", Socket,
  492. IioUdsUboxStackLimits->Mmio64Base, IioUdsUboxStackLimits->Mmio64Limit);
  493. PCIDEBUG ("[%d] Saved UBOX: 0x%08X..0x%08X %a\n", Socket,
  494. UboxStackLimits->HighMmio.Base, UboxStackLimits->HighMmio.Limit,
  495. (UboxStackLimits->HighMmio.Limit != 0 && Rejected) ? "rejected" : "");
  496. }
  497. }
  498. DEBUG ((DEBUG_INFO, "[PCI] Resource rebalance rejected ? %a\n", Rejected ? "TRUE" : "FALSE"));
  499. return Rejected;
  500. }
  501. /**
  502. Verify whether system resource map changed comparing to the state when rebalance request was created.
  503. @param[in] PciResConfigPtr - Buffer with the rebalance request.
  504. @return If current map is different than the one used when rebalance was created true is returned,
  505. otherwise false.
  506. **/
  507. BOOLEAN
  508. IsSystemMapChanged (
  509. IN SYSTEM_PCI_BASE_LIMITS *PciResConfigPtr
  510. )
  511. {
  512. UINT8 Socket;
  513. if (PciResConfigPtr->MmioHBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base ||
  514. PciResConfigPtr->MmioHGranularity != *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity) {
  515. DEBUG ((DEBUG_ERROR, "[PCI] %s: MMIOH Base %012llX [%llX] != %012llX [%llX] - system map changed\n",
  516. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  517. PciResConfigPtr->MmioHBase, PciResConfigPtr->MmioHGranularity,
  518. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base,
  519. *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity));
  520. return TRUE;
  521. }
  522. if (PciResConfigPtr->MmioLBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base ||
  523. PciResConfigPtr->MmioLLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit ||
  524. PciResConfigPtr->MmioLGranularity != mIioUds->IioUdsPtr->PlatformData.MmiolGranularity) {
  525. DEBUG ((DEBUG_ERROR, "[PCI] %s: MMIOL %08X..%08X [%X] != %08X..%08X [%X] - system map changed\n",
  526. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  527. PciResConfigPtr->MmioLBase, PciResConfigPtr->MmioLLimit, PciResConfigPtr->MmioLGranularity,
  528. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base,
  529. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit,
  530. mIioUds->IioUdsPtr->PlatformData.MmiolGranularity));
  531. return TRUE;
  532. }
  533. if (PciResConfigPtr->IoBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase ||
  534. PciResConfigPtr->IoLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit ||
  535. PciResConfigPtr->IoGranularity != mIioUds->IioUdsPtr->PlatformData.IoGranularity) {
  536. DEBUG ((DEBUG_ERROR, "[PCI] %s: I/O %04X..%04X [%X] != %04X..%04X [%X] - system map changed\n",
  537. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  538. PciResConfigPtr->IoBase, PciResConfigPtr->IoLimit, PciResConfigPtr->IoGranularity,
  539. mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase,
  540. mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit,
  541. mIioUds->IioUdsPtr->PlatformData.IoGranularity));
  542. return TRUE;
  543. }
  544. for (Socket = 0; Socket < NELEMENTS (PciResConfigPtr->Socket); Socket++) {
  545. if (PciResConfigPtr->StackPresentBitmap[Socket] !=
  546. mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap) {
  547. DEBUG ((DEBUG_ERROR, "[PCI] %s: Stack bitmap mismach (%04X != %04X) in socket %d - system map changed\n",
  548. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, PciResConfigPtr->StackPresentBitmap[Socket],
  549. mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap, Socket));
  550. return TRUE;
  551. }
  552. }
  553. return FALSE;
  554. } // IsSystemMapChanged()
  555. /**
  556. Adjust resource ratio assignment among CPU sockets to fit the resource needs from PCI devices.
  557. Update Setup variable if there are changes from the existing ratio requests for this boot.
  558. @param[in] HostBridgeInstance - The Host Bridge Instance where the resource adjustment happens.
  559. @param[out] Result - Output parameter. Indicates whether changes have been made.
  560. **/
  561. VOID
  562. AdjustResourceAmongRootBridges (
  563. IN PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance,
  564. OUT SOCKET_RESOURCE_ADJUSTMENT_RESULT *Result
  565. )
  566. {
  567. PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
  568. LIST_ENTRY *List;
  569. CPU_RESOURCE SocketResources[MAX_SOCKET];
  570. UINT64 SocketIoLength;
  571. UINT64 SocketMem32Length;
  572. UINT64 SocketMem64Length;
  573. UINT64 SocketIoBase;
  574. UINT64 SocketMem32Base;
  575. UINT64 SocketMem64Base;
  576. UINT64 RsvLenAtBegin;
  577. UINT64 RsvLenAtEnd;
  578. UINT64 StackLength;
  579. UINT64 NewLength;
  580. UINT64 Alignment;
  581. UINT64 Remainder;
  582. UINT8 Socket;
  583. UINT8 ValidSockets;
  584. BOOLEAN ChangedType[TypeMax];
  585. BOOLEAN ChangedTypeOOR[TypeMax]; // Change type for out of resources
  586. UINT8 TypeIndex;
  587. UINT8 ChangedBitMap;
  588. EFI_STATUS Status;
  589. UINTN VarSize;
  590. SYSTEM_PCI_BASE_LIMITS SocketPciResourceData;
  591. UINT8 Stack;
  592. UINT8 LastStack;
  593. UINT16 IoGranularity;
  594. UINT32 MmiolGranularity;
  595. UINT64 MmiohGranularity;
  596. BOOLEAN OutOfResources;
  597. UINT32 UboxMmioSize;
  598. BOOLEAN IsVirtualRootBridge;
  599. PCI_BASE_LIMITS *CurStackLimits;
  600. PCI_BASE_LIMITS *UboxStackLimits;
  601. PCI_BASE_LIMITS *CurSocketLimits;
  602. UINT32 PlatGlobalMmiolBase;
  603. UINT32 VtdBarSize;
  604. *Result = SocketResourceRatioNotChanged;
  605. SetMem (ChangedType, TypeMax, FALSE);
  606. SetMem (ChangedTypeOOR, TypeMax, FALSE);
  607. ChangedBitMap = 0;
  608. OutOfResources = FALSE;
  609. IsVirtualRootBridge = FALSE;
  610. IoGranularity = mIioUds->IioUdsPtr->PlatformData.IoGranularity;
  611. MmiolGranularity = mIioUds->IioUdsPtr->PlatformData.MmiolGranularity;
  612. MmiohGranularity = (UINT64) mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.lo;
  613. MmiohGranularity |= ((UINT64)mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.hi) << 32;
  614. ZeroMem (&SocketResources[0], sizeof(SocketResources));
  615. //
  616. // Read the system resource cfg from NVRAM. If the variable does not exist just create new one.
  617. // If variable exists, check if it was applied by KTI. If not we got two options possible:
  618. // (1) it is not valid because system resource map changed, or
  619. // (2) it is not valid because of unknown reason.
  620. // The first case is detected and new request shall be created for rebalance.
  621. // In the second case just continue boot to avoid reboot loop.
  622. //
  623. VarSize = sizeof(SocketPciResourceData);
  624. ZeroMem (&SocketPciResourceData, sizeof(SocketPciResourceData));
  625. Status = gRT->GetVariable (SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, &gEfiSocketPciResourceDataGuid,
  626. NULL, &VarSize, &SocketPciResourceData);
  627. if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND && Status != EFI_BUFFER_TOO_SMALL) {
  628. ASSERT_EFI_ERROR (Status);
  629. return;
  630. }
  631. if (Status == EFI_BUFFER_TOO_SMALL) {
  632. VarSize += 1; // Make it not equal to sizeof(SocketPciResourceData)
  633. }
  634. if (VarSize != sizeof(SocketPciResourceData)) {
  635. PCIDEBUG ("Got variable '%s' of unexpected size %d (expect %d)\n",
  636. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, VarSize, sizeof(SocketPciResourceData));
  637. }
  638. if (Status != EFI_NOT_FOUND) {
  639. //
  640. // Variable exists, let's check if it was applied by KTI.
  641. //
  642. if (IsResourceMapRejected (&SocketPciResourceData)) {
  643. //
  644. // Rejected so check if system resources map was changed.
  645. //
  646. if (!IsSystemMapChanged (&SocketPciResourceData) && VarSize == sizeof(SocketPciResourceData)) {
  647. DEBUG ((DEBUG_ERROR, "[PCI] ERROR: Resource rebalance rejected by KTI - continue without rebalance\n"));
  648. return;
  649. }
  650. ZeroMem (&SocketPciResourceData, sizeof(SocketPciResourceData));
  651. }
  652. }
  653. UboxMmioSize = mIioUds->IioUdsPtr->PlatformData.UboxMmioSize;
  654. PlatGlobalMmiolBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
  655. ValidSockets = 0;
  656. for (List = HostBridgeInstance->RootBridges.ForwardLink, Socket = 0; Socket < MAX_SOCKET; Socket ++) {
  657. if (!mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid) {
  658. continue;
  659. }
  660. ValidSockets++;
  661. //
  662. // Calculate the length of resources available per socket
  663. //
  664. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase >=
  665. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit) {
  666. SocketIoBase = 0;
  667. SocketIoLength = 0;
  668. } else {
  669. SocketIoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
  670. SocketIoLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit -
  671. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
  672. }
  673. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base >=
  674. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit) {
  675. SocketMem32Base = 0;
  676. SocketMem32Length = 0;
  677. } else {
  678. SocketMem32Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
  679. SocketMem32Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit -
  680. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
  681. // Reserve 8M for ubox mmio
  682. SocketMem32Length = SocketMem32Length - UboxMmioSize;
  683. }
  684. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base >=
  685. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit) {
  686. SocketMem64Base = 0;
  687. SocketMem64Length = 0;
  688. } else{
  689. SocketMem64Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
  690. SocketMem64Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit -
  691. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
  692. }
  693. // Get all the resources that are in this socket
  694. SocketResources[Socket].IoResourcesLeft = (UINT16)SocketIoLength;
  695. SocketResources[Socket].MmiolResourcesLeft = (UINT32)SocketMem32Length;
  696. SocketResources[Socket].MmiohResourcesLeft = (UINT64)SocketMem64Length;
  697. LastStack = LastStackOfSocket (Socket);
  698. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  699. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  700. continue;
  701. }
  702. RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
  703. //
  704. // Check IO Resource
  705. //
  706. Alignment = RootBridgeInstance->ResAllocNode[TypeIo].Alignment + 1;
  707. NewLength = RootBridgeInstance->ResAllocNode[TypeIo].Length;
  708. if (IsVirtualRootBridge) {
  709. NewLength += NewLength;
  710. }
  711. // IoTrap allocates 256 byte range from GCD for common pool usage
  712. // For device to fit move to the next available alignment
  713. if ((Socket == 0) && (Stack == 0)) {
  714. NewLength += Alignment;
  715. }
  716. if (NewLength != 0) {
  717. //
  718. // At least 2KB align per KTI requirement. Add the length requested with given alignment.
  719. // If the sum is not 2KB aligned add on the remainder that would make it align.
  720. // Bump up to 4KB for root bridge requirements
  721. // Have to make sure Alignment is handled for direct address allocation
  722. //
  723. Remainder = SocketIoBase & (Alignment - 1);
  724. if (Remainder != 0) {
  725. NewLength += Alignment - Remainder;
  726. }
  727. if (NewLength % (IoGranularity * 2)) {
  728. Remainder = (IoGranularity * 2) - (NewLength % (IoGranularity * 2));
  729. NewLength += Remainder;
  730. }
  731. //
  732. // Store length as length - 1 for handling
  733. //
  734. NewLength -= 1;
  735. // Zero StackLength if its disable or negative
  736. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase >=
  737. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit) {
  738. StackLength = 0;
  739. } else {
  740. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit -
  741. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase;
  742. }
  743. SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = (UINT16)NewLength;
  744. // Check if new length can fit in the socket or stack
  745. if (SocketResources[Socket].IoResourcesLeft > (UINT16)NewLength) {
  746. SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength + 1;
  747. } else if (SocketResources[Socket].IoResourcesLeft == (UINT16)NewLength) {
  748. SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength;
  749. } else {
  750. // If there are resources left consume them
  751. if (SocketResources[Socket].IoResourcesLeft != 0) {
  752. NewLength = NewLength - SocketResources[Socket].IoResourcesLeft - 1;
  753. SocketResources[Socket].IoResourcesLeft = 0;
  754. }
  755. SocketResources[Socket].IoResourceNeeds += (UINT16)NewLength + 1;
  756. OutOfResources = TRUE;
  757. ChangedTypeOOR[TypeIo] = TRUE;
  758. }
  759. SocketResources[Socket].StackRes[Stack].IoAlignment = Alignment;
  760. if (NewLength > StackLength) {
  761. SocketResources[Socket].StackRes[Stack].NeedIoUpdate = TRUE;
  762. //IoResourcesLeft is UINT16 type, not 2's-complement value.
  763. if (SocketResources[Socket].IoResourcesLeft > SocketIoLength) {
  764. DEBUG ((DEBUG_ERROR, "[PCI] Out of Resources for Socket = %x Stack = %x Type = %x\n",
  765. Socket, Stack, TypeIo));
  766. SocketResources[Socket].IoResourcesLeft = 0;
  767. }
  768. ChangedType[TypeIo] = TRUE;
  769. }
  770. SocketIoBase += SocketResources[Socket].StackRes[Stack].NumIoPortsDesired + 1;
  771. DEBUG ((DEBUG_INFO, "SocketResources[%x].IoResourceLeft = %x\n",
  772. Socket, SocketResources[Socket].IoResourcesLeft));
  773. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoAlignment = %x\n",
  774. Socket, Stack, SocketResources[Socket].StackRes[Stack].IoAlignment));
  775. } else {
  776. SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = 0;
  777. }
  778. //
  779. // Check Mmem32 resource. This Host bridge does not support separated MEM / PMEM requests,
  780. // so only count MEM requests here.
  781. //
  782. Alignment = RootBridgeInstance->ResAllocNode[TypeMem32].Alignment + 1;
  783. NewLength = RootBridgeInstance->ResAllocNode[TypeMem32].Length;
  784. //
  785. // Account for reserved regions at begin and end of the stack MMIO32 region.
  786. //
  787. RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Base -
  788. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
  789. RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
  790. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit;
  791. NewLength += RsvLenAtBegin + RsvLenAtEnd;
  792. if (Alignment < RsvLenAtBegin) {
  793. Alignment = RsvLenAtBegin;
  794. }
  795. if (Alignment < RsvLenAtEnd) {
  796. Alignment = RsvLenAtEnd;
  797. }
  798. //
  799. // Always account for VT-d reserved resource ranges.
  800. // TODO: Remove when VTd BAR is included in RsvLenAtEnd.
  801. //
  802. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress != 0) {
  803. VtdBarSize = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit -
  804. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress + 1;
  805. NewLength += VtdBarSize;
  806. if (Alignment < VtdBarSize) {
  807. Alignment = VtdBarSize;
  808. }
  809. }
  810. if (IsVirtualRootBridge) {
  811. NewLength += NewLength;
  812. }
  813. // PCH Allocates reserved MMIO for Sx SMI handler use
  814. // For device to fit move to the next available alignment
  815. if ((Socket == 0) && (Stack == 0)) {
  816. NewLength += Alignment;
  817. }
  818. //
  819. // Check if new length is big enough to support PEI MMIO resource assigment for the stacks
  820. //
  821. if (NewLength < mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32MinSize) {
  822. NewLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32MinSize;
  823. }
  824. if (NewLength != 0) {
  825. //
  826. // At least 4MB align per KTI requirement. Add the length requested with given alignment.
  827. // If the sum is not 4MB aligned add on the remainder that would make it align.
  828. // Have to make sure Alignment is handled for direct address allocation
  829. //
  830. Remainder = SocketMem32Base & (Alignment - 1);
  831. if (Remainder != 0) {
  832. NewLength += Alignment - Remainder;
  833. }
  834. if (NewLength % MmiolGranularity) {
  835. Remainder = MmiolGranularity - (NewLength % MmiolGranularity);
  836. NewLength += Remainder;
  837. }
  838. if (Stack == LastStack) {
  839. //
  840. // Ubox address must be 8MB aligned for the base address on most processors; skip check
  841. // if uboxMmioSize is 0 (avoid divide by zero exception).
  842. // At this point the requested resource has already been calculated to be satisfied.
  843. // Add granularity padding if necessary to satisfy Ubox requirement.
  844. //
  845. if (UboxMmioSize != 0 && (SocketMem32Base + NewLength) % UboxMmioSize) {
  846. Remainder = UboxMmioSize - (NewLength % UboxMmioSize);
  847. NewLength += Remainder;
  848. }
  849. }
  850. //
  851. // Store length as length - 1 for handling
  852. //
  853. NewLength -= 1;
  854. // Zero StackLength if its disable or negative
  855. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base >=
  856. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit) {
  857. StackLength = 0;
  858. } else {
  859. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
  860. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
  861. }
  862. SocketResources[Socket].StackRes[Stack].MmiolLength = (UINT32)NewLength;
  863. // Check if new length can fit in the socket or stack
  864. if (SocketResources[Socket].MmiolResourcesLeft > (UINT32)NewLength) {
  865. SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength + 1;
  866. } else if (SocketResources[Socket].MmiolResourcesLeft == (UINT32)NewLength) {
  867. SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength;
  868. } else {
  869. // If there are resources left consume them
  870. if (SocketResources[Socket].MmiolResourcesLeft) {
  871. NewLength = NewLength - SocketResources[Socket].MmiolResourcesLeft - 1;
  872. SocketResources[Socket].MmiolResourcesLeft = 0;
  873. }
  874. SocketResources[Socket].MmiolResourceNeeds += (UINT32)NewLength + 1;
  875. OutOfResources = TRUE;
  876. ChangedTypeOOR[TypeMem32] = TRUE;
  877. }
  878. SocketResources[Socket].StackRes[Stack].MmiolAlignment = Alignment;
  879. if (NewLength > StackLength) {
  880. SocketResources[Socket].StackRes[Stack].MmiolUpdate = 1;
  881. //MmiolResourcesLeft is UINT32 type, not 2's-complement value.
  882. if (SocketResources[Socket].MmiolResourcesLeft > SocketMem32Length) {
  883. DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
  884. Socket, Stack, TypeMem32));
  885. SocketResources[Socket].MmiolResourcesLeft = 0;
  886. }
  887. ChangedType[TypeMem32] = TRUE;
  888. }
  889. SocketMem32Base += SocketResources[Socket].StackRes[Stack].MmiolLength + 1;
  890. DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiolResourceLeft = %x\n",
  891. Socket, SocketResources[Socket].MmiolResourcesLeft));
  892. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolAlignment = %x\n",
  893. Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiolAlignment));
  894. } else {
  895. SocketResources[Socket].StackRes[Stack].MmiolLength = 0;
  896. }
  897. //
  898. // Check Mem64 resource. This Host bridge does not support separated MEM / PMEM requests, so only count MEM requests here.
  899. //
  900. Alignment = RootBridgeInstance->ResAllocNode[TypeMem64].Alignment + 1;
  901. NewLength = RootBridgeInstance->ResAllocNode[TypeMem64].Length;
  902. //
  903. // Account for reserved regions at begin and end of the stack MMIO32 region.
  904. //
  905. RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Base -
  906. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
  907. RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
  908. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Limit;
  909. NewLength += RsvLenAtBegin + RsvLenAtEnd;
  910. if (Alignment < RsvLenAtBegin) {
  911. Alignment = RsvLenAtBegin;
  912. }
  913. if (Alignment < RsvLenAtEnd) {
  914. Alignment = RsvLenAtEnd;
  915. }
  916. if (IsVirtualRootBridge) {
  917. NewLength += NewLength;
  918. }
  919. if (NewLength != 0) {
  920. //
  921. // At least 1GB align per KTI requirement. Add the length requested with given alignment.
  922. // If the sum is not 1GB aligned add on the remainder that would make it align.
  923. // Have to make sure Alignment is handled for direct address allocation
  924. //
  925. Remainder = SocketMem64Base & (Alignment - 1);
  926. if (Remainder != 0) {
  927. NewLength += Alignment - Remainder;
  928. }
  929. if (NewLength % MmiohGranularity) {
  930. Remainder = MmiohGranularity - (NewLength % MmiohGranularity);
  931. NewLength += Remainder;
  932. }
  933. NewLength = ALIGN_VALUE (NewLength, Alignment);
  934. //
  935. // Store length as length - 1 for handling
  936. //
  937. NewLength -= 1;
  938. // Zero StackLength if it's disable or negative
  939. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base >=
  940. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit) {
  941. StackLength = 0;
  942. } else {
  943. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
  944. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
  945. }
  946. SocketResources[Socket].StackRes[Stack].MmiohLength = NewLength;
  947. // Check if new length can fit in the socket or stack
  948. if (SocketResources[Socket].MmiohResourcesLeft > NewLength) {
  949. SocketResources[Socket].MmiohResourcesLeft -= NewLength + 1;
  950. } else if (SocketResources[Socket].MmiohResourcesLeft == NewLength) {
  951. SocketResources[Socket].MmiohResourcesLeft -= NewLength;
  952. } else {
  953. // If there are resources left consume them
  954. if (SocketResources[Socket].MmiohResourcesLeft != 0) {
  955. NewLength = NewLength - SocketResources[Socket].MmiohResourcesLeft - 1;
  956. SocketResources[Socket].MmiohResourcesLeft = 0;
  957. }
  958. SocketResources[Socket].MmiohResourceNeeds += NewLength + 1;
  959. OutOfResources = TRUE;
  960. ChangedTypeOOR[TypeMem64] = TRUE;
  961. }
  962. SocketResources[Socket].StackRes[Stack].MmiohAlignment = Alignment;
  963. if (NewLength > StackLength) {
  964. SocketResources[Socket].StackRes[Stack].MmiohUpdate = 1;
  965. //MmiohResourcesLeft is UINT64 type, not 2's-complement value.
  966. if (SocketResources[Socket].MmiohResourcesLeft > SocketMem64Length) {
  967. DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
  968. Socket, Stack, TypeMem64));
  969. SocketResources[Socket].MmiohResourcesLeft = 0;
  970. }
  971. ChangedType[TypeMem64] = TRUE;
  972. }
  973. SocketMem64Base += SocketResources[Socket].StackRes[Stack].MmiohLength + 1;
  974. DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiohResourceLeft = %lx\n",
  975. Socket, SocketResources[Socket].MmiohResourcesLeft));
  976. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohAlignment = %lx\n",
  977. Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiohAlignment));
  978. } else {
  979. SocketResources[Socket].StackRes[Stack].MmiohLength = 0;
  980. }
  981. List = List->ForwardLink;
  982. } // for Stack
  983. // Check and update all resource types in socket that needs adjustment
  984. for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
  985. if (ChangedType[TypeIndex]) {
  986. DEBUG ((DEBUG_INFO, "[%d] Adjust stack %s resources...\n", Socket, mPciResourceTypeStr[TypeIndex]));
  987. Status = AdjustResources (&SocketResources[Socket], Socket, TypeIndex);
  988. ChangedType[TypeIndex] = FALSE;
  989. if (Status == EFI_SUCCESS) {
  990. ChangedBitMap |= (1 << TypeIndex);
  991. } else {
  992. ChangedBitMap &= ~(1 << TypeIndex);
  993. }
  994. }
  995. }
  996. //
  997. // Account for Ubox resources to accurately calculate new alignments for the next socket
  998. //
  999. SocketMem32Base += UboxMmioSize;
  1000. } // for Socket ..
  1001. ASSERT (List == &HostBridgeInstance->RootBridges);
  1002. //
  1003. // If a socket is out of resources, try to adjusting sockets for more room.
  1004. //
  1005. if (OutOfResources && (MAX_SOCKET > 1) && (ValidSockets > 1)) {
  1006. for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
  1007. if (ChangedTypeOOR[TypeIndex]) {
  1008. DEBUG ((DEBUG_INFO, "Adjust socket %s resources...\n", mPciResourceTypeStr[TypeIndex]));
  1009. Status = AdjustSocketResources (SocketResources, TypeIndex, ValidSockets);
  1010. if (Status == EFI_SUCCESS) {
  1011. ChangedBitMap |= (1 << TypeIndex);
  1012. } else {
  1013. ChangedBitMap &= ~(1 << TypeIndex);
  1014. }
  1015. }
  1016. }
  1017. } else if (OutOfResources) {
  1018. if (ChangedTypeOOR[TypeMem64]) {
  1019. //
  1020. // Allow mmioh to be adjusted to access max available physical address range.
  1021. //
  1022. Status = AdjustSocketResources (SocketResources, TypeMem64, ValidSockets);
  1023. if (Status == EFI_SUCCESS) {
  1024. ChangedBitMap |= (1 << TypeIndex);
  1025. } else {
  1026. ChangedBitMap &= ~(1 << TypeIndex);
  1027. }
  1028. }
  1029. if (ChangedTypeOOR[TypeIo] || ChangedTypeOOR[TypeMem32]) {
  1030. DEBUG ((DEBUG_ERROR, "Clearing %s request\n", mPciResourceTypeStr[TypeIo]));
  1031. DEBUG ((DEBUG_ERROR, "Clearing %s request\n", mPciResourceTypeStr[TypeMem32]));
  1032. for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
  1033. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  1034. SocketResources[Socket].StackRes[Stack].NeedIoUpdate = 0;
  1035. SocketResources[Socket].StackRes[Stack].MmiolUpdate = 0;
  1036. }
  1037. }
  1038. }
  1039. }
  1040. //
  1041. // Update changed resource type.
  1042. // OemGetResourceMapUpdate() will only update changed resource type so it is alright if data is zero.
  1043. //
  1044. if (ChangedBitMap != 0) {
  1045. for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
  1046. SocketPciResourceData.StackPresentBitmap[Socket] = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap;
  1047. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  1048. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1049. continue;
  1050. }
  1051. CurStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[Stack];
  1052. //
  1053. // Disable stacks that have no resources and are assigned none.
  1054. // Reaching this far means the stack is valid and should be disabled if base equals limit and
  1055. // length is zero.
  1056. // Assigned address will be none zero at this point because CSTACK takes the first 4K in legacy
  1057. // IO space.
  1058. //
  1059. if ((SocketResources[Socket].StackRes[Stack].NeedIoUpdate) &&
  1060. (SocketResources[Socket].StackRes[Stack].IoLimit -
  1061. SocketResources[Socket].StackRes[Stack].IoBase == 0)) {
  1062. SocketResources[Socket].StackRes[Stack].IoBase = (UINT16)(-1);
  1063. SocketResources[Socket].StackRes[Stack].IoLimit = 0;
  1064. }
  1065. if ((SocketResources[Socket].StackRes[Stack].MmiolUpdate) &&
  1066. (SocketResources[Socket].StackRes[Stack].MmiolLimit -
  1067. SocketResources[Socket].StackRes[Stack].MmiolBase == 0)) {
  1068. SocketResources[Socket].StackRes[Stack].MmiolBase = (UINT32)(-1);
  1069. SocketResources[Socket].StackRes[Stack].MmiolLimit = 0;
  1070. }
  1071. if ((SocketResources[Socket].StackRes[Stack].MmiohUpdate) &&
  1072. (SocketResources[Socket].StackRes[Stack].MmiohLimit -
  1073. SocketResources[Socket].StackRes[Stack].MmiohBase == 0)) {
  1074. SocketResources[Socket].StackRes[Stack].MmiohBase = (UINT64)(-1);
  1075. SocketResources[Socket].StackRes[Stack].MmiohLimit = 0;
  1076. }
  1077. // Zero base if 4K because mIioUds struct reserves 4K of Io for legacy purposes
  1078. // Remove if mIioUds first base starts at zero
  1079. if (SocketResources[Socket].StackRes[Stack].IoBase == 0x1000){
  1080. SocketResources[Socket].StackRes[Stack].IoBase = 0;
  1081. }
  1082. if (SocketResources[Socket].StackRes[Stack].NeedIoUpdate) {
  1083. CurStackLimits->Io.Base = SocketResources[Socket].StackRes[Stack].IoBase;
  1084. CurStackLimits->Io.Limit = SocketResources[Socket].StackRes[Stack].IoLimit;
  1085. }
  1086. if (SocketResources[Socket].StackRes[Stack].MmiolUpdate) {
  1087. if ((Socket == 0) && (Stack == 0)) {
  1088. CurStackLimits->LowMmio.Base = PlatGlobalMmiolBase;
  1089. } else {
  1090. CurStackLimits->LowMmio.Base = SocketResources[Socket].StackRes[Stack].MmiolBase;
  1091. }
  1092. CurStackLimits->LowMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
  1093. }
  1094. if (SocketResources[Socket].StackRes[Stack].MmiohUpdate) {
  1095. CurStackLimits->HighMmio.Base = SocketResources[Socket].StackRes[Stack].MmiohBase;
  1096. CurStackLimits->HighMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
  1097. }
  1098. DEBUG((DEBUG_INFO, "\nSocketResources[%x].StackRes[%x].IoBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoBase));
  1099. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoLimit));
  1100. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolBase));
  1101. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolLimit));
  1102. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohBase =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohBase));
  1103. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohLimit =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohLimit));
  1104. } // for Stack
  1105. // Initialize to disabled
  1106. SocketResources[Socket].IoBase = (UINT16)(-1);
  1107. SocketResources[Socket].IoLimit = 0;
  1108. SocketResources[Socket].MmiolBase = (UINT32)(-1);
  1109. SocketResources[Socket].MmiolLimit = 0;
  1110. SocketResources[Socket].MmiohBase = (UINT64)(-1);
  1111. SocketResources[Socket].MmiohLimit = 0;
  1112. // Search backwards to find the beginning valid stack
  1113. for (Stack = MAX_IIO_STACK - 1; Stack < MAX_IIO_STACK ; Stack--) {
  1114. CurSocketLimits = &SocketPciResourceData.Socket[Socket].SocketLimits;
  1115. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1116. continue;
  1117. }
  1118. if (SocketResources[Socket].StackRes[Stack].IoBase != (UINT16)(-1)) {
  1119. SocketResources[Socket].IoBase = SocketResources[Socket].StackRes[Stack].IoBase;
  1120. }
  1121. if (SocketResources[Socket].StackRes[Stack].MmiolBase != (UINT32)(-1)) {
  1122. SocketResources[Socket].MmiolBase = SocketResources[Socket].StackRes[Stack].MmiolBase;
  1123. }
  1124. if (SocketResources[Socket].StackRes[Stack].MmiohBase != (UINT64)(-1)) {
  1125. SocketResources[Socket].MmiohBase = SocketResources[Socket].StackRes[Stack].MmiohBase;
  1126. }
  1127. } // for Stack
  1128. // Search to find the last valid limit
  1129. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  1130. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1131. continue;
  1132. }
  1133. if (SocketResources[Socket].StackRes[Stack].IoLimit != 0) {
  1134. SocketResources[Socket].IoLimit = SocketResources[Socket].StackRes[Stack].IoLimit;
  1135. }
  1136. if (SocketResources[Socket].StackRes[Stack].MmiolLimit) {
  1137. SocketResources[Socket].MmiolLimit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
  1138. }
  1139. if (SocketResources[Socket].StackRes[Stack].MmiohLimit) {
  1140. SocketResources[Socket].MmiohLimit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
  1141. }
  1142. } // for Stack
  1143. // Update socket level resource range
  1144. if (SocketResources[Socket].StackRes[0].NeedIoUpdate) {
  1145. CurSocketLimits->Io.Base = SocketResources[Socket].IoBase;
  1146. CurSocketLimits->Io.Limit = SocketResources[Socket].IoLimit;
  1147. }
  1148. if (SocketResources[Socket].StackRes[0].MmiolUpdate) {
  1149. //
  1150. // Apply stolen 8M for ubox mmio per socket
  1151. //
  1152. if (UboxMmioSize != 0) {
  1153. UboxStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK];
  1154. UboxStackLimits->LowMmio.Base = SocketResources[Socket].MmiolLimit + 1;
  1155. SocketResources[Socket].MmiolLimit = (UINT32)UboxStackLimits->LowMmio.Base + UboxMmioSize - 1;
  1156. UboxStackLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
  1157. }
  1158. CurSocketLimits->LowMmio.Base = SocketResources[Socket].MmiolBase;
  1159. CurSocketLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
  1160. }
  1161. if (SocketResources[Socket].StackRes[0].MmiohUpdate) {
  1162. CurSocketLimits->HighMmio.Base = SocketResources[Socket].MmiohBase;
  1163. CurSocketLimits->HighMmio.Limit = SocketResources[Socket].MmiohLimit;
  1164. }
  1165. DEBUG((DEBUG_INFO, "\nSocketResources[%x].UboxBase = %x\n",
  1166. Socket, SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK].LowMmio.Base));
  1167. DEBUG((DEBUG_INFO, "SocketResources[%x].UboxLimit = %x\n",
  1168. Socket, SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK].LowMmio.Limit));
  1169. DEBUG((DEBUG_INFO, "\nSocketResources[%x].IoBase =%x\n",Socket,SocketResources[Socket].IoBase));
  1170. DEBUG((DEBUG_INFO, "SocketResources[%x].IoLimit =%x\n",Socket,SocketResources[Socket].IoLimit));
  1171. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolBase =%x\n",Socket,SocketResources[Socket].MmiolBase));
  1172. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolLimit =%x\n",Socket,SocketResources[Socket].MmiolLimit));
  1173. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohBase =%lx\n",Socket,SocketResources[Socket].MmiohBase));
  1174. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohLimit =%lx\n",Socket,SocketResources[Socket].MmiohLimit));
  1175. } // for Socket
  1176. SocketPciResourceData.MmioHBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base;
  1177. SocketPciResourceData.MmioHGranularity = *(UINT64*)&mIioUds->IioUdsPtr->PlatformData.MmiohGranularity;
  1178. SocketPciResourceData.MmioLBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
  1179. SocketPciResourceData.MmioLLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit;
  1180. SocketPciResourceData.MmioLGranularity = mIioUds->IioUdsPtr->PlatformData.MmiolGranularity;
  1181. SocketPciResourceData.IoBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase;
  1182. SocketPciResourceData.IoLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit;
  1183. SocketPciResourceData.IoGranularity = mIioUds->IioUdsPtr->PlatformData.IoGranularity;
  1184. PCIDEBUG("Writing resource rebalance request '%s':\n", SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME);
  1185. PCIDEBUG("System I/O : %04X..%04X [%X]\n", SocketPciResourceData.IoBase, SocketPciResourceData.IoLimit, SocketPciResourceData.IoGranularity);
  1186. PCIDEBUG("System MMIOL: %08X..%08X [%X]\n", SocketPciResourceData.MmioLBase, SocketPciResourceData.MmioLLimit, SocketPciResourceData.MmioLGranularity);
  1187. PCIDEBUG("System MMIOH: %012llX [%llX]\n", SocketPciResourceData.MmioHBase, SocketPciResourceData.MmioHGranularity);
  1188. for (Socket = 0; Socket < NELEMENTS (SocketPciResourceData.Socket); Socket++) {
  1189. PCIDEBUG("[%d] StackPresent: 0x%04X\n", Socket, SocketPciResourceData.StackPresentBitmap[Socket]);
  1190. PCIDEBUG("[%d] I/O : %04X..%04X\n", Socket,
  1191. SocketPciResourceData.Socket[Socket].SocketLimits.Io.Base,
  1192. SocketPciResourceData.Socket[Socket].SocketLimits.Io.Limit);
  1193. PCIDEBUG("[%d] MMIOL: %08X..%08X\n", Socket,
  1194. SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Base,
  1195. SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Limit);
  1196. PCIDEBUG("[%d] MMIOH: %012llX..%012llX\n", Socket,
  1197. SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Base,
  1198. SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Limit);
  1199. for (Stack = 0; Stack < NELEMENTS (SocketPciResourceData.Socket[Socket].StackLimits); Stack++) {
  1200. PCIDEBUG("[%d.%d] I/O : %04X..%04X\n", Socket, Stack,
  1201. SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Base,
  1202. SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Limit);
  1203. PCIDEBUG("[%d.%d] MMIOL: %08X..%08X\n", Socket, Stack,
  1204. SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Base,
  1205. SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Limit);
  1206. PCIDEBUG("[%d.%d] MMIOH: %012llX..%012llX\n", Socket, Stack,
  1207. SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Base,
  1208. SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Limit);
  1209. }
  1210. }
  1211. *Result = SocketResourceRatioChanged;
  1212. Status = gRT->SetVariable(
  1213. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  1214. &gEfiSocketPciResourceDataGuid,
  1215. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  1216. sizeof(SocketPciResourceData),
  1217. &SocketPciResourceData
  1218. );
  1219. ASSERT_EFI_ERROR(Status);
  1220. }
  1221. return;
  1222. }