Pptt.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /** @file
  2. *
  3. * Copyright (c) 2018, Hisilicon Limited. All rights reserved.
  4. * Copyright (c) 2018, Linaro Limited. All rights reserved.
  5. *
  6. * This program and the accompanying materials
  7. * are licensed and made available under the terms and conditions of the BSD License
  8. * which accompanies this distribution. The full text of the license may be found at
  9. * http://opensource.org/licenses/bsd-license.php
  10. *
  11. * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  13. *
  14. * Based on the files under Platform/ARM/JunoPkg/AcpiTables/
  15. *
  16. **/
  17. #include "Pptt.h"
  18. EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol = NULL;
  19. EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol = NULL;
  20. EFI_ACPI_DESCRIPTION_HEADER mPpttHeader =
  21. ARM_ACPI_HEADER (
  22. EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
  23. EFI_ACPI_DESCRIPTION_HEADER,
  24. EFI_ACPI_6_2_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
  25. );
  26. EFI_ACPI_6_2_PPTT_STRUCTURE_ID mPpttSocketType2[PPTT_SOCKET_COMPONENT_NO] =
  27. {
  28. {2, sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID), {0, 0}, PPTT_VENDOR_ID, 0, 0, 0, 0, 0}
  29. };
  30. EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE mPpttCacheType1[PPTT_CACHE_NO];
  31. STATIC
  32. VOID
  33. InitCacheInfo (
  34. VOID
  35. )
  36. {
  37. UINT8 Index;
  38. EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES Type1Attributes;
  39. CSSELR_DATA CsselrData;
  40. CCSIDR_DATA CcsidrData;
  41. for (Index = 0; Index < PPTT_CACHE_NO; Index++) {
  42. CsselrData.Data = 0;
  43. CcsidrData.Data = 0;
  44. SetMem (
  45. &Type1Attributes,
  46. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES),
  47. 0
  48. );
  49. if (Index == 0) { //L1I
  50. CsselrData.Bits.InD = 1;
  51. CsselrData.Bits.Level = 0;
  52. Type1Attributes.CacheType = 1;
  53. } else if (Index == 1) {
  54. Type1Attributes.CacheType = 0;
  55. CsselrData.Bits.Level = Index - 1;
  56. } else {
  57. Type1Attributes.CacheType = 2;
  58. CsselrData.Bits.Level = Index - 1;
  59. }
  60. CcsidrData.Data = ReadCCSIDR (CsselrData.Data);
  61. if (CcsidrData.Bits.Wa == 1) {
  62. Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_WRITE;
  63. if (CcsidrData.Bits.Ra == 1) {
  64. Type1Attributes.AllocationType = EFI_ACPI_6_2_CACHE_ATTRIBUTES_ALLOCATION_READ_WRITE;
  65. }
  66. }
  67. if (CcsidrData.Bits.Wt == 1) {
  68. Type1Attributes.WritePolicy = 1;
  69. }
  70. DEBUG ((DEBUG_INFO,
  71. "[Acpi PPTT] Level = %x!CcsidrData = %x!\n",
  72. CsselrData.Bits.Level,
  73. CcsidrData.Data));
  74. mPpttCacheType1[Index].Type = EFI_ACPI_6_2_PPTT_TYPE_CACHE;
  75. mPpttCacheType1[Index].Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE);
  76. mPpttCacheType1[Index].Reserved[0] = 0;
  77. mPpttCacheType1[Index].Reserved[1] = 0;
  78. mPpttCacheType1[Index].Flags.SizePropertyValid = 1;
  79. mPpttCacheType1[Index].Flags.NumberOfSetsValid = 1;
  80. mPpttCacheType1[Index].Flags.AssociativityValid = 1;
  81. mPpttCacheType1[Index].Flags.AllocationTypeValid = 1;
  82. mPpttCacheType1[Index].Flags.CacheTypeValid = 1;
  83. mPpttCacheType1[Index].Flags.WritePolicyValid = 1;
  84. mPpttCacheType1[Index].Flags.LineSizeValid = 1;
  85. mPpttCacheType1[Index].Flags.Reserved = 0;
  86. mPpttCacheType1[Index].NextLevelOfCache = 0;
  87. if (Index != PPTT_CACHE_NO - 1) {
  88. mPpttCacheType1[Index].NumberOfSets = (UINT16)CcsidrData.Bits.NumSets + 1;
  89. mPpttCacheType1[Index].Associativity = (UINT16)CcsidrData.Bits.Associativity + 1;
  90. mPpttCacheType1[Index].LineSize = (UINT16)( 1 << (CcsidrData.Bits.LineSize + 4));
  91. mPpttCacheType1[Index].Size = mPpttCacheType1[Index].LineSize * \
  92. mPpttCacheType1[Index].Associativity * \
  93. mPpttCacheType1[Index].NumberOfSets;
  94. CopyMem (
  95. &mPpttCacheType1[Index].Attributes,
  96. &Type1Attributes,
  97. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES)
  98. );
  99. } else {
  100. // L3 cache
  101. mPpttCacheType1[Index].Size = 0x1000000; // 16m
  102. mPpttCacheType1[Index].NumberOfSets = 0x2000;
  103. mPpttCacheType1[Index].Associativity = 0x10; // CacheAssociativity16Way
  104. SetMem (
  105. &mPpttCacheType1[Index].Attributes,
  106. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE_ATTRIBUTES),
  107. 0x0A
  108. );
  109. mPpttCacheType1[Index].LineSize = 0x80; // 128byte
  110. }
  111. }
  112. }
  113. STATIC
  114. EFI_STATUS
  115. AddCoreTable (
  116. IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
  117. IN OUT UINT32 *PpttTableLengthRemain,
  118. IN UINT32 Parent,
  119. IN UINT32 ResourceNo,
  120. IN UINT32 ProcessorId
  121. )
  122. {
  123. EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
  124. EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *PpttType1;
  125. UINT32 *PrivateResource;
  126. UINT8 Index;
  127. if (*PpttTableLengthRemain <
  128. (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
  129. return EFI_OUT_OF_RESOURCES;
  130. }
  131. PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
  132. PpttTable->Length);
  133. PpttType0->Type = 0;
  134. SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
  135. PpttType0->Flags.AcpiProcessorIdValid = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID;
  136. PpttType0->Parent= Parent;
  137. PpttType0->AcpiProcessorId = ProcessorId;
  138. PpttType0->NumberOfPrivateResources = ResourceNo;
  139. PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
  140. ResourceNo * 4;
  141. *PpttTableLengthRemain -= (UINTN)PpttType0->Length;
  142. PpttTable->Length += PpttType0->Length;
  143. PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
  144. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
  145. // Add cache type structure
  146. for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) {
  147. if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
  148. return EFI_OUT_OF_RESOURCES;
  149. }
  150. *PrivateResource = PpttTable->Length;
  151. PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
  152. PpttTable->Length);
  153. gBS->CopyMem (
  154. PpttType1,
  155. &mPpttCacheType1[Index],
  156. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
  157. );
  158. *PpttTableLengthRemain -= PpttType1->Length;
  159. PpttTable->Length += PpttType1->Length;
  160. }
  161. return EFI_SUCCESS;
  162. }
  163. STATIC
  164. EFI_STATUS
  165. AddClusterTable (
  166. IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
  167. IN OUT UINT32 *PpttTableLengthRemain,
  168. IN UINT32 Parent,
  169. IN UINT32 ResourceNo
  170. )
  171. {
  172. EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
  173. EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *PpttType1;
  174. UINT32 *PrivateResource;
  175. if ((*PpttTableLengthRemain) <
  176. (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
  177. return EFI_OUT_OF_RESOURCES;
  178. }
  179. PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
  180. PpttTable->Length);
  181. PpttType0->Type = 0;
  182. SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
  183. PpttType0->Parent= Parent;
  184. PpttType0->NumberOfPrivateResources = ResourceNo;
  185. PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
  186. ResourceNo * 4;
  187. *PpttTableLengthRemain -= PpttType0->Length;
  188. PpttTable->Length += PpttType0->Length;
  189. PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
  190. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
  191. // Add cache type structure
  192. if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
  193. return EFI_OUT_OF_RESOURCES;
  194. }
  195. *PrivateResource = PpttTable->Length;
  196. PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
  197. PpttTable->Length);
  198. gBS->CopyMem (
  199. PpttType1,
  200. &mPpttCacheType1[2],
  201. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
  202. );
  203. *PpttTableLengthRemain -= PpttType1->Length;
  204. PpttTable->Length += PpttType1->Length;
  205. return EFI_SUCCESS;
  206. }
  207. STATIC
  208. EFI_STATUS
  209. AddScclTable (
  210. IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
  211. IN OUT UINT32 *PpttTableLengthRemain,
  212. IN UINT32 Parent,
  213. IN UINT32 ResourceNo
  214. )
  215. {
  216. EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
  217. EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *PpttType1;
  218. UINT32 *PrivateResource;
  219. if (*PpttTableLengthRemain <
  220. (sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) + ResourceNo * 4)) {
  221. return EFI_OUT_OF_RESOURCES;
  222. }
  223. PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
  224. PpttTable->Length);
  225. PpttType0->Type = 0;
  226. SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
  227. PpttType0->Parent= Parent;
  228. PpttType0->NumberOfPrivateResources = ResourceNo;
  229. PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
  230. ResourceNo * 4;
  231. *PpttTableLengthRemain -= PpttType0->Length;
  232. PpttTable->Length += PpttType0->Length;
  233. PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
  234. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
  235. // Add cache type structure
  236. if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)) {
  237. return EFI_OUT_OF_RESOURCES;
  238. }
  239. *PrivateResource = PpttTable->Length;
  240. PpttType1 = (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE *)((UINT8 *)PpttTable +
  241. PpttTable->Length);
  242. gBS->CopyMem (
  243. PpttType1,
  244. &mPpttCacheType1[3],
  245. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_CACHE)
  246. );
  247. *PpttTableLengthRemain -= PpttType1->Length;
  248. PpttTable->Length += PpttType1->Length;
  249. return EFI_SUCCESS;
  250. }
  251. STATIC
  252. EFI_STATUS
  253. AddSocketTable (
  254. IN EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
  255. IN OUT UINT32 *PpttTableLengthRemain,
  256. IN UINT32 Parent,
  257. IN UINT32 ResourceNo
  258. )
  259. {
  260. EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *PpttType0;
  261. EFI_ACPI_6_2_PPTT_STRUCTURE_ID *PpttType2;
  262. UINT32 *PrivateResource;
  263. UINT8 Index;
  264. if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR)) {
  265. return EFI_OUT_OF_RESOURCES;
  266. }
  267. PpttType0 = (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR *)((UINT8 *)PpttTable +
  268. PpttTable->Length);
  269. PpttType0->Type = 0;
  270. SetMem (&PpttType0->Flags, sizeof (PpttType0->Flags), 0);
  271. PpttType0->Flags.PhysicalPackage = EFI_ACPI_6_2_PPTT_PROCESSOR_ID_VALID;
  272. PpttType0->Parent= Parent;
  273. PpttType0->NumberOfPrivateResources = ResourceNo;
  274. PpttType0->Length = sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR) +
  275. ResourceNo * 4;
  276. PpttTable->Length += PpttType0->Length;
  277. *PpttTableLengthRemain -= PpttType0->Length;
  278. if (*PpttTableLengthRemain < ResourceNo * 4) {
  279. return EFI_OUT_OF_RESOURCES;
  280. }
  281. PrivateResource = (UINT32 *)((UINT8 *)PpttType0 +
  282. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_PROCESSOR));
  283. DEBUG ((DEBUG_INFO,
  284. "[Acpi PPTT] sizeof(EFI_ACPI_6_2_PPTT_STRUCTURE_ID) = %x!\n",
  285. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)));
  286. for (Index = 0; Index < ResourceNo; Index++, PrivateResource++) {
  287. if (*PpttTableLengthRemain < sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)) {
  288. return EFI_OUT_OF_RESOURCES;
  289. }
  290. *PrivateResource = PpttTable->Length;
  291. PpttType2 = (EFI_ACPI_6_2_PPTT_STRUCTURE_ID *)((UINT8 *)PpttTable +
  292. PpttTable->Length);
  293. gBS->CopyMem (
  294. PpttType2,
  295. &mPpttSocketType2[Index],
  296. sizeof (EFI_ACPI_6_2_PPTT_STRUCTURE_ID)
  297. );
  298. *PpttTableLengthRemain -= PpttType2->Length;
  299. PpttTable->Length += PpttType2->Length;
  300. }
  301. return EFI_SUCCESS;
  302. }
  303. STATIC
  304. VOID
  305. GetApic (
  306. IN EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE *ApicTable,
  307. IN OUT EFI_ACPI_DESCRIPTION_HEADER *PpttTable,
  308. IN UINT32 PpttTableLengthRemain,
  309. IN UINT32 Index1
  310. )
  311. {
  312. UINT32 IndexSocket, IndexSccl, IndexCluster, IndexCore;
  313. UINT32 SocketOffset, ScclOffset, ClusterOffset;
  314. UINT32 Parent = 0;
  315. UINT32 ResourceNo = 0;
  316. // Get APIC data
  317. for (IndexSocket = 0; IndexSocket < PPTT_SOCKET_NO; IndexSocket++) {
  318. SocketOffset = 0;
  319. for (IndexSccl = 0; IndexSccl < PPTT_SCCL_NO; IndexSccl++) {
  320. ScclOffset = 0;
  321. for (IndexCluster = 0; IndexCluster < PPTT_CLUSTER_NO; IndexCluster++) {
  322. ClusterOffset = 0;
  323. for (IndexCore = 0; IndexCore < PPTT_CORE_NO; IndexCore++) {
  324. if (ApicTable->GicInterfaces[Index1].AcpiProcessorUid != Index1) {
  325. // This processor is unusable
  326. DEBUG ((DEBUG_ERROR, "[Acpi PPTT] Please check MADT table for UID!\n"));
  327. return;
  328. }
  329. if ((ApicTable->GicInterfaces[Index1].Flags & BIT0) == 0) {
  330. // This processor is unusable
  331. Index1++;
  332. continue;
  333. }
  334. if (SocketOffset == 0) {
  335. // Add socket0 for type0 table
  336. ResourceNo = PPTT_SOCKET_COMPONENT_NO;
  337. SocketOffset = PpttTable->Length;
  338. Parent = 0;
  339. AddSocketTable (
  340. PpttTable,
  341. &PpttTableLengthRemain,
  342. Parent,
  343. ResourceNo
  344. );
  345. }
  346. if (ScclOffset == 0) {
  347. // Add socket0sccl0 for type0 table
  348. ResourceNo = 1;
  349. ScclOffset = PpttTable->Length;
  350. Parent = SocketOffset;
  351. AddScclTable (
  352. PpttTable,
  353. &PpttTableLengthRemain,
  354. Parent,
  355. ResourceNo
  356. );
  357. }
  358. if (ClusterOffset == 0) {
  359. // Add socket0sccl0ClusterId for type0 table
  360. ResourceNo = 1;
  361. ClusterOffset = PpttTable->Length ;
  362. Parent = ScclOffset;
  363. AddClusterTable (
  364. PpttTable,
  365. &PpttTableLengthRemain,
  366. Parent,
  367. ResourceNo
  368. );
  369. }
  370. // Add socket0sccl0ClusterIdCoreId for type0 table
  371. ResourceNo = 2;
  372. Parent = ClusterOffset;
  373. AddCoreTable (
  374. PpttTable,
  375. &PpttTableLengthRemain,
  376. Parent,
  377. ResourceNo,
  378. Index1
  379. );
  380. Index1++;
  381. }
  382. }
  383. }
  384. }
  385. return ;
  386. }
  387. STATIC
  388. VOID
  389. PpttSetAcpiTable (
  390. IN EFI_EVENT Event,
  391. IN VOID *Context
  392. )
  393. {
  394. UINTN AcpiTableHandle;
  395. EFI_STATUS Status;
  396. UINT8 Checksum;
  397. EFI_ACPI_SDT_HEADER *Table;
  398. EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE *ApicTable;
  399. EFI_ACPI_TABLE_VERSION TableVersion;
  400. EFI_ACPI_DESCRIPTION_HEADER *PpttTable;
  401. UINTN TableKey;
  402. UINT32 Index0, Index1;
  403. UINT32 PpttTableLengthRemain = 0;
  404. gBS->CloseEvent (Event);
  405. InitCacheInfo ();
  406. PpttTable = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (PPTT_TABLE_MAX_LEN);
  407. gBS->CopyMem (
  408. (VOID *)PpttTable,
  409. &mPpttHeader,
  410. sizeof (EFI_ACPI_DESCRIPTION_HEADER)
  411. );
  412. PpttTableLengthRemain = PPTT_TABLE_MAX_LEN - sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  413. for (Index0 = 0; Index0 < EFI_ACPI_MAX_NUM_TABLES; Index0++) {
  414. Status = mAcpiSdtProtocol->GetAcpiTable (
  415. Index0,
  416. &Table,
  417. &TableVersion,
  418. &TableKey
  419. );
  420. if (EFI_ERROR (Status)) {
  421. break;
  422. }
  423. // Find APIC table
  424. if (Table->Signature == EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE) {
  425. break;
  426. }
  427. }
  428. if (!EFI_ERROR (Status) && (Index0 != EFI_ACPI_MAX_NUM_TABLES)) {
  429. ApicTable = (EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE *)Table;
  430. Index1 = 0;
  431. GetApic (ApicTable, PpttTable, PpttTableLengthRemain, Index1);
  432. Checksum = CalculateCheckSum8 ((UINT8 *)(PpttTable), PpttTable->Length);
  433. PpttTable->Checksum = Checksum;
  434. AcpiTableHandle = 0;
  435. Status = mAcpiTableProtocol->InstallAcpiTable (
  436. mAcpiTableProtocol,
  437. PpttTable,
  438. PpttTable->Length,
  439. &AcpiTableHandle);
  440. }
  441. FreePool (PpttTable);
  442. return ;
  443. }
  444. EFI_STATUS
  445. EFIAPI
  446. PpttEntryPoint(
  447. IN EFI_HANDLE ImageHandle,
  448. IN EFI_SYSTEM_TABLE *SystemTable
  449. )
  450. {
  451. EFI_STATUS Status;
  452. EFI_EVENT ReadyToBootEvent;
  453. Status = gBS->LocateProtocol (
  454. &gEfiAcpiTableProtocolGuid,
  455. NULL,
  456. (VOID **)&mAcpiTableProtocol);
  457. ASSERT_EFI_ERROR (Status);
  458. Status = gBS->LocateProtocol (
  459. &gEfiAcpiSdtProtocolGuid,
  460. NULL,
  461. (VOID **)&mAcpiSdtProtocol);
  462. ASSERT_EFI_ERROR (Status);
  463. Status = EfiCreateEventReadyToBootEx (
  464. TPL_NOTIFY,
  465. PpttSetAcpiTable,
  466. NULL,
  467. &ReadyToBootEvent
  468. );
  469. ASSERT_EFI_ERROR (Status);
  470. DEBUG ((DEBUG_INFO, "Acpi Pptt init done.\n"));
  471. return Status;
  472. }