TianoCore EDK2 master
Loading...
Searching...
No Matches
PcctGenerator.c
Go to the documentation of this file.
1
13#include <Library/AcpiLib.h>
15#include <Library/DebugLib.h>
17#include <Protocol/AcpiTable.h>
18
19// Module specific include files.
20#include <AcpiTableGenerator.h>
25#include "PcctGenerator.h"
26
47 );
48
56 );
57
65 );
66
74 );
75
83 );
84
92 );
93
108
119STATIC
121EFIAPI
124 IN UINT32 Count
125 )
126{
127 VOID **Table;
128
129 if ((MappingTable == NULL) ||
130 (Count == 0))
131 {
132 ASSERT (0);
133 return EFI_INVALID_PARAMETER;
134 }
135
136 Table = AllocateZeroPool (sizeof (*Table) * Count);
137 if (Table == NULL) {
138 ASSERT (0);
139 return EFI_OUT_OF_RESOURCES;
140 }
141
142 MappingTable->Table = Table;
143 MappingTable->MaxIndex = Count;
144
145 return EFI_SUCCESS;
146}
147
152STATIC
153VOID
154EFIAPI
157 )
158{
159 ASSERT (MappingTable != NULL);
160 ASSERT (MappingTable->Table != NULL);
161
162 if (MappingTable->Table != NULL) {
164 }
165}
166
179STATIC
181EFIAPI
184 IN VOID *PccSubspace,
185 IN UINT32 Index
186 )
187{
188 if ((MappingTable == NULL) ||
189 (MappingTable->Table == NULL) ||
190 (PccSubspace == NULL))
191 {
192 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
193 return EFI_INVALID_PARAMETER;
194 }
195
196 if ((Index >= MappingTable->MaxIndex) ||
197 (MappingTable->Table[Index] != 0))
198 {
199 ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL);
200 return EFI_BUFFER_TOO_SMALL;
201 }
202
203 // Just map the Pcc Subspace in the Table.
204 MappingTable->Table[Index] = PccSubspace;
205 return EFI_SUCCESS;
206}
207
219STATIC
221EFIAPI
224 IN VOID *CmPccArray,
225 IN UINT32 CmPccCount
226 )
227{
228 EFI_STATUS Status;
229 UINT8 *PccBuffer;
230 UINT32 Index;
231 UINT32 CmObjSize;
232 PCC_SUBSPACE_GENERIC_INFO *GenericPcc;
233
234 if (CmPccCount == 0) {
235 return EFI_SUCCESS;
236 }
237
238 if ((CmPccArray == NULL) || (MappingTable == NULL)) {
239 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
240 return EFI_INVALID_PARAMETER;
241 }
242
243 GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)CmPccArray;
244
245 switch (GenericPcc->Type) {
246 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
247 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO);
248 break;
249
250 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
251 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO);
252 break;
253
254 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
255 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO);
256 break;
257
258 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
259 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO);
260 break;
261
262 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
263 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO);
264 break;
265
266 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
267 CmObjSize = sizeof (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO);
268 break;
269
270 default:
271 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
272 return EFI_INVALID_PARAMETER;
273 }
274
275 PccBuffer = (UINT8 *)CmPccArray;
276
277 // Map the Pcc channel to their Subspace Id.
278 for (Index = 0; Index < CmPccCount; Index++) {
279 GenericPcc = (PCC_SUBSPACE_GENERIC_INFO *)PccBuffer;
280
281 Status = MappingTableAdd (
283 PccBuffer,
284 GenericPcc->SubspaceId
285 );
286 if (EFI_ERROR (Status)) {
287 ASSERT_EFI_ERROR (Status);
288 return Status;
289 }
290
291 PccBuffer += CmObjSize;
292 }
293
294 return EFI_SUCCESS;
295}
296
305STATIC
307EFIAPI
311 )
312{
315
316 if ((PccCmObj == NULL) ||
317 (PccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC) ||
318 (PccAcpi == NULL))
319 {
320 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
321 return EFI_INVALID_PARAMETER;
322 }
323
324 Doorbell = &PccCmObj->DoorbellReg;
325 ChannelTiming = &PccCmObj->ChannelTiming;
326
327 PccAcpi->Type = PccCmObj->Type;
328 PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
329 *(UINT32 *)&PccAcpi->Reserved[0] = EFI_ACPI_RESERVED_DWORD;
330 *(UINT16 *)&PccAcpi->Reserved[4] = EFI_ACPI_RESERVED_WORD;
331 PccAcpi->BaseAddress = PccCmObj->BaseAddress;
332 PccAcpi->AddressLength = PccCmObj->AddressLength;
333
334 CopyMem (
335 &PccAcpi->DoorbellRegister,
336 &Doorbell->Register,
338 );
339 PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
340 PccAcpi->DoorbellWrite = Doorbell->WriteMask;
341
342 PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
343 PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
344 PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
345
346 return EFI_SUCCESS;
347}
348
357STATIC
359EFIAPI
363 )
364{
368
369 GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
370
371 if ((PccCmObj == NULL) ||
372 (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS) ||
373 (PccAcpi == NULL))
374 {
375 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
376 return EFI_INVALID_PARAMETER;
377 }
378
379 Doorbell = &GenericPccCmObj->DoorbellReg;
380 ChannelTiming = &GenericPccCmObj->ChannelTiming;
381
382 ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
383
384 PccAcpi->Type = GenericPccCmObj->Type;
386 PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
387 PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
388 PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
389 PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
390 PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
391
392 CopyMem (
393 &PccAcpi->DoorbellRegister,
394 &Doorbell->Register,
396 );
397 PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
398 PccAcpi->DoorbellWrite = Doorbell->WriteMask;
399
400 PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
401 PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
402 PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
403
404 if ((PccCmObj->PlatIrq.Interrupt != 0)) {
406 }
407
408 return EFI_SUCCESS;
409}
410
419STATIC
421EFIAPI
425 )
426{
429 PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
431
432 GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
433
434 if ((PccCmObj == NULL) ||
435 (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS) ||
436 (PccAcpi == NULL))
437 {
438 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
439 return EFI_INVALID_PARAMETER;
440 }
441
442 Doorbell = &GenericPccCmObj->DoorbellReg;
443 PlatIrqAck = &PccCmObj->PlatIrqAckReg;
444 ChannelTiming = &GenericPccCmObj->ChannelTiming;
445
446 ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
447
448 PccAcpi->Type = GenericPccCmObj->Type;
450 PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
451 PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
452 PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
453 PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
454 PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
455 PccAcpi->AddressLength = GenericPccCmObj->AddressLength;
456
457 CopyMem (
458 &PccAcpi->DoorbellRegister,
459 &Doorbell->Register,
461 );
462 PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
463 PccAcpi->DoorbellWrite = Doorbell->WriteMask;
464
465 PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
466 PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
467 PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
468
469 CopyMem (
470 &PccAcpi->PlatformInterruptAckRegister,
471 &PlatIrqAck->Register,
473 );
474 PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask;
475 PccAcpi->PlatformInterruptAckWrite = PlatIrqAck->WriteMask;
476
477 if ((PccCmObj->PlatIrq.Interrupt != 0)) {
479 }
480
481 return EFI_SUCCESS;
482}
483
492STATIC
494EFIAPI
498 )
499{
502 PCC_MAILBOX_REGISTER_INFO *PlatIrqAck;
503 PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
504 PCC_MAILBOX_REGISTER_INFO *CmdCompleteUpdate;
505 PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
507
508 GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
509
510 if ((PccCmObj == NULL) ||
511 ((GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC) &&
512 (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC)) ||
513 (PccAcpi == NULL))
514 {
515 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
516 return EFI_INVALID_PARAMETER;
517 }
518
519 Doorbell = &GenericPccCmObj->DoorbellReg;
520 PlatIrqAck = &PccCmObj->PlatIrqAckReg;
521 CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg;
522 CmdCompleteUpdate = &PccCmObj->CmdCompleteUpdateReg;
523 ErrorStatus = &PccCmObj->ErrorStatusReg;
524 ChannelTiming = &GenericPccCmObj->ChannelTiming;
525
526 ASSERT ((PccCmObj->PlatIrq.Flags & ~MAX_UINT8) == 0);
527 ASSERT ((GenericPccCmObj->AddressLength & ~MAX_UINT32) == 0);
528
529 PccAcpi->Type = GenericPccCmObj->Type;
530 PccAcpi->Length = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
531 PccAcpi->PlatformInterrupt = PccCmObj->PlatIrq.Interrupt;
532 PccAcpi->PlatformInterruptFlags = (UINT8)PccCmObj->PlatIrq.Flags;
533 PccAcpi->Reserved = EFI_ACPI_RESERVED_BYTE;
534 PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
535 PccAcpi->AddressLength = (UINT32)GenericPccCmObj->AddressLength;
536
537 CopyMem (
538 &PccAcpi->DoorbellRegister,
539 &Doorbell->Register,
541 );
542 PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
543 PccAcpi->DoorbellWrite = Doorbell->WriteMask;
544
545 PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
546 PccAcpi->MaximumPeriodicAccessRate = ChannelTiming->MaxPeriodicAccessRate;
547 PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
548
549 CopyMem (
550 &PccAcpi->PlatformInterruptAckRegister,
551 &PlatIrqAck->Register,
553 );
554 PccAcpi->PlatformInterruptAckPreserve = PlatIrqAck->PreserveMask;
555 PccAcpi->PlatformInterruptAckSet = PlatIrqAck->WriteMask;
556
557 PccAcpi->Reserved1[0] = EFI_ACPI_RESERVED_BYTE;
558 PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
559 PccAcpi->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
560 PccAcpi->Reserved1[3] = EFI_ACPI_RESERVED_BYTE;
561 PccAcpi->Reserved1[4] = EFI_ACPI_RESERVED_BYTE;
562 PccAcpi->Reserved1[5] = EFI_ACPI_RESERVED_BYTE;
563 PccAcpi->Reserved1[6] = EFI_ACPI_RESERVED_BYTE;
564 PccAcpi->Reserved1[7] = EFI_ACPI_RESERVED_BYTE;
565
566 CopyMem (
567 &PccAcpi->CommandCompleteCheckRegister,
568 &CmdCompleteCheck->Register,
570 );
571 PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask;
572 // No Write mask.
573
574 CopyMem (
575 &PccAcpi->CommandCompleteUpdateRegister,
576 &CmdCompleteUpdate->Register,
578 );
579 PccAcpi->CommandCompleteUpdatePreserve = CmdCompleteUpdate->PreserveMask;
580 PccAcpi->CommandCompleteUpdateSet = CmdCompleteUpdate->WriteMask;
581
582 CopyMem (
583 &PccAcpi->ErrorStatusRegister,
584 &ErrorStatus->Register,
586 );
587 PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask;
588 // No Write mask.
589
590 if (GenericPccCmObj->Type == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
592 } else if ((PccCmObj->PlatIrq.Interrupt != 0)) {
594 }
595
596 return EFI_SUCCESS;
597}
598
607STATIC
609EFIAPI
613 )
614{
617 PCC_MAILBOX_REGISTER_INFO *CmdCompleteCheck;
618 PCC_MAILBOX_REGISTER_INFO *ErrorStatus;
620
621 GenericPccCmObj = (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)PccCmObj;
622
623 if ((PccCmObj == NULL) ||
624 (GenericPccCmObj->Type != EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS) ||
625 (PccAcpi == NULL))
626 {
627 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
628 return EFI_INVALID_PARAMETER;
629 }
630
631 Doorbell = &GenericPccCmObj->DoorbellReg;
632 CmdCompleteCheck = &PccCmObj->CmdCompleteCheckReg;
633 ErrorStatus = &PccCmObj->ErrorStatusReg;
634 ChannelTiming = &GenericPccCmObj->ChannelTiming;
635
636 PccAcpi->Type = GenericPccCmObj->Type;
638 PccAcpi->Version = PccCmObj->Version;
639 PccAcpi->BaseAddress = GenericPccCmObj->BaseAddress;
640 PccAcpi->SharedMemoryRangeLength = GenericPccCmObj->AddressLength;
641
642 CopyMem (
643 &PccAcpi->DoorbellRegister,
644 &Doorbell->Register,
646 );
647 PccAcpi->DoorbellPreserve = Doorbell->PreserveMask;
648 PccAcpi->DoorbellWrite = Doorbell->WriteMask;
649
650 CopyMem (
651 &PccAcpi->CommandCompleteCheckRegister,
652 &CmdCompleteCheck->Register,
654 );
655 PccAcpi->CommandCompleteCheckMask = CmdCompleteCheck->PreserveMask;
656 // No Write mask.
657
658 CopyMem (
659 &PccAcpi->ErrorStatusRegister,
660 &ErrorStatus->Register,
662 );
663 PccAcpi->ErrorStatusMask = ErrorStatus->PreserveMask;
664 // No Write mask.
665
666 PccAcpi->NominalLatency = ChannelTiming->NominalLatency;
667 // No MaximumPeriodicAccessRate.
668 PccAcpi->MinimumRequestTurnaroundTime = ChannelTiming->MinRequestTurnaroundTime;
669
670 return EFI_SUCCESS;
671}
672
683STATIC
685EFIAPI
688 IN VOID *Pcc,
689 IN UINT32 Size
690 )
691{
692 EFI_STATUS Status;
693 UINT8 *PccBuffer;
694 UINT32 CmObjSize;
695 UINT32 Index;
696 UINT32 MaxIndex;
697 VOID **Table;
698 VOID *CurrentPccSubspace;
699
700 ASSERT (MappingTable != NULL);
701 ASSERT (MappingTable->Table != NULL);
702
703 PccBuffer = Pcc;
704 MaxIndex = MappingTable->MaxIndex;
705 Table = MappingTable->Table;
706
707 for (Index = 0; Index < MaxIndex; Index++) {
708 CurrentPccSubspace = Table[Index];
709 if (CurrentPccSubspace == NULL) {
710 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
711 return EFI_INVALID_PARAMETER;
712 }
713
714 switch (((PCC_SUBSPACE_GENERIC_INFO *)CurrentPccSubspace)->Type) {
715 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
716 Status = AddSubspaceStructType0 (
717 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *)CurrentPccSubspace,
719 );
720
721 CmObjSize = sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
722 break;
723
724 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
725 Status = AddSubspaceStructType1 (
726 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *)CurrentPccSubspace,
728 );
729
731 break;
732
733 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
734 Status = AddSubspaceStructType2 (
735 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *)CurrentPccSubspace,
737 );
738
740 break;
741
742 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
743 Status = AddSubspaceStructType34 (
744 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *)CurrentPccSubspace,
746 );
747
749 break;
750
751 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
752 Status = AddSubspaceStructType34 (
753 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO *)CurrentPccSubspace,
755 );
756
758 break;
759
760 case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
761 Status = AddSubspaceStructType5 (
762 (CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *)CurrentPccSubspace,
764 );
765
767 break;
768
769 default:
770 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
771 return EFI_INVALID_PARAMETER;
772 } // switch
773
774 if (EFI_ERROR (Status)) {
775 ASSERT_EFI_ERROR (Status);
776 return Status;
777 }
778
779 if (Size < CmObjSize) {
780 ASSERT_EFI_ERROR (EFI_BUFFER_TOO_SMALL);
781 return EFI_BUFFER_TOO_SMALL;
782 }
783
784 PccBuffer += CmObjSize;
785 Size -= CmObjSize;
786 } // for
787
788 return EFI_SUCCESS;
789}
790
815STATIC
817EFIAPI
823 )
824{
825 EFI_STATUS Status;
827 UINT32 TableSize;
829 UINT8 *Buffer;
830
832 UINT32 MappingTableCount;
833
835 UINT32 PccType0Count;
837 UINT32 PccType1Count;
839 UINT32 PccType2Count;
841 UINT32 PccType3Count;
843 UINT32 PccType4Count;
845 UINT32 PccType5Count;
846
847 ASSERT (This != NULL);
848 ASSERT (AcpiTableInfo != NULL);
849 ASSERT (CfgMgrProtocol != NULL);
850 ASSERT (Table != NULL);
851 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
852 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
853
854 if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
855 (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
856 {
857 DEBUG ((
858 DEBUG_ERROR,
859 "ERROR: PCCT: Requested table revision = %d, is not supported."
860 "Supported table revision: Minimum = %d, Maximum = %d\n",
861 AcpiTableInfo->AcpiTableRevision,
862 This->MinAcpiTableRevision,
863 This->AcpiTableRevision
864 ));
865 ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
866 return EFI_INVALID_PARAMETER;
867 }
868
870 MappingTable = &Generator->MappingTable;
871 *Table = NULL;
872
873 // First get all the Pcc Subpace CmObj of type X.
874
875 Status = GetEArchCommonObjPccSubspaceType0Info (
876 CfgMgrProtocol,
878 &PccType0,
879 &PccType0Count
880 );
881 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
882 ASSERT_EFI_ERROR (Status);
883 goto error_handler;
884 }
885
886 Status = GetEArchCommonObjPccSubspaceType1Info (
887 CfgMgrProtocol,
889 &PccType1,
890 &PccType1Count
891 );
892 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
893 ASSERT_EFI_ERROR (Status);
894 goto error_handler;
895 }
896
897 Status = GetEArchCommonObjPccSubspaceType2Info (
898 CfgMgrProtocol,
900 &PccType2,
901 &PccType2Count
902 );
903 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
904 ASSERT_EFI_ERROR (Status);
905 goto error_handler;
906 }
907
908 Status = GetEArchCommonObjPccSubspaceType3Info (
909 CfgMgrProtocol,
911 &PccType3,
912 &PccType3Count
913 );
914 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
915 ASSERT_EFI_ERROR (Status);
916 goto error_handler;
917 }
918
919 Status = GetEArchCommonObjPccSubspaceType4Info (
920 CfgMgrProtocol,
922 &PccType4,
923 &PccType4Count
924 );
925 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
926 ASSERT_EFI_ERROR (Status);
927 goto error_handler;
928 }
929
930 Status = GetEArchCommonObjPccSubspaceType5Info (
931 CfgMgrProtocol,
933 &PccType5,
934 &PccType5Count
935 );
936 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
937 ASSERT_EFI_ERROR (Status);
938 goto error_handler;
939 }
940
941 // Count the number of Pcc Subspaces.
942 MappingTableCount = PccType0Count;
943 MappingTableCount += PccType1Count;
944 MappingTableCount += PccType2Count;
945 MappingTableCount += PccType3Count;
946 MappingTableCount += PccType4Count;
947 MappingTableCount += PccType5Count;
948
949 Status = MappingTableInitialize (MappingTable, MappingTableCount);
950 if (EFI_ERROR (Status)) {
951 ASSERT_EFI_ERROR (Status);
952 goto error_handler;
953 }
954
955 // Map the Subspace Ids for all types.
956
957 Status = MapPccSubspaceId (MappingTable, PccType0, PccType0Count);
958 if (EFI_ERROR (Status)) {
959 ASSERT_EFI_ERROR (Status);
960 goto error_handler;
961 }
962
963 Status = MapPccSubspaceId (MappingTable, PccType1, PccType1Count);
964 if (EFI_ERROR (Status)) {
965 ASSERT_EFI_ERROR (Status);
966 goto error_handler;
967 }
968
969 Status = MapPccSubspaceId (MappingTable, PccType2, PccType2Count);
970 if (EFI_ERROR (Status)) {
971 ASSERT_EFI_ERROR (Status);
972 goto error_handler;
973 }
974
975 Status = MapPccSubspaceId (MappingTable, PccType3, PccType3Count);
976 if (EFI_ERROR (Status)) {
977 ASSERT_EFI_ERROR (Status);
978 goto error_handler;
979 }
980
981 Status = MapPccSubspaceId (MappingTable, PccType4, PccType4Count);
982 if (EFI_ERROR (Status)) {
983 ASSERT_EFI_ERROR (Status);
984 goto error_handler;
985 }
986
987 Status = MapPccSubspaceId (MappingTable, PccType5, PccType5Count);
988 if (EFI_ERROR (Status)) {
989 ASSERT_EFI_ERROR (Status);
990 goto error_handler;
991 }
992
993 // Compute the size of the PCCT table.
995 TableSize += PccType0Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC);
996 TableSize += PccType1Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS);
997 TableSize += PccType2Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
998 TableSize += PccType3Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC);
999 TableSize += PccType4Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC);
1000 TableSize += PccType5Count * sizeof (EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS);
1001
1002 // Allocate a Buffer for the PCCT table.
1003 *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize);
1004 if (*Table == NULL) {
1005 Status = EFI_OUT_OF_RESOURCES;
1006 ASSERT_EFI_ERROR (Status);
1007 goto error_handler;
1008 }
1009
1011
1012 Status = AddAcpiHeader (
1013 CfgMgrProtocol,
1014 This,
1015 &Pcct->Header,
1016 AcpiTableInfo,
1017 TableSize
1018 );
1019 if (EFI_ERROR (Status)) {
1020 DEBUG ((
1021 DEBUG_ERROR,
1022 "ERROR: PCCT: Failed to add ACPI header. Status = %r\n",
1023 Status
1024 ));
1025 ASSERT_EFI_ERROR (Status);
1026 goto error_handler;
1027 }
1028
1029 Buffer = (UINT8 *)Pcct;
1032
1033 // Populate the PCCT table by following the Subspace Id mapping.
1034 Status = PopulatePcctTable (MappingTable, Buffer, TableSize);
1035 if (EFI_ERROR (Status)) {
1036 ASSERT_EFI_ERROR (Status);
1037 goto error_handler;
1038 }
1039
1040 // Setup the Reserved fields once mHasPlatformInterrupt hase been populated.
1041 Pcct->Flags = mHasPlatformInterrupt;
1042 Pcct->Reserved = EFI_ACPI_RESERVED_QWORD;
1043
1045
1046 return Status;
1047
1048error_handler:
1049 DEBUG ((
1050 DEBUG_ERROR,
1051 "ERROR: PCCT: Failed to install table. Status = %r\n",
1052 Status
1053 ));
1054
1055 if (*Table != NULL) {
1056 FreePool (*Table);
1057 *Table = NULL;
1058 }
1059
1061
1062 return Status;
1063}
1064
1076STATIC
1078EFIAPI
1084 )
1085{
1086 ASSERT (This != NULL);
1087 ASSERT (AcpiTableInfo != NULL);
1088 ASSERT (CfgMgrProtocol != NULL);
1089 ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
1090 ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
1091
1092 if ((Table == NULL) || (*Table == NULL)) {
1093 DEBUG ((DEBUG_ERROR, "ERROR: PCCT: Invalid Table Pointer\n"));
1094 ASSERT ((Table != NULL) && (*Table != NULL));
1095 return EFI_INVALID_PARAMETER;
1096 }
1097
1098 FreePool (*Table);
1099 *Table = NULL;
1100 return EFI_SUCCESS;
1101}
1102
1105#define PCCT_GENERATOR_REVISION CREATE_REVISION (1, 0)
1106
1109STATIC
1111 // ACPI table generator header
1112 {
1113 // Generator ID
1115 // Generator Description
1116 L"ACPI.STD.PCCT.GENERATOR",
1117 // ACPI Table Signature
1119 // ACPI Table Revision supported by this Generator
1121 // Minimum ACPI Table Revision supported by this Generator
1123 // Creator ID
1125 // Creator Revision
1127 // Build Table function
1129 // Free Resource function
1131 // Extended build function not needed
1132 NULL,
1133 // Extended build function not implemented by the generator.
1134 // Hence extended free resource function is not required.
1135 NULL
1136 },
1137
1138 // Private fields are defined from here.
1139
1140 // Mapping Table
1141 {
1142 // Table
1143 NULL,
1144 // MaxIndex
1145 0,
1146 },
1147};
1148
1160EFIAPI
1162 IN EFI_HANDLE ImageHandle,
1163 IN EFI_SYSTEM_TABLE *SystemTable
1164 )
1165{
1166 EFI_STATUS Status;
1167
1169 DEBUG ((DEBUG_INFO, "PCCT: Register Generator. Status = %r\n", Status));
1170 ASSERT_EFI_ERROR (Status);
1171 return Status;
1172}
1173
1184EFIAPI
1186 IN EFI_HANDLE ImageHandle,
1187 IN EFI_SYSTEM_TABLE *SystemTable
1188 )
1189{
1190 EFI_STATUS Status;
1191
1193 DEBUG ((DEBUG_INFO, "PCCT: Deregister Generator. Status = %r\n", Status));
1194 ASSERT_EFI_ERROR (Status);
1195 return Status;
1196}
#define EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE
Definition: Acpi64.h:3095
#define EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION
Definition: Acpi64.h:2414
EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC EFI_ACPI_6_4_PCCT_SUBSPACE_4_EXTENDED_PCC
Definition: Acpi64.h:2558
EFI_STATUS EFIAPI RegisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
EFI_STATUS EFIAPI DeregisterAcpiTableGenerator(IN CONST ACPI_TABLE_GENERATOR *CONST Generator)
#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId)
#define TABLE_GENERATOR_CREATOR_ID
@ EStdAcpiTableIdPcct
PCCT Generator.
struct CmArchCommonPccSubspaceType2Info CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO
struct CmArchCommonPccSubspaceType5Info CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO
struct CmArchCommonPccSubspaceType3Info CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO
struct CmArchCommonPccSubspaceType1Info CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO
CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE4_INFO
PCC_SUBSPACE_GENERIC_INFO CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO
@ EArchCommonObjPccSubspaceType4Info
23 - Pcc Subspace Type 4 Info
@ EArchCommonObjPccSubspaceType2Info
21 - Pcc Subspace Type 2 Info
@ EArchCommonObjPccSubspaceType5Info
24 - Pcc Subspace Type 5 Info
@ EArchCommonObjPccSubspaceType3Info
22 - Pcc Subspace Type 3 Info
@ EArchCommonObjPccSubspaceType1Info
20 - Pcc Subspace Type 1 Info
@ EArchCommonObjPccSubspaceType0Info
19 - Pcc Subspace Type 0 Info
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type)
@ EObjNameSpaceArchCommon
Arch Common Objects Namespace.
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
STATIC EFI_STATUS EFIAPI FreePcctTableResources(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
STATIC BOOLEAN mHasPlatformInterrupt
STATIC EFI_STATUS EFIAPI AddSubspaceStructType2(IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE2_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PccAcpi)
STATIC EFI_STATUS EFIAPI MappingTableAdd(IN MAPPING_TABLE *MappingTable, IN VOID *PccSubspace, IN UINT32 Index)
STATIC EFI_STATUS EFIAPI AddSubspaceStructType0(IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE0_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_GENERIC *PccAcpi)
STATIC EFI_STATUS EFIAPI BuildPcctTable(IN CONST ACPI_TABLE_GENERATOR *CONST This, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table)
STATIC EFI_STATUS EFIAPI MapPccSubspaceId(IN MAPPING_TABLE *MappingTable, IN VOID *CmPccArray, IN UINT32 CmPccCount)
#define PCCT_GENERATOR_REVISION
STATIC EFI_STATUS EFIAPI AddSubspaceStructType5(IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE5_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_5_HW_REGISTERS_COMMUNICATIONS *PccAcpi)
STATIC EFI_STATUS EFIAPI MappingTableInitialize(IN MAPPING_TABLE *MappingTable, IN UINT32 Count)
STATIC VOID EFIAPI MappingTableFree(IN OUT MAPPING_TABLE *MappingTable)
STATIC ACPI_PCCT_GENERATOR PcctGenerator
EFI_STATUS EFIAPI AcpiPcctLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI AcpiPcctLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_STATUS EFIAPI AddSubspaceStructType34(IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE3_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_3_EXTENDED_PCC *PccAcpi)
STATIC EFI_STATUS EFIAPI AddSubspaceStructType1(IN CM_ARCH_COMMON_PCC_SUBSPACE_TYPE1_INFO *PccCmObj, IN EFI_ACPI_6_4_PCCT_SUBSPACE_1_HW_REDUCED_COMMUNICATIONS *PccAcpi)
STATIC EFI_STATUS EFIAPI PopulatePcctTable(IN MAPPING_TABLE *MappingTable, IN VOID *Pcc, IN UINT32 Size)
#define CM_NULL_TOKEN
EFI_STATUS EFIAPI AddAcpiHeader(IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, IN CONST ACPI_TABLE_GENERATOR *CONST Generator, IN OUT EFI_ACPI_DESCRIPTION_HEADER *CONST AcpiHeader, IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, IN CONST UINT32 Length)
Definition: TableHelper.c:114
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
ACPI_TABLE_GENERATOR Header
ACPI Table generator header.
Definition: PcctGenerator.h:33
UINT32 MaxIndex
Number of entries in the Table.
EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE Register
GAS describing the Register.
UINT64 WriteMask
Mask of bits to set when writing.
UINT32 NominalLatency
Expected latency to process a command, in microseconds.
PCC_SUBSPACE_CHANNEL_TIMING_INFO ChannelTiming
Mailbox Timings.
UINT8 Type
Table type (or subspace).
PCC_MAILBOX_REGISTER_INFO DoorbellReg
Doorbell Register.
UINT64 AddressLength
Address length.