]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiS3.c
MdeModulePkg/SdMmcPciHcDxe: Add V3 64b DMA Support
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / NvmExpressPei / NvmExpressPeiS3.c
1 /** @file
2 The NvmExpressPei driver is used to manage non-volatile memory subsystem
3 which follows NVM Express specification at PEI phase.
4
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions
9 of the BSD License which accompanies this distribution. The
10 full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 #include "NvmExpressPei.h"
19
20 #include <Guid/S3StorageDeviceInitList.h>
21
22 #include <Library/LockBoxLib.h>
23
24 /**
25 Determine if a specific NVM Express controller can be skipped for S3 phase.
26
27 @param[in] HcDevicePath Device path of the controller.
28 @param[in] HcDevicePathLength Length of the device path specified by
29 HcDevicePath.
30
31 @retval The number of ports that need to be enumerated.
32
33 **/
34 BOOLEAN
35 NvmeS3SkipThisController (
36 IN EFI_DEVICE_PATH_PROTOCOL *HcDevicePath,
37 IN UINTN HcDevicePathLength
38 )
39 {
40 EFI_STATUS Status;
41 UINT8 DummyData;
42 UINTN S3InitDevicesLength;
43 EFI_DEVICE_PATH_PROTOCOL *S3InitDevices;
44 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
45 UINTN DevicePathInstLength;
46 BOOLEAN EntireEnd;
47 BOOLEAN Skip;
48
49 //
50 // From the LockBox, get the list of device paths for devices need to be
51 // initialized in S3.
52 //
53 S3InitDevices = NULL;
54 S3InitDevicesLength = sizeof (DummyData);
55 EntireEnd = FALSE;
56 Skip = TRUE;
57 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, &DummyData, &S3InitDevicesLength);
58 if (Status != EFI_BUFFER_TOO_SMALL) {
59 return Skip;
60 } else {
61 S3InitDevices = AllocatePool (S3InitDevicesLength);
62 if (S3InitDevices == NULL) {
63 return Skip;
64 }
65
66 Status = RestoreLockBox (&gS3StorageDeviceInitListGuid, S3InitDevices, &S3InitDevicesLength);
67 if (EFI_ERROR (Status)) {
68 return Skip;
69 }
70 }
71
72 if (S3InitDevices == NULL) {
73 return Skip;
74 }
75
76 //
77 // Only need to initialize the controllers that exist in the device list.
78 //
79 do {
80 //
81 // Fetch the size of current device path instance.
82 //
83 Status = GetDevicePathInstanceSize (
84 S3InitDevices,
85 &DevicePathInstLength,
86 &EntireEnd
87 );
88 if (EFI_ERROR (Status)) {
89 break;
90 }
91
92 DevicePathInst = S3InitDevices;
93 S3InitDevices = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN) S3InitDevices + DevicePathInstLength);
94
95 if (HcDevicePathLength >= DevicePathInstLength) {
96 continue;
97 }
98
99 //
100 // Compare the device paths to determine if the device is managed by this
101 // controller.
102 //
103 if (CompareMem (
104 DevicePathInst,
105 HcDevicePath,
106 HcDevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)
107 ) == 0) {
108 Skip = FALSE;
109 break;
110 }
111 } while (!EntireEnd);
112
113 return Skip;
114 }