PciRebalance.c 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  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, "ERROR: Resource Type Unknown = %x\n",ResourceType));
  366. Status = EFI_INVALID_PARAMETER;
  367. break;
  368. } // switch
  369. return Status;
  370. }
  371. /**
  372. Calculate current system resource map with retrieved 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, Rejected ? "rejected" : "");
  424. if (IioUdsStackLimits->Mmio32Base != StackLimits->LowMmio.Base && StackLimits->LowMmio.Base != 0) {
  425. Rejected = TRUE;
  426. }
  427. if (IioUdsStackLimits->Mmio32Limit != StackLimits->LowMmio.Limit && StackLimits->LowMmio.Limit != 0) {
  428. Rejected = TRUE;
  429. }
  430. PCIDEBUG ("[%d.%d] Current MMIOL: 0x%08X..0x%08X\n", Socket, Stack,
  431. IioUdsStackLimits->Mmio32Base, IioUdsStackLimits->Mmio32Limit);
  432. PCIDEBUG ("[%d.%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket, Stack,
  433. StackLimits->LowMmio.Base, StackLimits->LowMmio.Limit, Rejected ? "rejected" : "");
  434. if (IioUdsStackLimits->Mmio64Base != StackLimits->HighMmio.Base && StackLimits->HighMmio.Base != 0) {
  435. Rejected = TRUE;
  436. }
  437. if (IioUdsStackLimits->Mmio64Limit != StackLimits->HighMmio.Limit && StackLimits->HighMmio.Limit != 0) {
  438. Rejected = TRUE;
  439. }
  440. PCIDEBUG ("[%d.%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket, Stack,
  441. IioUdsStackLimits->Mmio64Base, IioUdsStackLimits->Mmio64Limit);
  442. PCIDEBUG ("[%d.%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket, Stack,
  443. StackLimits->HighMmio.Base, StackLimits->HighMmio.Limit, Rejected ? "rejected" : "");
  444. }
  445. }
  446. //
  447. // Per socket
  448. //
  449. if (IioUdsSocketLimits->PciResourceIoBase != SocketLimits->Io.Base && SocketLimits->Io.Base != 0) {
  450. Rejected = TRUE;
  451. }
  452. if (IioUdsSocketLimits->PciResourceIoLimit != SocketLimits->Io.Limit && SocketLimits->Io.Limit != 0) {
  453. Rejected = TRUE;
  454. }
  455. PCIDEBUG("[%d] Current I/O: 0x%04X..0x%04X\n", Socket,
  456. IioUdsSocketLimits->PciResourceIoBase, IioUdsSocketLimits->PciResourceIoLimit);
  457. PCIDEBUG("[%d] Saved I/O: 0x%04X..0x%04X %a\n", Socket,
  458. SocketLimits->Io.Base, SocketLimits->Io.Limit, Rejected ? "rejected" : "");
  459. if (IioUdsSocketLimits->Mmio32Base != SocketLimits->LowMmio.Base && SocketLimits->LowMmio.Base != 0) {
  460. Rejected = TRUE;
  461. }
  462. if (IioUdsSocketLimits->Mmio32Limit != SocketLimits->LowMmio.Limit && SocketLimits->LowMmio.Limit != 0) {
  463. Rejected = TRUE;
  464. }
  465. PCIDEBUG ("[%d] Current MMIOL: 0x%08X..0x%08X\n", Socket,
  466. IioUdsSocketLimits->Mmio32Base, IioUdsSocketLimits->Mmio32Limit);
  467. PCIDEBUG ("[%d] Saved MMIOL: 0x%08X..0x%08X %a\n", Socket,
  468. SocketLimits->LowMmio.Base, SocketLimits->LowMmio.Limit, Rejected ? "rejected" : "");
  469. if (IioUdsSocketLimits->Mmio64Base != SocketLimits->HighMmio.Base && SocketLimits->HighMmio.Base != 0) {
  470. Rejected = TRUE;
  471. }
  472. if (IioUdsSocketLimits->Mmio64Limit != SocketLimits->HighMmio.Limit && SocketLimits->HighMmio.Limit != 0) {
  473. Rejected = TRUE;
  474. }
  475. PCIDEBUG ("[%d] Current MMIOH: 0x%012llX..0x%012llX\n", Socket,
  476. IioUdsSocketLimits->Mmio64Base, IioUdsSocketLimits->Mmio64Limit);
  477. PCIDEBUG ("[%d] Saved MMIOH: 0x%012llX..0x%012llX %a\n", Socket,
  478. SocketLimits->HighMmio.Base, SocketLimits->HighMmio.Limit, Rejected ? "rejected" : "");
  479. if (IioUdsUboxStackLimits->Mmio64Base != UboxStackLimits->HighMmio.Base && UboxStackLimits->HighMmio.Base != 0) {
  480. Rejected = TRUE;
  481. }
  482. if (IioUdsUboxStackLimits->Mmio64Limit != UboxStackLimits->HighMmio.Limit && UboxStackLimits->HighMmio.Limit != 0) {
  483. Rejected = TRUE;
  484. }
  485. PCIDEBUG ("[%d] Current UBOX: 0x%08X..0x%08X\n", Socket,
  486. IioUdsUboxStackLimits->Mmio64Base, IioUdsUboxStackLimits->Mmio64Limit);
  487. PCIDEBUG ("[%d] Saved UBOX: 0x%08X..0x%08X %a\n", Socket,
  488. UboxStackLimits->HighMmio.Base, UboxStackLimits->HighMmio.Limit, Rejected ? "rejected" : "");
  489. }
  490. }
  491. DEBUG ((DEBUG_INFO, "[PCI] Resource rebalance rejected ? %a\n", Rejected ? "TRUE" : "FALSE"));
  492. return Rejected;
  493. }
  494. /**
  495. Read SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME variable from flash and verify its content.
  496. If the variable does not exist, or is not valid for current system configuration
  497. the buffer at *PciResConfigPtr is just cleared.
  498. @param[out] PciResConfigPtr - Buffer for the resource configuration variable.
  499. @retval EFI_SUCCESS The function completed successfully.
  500. @retval EFI_NOT_FOUND The variable was not found.
  501. @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error.
  502. @retval EFI_SECURITY_VIOLATION The variable could not be retrieved due to an authentication failure.
  503. **/
  504. EFI_STATUS
  505. PciHostReadResourceConfig (
  506. OUT SYSTEM_PCI_BASE_LIMITS *PciResConfigPtr
  507. )
  508. {
  509. UINTN VarSize;
  510. EFI_STATUS Status;
  511. UINT8 Socket;
  512. VarSize = sizeof(*PciResConfigPtr);
  513. Status = gRT->GetVariable (SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, &gEfiSocketPciResourceDataGuid,
  514. NULL, &VarSize, PciResConfigPtr);
  515. if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
  516. goto ErrExit;
  517. }
  518. if (Status == EFI_BUFFER_TOO_SMALL || VarSize != sizeof(*PciResConfigPtr)) {
  519. PCIDEBUG ("Got variable '%s' of unexpected size %d (expect %d) - overwrite\n",
  520. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, VarSize, sizeof(*PciResConfigPtr));
  521. Status = EFI_NOT_FOUND;
  522. goto ErrExit;
  523. }
  524. //
  525. // If any of the below checks fails clear the buffer and return EFI_NOT_FOUND.
  526. //
  527. Status = EFI_NOT_FOUND;
  528. if (PciResConfigPtr->MmioHBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base ||
  529. PciResConfigPtr->MmioHLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Limit) {
  530. PCIDEBUG ("%s: Memory map changed (MMIOH %012llX..%012llX != %012llX..%012llX) - overwrite\n",
  531. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  532. PciResConfigPtr->MmioHBase, PciResConfigPtr->MmioHLimit,
  533. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base,
  534. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Limit);
  535. goto ErrExit;
  536. }
  537. if (PciResConfigPtr->MmioLBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base ||
  538. PciResConfigPtr->MmioLLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit) {
  539. PCIDEBUG ("%s: Memory map changed (MMIOL %08X..%08X != %08X..%08X) - overwrite\n",
  540. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  541. PciResConfigPtr->MmioLBase, PciResConfigPtr->MmioLLimit,
  542. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base,
  543. mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit);
  544. goto ErrExit;
  545. }
  546. if (PciResConfigPtr->IoBase != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase ||
  547. PciResConfigPtr->IoLimit != mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit) {
  548. PCIDEBUG ("%s: Memory map changed (I/O %04X..%04X != %04X..%04X) - overwrite\n",
  549. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  550. PciResConfigPtr->IoBase, PciResConfigPtr->IoLimit,
  551. mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase,
  552. mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit);
  553. goto ErrExit;
  554. }
  555. for (Socket = 0; Socket < NELEMENTS (PciResConfigPtr->Socket); Socket++) {
  556. if (PciResConfigPtr->StackPresentBitmap[Socket] !=
  557. mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap) {
  558. PCIDEBUG ("%s: Stack bitmap mismach (%04X != %04X) in socket %d - overwrite\n",
  559. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME, PciResConfigPtr->StackPresentBitmap[Socket],
  560. mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap, Socket);
  561. goto ErrExit;
  562. }
  563. }
  564. return EFI_SUCCESS;
  565. ErrExit:
  566. ZeroMem (PciResConfigPtr, sizeof(*PciResConfigPtr));
  567. return Status;
  568. } // PciHostReadResourceConfig()
  569. /**
  570. Adjust resource ratio assignment among CPU sockets to fit the resource needs from PCI devices.
  571. Update Setup variable if there are changes from the existing ratio requests for this boot.
  572. @param[in] HostBridgeInstance - The Host Bridge Instance where the resource adjustment happens.
  573. @param[out] Result - Output parameter. Indicates whether changes have been made.
  574. **/
  575. VOID
  576. AdjustResourceAmongRootBridges (
  577. IN PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance,
  578. OUT SOCKET_RESOURCE_ADJUSTMENT_RESULT *Result
  579. )
  580. {
  581. PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
  582. LIST_ENTRY *List;
  583. CPU_RESOURCE SocketResources[MAX_SOCKET];
  584. UINT64 SocketIoLength;
  585. UINT64 SocketMem32Length;
  586. UINT64 SocketMem64Length;
  587. UINT64 SocketIoBase;
  588. UINT64 SocketMem32Base;
  589. UINT64 SocketMem64Base;
  590. UINT64 RsvLenAtBegin;
  591. UINT64 RsvLenAtEnd;
  592. UINT64 StackLength;
  593. UINT64 NewLength;
  594. UINT64 Alignment;
  595. UINT64 Remainder;
  596. UINT8 Socket;
  597. UINT8 ValidSockets;
  598. BOOLEAN ChangedType[TypeMax];
  599. BOOLEAN ChangedTypeOOR[TypeMax]; // Change type for out of resources
  600. UINT8 TypeIndex;
  601. UINT8 ChangedBitMap;
  602. EFI_STATUS Status;
  603. SYSTEM_PCI_BASE_LIMITS SocketPciResourceData;
  604. UINT8 Stack;
  605. UINT8 LastStack;
  606. UINT16 IoGranularity;
  607. UINT32 MmiolGranularity;
  608. UINT64 MmiohGranularity;
  609. BOOLEAN OutOfResources;
  610. UINT32 UboxMmioSize;
  611. BOOLEAN IsVirtualRootBridge;
  612. PCI_BASE_LIMITS *CurStackLimits;
  613. PCI_BASE_LIMITS *UboxStackLimits;
  614. PCI_BASE_LIMITS *CurSocketLimits;
  615. UINT32 PlatGlobalMmiolBase;
  616. UINT32 VtdBarSize;
  617. *Result = SocketResourceRatioNotChanged;
  618. SetMem (ChangedType, TypeMax, FALSE);
  619. SetMem (ChangedTypeOOR, TypeMax, FALSE);
  620. ChangedBitMap = 0;
  621. OutOfResources = FALSE;
  622. IsVirtualRootBridge = FALSE;
  623. IoGranularity = mIioUds->IioUdsPtr->PlatformData.IoGranularity;
  624. MmiolGranularity = mIioUds->IioUdsPtr->PlatformData.MmiolGranularity;
  625. MmiohGranularity = (UINT64) mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.lo;
  626. MmiohGranularity |= ((UINT64)mIioUds->IioUdsPtr->PlatformData.MmiohGranularity.hi) << 32;
  627. ZeroMem (&SocketResources[0], sizeof(SocketResources));
  628. //
  629. // Read the system resource cfg from NVRAM. If the variable does not exist, or is
  630. // not valid for current system configuration the buffer SocketPciResourceData
  631. // is just cleared.
  632. //
  633. Status = PciHostReadResourceConfig (&SocketPciResourceData);
  634. if (EFI_ERROR (Status)) {
  635. if (Status != EFI_NOT_FOUND) {
  636. ASSERT_EFI_ERROR (Status);
  637. return;
  638. }
  639. //
  640. // Variable is not initialized yet, go with empty structure.
  641. //
  642. } else if (IsResourceMapRejected (&SocketPciResourceData)) {
  643. //
  644. // If variable is already initialized, but rejected by KTI do not reboot to avoid loop.
  645. //
  646. return;
  647. }
  648. UboxMmioSize = mIioUds->IioUdsPtr->PlatformData.UboxMmioSize;
  649. PlatGlobalMmiolBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
  650. ValidSockets = 0;
  651. for (List = HostBridgeInstance->RootBridges.ForwardLink, Socket = 0; Socket < MAX_SOCKET; Socket ++) {
  652. if (!mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Valid) {
  653. continue;
  654. }
  655. ValidSockets++;
  656. //
  657. // Calculate the length of resources available per socket
  658. //
  659. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase >=
  660. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit) {
  661. SocketIoBase = 0;
  662. SocketIoLength = 0;
  663. } else {
  664. SocketIoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
  665. SocketIoLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoLimit -
  666. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].PciResourceIoBase;
  667. }
  668. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base >=
  669. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit) {
  670. SocketMem32Base = 0;
  671. SocketMem32Length = 0;
  672. } else {
  673. SocketMem32Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
  674. SocketMem32Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Limit -
  675. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio32Base;
  676. // Reserve 8M for ubox mmio
  677. SocketMem32Length = SocketMem32Length - UboxMmioSize;
  678. }
  679. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base >=
  680. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit) {
  681. SocketMem64Base = 0;
  682. SocketMem64Length = 0;
  683. } else{
  684. SocketMem64Base = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
  685. SocketMem64Length = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Limit -
  686. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].Mmio64Base;
  687. }
  688. // Get all the resources that are in this socket
  689. SocketResources[Socket].IoResourcesLeft = (UINT16)SocketIoLength;
  690. SocketResources[Socket].MmiolResourcesLeft = (UINT32)SocketMem32Length;
  691. SocketResources[Socket].MmiohResourcesLeft = (UINT64)SocketMem64Length;
  692. LastStack = LastStackOfSocket (Socket);
  693. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  694. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  695. continue;
  696. }
  697. RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
  698. //
  699. // Check IO Resource
  700. //
  701. Alignment = RootBridgeInstance->ResAllocNode[TypeIo].Alignment + 1;
  702. NewLength = RootBridgeInstance->ResAllocNode[TypeIo].Length;
  703. if (IsVirtualRootBridge) {
  704. NewLength += NewLength;
  705. }
  706. // IoTrap allocates 256 byte range from GCD for common pool usage
  707. // For device to fit move to the next available alignment
  708. if ((Socket == 0) && (Stack == 0)) {
  709. NewLength += Alignment;
  710. }
  711. if (NewLength != 0) {
  712. //
  713. // At least 2KB align per KTI requirement. Add the length requested with given alignment.
  714. // If the sum is not 2KB aligned add on the remainder that would make it align.
  715. // Bump up to 4KB for root bridge requirements
  716. // Have to make sure Alignment is handled for direct address allocation
  717. //
  718. Remainder = SocketIoBase & (Alignment - 1);
  719. if (Remainder != 0) {
  720. NewLength += Alignment - Remainder;
  721. }
  722. if (NewLength % (IoGranularity * 2)) {
  723. Remainder = (IoGranularity * 2) - (NewLength % (IoGranularity * 2));
  724. NewLength += Remainder;
  725. }
  726. //
  727. // Store length as length - 1 for handling
  728. //
  729. NewLength -= 1;
  730. // Zero StackLength if its disable or negative
  731. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase >=
  732. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit) {
  733. StackLength = 0;
  734. } else {
  735. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoLimit -
  736. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceIoBase;
  737. }
  738. SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = (UINT16)NewLength;
  739. // Check if new length can fit in the socket or stack
  740. if (SocketResources[Socket].IoResourcesLeft > (UINT16)NewLength) {
  741. SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength + 1;
  742. } else if (SocketResources[Socket].IoResourcesLeft == (UINT16)NewLength) {
  743. SocketResources[Socket].IoResourcesLeft -= (UINT16)NewLength;
  744. } else {
  745. // If there are resources left consume them
  746. if (SocketResources[Socket].IoResourcesLeft != 0) {
  747. NewLength = NewLength - SocketResources[Socket].IoResourcesLeft - 1;
  748. SocketResources[Socket].IoResourcesLeft = 0;
  749. }
  750. SocketResources[Socket].IoResourceNeeds += (UINT16)NewLength + 1;
  751. OutOfResources = TRUE;
  752. ChangedTypeOOR[TypeIo] = TRUE;
  753. }
  754. SocketResources[Socket].StackRes[Stack].IoAlignment = Alignment;
  755. if (NewLength > StackLength) {
  756. SocketResources[Socket].StackRes[Stack].NeedIoUpdate = TRUE;
  757. //IoResourcesLeft is UINT16 type, not 2's-complement value.
  758. if (SocketResources[Socket].IoResourcesLeft > SocketIoLength) {
  759. DEBUG ((DEBUG_ERROR, "[PCI] Out of Resources for Socket = %x Stack = %x Type = %x\n",
  760. Socket, Stack, TypeIo));
  761. SocketResources[Socket].IoResourcesLeft = 0;
  762. }
  763. ChangedType[TypeIo] = TRUE;
  764. }
  765. SocketIoBase += SocketResources[Socket].StackRes[Stack].NumIoPortsDesired + 1;
  766. DEBUG ((DEBUG_INFO, "SocketResources[%x].IoResourceLeft = %x\n",
  767. Socket, SocketResources[Socket].IoResourcesLeft));
  768. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoAlignment = %x\n",
  769. Socket, Stack, SocketResources[Socket].StackRes[Stack].IoAlignment));
  770. } else {
  771. SocketResources[Socket].StackRes[Stack].NumIoPortsDesired = 0;
  772. }
  773. //
  774. // Check Mmem32 resource. This Host bridge does not support separated MEM / PMEM requests,
  775. // so only count MEM requests here.
  776. //
  777. Alignment = RootBridgeInstance->ResAllocNode[TypeMem32].Alignment + 1;
  778. NewLength = RootBridgeInstance->ResAllocNode[TypeMem32].Length;
  779. //
  780. // Account for reserved regions at begin and end of the stack MMIO32 region.
  781. //
  782. RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Base -
  783. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
  784. RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
  785. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit;
  786. NewLength += RsvLenAtBegin + RsvLenAtEnd;
  787. if (Alignment < RsvLenAtBegin) {
  788. Alignment = RsvLenAtBegin;
  789. }
  790. if (Alignment < RsvLenAtEnd) {
  791. Alignment = RsvLenAtEnd;
  792. }
  793. //
  794. // Always account for VT-d reserved resource ranges.
  795. // TODO: Remove when VTd BAR is included in RsvLenAtEnd.
  796. //
  797. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress != 0) {
  798. VtdBarSize = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem32Limit -
  799. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].VtdBarAddress + 1;
  800. NewLength += VtdBarSize;
  801. if (Alignment < VtdBarSize) {
  802. Alignment = VtdBarSize;
  803. }
  804. }
  805. if (IsVirtualRootBridge) {
  806. NewLength += NewLength;
  807. }
  808. // PCH Allocates reserved MMIO for Sx SMI handler use
  809. // For device to fit move to the next available alignment
  810. if ((Socket == 0) && (Stack == 0)) {
  811. NewLength += Alignment;
  812. }
  813. if (NewLength != 0) {
  814. //
  815. // At least 4MB align per KTI requirement. Add the length requested with given alignment.
  816. // If the sum is not 4MB aligned add on the remainder that would make it align.
  817. // Have to make sure Alignment is handled for direct address allocation
  818. //
  819. Remainder = SocketMem32Base & (Alignment - 1);
  820. if (Remainder != 0) {
  821. NewLength += Alignment - Remainder;
  822. }
  823. if (NewLength % MmiolGranularity) {
  824. Remainder = MmiolGranularity - (NewLength % MmiolGranularity);
  825. NewLength += Remainder;
  826. }
  827. if (Stack == LastStack) {
  828. //
  829. // Ubox address must be 8MB aligned for the base address on most processors; skip check
  830. // if uboxMmioSize is 0 (avoid divide by zero exception).
  831. // At this point the requested resource has already been calculated to be satisfied.
  832. // Add granularity padding if necessary to satisfy Ubox requirement.
  833. //
  834. if (UboxMmioSize != 0 && (SocketMem32Base + NewLength) % UboxMmioSize) {
  835. Remainder = UboxMmioSize - (NewLength % UboxMmioSize);
  836. NewLength += Remainder;
  837. }
  838. }
  839. //
  840. // Store length as length - 1 for handling
  841. //
  842. NewLength -= 1;
  843. // Zero StackLength if its disable or negative
  844. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base >=
  845. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit) {
  846. StackLength = 0;
  847. } else {
  848. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Limit -
  849. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio32Base;
  850. }
  851. SocketResources[Socket].StackRes[Stack].MmiolLength = (UINT32)NewLength;
  852. // Check if new length can fit in the socket or stack
  853. if (SocketResources[Socket].MmiolResourcesLeft > (UINT32)NewLength) {
  854. SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength + 1;
  855. } else if (SocketResources[Socket].MmiolResourcesLeft == (UINT32)NewLength) {
  856. SocketResources[Socket].MmiolResourcesLeft -= (UINT32)NewLength;
  857. } else {
  858. // If there are resources left consume them
  859. if (SocketResources[Socket].MmiolResourcesLeft) {
  860. NewLength = NewLength - SocketResources[Socket].MmiolResourcesLeft - 1;
  861. SocketResources[Socket].MmiolResourcesLeft = 0;
  862. }
  863. SocketResources[Socket].MmiolResourceNeeds += (UINT32)NewLength + 1;
  864. OutOfResources = TRUE;
  865. ChangedTypeOOR[TypeMem32] = TRUE;
  866. }
  867. SocketResources[Socket].StackRes[Stack].MmiolAlignment = Alignment;
  868. if (NewLength > StackLength) {
  869. SocketResources[Socket].StackRes[Stack].MmiolUpdate = 1;
  870. //MmiolResourcesLeft is UINT32 type, not 2's-complement value.
  871. if (SocketResources[Socket].MmiolResourcesLeft > SocketMem32Length) {
  872. DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
  873. Socket, Stack, TypeMem32));
  874. SocketResources[Socket].MmiolResourcesLeft = 0;
  875. }
  876. ChangedType[TypeMem32] = TRUE;
  877. }
  878. SocketMem32Base += SocketResources[Socket].StackRes[Stack].MmiolLength + 1;
  879. DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiolResourceLeft = %x\n",
  880. Socket, SocketResources[Socket].MmiolResourcesLeft));
  881. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolAlignment = %x\n",
  882. Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiolAlignment));
  883. } else {
  884. SocketResources[Socket].StackRes[Stack].MmiolLength = 0;
  885. }
  886. //
  887. // Check Mem64 resource. This Host bridge does not support separated MEM / PMEM requests, so only count MEM requests here.
  888. //
  889. Alignment = RootBridgeInstance->ResAllocNode[TypeMem64].Alignment + 1;
  890. NewLength = RootBridgeInstance->ResAllocNode[TypeMem64].Length;
  891. //
  892. // Account for reserved regions at begin and end of the stack MMIO32 region.
  893. //
  894. RsvLenAtBegin = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Base -
  895. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
  896. RsvLenAtEnd = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
  897. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].PciResourceMem64Limit;
  898. NewLength += RsvLenAtBegin + RsvLenAtEnd;
  899. if (Alignment < RsvLenAtBegin) {
  900. Alignment = RsvLenAtBegin;
  901. }
  902. if (Alignment < RsvLenAtEnd) {
  903. Alignment = RsvLenAtEnd;
  904. }
  905. if (IsVirtualRootBridge) {
  906. NewLength += NewLength;
  907. }
  908. if (NewLength != 0) {
  909. //
  910. // At least 1GB align per KTI requirement. Add the length requested with given alignment.
  911. // If the sum is not 1GB aligned add on the remainder that would make it align.
  912. // Have to make sure Alignment is handled for direct address allocation
  913. //
  914. Remainder = SocketMem64Base & (Alignment - 1);
  915. if (Remainder != 0) {
  916. NewLength += Alignment - Remainder;
  917. }
  918. if (NewLength % MmiohGranularity) {
  919. Remainder = MmiohGranularity - (NewLength % MmiohGranularity);
  920. NewLength += Remainder;
  921. }
  922. //
  923. // Store length as length - 1 for handling
  924. //
  925. NewLength -= 1;
  926. // Zero StackLength if it's disable or negative
  927. if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base >=
  928. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit) {
  929. StackLength = 0;
  930. } else {
  931. StackLength = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Limit -
  932. mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].Mmio64Base;
  933. }
  934. SocketResources[Socket].StackRes[Stack].MmiohLength = NewLength;
  935. // Check if new length can fit in the socket or stack
  936. if (SocketResources[Socket].MmiohResourcesLeft > NewLength) {
  937. SocketResources[Socket].MmiohResourcesLeft -= NewLength + 1;
  938. } else if (SocketResources[Socket].MmiohResourcesLeft == NewLength) {
  939. SocketResources[Socket].MmiohResourcesLeft -= NewLength;
  940. } else {
  941. // If there are resources left consume them
  942. if (SocketResources[Socket].MmiohResourcesLeft != 0) {
  943. NewLength = NewLength - SocketResources[Socket].MmiohResourcesLeft - 1;
  944. SocketResources[Socket].MmiohResourcesLeft = 0;
  945. }
  946. SocketResources[Socket].MmiohResourceNeeds += NewLength + 1;
  947. OutOfResources = TRUE;
  948. ChangedTypeOOR[TypeMem64] = TRUE;
  949. }
  950. SocketResources[Socket].StackRes[Stack].MmiohAlignment = Alignment;
  951. if (NewLength > StackLength) {
  952. SocketResources[Socket].StackRes[Stack].MmiohUpdate = 1;
  953. //MmiohResourcesLeft is UINT64 type, not 2's-complement value.
  954. if (SocketResources[Socket].MmiohResourcesLeft > SocketMem64Length) {
  955. DEBUG ((DEBUG_ERROR, "Out of Resources for Socket = %x Stack = %x Type = %x\n",
  956. Socket, Stack, TypeMem64));
  957. SocketResources[Socket].MmiohResourcesLeft = 0;
  958. }
  959. ChangedType[TypeMem64] = TRUE;
  960. }
  961. SocketMem64Base += SocketResources[Socket].StackRes[Stack].MmiohLength + 1;
  962. DEBUG ((DEBUG_INFO, "SocketResources[%x].MmiohResourceLeft = %lx\n",
  963. Socket, SocketResources[Socket].MmiohResourcesLeft));
  964. DEBUG ((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohAlignment = %lx\n",
  965. Socket, Stack, SocketResources[Socket].StackRes[Stack].MmiohAlignment));
  966. } else {
  967. SocketResources[Socket].StackRes[Stack].MmiohLength = 0;
  968. }
  969. List = List->ForwardLink;
  970. } // for Stack
  971. // Check and update all resource types in socket that needs adjustment
  972. for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
  973. if (ChangedType[TypeIndex]) {
  974. DEBUG ((DEBUG_INFO, "[%d] Adjust stack %s resources...\n", Socket, mPciResourceTypeStr[TypeIndex]));
  975. Status = AdjustResources (&SocketResources[Socket], Socket, TypeIndex);
  976. ChangedType[TypeIndex] = FALSE;
  977. if (Status == EFI_SUCCESS) {
  978. ChangedBitMap |= (1 << TypeIndex);
  979. } else {
  980. ChangedBitMap &= ~(1 << TypeIndex);
  981. }
  982. }
  983. }
  984. //
  985. // Account for Ubox resources to accurately calculate new alignments for the next socket
  986. //
  987. SocketMem32Base += UboxMmioSize;
  988. } // for Socket ..
  989. ASSERT (List == &HostBridgeInstance->RootBridges);
  990. //
  991. // If a socket is out of resources, try to adjusting sockets for more room.
  992. //
  993. if (OutOfResources && (MAX_SOCKET > 1) && (ValidSockets > 1)) {
  994. for (TypeIndex = 0; TypeIndex < TypeMax; TypeIndex++) {
  995. if (ChangedTypeOOR[TypeIndex]) {
  996. DEBUG ((DEBUG_INFO, "Adjust socket %s resources...\n", mPciResourceTypeStr[TypeIndex]));
  997. Status = AdjustSocketResources (SocketResources, TypeIndex, ValidSockets);
  998. if (Status == EFI_SUCCESS) {
  999. ChangedBitMap |= (1 << TypeIndex);
  1000. } else {
  1001. ChangedBitMap &= ~(1 << TypeIndex);
  1002. }
  1003. }
  1004. }
  1005. } else if (OutOfResources && ChangedTypeOOR[TypeMem64]){
  1006. //
  1007. // Allow mmioh to be adjusted to access max available physical address range.
  1008. //
  1009. Status = AdjustSocketResources (SocketResources, TypeMem64, ValidSockets);
  1010. if (Status == EFI_SUCCESS) {
  1011. ChangedBitMap |= (1 << TypeIndex);
  1012. } else {
  1013. ChangedBitMap &= ~(1 << TypeIndex);
  1014. }
  1015. }
  1016. // Update changed resource type.
  1017. // OemGetResourceMapUpdate() will only update changed resource type so it is alright if data is zero.
  1018. if (ChangedBitMap != 0) {
  1019. for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
  1020. SocketPciResourceData.StackPresentBitmap[Socket] = mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap;
  1021. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  1022. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1023. continue;
  1024. }
  1025. CurStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[Stack];
  1026. //
  1027. // Disable stacks that have no resources and are assigned none.
  1028. // Reaching this far means the stack is valid and should be disabled if base equals limit and
  1029. // length is zero.
  1030. // Assigned address will be none zero at this point because CSTACK takes the first 4K in legacy
  1031. // IO space.
  1032. //
  1033. if ((SocketResources[Socket].StackRes[Stack].NeedIoUpdate) &&
  1034. (SocketResources[Socket].StackRes[Stack].IoLimit -
  1035. SocketResources[Socket].StackRes[Stack].IoBase == 0)) {
  1036. SocketResources[Socket].StackRes[Stack].IoBase = (UINT16)(-1);
  1037. SocketResources[Socket].StackRes[Stack].IoLimit = 0;
  1038. }
  1039. if ((SocketResources[Socket].StackRes[Stack].MmiolUpdate) &&
  1040. (SocketResources[Socket].StackRes[Stack].MmiolLimit -
  1041. SocketResources[Socket].StackRes[Stack].MmiolBase == 0)) {
  1042. SocketResources[Socket].StackRes[Stack].MmiolBase = (UINT32)(-1);
  1043. SocketResources[Socket].StackRes[Stack].MmiolLimit = 0;
  1044. }
  1045. if ((SocketResources[Socket].StackRes[Stack].MmiohUpdate) &&
  1046. (SocketResources[Socket].StackRes[Stack].MmiohLimit -
  1047. SocketResources[Socket].StackRes[Stack].MmiohBase == 0)) {
  1048. SocketResources[Socket].StackRes[Stack].MmiohBase = (UINT64)(-1);
  1049. SocketResources[Socket].StackRes[Stack].MmiohLimit = 0;
  1050. }
  1051. // Zero base if 4K because mIioUds struct reserves 4K of Io for legacy purposes
  1052. // Remove if mIioUds first base starts at zero
  1053. if (SocketResources[Socket].StackRes[Stack].IoBase == 0x1000){
  1054. SocketResources[Socket].StackRes[Stack].IoBase = 0;
  1055. }
  1056. if (SocketResources[Socket].StackRes[Stack].NeedIoUpdate) {
  1057. CurStackLimits->Io.Base = SocketResources[Socket].StackRes[Stack].IoBase;
  1058. CurStackLimits->Io.Limit = SocketResources[Socket].StackRes[Stack].IoLimit;
  1059. }
  1060. if (SocketResources[Socket].StackRes[Stack].MmiolUpdate) {
  1061. if ((Socket == 0) && (Stack == 0)) {
  1062. CurStackLimits->LowMmio.Base = PlatGlobalMmiolBase;
  1063. } else {
  1064. CurStackLimits->LowMmio.Base = SocketResources[Socket].StackRes[Stack].MmiolBase;
  1065. }
  1066. CurStackLimits->LowMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
  1067. }
  1068. if (SocketResources[Socket].StackRes[Stack].MmiohUpdate) {
  1069. CurStackLimits->HighMmio.Base = SocketResources[Socket].StackRes[Stack].MmiohBase;
  1070. CurStackLimits->HighMmio.Limit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
  1071. }
  1072. DEBUG((DEBUG_INFO, "\nSocketResources[%x].StackRes[%x].IoBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoBase));
  1073. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].IoLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].IoLimit));
  1074. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolBase =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolBase));
  1075. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiolLimit =%x\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiolLimit));
  1076. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohBase =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohBase));
  1077. DEBUG((DEBUG_INFO, "SocketResources[%x].StackRes[%x].MmiohLimit =%lx\n",Socket,Stack,SocketResources[Socket].StackRes[Stack].MmiohLimit));
  1078. } // for Stack
  1079. // Initialize to disabled
  1080. SocketResources[Socket].IoBase = (UINT16)(-1);
  1081. SocketResources[Socket].IoLimit = 0;
  1082. SocketResources[Socket].MmiolBase = (UINT32)(-1);
  1083. SocketResources[Socket].MmiolLimit = 0;
  1084. SocketResources[Socket].MmiohBase = (UINT64)(-1);
  1085. SocketResources[Socket].MmiohLimit = 0;
  1086. // Search backwards to find the beginning valid stack
  1087. for (Stack = MAX_IIO_STACK - 1; Stack < MAX_IIO_STACK ; Stack--) {
  1088. CurSocketLimits = &SocketPciResourceData.Socket[Socket].SocketLimits;
  1089. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1090. continue;
  1091. }
  1092. if (SocketResources[Socket].StackRes[Stack].IoBase != (UINT16)(-1)) {
  1093. SocketResources[Socket].IoBase = SocketResources[Socket].StackRes[Stack].IoBase;
  1094. }
  1095. if (SocketResources[Socket].StackRes[Stack].MmiolBase != (UINT32)(-1)) {
  1096. SocketResources[Socket].MmiolBase = SocketResources[Socket].StackRes[Stack].MmiolBase;
  1097. }
  1098. if (SocketResources[Socket].StackRes[Stack].MmiohBase != (UINT64)(-1)) {
  1099. SocketResources[Socket].MmiohBase = SocketResources[Socket].StackRes[Stack].MmiohBase;
  1100. }
  1101. } // for Stack
  1102. // Search to find the last valid limit
  1103. for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
  1104. if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack))) {
  1105. continue;
  1106. }
  1107. if (SocketResources[Socket].StackRes[Stack].IoLimit != 0) {
  1108. SocketResources[Socket].IoLimit = SocketResources[Socket].StackRes[Stack].IoLimit;
  1109. }
  1110. if (SocketResources[Socket].StackRes[Stack].MmiolLimit) {
  1111. SocketResources[Socket].MmiolLimit = SocketResources[Socket].StackRes[Stack].MmiolLimit;
  1112. }
  1113. if (SocketResources[Socket].StackRes[Stack].MmiohLimit) {
  1114. SocketResources[Socket].MmiohLimit = SocketResources[Socket].StackRes[Stack].MmiohLimit;
  1115. }
  1116. } // for Stack
  1117. // Update socket level resource range
  1118. if (SocketResources[Socket].StackRes[0].NeedIoUpdate) {
  1119. CurSocketLimits->Io.Base = SocketResources[Socket].IoBase;
  1120. CurSocketLimits->Io.Limit = SocketResources[Socket].IoLimit;
  1121. }
  1122. if (SocketResources[Socket].StackRes[0].MmiolUpdate) {
  1123. //
  1124. // Apply stolen 8M for ubox mmio per socket
  1125. //
  1126. if (UboxMmioSize != 0) {
  1127. UboxStackLimits = &SocketPciResourceData.Socket[Socket].StackLimits[UBOX_STACK];
  1128. UboxStackLimits->LowMmio.Base = SocketResources[Socket].MmiolLimit + 1;
  1129. SocketResources[Socket].MmiolLimit = (UINT32)UboxStackLimits->LowMmio.Base + UboxMmioSize - 1;
  1130. UboxStackLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
  1131. }
  1132. CurSocketLimits->LowMmio.Base = SocketResources[Socket].MmiolBase;
  1133. CurSocketLimits->LowMmio.Limit = SocketResources[Socket].MmiolLimit;
  1134. }
  1135. if (SocketResources[Socket].StackRes[0].MmiohUpdate) {
  1136. CurSocketLimits->HighMmio.Base = SocketResources[Socket].MmiohBase;
  1137. CurSocketLimits->HighMmio.Limit = SocketResources[Socket].MmiohLimit;
  1138. }
  1139. DEBUG((DEBUG_INFO, "\nSocketResources[%x].UboxBase =%x\n",Socket,UboxStackLimits->LowMmio.Base));
  1140. DEBUG((DEBUG_INFO, "SocketResources[%x].UboxLimit =%x\n",Socket,UboxStackLimits->LowMmio.Limit));
  1141. DEBUG((DEBUG_INFO, "\nSocketResources[%x].IoBase =%x\n",Socket,SocketResources[Socket].IoBase));
  1142. DEBUG((DEBUG_INFO, "SocketResources[%x].IoLimit =%x\n",Socket,SocketResources[Socket].IoLimit));
  1143. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolBase =%x\n",Socket,SocketResources[Socket].MmiolBase));
  1144. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiolLimit =%x\n",Socket,SocketResources[Socket].MmiolLimit));
  1145. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohBase =%lx\n",Socket,SocketResources[Socket].MmiohBase));
  1146. DEBUG((DEBUG_INFO, "SocketResources[%x].MmiohLimit =%lx\n",Socket,SocketResources[Socket].MmiohLimit));
  1147. } // for Socket
  1148. SocketPciResourceData.MmioHBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Base;
  1149. SocketPciResourceData.MmioHLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio64Limit;
  1150. SocketPciResourceData.MmioLBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Base;
  1151. SocketPciResourceData.MmioLLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalMmio32Limit;
  1152. SocketPciResourceData.IoBase = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoBase;
  1153. SocketPciResourceData.IoLimit = mIioUds->IioUdsPtr->PlatformData.PlatGlobalIoLimit;
  1154. PCIDEBUG("Writing resource rebalance request '%s':\n", SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME);
  1155. PCIDEBUG("System I/O : %04X..%04X\n", SocketPciResourceData.IoBase, SocketPciResourceData.IoLimit);
  1156. PCIDEBUG("System MMIOL: %08X..%08X\n", SocketPciResourceData.MmioLBase, SocketPciResourceData.MmioLLimit);
  1157. PCIDEBUG("System MMIOH: %012llX..%012llX\n", SocketPciResourceData.MmioHBase, SocketPciResourceData.MmioHLimit);
  1158. for (Socket = 0; Socket < NELEMENTS (SocketPciResourceData.Socket); Socket++) {
  1159. PCIDEBUG("[%d] StackPresent: 0x%04X\n", Socket, SocketPciResourceData.StackPresentBitmap[Socket]);
  1160. PCIDEBUG("[%d] I/O : %04X..%04X\n", Socket,
  1161. SocketPciResourceData.Socket[Socket].SocketLimits.Io.Base,
  1162. SocketPciResourceData.Socket[Socket].SocketLimits.Io.Limit);
  1163. PCIDEBUG("[%d] MMIOL: %08X..%08X\n", Socket,
  1164. SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Base,
  1165. SocketPciResourceData.Socket[Socket].SocketLimits.LowMmio.Limit);
  1166. PCIDEBUG("[%d] MMIOH: %012llX..%012llX\n", Socket,
  1167. SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Base,
  1168. SocketPciResourceData.Socket[Socket].SocketLimits.HighMmio.Limit);
  1169. for (Stack = 0; Stack < NELEMENTS (SocketPciResourceData.Socket[Socket].StackLimits); Stack++) {
  1170. PCIDEBUG("[%d.%d] I/O : %04X..%04X\n", Socket, Stack,
  1171. SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Base,
  1172. SocketPciResourceData.Socket[Socket].StackLimits[Stack].Io.Limit);
  1173. PCIDEBUG("[%d.%d] MMIOL: %08X..%08X\n", Socket, Stack,
  1174. SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Base,
  1175. SocketPciResourceData.Socket[Socket].StackLimits[Stack].LowMmio.Limit);
  1176. PCIDEBUG("[%d.%d] MMIOH: %012llX..%012llX\n", Socket, Stack,
  1177. SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Base,
  1178. SocketPciResourceData.Socket[Socket].StackLimits[Stack].HighMmio.Limit);
  1179. }
  1180. }
  1181. *Result = SocketResourceRatioChanged;
  1182. Status = gRT->SetVariable(
  1183. SYSTEM_PCI_RESOURCE_CONFIGURATION_DATA_NAME,
  1184. &gEfiSocketPciResourceDataGuid,
  1185. EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
  1186. sizeof(SocketPciResourceData),
  1187. &SocketPciResourceData
  1188. );
  1189. ASSERT_EFI_ERROR(Status);
  1190. }
  1191. return;
  1192. }