TianoCore EDK2 master
Loading...
Searching...
No Matches
RamDiskProtocol.c
Go to the documentation of this file.
1
11#include "RamDiskImpl.h"
12
13RAM_DISK_PRIVATE_DATA mRamDiskPrivateDataTemplate = {
14 RAM_DISK_PRIVATE_DATA_SIGNATURE,
15 NULL
16};
17
18MEDIA_RAM_DISK_DEVICE_PATH mRamDiskDeviceNodeTemplate = {
19 {
20 MEDIA_DEVICE_PATH,
22 {
23 (UINT8)(sizeof (MEDIA_RAM_DISK_DEVICE_PATH)),
24 (UINT8)((sizeof (MEDIA_RAM_DISK_DEVICE_PATH)) >> 8)
25 }
26 }
27};
28
29BOOLEAN mRamDiskSsdtTableKeyValid = FALSE;
30UINTN mRamDiskSsdtTableKey;
31
39VOID
41 IN RAM_DISK_PRIVATE_DATA *PrivateData,
42 IN OUT MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode
43 )
44{
46 (UINT64 *)&(RamDiskDevNode->StartingAddr[0]),
47 (UINT64)PrivateData->StartingAddr
48 );
50 (UINT64 *)&(RamDiskDevNode->EndingAddr[0]),
51 (UINT64)PrivateData->StartingAddr + PrivateData->Size - 1
52 );
53 CopyGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid);
54 RamDiskDevNode->Instance = PrivateData->InstanceNumber;
55}
56
66 VOID
67 )
68{
69 EFI_STATUS Status;
71 UINTN SectionInstance;
72 UINTN TableSize;
73
74 Status = EFI_SUCCESS;
75 SectionInstance = 0;
76
77 //
78 // Scan all the EFI raw section instances in FV to find the NVDIMM root
79 // device SSDT.
80 //
81 while (TRUE) {
82 Status = GetSectionFromFv (
83 &gEfiCallerIdGuid,
84 EFI_SECTION_RAW,
85 SectionInstance,
86 (VOID **)&Table,
87 &TableSize
88 );
89 if (EFI_ERROR (Status)) {
90 break;
91 }
92
93 if (Table->OemTableId == SIGNATURE_64 ('R', 'a', 'm', 'D', 'i', 's', 'k', ' ')) {
94 Status = mAcpiTableProtocol->InstallAcpiTable (
95 mAcpiTableProtocol,
96 Table,
97 TableSize,
98 &mRamDiskSsdtTableKey
99 );
100 ASSERT_EFI_ERROR (Status);
101
102 if (!EFI_ERROR (Status)) {
103 mRamDiskSsdtTableKeyValid = TRUE;
104 }
105
106 FreePool (Table);
107 return Status;
108 } else {
109 FreePool (Table);
110 SectionInstance++;
111 }
112 }
113
114 return Status;
115}
116
129 IN RAM_DISK_PRIVATE_DATA *PrivateData
130 )
131{
132 EFI_STATUS Status;
133 EFI_MEMORY_DESCRIPTOR *MemoryMap;
134 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;
135 EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
136 UINTN TableIndex;
137 VOID *TableHeader;
138 EFI_ACPI_TABLE_VERSION TableVersion;
139 UINTN TableKey;
140 EFI_ACPI_DESCRIPTION_HEADER *NfitHeader;
142 *SpaRange;
143 VOID *Nfit;
144 UINT32 NfitLen;
145 UINTN MemoryMapSize;
146 UINTN MapKey;
147 UINTN DescriptorSize;
148 UINT32 DescriptorVersion;
149 UINT64 CurrentData;
150 UINT8 Checksum;
151 BOOLEAN MemoryFound;
152
153 //
154 // Get the EFI memory map.
155 //
156 MemoryMapSize = 0;
157 MemoryMap = NULL;
158 MemoryFound = FALSE;
159
160 Status = gBS->GetMemoryMap (
161 &MemoryMapSize,
162 MemoryMap,
163 &MapKey,
164 &DescriptorSize,
165 &DescriptorVersion
166 );
167 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
168 do {
169 MemoryMap = (EFI_MEMORY_DESCRIPTOR *)AllocatePool (MemoryMapSize);
170 ASSERT (MemoryMap != NULL);
171 Status = gBS->GetMemoryMap (
172 &MemoryMapSize,
173 MemoryMap,
174 &MapKey,
175 &DescriptorSize,
176 &DescriptorVersion
177 );
178 if (EFI_ERROR (Status)) {
179 FreePool (MemoryMap);
180 }
181 } while (Status == EFI_BUFFER_TOO_SMALL);
182
183 ASSERT_EFI_ERROR (Status);
184
185 MemoryMapEntry = MemoryMap;
186 MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);
187 while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {
188 if ((MemoryMapEntry->Type == EfiReservedMemoryType) &&
189 (MemoryMapEntry->PhysicalStart <= PrivateData->StartingAddr) &&
190 (MemoryMapEntry->PhysicalStart +
191 MultU64x32 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SIZE)
192 >= PrivateData->StartingAddr + PrivateData->Size))
193 {
194 MemoryFound = TRUE;
195 DEBUG ((
196 DEBUG_INFO,
197 "RamDiskPublishNfit: RAM disk with reserved memory type, will publish to NFIT.\n"
198 ));
199 break;
200 }
201
202 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
203 }
204
205 FreePool (MemoryMap);
206
207 if (!MemoryFound) {
208 return EFI_NOT_FOUND;
209 }
210
211 //
212 // Determine whether there is a NFIT already in the ACPI table.
213 //
214 Status = EFI_SUCCESS;
215 TableIndex = 0;
216 TableKey = 0;
217 TableHeader = NULL;
218
219 while (!EFI_ERROR (Status)) {
220 Status = mAcpiSdtProtocol->GetAcpiTable (
221 TableIndex,
222 (EFI_ACPI_SDT_HEADER **)&TableHeader,
223 &TableVersion,
224 &TableKey
225 );
226 if (!EFI_ERROR (Status)) {
227 TableIndex++;
228
229 if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature ==
231 {
232 break;
233 }
234 }
235 }
236
237 if (!EFI_ERROR (Status)) {
238 //
239 // A NFIT is already in the ACPI table.
240 //
241 DEBUG ((
242 DEBUG_INFO,
243 "RamDiskPublishNfit: A NFIT is already exist in the ACPI Table.\n"
244 ));
245
246 NfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)TableHeader;
247 NfitLen = NfitHeader->Length + sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE);
248 Nfit = AllocateZeroPool (NfitLen);
249 if (Nfit == NULL) {
250 return EFI_OUT_OF_RESOURCES;
251 }
252
253 CopyMem (Nfit, TableHeader, NfitHeader->Length);
254
255 //
256 // Update the NFIT head pointer.
257 //
258 NfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Nfit;
259
260 //
261 // Uninstall the origin NFIT from the ACPI table.
262 //
263 Status = mAcpiTableProtocol->UninstallAcpiTable (
264 mAcpiTableProtocol,
265 TableKey
266 );
267 ASSERT_EFI_ERROR (Status);
268
269 if (EFI_ERROR (Status)) {
270 FreePool (Nfit);
271 return Status;
272 }
273
274 //
275 // Append the System Physical Address (SPA) Range Structure at the end
276 // of the origin NFIT.
277 //
279 ((UINT8 *)Nfit + NfitHeader->Length);
280
281 //
282 // Update the length field of the NFIT
283 //
284 NfitHeader->Length = NfitLen;
285
286 //
287 // The checksum will be updated after the new contents are appended.
288 //
289 NfitHeader->Checksum = 0;
290 } else {
291 //
292 // Assumption is made that if no NFIT is in the ACPI table, there is no
293 // NVDIMM root device in the \SB scope.
294 // Therefore, a NVDIMM root device will be reported via Secondary System
295 // Description Table (SSDT).
296 //
297 Status = RamDiskPublishSsdt ();
298 if (EFI_ERROR (Status)) {
299 return Status;
300 }
301
302 //
303 // No NFIT is in the ACPI table, we will create one here.
304 //
305 DEBUG ((
306 DEBUG_INFO,
307 "RamDiskPublishNfit: No NFIT is in the ACPI Table, will create one.\n"
308 ));
309
312 Nfit = AllocateZeroPool (NfitLen);
313 if (Nfit == NULL) {
314 return EFI_OUT_OF_RESOURCES;
315 }
316
318 ((UINT8 *)Nfit + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));
319
320 NfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Nfit;
322 NfitHeader->Length = NfitLen;
323 NfitHeader->Revision = EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION;
324 NfitHeader->Checksum = 0;
325 NfitHeader->OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);
326 NfitHeader->CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);
327 NfitHeader->CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);
328 CurrentData = PcdGet64 (PcdAcpiDefaultOemTableId);
329 CopyMem (NfitHeader->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (NfitHeader->OemId));
330 CopyMem (&NfitHeader->OemTableId, &CurrentData, sizeof (UINT64));
331 }
332
333 //
334 // Fill in the content of the SPA Range Structure.
335 //
336 SpaRange->Type = EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE;
338 SpaRange->SystemPhysicalAddressRangeBase = PrivateData->StartingAddr;
339 SpaRange->SystemPhysicalAddressRangeLength = PrivateData->Size;
340 CopyGuid (&SpaRange->AddressRangeTypeGUID, &PrivateData->TypeGuid);
341
342 Checksum = CalculateCheckSum8 ((UINT8 *)Nfit, NfitHeader->Length);
343 NfitHeader->Checksum = Checksum;
344
345 //
346 // Publish the NFIT to the ACPI table.
347 // Note, since the NFIT might be modified by other driver, therefore, we
348 // do not track the returning TableKey from the InstallAcpiTable().
349 //
350 Status = mAcpiTableProtocol->InstallAcpiTable (
351 mAcpiTableProtocol,
352 Nfit,
353 NfitHeader->Length,
354 &TableKey
355 );
356 ASSERT_EFI_ERROR (Status);
357
358 FreePool (Nfit);
359
360 if (EFI_ERROR (Status)) {
361 return Status;
362 }
363
364 PrivateData->InNfit = TRUE;
365
366 return EFI_SUCCESS;
367}
368
381 IN RAM_DISK_PRIVATE_DATA *PrivateData
382 )
383{
384 EFI_STATUS Status;
385 UINTN TableIndex;
386 VOID *TableHeader;
387 EFI_ACPI_TABLE_VERSION TableVersion;
388 UINTN TableKey;
389 EFI_ACPI_DESCRIPTION_HEADER *NewNfitHeader;
391 *SpaRange;
392 VOID *NewNfit;
393 VOID *NewNfitPtr;
394 EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *NfitStructHeader;
395 UINT32 NewNfitLen;
396 UINT32 RemainLen;
397 UINT8 Checksum;
398
399 //
400 // Find the NFIT in the ACPI table.
401 //
402 Status = EFI_SUCCESS;
403 TableIndex = 0;
404 TableKey = 0;
405 TableHeader = NULL;
406
407 while (!EFI_ERROR (Status)) {
408 Status = mAcpiSdtProtocol->GetAcpiTable (
409 TableIndex,
410 (EFI_ACPI_SDT_HEADER **)&TableHeader,
411 &TableVersion,
412 &TableKey
413 );
414 if (!EFI_ERROR (Status)) {
415 TableIndex++;
416
417 if (((EFI_ACPI_SDT_HEADER *)TableHeader)->Signature ==
419 {
420 break;
421 }
422 }
423 }
424
425 if (EFI_ERROR (Status)) {
426 //
427 // No NFIT is found in the ACPI table.
428 //
429 return EFI_NOT_FOUND;
430 }
431
432 NewNfitLen = ((EFI_ACPI_DESCRIPTION_HEADER *)TableHeader)->Length -
434
435 //
436 // After removing this RAM disk from the NFIT, if no other structure is in
437 // the NFIT, we just remove the NFIT and the SSDT which is used to report
438 // the NVDIMM root device.
439 //
440 if (NewNfitLen == sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE)) {
441 //
442 // Remove the NFIT.
443 //
444 Status = mAcpiTableProtocol->UninstallAcpiTable (
445 mAcpiTableProtocol,
446 TableKey
447 );
448 ASSERT_EFI_ERROR (Status);
449 if (EFI_ERROR (Status)) {
450 return Status;
451 }
452
453 //
454 // Remove the SSDT which is used by RamDiskDxe driver to report the NVDIMM
455 // root device.
456 // We do not care the return status since this SSDT might already be
457 // uninstalled by other drivers to update the information of the NVDIMM
458 // root device.
459 //
460 if (mRamDiskSsdtTableKeyValid) {
461 mRamDiskSsdtTableKeyValid = FALSE;
462
463 mAcpiTableProtocol->UninstallAcpiTable (
464 mAcpiTableProtocol,
465 mRamDiskSsdtTableKey
466 );
467 }
468
469 return EFI_SUCCESS;
470 }
471
472 NewNfit = AllocateZeroPool (NewNfitLen);
473 if (NewNfit == NULL) {
474 return EFI_OUT_OF_RESOURCES;
475 }
476
477 //
478 // Get a copy of the old NFIT header content.
479 //
480 CopyMem (NewNfit, TableHeader, sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));
481 NewNfitHeader = (EFI_ACPI_DESCRIPTION_HEADER *)NewNfit;
482 NewNfitHeader->Length = NewNfitLen;
483 NewNfitHeader->Checksum = 0;
484
485 //
486 // Copy the content of required NFIT structures.
487 //
488 NewNfitPtr = (UINT8 *)NewNfit + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE);
489 RemainLen = NewNfitLen - sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE);
490 NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
491 ((UINT8 *)TableHeader + sizeof (EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE));
492 while (RemainLen > 0) {
493 if ((NfitStructHeader->Type == EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE) &&
494 (NfitStructHeader->Length == sizeof (EFI_ACPI_6_1_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE)))
495 {
497
498 if ((SpaRange->SystemPhysicalAddressRangeBase == PrivateData->StartingAddr) &&
499 (SpaRange->SystemPhysicalAddressRangeLength == PrivateData->Size) &&
500 (CompareGuid (&SpaRange->AddressRangeTypeGUID, &PrivateData->TypeGuid)))
501 {
502 //
503 // Skip the SPA Range Structure for the RAM disk to be unpublished
504 // from NFIT.
505 //
506 NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
507 ((UINT8 *)NfitStructHeader + NfitStructHeader->Length);
508 continue;
509 }
510 }
511
512 //
513 // Copy the content of origin NFIT.
514 //
515 CopyMem (NewNfitPtr, NfitStructHeader, NfitStructHeader->Length);
516 NewNfitPtr = (UINT8 *)NewNfitPtr + NfitStructHeader->Length;
517
518 //
519 // Move to the header of next NFIT structure.
520 //
521 RemainLen -= NfitStructHeader->Length;
522 NfitStructHeader = (EFI_ACPI_6_1_NFIT_STRUCTURE_HEADER *)
523 ((UINT8 *)NfitStructHeader + NfitStructHeader->Length);
524 }
525
526 Checksum = CalculateCheckSum8 ((UINT8 *)NewNfit, NewNfitHeader->Length);
527 NewNfitHeader->Checksum = Checksum;
528
529 Status = mAcpiTableProtocol->UninstallAcpiTable (
530 mAcpiTableProtocol,
531 TableKey
532 );
533 ASSERT_EFI_ERROR (Status);
534
535 if (EFI_ERROR (Status)) {
536 FreePool (NewNfit);
537 return Status;
538 }
539
540 //
541 // Publish the NFIT to the ACPI table.
542 // Note, since the NFIT might be modified by other driver, therefore, we
543 // do not track the returning TableKey from the InstallAcpiTable().
544 //
545 Status = mAcpiTableProtocol->InstallAcpiTable (
546 mAcpiTableProtocol,
547 NewNfit,
548 NewNfitLen,
549 &TableKey
550 );
551 ASSERT_EFI_ERROR (Status);
552
553 FreePool (NewNfit);
554 if (EFI_ERROR (Status)) {
555 return Status;
556 }
557
558 return EFI_SUCCESS;
559}
560
592EFIAPI
594 IN UINT64 RamDiskBase,
595 IN UINT64 RamDiskSize,
596 IN EFI_GUID *RamDiskType,
597 IN EFI_DEVICE_PATH *ParentDevicePath OPTIONAL,
598 OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
599 )
600{
601 EFI_STATUS Status;
602 RAM_DISK_PRIVATE_DATA *PrivateData;
603 RAM_DISK_PRIVATE_DATA *RegisteredPrivateData;
604 MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode;
605 UINTN DevicePathSize;
606 LIST_ENTRY *Entry;
607
608 if ((0 == RamDiskSize) || (NULL == RamDiskType) || (NULL == DevicePath)) {
609 return EFI_INVALID_PARAMETER;
610 }
611
612 //
613 // Add check to prevent data read across the memory boundary
614 //
615 if ((RamDiskSize > MAX_UINTN) ||
616 (RamDiskBase > MAX_UINTN - RamDiskSize + 1))
617 {
618 return EFI_INVALID_PARAMETER;
619 }
620
621 RamDiskDevNode = NULL;
622
623 //
624 // Create a new RAM disk instance and initialize its private data
625 //
626 PrivateData = AllocateCopyPool (
627 sizeof (RAM_DISK_PRIVATE_DATA),
628 &mRamDiskPrivateDataTemplate
629 );
630 if (NULL == PrivateData) {
631 return EFI_OUT_OF_RESOURCES;
632 }
633
634 PrivateData->StartingAddr = RamDiskBase;
635 PrivateData->Size = RamDiskSize;
636 CopyGuid (&PrivateData->TypeGuid, RamDiskType);
637 InitializeListHead (&PrivateData->ThisInstance);
638
639 //
640 // Generate device path information for the registered RAM disk
641 //
642 RamDiskDevNode = AllocateCopyPool (
644 &mRamDiskDeviceNodeTemplate
645 );
646 if (NULL == RamDiskDevNode) {
647 Status = EFI_OUT_OF_RESOURCES;
648 goto ErrorExit;
649 }
650
651 RamDiskInitDeviceNode (PrivateData, RamDiskDevNode);
652
653 *DevicePath = AppendDevicePathNode (
654 ParentDevicePath,
655 (EFI_DEVICE_PATH_PROTOCOL *)RamDiskDevNode
656 );
657 if (NULL == *DevicePath) {
658 Status = EFI_OUT_OF_RESOURCES;
659 goto ErrorExit;
660 }
661
662 PrivateData->DevicePath = *DevicePath;
663
664 //
665 // Check whether the created device path is already present in the handle
666 // database
667 //
668 if (!IsListEmpty (&RegisteredRamDisks)) {
669 DevicePathSize = GetDevicePathSize (PrivateData->DevicePath);
670
671 BASE_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
672 RegisteredPrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
673 if (DevicePathSize == GetDevicePathSize (RegisteredPrivateData->DevicePath)) {
674 //
675 // Compare device path
676 //
677 if ((CompareMem (
678 PrivateData->DevicePath,
679 RegisteredPrivateData->DevicePath,
680 DevicePathSize
681 )) == 0)
682 {
683 *DevicePath = NULL;
684 Status = EFI_ALREADY_STARTED;
685 goto ErrorExit;
686 }
687 }
688 }
689 }
690
691 //
692 // Fill Block IO protocol informations for the RAM disk
693 //
694 RamDiskInitBlockIo (PrivateData);
695
696 //
697 // Install EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL on a new
698 // handle
699 //
700 Status = gBS->InstallMultipleProtocolInterfaces (
701 &PrivateData->Handle,
702 &gEfiBlockIoProtocolGuid,
703 &PrivateData->BlockIo,
704 &gEfiBlockIo2ProtocolGuid,
705 &PrivateData->BlockIo2,
706 &gEfiDevicePathProtocolGuid,
707 PrivateData->DevicePath,
708 NULL
709 );
710 if (EFI_ERROR (Status)) {
711 goto ErrorExit;
712 }
713
714 //
715 // Insert the newly created one to the registered RAM disk list
716 //
717 InsertTailList (&RegisteredRamDisks, &PrivateData->ThisInstance);
718
719 gBS->ConnectController (PrivateData->Handle, NULL, NULL, TRUE);
720
721 FreePool (RamDiskDevNode);
722
723 if ((mAcpiTableProtocol != NULL) && (mAcpiSdtProtocol != NULL)) {
724 RamDiskPublishNfit (PrivateData);
725 }
726
727 return EFI_SUCCESS;
728
729ErrorExit:
730 if (RamDiskDevNode != NULL) {
731 FreePool (RamDiskDevNode);
732 }
733
734 if (PrivateData != NULL) {
735 if (PrivateData->DevicePath) {
736 FreePool (PrivateData->DevicePath);
737 }
738
739 FreePool (PrivateData);
740 }
741
742 return Status;
743}
744
761EFIAPI
763 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
764 )
765{
766 LIST_ENTRY *Entry;
767 LIST_ENTRY *NextEntry;
768 BOOLEAN Found;
769 UINT64 StartingAddr;
770 UINT64 EndingAddr;
772 MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode;
773 RAM_DISK_PRIVATE_DATA *PrivateData;
774
775 if (NULL == DevicePath) {
776 return EFI_INVALID_PARAMETER;
777 }
778
779 //
780 // Locate the RAM disk device node.
781 //
782 RamDiskDevNode = NULL;
783 Header = DevicePath;
784 do {
785 //
786 // Test if the current device node is a RAM disk.
787 //
788 if ((MEDIA_DEVICE_PATH == Header->Type) &&
789 (MEDIA_RAM_DISK_DP == Header->SubType))
790 {
791 RamDiskDevNode = (MEDIA_RAM_DISK_DEVICE_PATH *)Header;
792
793 break;
794 }
795
796 Header = NextDevicePathNode (Header);
797 } while ((Header->Type != END_DEVICE_PATH_TYPE));
798
799 if (NULL == RamDiskDevNode) {
800 return EFI_UNSUPPORTED;
801 }
802
803 Found = FALSE;
804 StartingAddr = ReadUnaligned64 ((UINT64 *)&(RamDiskDevNode->StartingAddr[0]));
805 EndingAddr = ReadUnaligned64 ((UINT64 *)&(RamDiskDevNode->EndingAddr[0]));
806
807 if (!IsListEmpty (&RegisteredRamDisks)) {
808 BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
809 PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
810
811 //
812 // Unregister the RAM disk given by its starting address, ending address
813 // and type guid.
814 //
815 if ((StartingAddr == PrivateData->StartingAddr) &&
816 (EndingAddr == PrivateData->StartingAddr + PrivateData->Size - 1) &&
817 (CompareGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid)))
818 {
819 //
820 // Remove the content for this RAM disk in NFIT.
821 //
822 if (PrivateData->InNfit) {
823 RamDiskUnpublishNfit (PrivateData);
824 }
825
826 //
827 // Uninstall the EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO(2)_PROTOCOL
828 //
829 gBS->UninstallMultipleProtocolInterfaces (
830 PrivateData->Handle,
831 &gEfiBlockIoProtocolGuid,
832 &PrivateData->BlockIo,
833 &gEfiBlockIo2ProtocolGuid,
834 &PrivateData->BlockIo2,
835 &gEfiDevicePathProtocolGuid,
836 (EFI_DEVICE_PATH_PROTOCOL *)PrivateData->DevicePath,
837 NULL
838 );
839
840 RemoveEntryList (&PrivateData->ThisInstance);
841
842 if (RamDiskCreateHii == PrivateData->CreateMethod) {
843 //
844 // If a RAM disk is created within HII, then the RamDiskDxe driver
845 // driver is responsible for freeing the allocated memory for the
846 // RAM disk.
847 //
848 FreePool ((VOID *)(UINTN)PrivateData->StartingAddr);
849 }
850
851 FreePool (PrivateData->DevicePath);
852 FreePool (PrivateData);
853 Found = TRUE;
854
855 break;
856 }
857 }
858 }
859
860 if (TRUE == Found) {
861 return EFI_SUCCESS;
862 } else {
863 return EFI_NOT_FOUND;
864 }
865}
UINT64 UINTN
#define EFI_ACPI_6_1_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE
Definition: Acpi61.h:2253
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
#define BASE_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead)
Definition: BaseLib.h:2929
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:71
#define BASE_LIST_FOR_EACH(Entry, ListHead)
Definition: BaseLib.h:2913
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINT64 EFIAPI WriteUnaligned64(OUT UINT64 *Buffer, IN UINT64 Value)
Definition: Unaligned.c:236
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
#define MEDIA_RAM_DISK_DP
Definition: DevicePath.h:1205
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS EFIAPI GetSectionFromFv(IN CONST EFI_GUID *NameGuid, IN EFI_SECTION_TYPE SectionType, IN UINTN SectionInstance, OUT VOID **Buffer, OUT UINTN *Size)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define NULL
Definition: Base.h:319
#define SIGNATURE_64(A, B, C, D, E, F, G, H)
Definition: Base.h:1331
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#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
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID RamDiskInitBlockIo(IN RAM_DISK_PRIVATE_DATA *PrivateData)
EFI_STATUS RamDiskPublishSsdt(VOID)
EFI_STATUS RamDiskUnpublishNfit(IN RAM_DISK_PRIVATE_DATA *PrivateData)
EFI_STATUS RamDiskPublishNfit(IN RAM_DISK_PRIVATE_DATA *PrivateData)
EFI_STATUS EFIAPI RamDiskRegister(IN UINT64 RamDiskBase, IN UINT64 RamDiskSize, IN EFI_GUID *RamDiskType, IN EFI_DEVICE_PATH *ParentDevicePath OPTIONAL, OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath)
EFI_STATUS EFIAPI RamDiskUnregister(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID RamDiskInitDeviceNode(IN RAM_DISK_PRIVATE_DATA *PrivateData, IN OUT MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiReservedMemoryType
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: UefiSpec.h:155
Definition: Base.h:213