AmpereCpuLibCommon.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /** @file
  2. Copyright (c) 2021 - 2023, Ampere Computing LLC. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. **/
  5. #include <PiPei.h>
  6. #include <Uefi.h>
  7. #include <Guid/PlatformInfoHob.h>
  8. #include <Library/AmpereCpuLib.h>
  9. #include <Library/ArmLib/ArmLibPrivate.h>
  10. #include <Library/BaseMemoryLib.h>
  11. #include <Library/DebugLib.h>
  12. #include <Library/IoLib.h>
  13. #include <Library/NVParamLib.h>
  14. #include <NVParamDef.h>
  15. #include <Platform/Ac01.h>
  16. UINT32 Ac01CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  17. 36, 37, 40, 41, 52, 53, 56, 57, 32, 33,
  18. 44, 45, 48, 49, 60, 61, 20, 21, 24, 25,
  19. 68, 69, 72, 73, 16, 17, 28, 29, 64, 65,
  20. 76, 77, 4, 5, 8, 9, 0, 1, 12, 13,
  21. 38, 39, 42, 43, 54, 55, 58, 59, 34, 35,
  22. 46, 47, 50, 51, 62, 63, 22, 23, 26, 27,
  23. 70, 71, 74, 75, 18, 19, 30, 31, 66, 67,
  24. 78, 79, 6, 7, 10, 11, 2, 3, 14, 15,
  25. 80, 81, 82, 83, 84, 85, 86, 87,
  26. 88, 89, 90, 91, 92, 93, 94, 95,
  27. 96, 97, 98, 99, 100, 101, 102, 103,
  28. 104, 105, 106, 107, 108, 109, 110, 111,
  29. 112, 113, 114, 115, 116, 117, 118, 119,
  30. 120, 121, 122, 123, 124, 125, 126, 127,
  31. };
  32. UINT32 Ac01CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  33. 32, 33, 48, 49, 16, 17, 64, 65, 36, 37,
  34. 52, 53, 0, 1, 20, 21, 68, 69, 4, 5,
  35. 34, 35, 50, 51, 18, 19, 66, 67, 38, 39,
  36. 54, 55, 2, 3, 22, 23, 70, 71, 6, 7,
  37. 44, 45, 60, 61, 28, 29, 76, 77, 40, 41,
  38. 56, 57, 12, 13, 24, 25, 72, 73, 8, 9,
  39. 46, 47, 62, 63, 30, 31, 78, 79, 42, 43,
  40. 58, 59, 14, 15, 26, 27, 74, 75, 10, 11,
  41. 80, 81, 82, 83, 84, 85, 86, 87,
  42. 88, 89, 90, 91, 92, 93, 94, 95,
  43. 96, 97, 98, 99, 100, 101, 102, 103,
  44. 104, 105, 106, 107, 108, 109, 110, 111,
  45. 112, 113, 114, 115, 116, 117, 118, 119,
  46. 120, 121, 122, 123, 124, 125, 126, 127,
  47. };
  48. UINT32 Ac01CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  49. 16, 17, 32, 33, 0, 1, 20, 21, 4, 5,
  50. 18, 19, 34, 35, 2, 3, 22, 23, 6, 7,
  51. 48, 49, 64, 65, 52, 53, 68, 69, 36, 37,
  52. 50, 51, 66, 67, 54, 55, 70, 71, 38, 39,
  53. 28, 29, 44, 45, 12, 13, 24, 25, 8, 9,
  54. 30, 31, 46, 47, 14, 15, 26, 27, 10, 11,
  55. 60, 61, 76, 77, 56, 57, 72, 73, 40, 41,
  56. 62, 63, 78, 79, 58, 59, 74, 75, 42, 43,
  57. 80, 81, 82, 83, 84, 85, 86, 87,
  58. 88, 89, 90, 91, 92, 93, 94, 95,
  59. 96, 97, 98, 99, 100, 101, 102, 103,
  60. 104, 105, 106, 107, 108, 109, 110, 111,
  61. 112, 113, 114, 115, 116, 117, 118, 119,
  62. 120, 121, 122, 123, 124, 125, 126, 127,
  63. };
  64. UINT32 Ac02CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  65. 36, 37, 40, 41, 52, 53, 56, 57, 32, 33,
  66. 44, 45, 48, 49, 60, 61, 20, 21, 24, 25,
  67. 68, 69, 72, 73, 16, 17, 28, 29, 64, 65,
  68. 76, 77, 4, 5, 8, 9, 84, 85, 88, 89,
  69. 0, 1, 12, 13, 80, 81, 92, 93, 100, 101,
  70. 104, 105, 96, 97, 108, 109, 116, 117, 120, 121,
  71. 112, 113, 124, 125, 38, 39, 42, 43, 54, 55,
  72. 58, 59, 34, 35, 46, 47, 50, 51, 62, 63,
  73. 22, 23, 26, 27, 70, 71, 74, 75, 18, 19,
  74. 30, 31, 66, 67, 78, 79, 6, 7, 10, 11,
  75. 86, 87, 90, 91, 2, 3, 14, 15, 82, 83,
  76. 94, 95, 102, 103, 106, 107, 98, 99, 110, 111,
  77. 118, 119, 122, 123, 114, 115, 126, 127,
  78. };
  79. UINT32 Ac02CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  80. 32, 33, 48, 49, 16, 17, 64, 65, 36, 37,
  81. 52, 53, 0, 1, 20, 21, 68, 69, 80, 81,
  82. 4, 5, 84, 85, 96, 97, 100, 101, 112, 113,
  83. 116, 117, 34, 35, 50, 51, 18, 19, 66, 67,
  84. 38, 39, 54, 55, 2, 3, 22, 23, 70, 71,
  85. 82, 83, 6, 7, 86, 87, 98, 99, 102, 103,
  86. 114, 115, 118, 119, 44, 45, 60, 61, 28, 29,
  87. 76, 77, 40, 41, 56, 57, 12, 13, 24, 25,
  88. 72, 73, 92, 93, 8, 9, 88, 89, 108, 109,
  89. 104, 105, 124, 125, 120, 121, 46, 47, 62, 63,
  90. 30, 31, 78, 79, 42, 43, 58, 59, 14, 15,
  91. 26, 27, 74, 75, 94, 95, 10, 11, 90, 91,
  92. 110, 111, 106, 107, 126, 127, 122, 123,
  93. };
  94. UINT32 Ac02CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
  95. 16, 17, 32, 33, 0, 1, 20, 21,
  96. 36, 37, 4, 5, 84, 85, 96, 97,
  97. 18, 19, 34, 35, 2, 3, 22, 23,
  98. 38, 39, 6, 7, 86, 87, 98, 99,
  99. 48, 49, 64, 65, 52, 53, 68, 69,
  100. 80, 81, 100, 101, 112, 113, 116, 117,
  101. 50, 51, 66, 67, 54, 55, 70, 71,
  102. 82, 83, 102, 103, 114, 115, 118, 119,
  103. 28, 29, 44, 45, 12, 13, 24, 25,
  104. 40, 41, 8, 9, 88, 89, 108, 109,
  105. 30, 31, 46, 47, 14, 15, 26, 27,
  106. 42, 43, 10, 11, 90, 91, 110, 111,
  107. 60, 61, 76, 77, 56, 57, 72, 73,
  108. 92, 93, 104, 105, 124, 125, 120, 121,
  109. 62, 63, 78, 79, 58, 59, 74, 75,
  110. 94, 95, 106, 107, 126, 127, 122, 123,
  111. };
  112. PLATFORM_INFO_HOB *
  113. GetPlatformHob (
  114. VOID
  115. );
  116. /**
  117. Get current CPU frequency.
  118. @param Socket Socket index.
  119. @return UINTN Current CPU frequency.
  120. **/
  121. UINTN
  122. EFIAPI
  123. CpuGetCurrentFreq (
  124. UINT8 Socket
  125. )
  126. {
  127. PLATFORM_INFO_HOB *PlatformHob;
  128. PlatformHob = GetPlatformHob ();
  129. ASSERT (PlatformHob != NULL);
  130. return PlatformHob->CpuClk;
  131. }
  132. /**
  133. Get maximum CPU frequency.
  134. @param Socket Socket index.
  135. @return UINTN Maximum CPU frequency.
  136. **/
  137. UINTN
  138. EFIAPI
  139. CpuGetMaxFreq (
  140. UINT8 Socket
  141. )
  142. {
  143. PLATFORM_INFO_HOB *PlatformHob;
  144. PlatformHob = GetPlatformHob ();
  145. ASSERT (PlatformHob != NULL);
  146. if (PlatformHob->TurboCapability[Socket]) {
  147. return PlatformHob->TurboFrequency[Socket];
  148. }
  149. return PlatformHob->CpuClk;
  150. }
  151. /**
  152. Get CPU voltage.
  153. @param Socket Socket index.
  154. @return UINT8 CPU voltage.
  155. **/
  156. UINT8
  157. EFIAPI
  158. CpuGetVoltage (
  159. UINT8 Socket
  160. )
  161. {
  162. PLATFORM_INFO_HOB *PlatformHob;
  163. UINT8 Voltage;
  164. PlatformHob = GetPlatformHob ();
  165. ASSERT (PlatformHob != NULL);
  166. Voltage = 0x80 | (PlatformHob->CoreVoltage[Socket] / 100);
  167. return Voltage;
  168. }
  169. /**
  170. Get CPU Core order number.
  171. @return UINT32* The order number.
  172. **/
  173. UINT32 *
  174. CpuGetCoreOrder (
  175. VOID
  176. )
  177. {
  178. UINT32 *CoreOrder;
  179. UINT8 SubNumaMode;
  180. BOOLEAN IsAc01;
  181. SubNumaMode = CpuGetSubNumaMode ();
  182. IsAc01 = IsAc01Processor ();
  183. switch (SubNumaMode) {
  184. case SUBNUMA_MODE_MONOLITHIC:
  185. default:
  186. CoreOrder = IsAc01 ? Ac01CoreOrderMonolithic : Ac02CoreOrderMonolithic;
  187. break;
  188. case SUBNUMA_MODE_HEMISPHERE:
  189. CoreOrder = IsAc01 ? Ac01CoreOrderHemisphere : Ac02CoreOrderHemisphere;
  190. break;
  191. case SUBNUMA_MODE_QUADRANT:
  192. CoreOrder = IsAc01 ? Ac01CoreOrderQuadrant : Ac02CoreOrderQuadrant;
  193. break;
  194. }
  195. return CoreOrder;
  196. }
  197. /**
  198. Get the SubNUMA mode.
  199. @return UINT8 The SubNUMA mode.
  200. **/
  201. UINT8
  202. EFIAPI
  203. CpuGetSubNumaMode (
  204. VOID
  205. )
  206. {
  207. PLATFORM_INFO_HOB *PlatformHob;
  208. PlatformHob = GetPlatformHob ();
  209. if (PlatformHob == NULL) {
  210. return SUBNUMA_MODE_MONOLITHIC;
  211. }
  212. return PlatformHob->SubNumaMode[0];
  213. }
  214. /**
  215. Get the number of SubNUMA region.
  216. @return UINT8 The number of SubNUMA region.
  217. **/
  218. UINT8
  219. EFIAPI
  220. CpuGetNumberOfSubNumaRegion (
  221. VOID
  222. )
  223. {
  224. UINT8 SubNumaMode;
  225. UINT8 NumberOfSubNumaRegion;
  226. SubNumaMode = CpuGetSubNumaMode ();
  227. ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
  228. switch (SubNumaMode) {
  229. case SUBNUMA_MODE_MONOLITHIC:
  230. NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION;
  231. break;
  232. case SUBNUMA_MODE_HEMISPHERE:
  233. NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION;
  234. break;
  235. case SUBNUMA_MODE_QUADRANT:
  236. NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION;
  237. break;
  238. default:
  239. // Should never reach there.
  240. NumberOfSubNumaRegion = 0;
  241. ASSERT (FALSE);
  242. break;
  243. }
  244. return NumberOfSubNumaRegion;
  245. }
  246. STATIC
  247. UINT8
  248. CpuGetLogicCoreId (
  249. UINT32 PhyCoreId
  250. )
  251. {
  252. UINT32 *CoreOrder;
  253. UINT8 LogicCoreId;
  254. UINT8 SktMaxCoreNum ;
  255. CoreOrder = CpuGetCoreOrder();
  256. SktMaxCoreNum = PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM;
  257. for (LogicCoreId = 0; LogicCoreId < SktMaxCoreNum; LogicCoreId++) {
  258. if (CoreOrder[LogicCoreId] == PhyCoreId) {
  259. return LogicCoreId;
  260. }
  261. }
  262. return 0;
  263. }
  264. UINT8
  265. EFIAPI
  266. CpuGetSubNumNode (
  267. UINT8 SocketId,
  268. UINT16 Cpm
  269. )
  270. {
  271. UINT8 LogicCoreId;
  272. UINT8 MaxFamliyCore;
  273. UINT8 MaxNumCorePerNode;
  274. UINT8 SubNumaNode;
  275. LogicCoreId = CpuGetLogicCoreId (Cpm * PLATFORM_CPU_NUM_CORES_PER_CPM);
  276. MaxFamliyCore = IsAc01Processor () ? MAX_AMPERE_ALTRA_CORES : MAX_AMPERE_ALTRA_MAX_CORES;
  277. switch (CpuGetSubNumaMode ()) {
  278. case SUBNUMA_MODE_MONOLITHIC:
  279. SubNumaNode = (SocketId == 0) ? 0 : 1;
  280. break;
  281. case SUBNUMA_MODE_HEMISPHERE:
  282. MaxNumCorePerNode = MaxFamliyCore / HEMISPHERE_NUM_OF_REGION;
  283. SubNumaNode = LogicCoreId / MaxNumCorePerNode;
  284. if (SocketId == 1) {
  285. SubNumaNode += HEMISPHERE_NUM_OF_REGION;
  286. }
  287. break;
  288. case SUBNUMA_MODE_QUADRANT:
  289. MaxNumCorePerNode = MaxFamliyCore / QUADRANT_NUM_OF_REGION;
  290. SubNumaNode = LogicCoreId / MaxNumCorePerNode;
  291. if (SocketId == 1) {
  292. SubNumaNode += QUADRANT_NUM_OF_REGION;
  293. }
  294. break;
  295. default:
  296. // Should never reach there.
  297. SubNumaNode = (SocketId == 0) ? 0 : 1;
  298. ASSERT (FALSE);
  299. break;
  300. }
  301. return SubNumaNode;
  302. }
  303. /**
  304. Get the number of supported socket.
  305. @return UINT8 Number of supported socket.
  306. **/
  307. UINT8
  308. EFIAPI
  309. GetNumberOfSupportedSockets (
  310. VOID
  311. )
  312. {
  313. PLATFORM_INFO_HOB *PlatformHob;
  314. PlatformHob = GetPlatformHob ();
  315. if (PlatformHob == NULL) {
  316. //
  317. // By default, the number of supported sockets is 1.
  318. //
  319. return 1;
  320. }
  321. return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN));
  322. }
  323. /**
  324. Get the number of active socket.
  325. @return UINT8 Number of active socket.
  326. **/
  327. UINT8
  328. EFIAPI
  329. GetNumberOfActiveSockets (
  330. VOID
  331. )
  332. {
  333. UINT8 NumberOfActiveSockets, Count, Index, Index1;
  334. PLATFORM_CLUSTER_EN *Socket;
  335. PLATFORM_INFO_HOB *PlatformHob;
  336. PlatformHob = GetPlatformHob ();
  337. if (PlatformHob == NULL) {
  338. //
  339. // By default, the number of active sockets is 1.
  340. //
  341. return 1;
  342. }
  343. NumberOfActiveSockets = 0;
  344. for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
  345. Socket = &PlatformHob->ClusterEn[Index];
  346. Count = ARRAY_SIZE (Socket->EnableMask);
  347. for (Index1 = 0; Index1 < Count; Index1++) {
  348. if (Socket->EnableMask[Index1] != 0) {
  349. NumberOfActiveSockets++;
  350. break;
  351. }
  352. }
  353. }
  354. return NumberOfActiveSockets;
  355. }
  356. /**
  357. Get the number of active CPM per socket.
  358. @param SocketId Socket index.
  359. @return UINT16 Number of CPM.
  360. **/
  361. UINT16
  362. EFIAPI
  363. GetNumberOfActiveCPMsPerSocket (
  364. UINT8 SocketId
  365. )
  366. {
  367. UINT16 NumberOfCPMs, Count, Index;
  368. UINT32 Val32;
  369. PLATFORM_CLUSTER_EN *Socket;
  370. PLATFORM_INFO_HOB *PlatformHob;
  371. PlatformHob = GetPlatformHob ();
  372. if (PlatformHob == NULL) {
  373. return 0;
  374. }
  375. if (SocketId >= GetNumberOfActiveSockets ()) {
  376. return 0;
  377. }
  378. NumberOfCPMs = 0;
  379. Socket = &PlatformHob->ClusterEn[SocketId];
  380. Count = ARRAY_SIZE (Socket->EnableMask);
  381. for (Index = 0; Index < Count; Index++) {
  382. Val32 = Socket->EnableMask[Index];
  383. while (Val32 > 0) {
  384. if ((Val32 & 0x1) != 0) {
  385. NumberOfCPMs++;
  386. }
  387. Val32 >>= 1;
  388. }
  389. }
  390. return NumberOfCPMs;
  391. }
  392. /**
  393. Get the number of configured CPM per socket. This number
  394. should be the same for all sockets.
  395. @param SocketId Socket index.
  396. @return UINT8 Number of configured CPM.
  397. **/
  398. UINT16
  399. EFIAPI
  400. GetNumberOfConfiguredCPMs (
  401. UINT8 SocketId
  402. )
  403. {
  404. EFI_STATUS Status;
  405. UINT32 Value;
  406. UINT32 Param, ParamStart, ParamEnd;
  407. UINT16 Count;
  408. Count = 0;
  409. ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
  410. ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
  411. for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
  412. Status = NVParamGet (
  413. Param,
  414. NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
  415. &Value
  416. );
  417. if (EFI_ERROR (Status)) {
  418. break;
  419. }
  420. while (Value != 0) {
  421. if ((Value & 0x01) != 0) {
  422. Count++;
  423. }
  424. Value >>= 1;
  425. }
  426. }
  427. return Count;
  428. }
  429. /**
  430. Set the number of configured CPM per socket.
  431. @param SocketId Socket index.
  432. @param NumberOfCPMs Number of CPM to be configured.
  433. @return EFI_SUCCESS Operation succeeded.
  434. @return Others An error has occurred.
  435. **/
  436. EFI_STATUS
  437. EFIAPI
  438. SetNumberOfConfiguredCPMs (
  439. UINT8 SocketId,
  440. UINT16 NumberOfCPMs
  441. )
  442. {
  443. EFI_STATUS Status;
  444. UINT32 Value;
  445. UINT32 Param, ParamStart, ParamEnd;
  446. BOOLEAN IsClear;
  447. IsClear = FALSE;
  448. if (NumberOfCPMs == 0) {
  449. IsClear = TRUE;
  450. }
  451. Status = EFI_SUCCESS;
  452. ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
  453. ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
  454. for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
  455. if (NumberOfCPMs >= 32) {
  456. Value = 0xffffffff;
  457. NumberOfCPMs -= 32;
  458. } else {
  459. Value = 0;
  460. while (NumberOfCPMs > 0) {
  461. Value |= (1 << (--NumberOfCPMs));
  462. }
  463. }
  464. if (IsClear) {
  465. /* Clear this param */
  466. Status = NVParamClr (
  467. Param,
  468. NV_PERM_BIOS | NV_PERM_MANU
  469. );
  470. } else {
  471. Status = NVParamSet (
  472. Param,
  473. NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
  474. NV_PERM_BIOS | NV_PERM_MANU,
  475. Value
  476. );
  477. }
  478. }
  479. return Status;
  480. }
  481. /**
  482. Get the maximum number of core per socket.
  483. @return UINT16 Maximum number of core.
  484. **/
  485. UINT16
  486. EFIAPI
  487. GetMaximumNumberOfCores (
  488. VOID
  489. )
  490. {
  491. PLATFORM_INFO_HOB *PlatformHob;
  492. PlatformHob = GetPlatformHob ();
  493. if (PlatformHob == NULL) {
  494. return 0;
  495. }
  496. return PlatformHob->MaxNumOfCore[0];
  497. }
  498. /**
  499. Get the number of active cores of a sockets.
  500. @param SocketId Socket Index.
  501. @return UINT16 Number of active core.
  502. **/
  503. UINT16
  504. EFIAPI
  505. GetNumberOfActiveCoresPerSocket (
  506. UINT8 SocketId
  507. )
  508. {
  509. return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM;
  510. }
  511. /**
  512. Get the number of active cores of all sockets.
  513. @return UINT16 Number of active core.
  514. **/
  515. UINT16
  516. EFIAPI
  517. GetNumberOfActiveCores (
  518. VOID
  519. )
  520. {
  521. UINT16 NumberOfActiveCores;
  522. UINT8 Index;
  523. NumberOfActiveCores = 0;
  524. for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) {
  525. NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index);
  526. }
  527. return NumberOfActiveCores;
  528. }
  529. /**
  530. Check if the logical CPU is enabled or not.
  531. @param CpuId The logical Cpu ID. Started from 0.
  532. @return BOOLEAN TRUE if the Cpu enabled
  533. FALSE if the Cpu disabled.
  534. **/
  535. BOOLEAN
  536. EFIAPI
  537. IsCpuEnabled (
  538. UINT16 CpuId
  539. )
  540. {
  541. PLATFORM_CLUSTER_EN *Socket;
  542. PLATFORM_INFO_HOB *PlatformHob;
  543. UINT8 SocketId;
  544. UINT16 ClusterId;
  545. SocketId = SOCKET_ID (CpuId);
  546. ClusterId = CLUSTER_ID (CpuId);
  547. PlatformHob = GetPlatformHob ();
  548. if (PlatformHob == NULL) {
  549. return FALSE;
  550. }
  551. if (SocketId >= GetNumberOfActiveSockets ()) {
  552. return FALSE;
  553. }
  554. Socket = &PlatformHob->ClusterEn[SocketId];
  555. if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) {
  556. return TRUE;
  557. }
  558. return FALSE;
  559. }
  560. /**
  561. Check if the slave socket is present
  562. @return BOOLEAN TRUE if the Slave Cpu is present
  563. FALSE if the Slave Cpu is not present
  564. **/
  565. BOOLEAN
  566. EFIAPI
  567. IsSlaveSocketAvailable (
  568. VOID
  569. )
  570. {
  571. UINT32 Value;
  572. Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET);
  573. return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE;
  574. }
  575. /**
  576. Check if the slave socket is active
  577. @return BOOLEAN TRUE if the Slave CPU Socket is active.
  578. FALSE if the Slave CPU Socket is not active.
  579. **/
  580. BOOLEAN
  581. EFIAPI
  582. IsSlaveSocketActive (
  583. VOID
  584. )
  585. {
  586. return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE;
  587. }
  588. /**
  589. Check if the CPU product ID is Ac01
  590. @return BOOLEAN TRUE if the Product ID is Ac01
  591. FALSE otherwise.
  592. **/
  593. BOOLEAN
  594. EFIAPI
  595. IsAc01Processor (
  596. VOID
  597. )
  598. {
  599. PLATFORM_INFO_HOB *PlatformHob;
  600. PlatformHob = GetPlatformHob ();
  601. ASSERT (PlatformHob != NULL);
  602. if (PlatformHob != NULL) {
  603. if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) {
  604. return TRUE;
  605. }
  606. }
  607. return FALSE;
  608. }