IntelSiliconPkg/VtdInfoSample: Fix IGD RMRR memory.
[mirror_edk2.git] / IntelSiliconPkg / Feature / VTd / PlatformVTdInfoSamplePei / PlatformVTdInfoSamplePei.c
1 /** @file
2 Platform VTd Info Sample PEI driver.
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <PiPei.h>
16
17 #include <Ppi/VtdInfo.h>
18
19 #include <Library/PeiServicesLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/PciLib.h>
22 #include <Library/IoLib.h>
23
24 #define R_SA_MCHBAR (0x48)
25 #define R_SA_GGC (0x50)
26 #define N_SKL_SA_GGC_GGMS_OFFSET (0x6)
27 #define B_SKL_SA_GGC_GGMS_MASK (0xc0)
28 #define N_SKL_SA_GGC_GMS_OFFSET (0x8)
29 #define B_SKL_SA_GGC_GMS_MASK (0xff00)
30 #define V_SKL_SA_GGC_GGMS_8MB 3
31 #define R_SA_TOLUD (0xbc)
32
33 #define R_SA_MCHBAR_VTD1_OFFSET 0x5400 ///< HW UNIT for IGD
34 #define R_SA_MCHBAR_VTD2_OFFSET 0x5410 ///< HW UNIT for all other - PEG, USB, SATA etc
35
36 typedef struct {
37 EFI_ACPI_DMAR_HEADER DmarHeader;
38 //
39 // VTd engine 1 - integrated graphic
40 //
41 EFI_ACPI_DMAR_DRHD_HEADER Drhd1;
42 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER Drhd11;
43 EFI_ACPI_DMAR_PCI_PATH Drhd111;
44 //
45 // VTd engine 2 - all rest
46 //
47 EFI_ACPI_DMAR_DRHD_HEADER Drhd2;
48 //
49 // RMRR 1 - integrated graphic
50 //
51 EFI_ACPI_DMAR_RMRR_HEADER Rmrr1;
52 EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER Rmrr11;
53 EFI_ACPI_DMAR_PCI_PATH Rmrr111;
54 } MY_VTD_INFO_PPI;
55
56 MY_VTD_INFO_PPI mPlatformVTdSample = {
57 { // DmarHeader
58 { // Header
59 EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE,
60 sizeof(MY_VTD_INFO_PPI),
61 EFI_ACPI_DMAR_REVISION,
62 },
63 0x26, // HostAddressWidth
64 },
65
66 { // Drhd1
67 { // Header
68 EFI_ACPI_DMAR_TYPE_DRHD,
69 sizeof(EFI_ACPI_DMAR_DRHD_HEADER) +
70 sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
71 sizeof(EFI_ACPI_DMAR_PCI_PATH)
72 },
73 0, // Flags
74 0, // Reserved
75 0, // SegmentNumber
76 0xFED90000 // RegisterBaseAddress -- TO BE PATCHED
77 },
78 { // Drhd11
79 EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,
80 sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
81 sizeof(EFI_ACPI_DMAR_PCI_PATH),
82 0, // Reserved2
83 0, // EnumerationId
84 0 // StartBusNumber
85 },
86 { // Drhd111
87 2, // Device
88 0 // Function
89 },
90
91 { // Drhd2
92 { // Header
93 EFI_ACPI_DMAR_TYPE_DRHD,
94 sizeof(EFI_ACPI_DMAR_DRHD_HEADER)
95 },
96 EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL, // Flags
97 0, // Reserved
98 0, // SegmentNumber
99 0xFED91000 // RegisterBaseAddress -- TO BE PATCHED
100 },
101
102 { // Rmrr1
103 { // Header
104 EFI_ACPI_DMAR_TYPE_RMRR,
105 sizeof(EFI_ACPI_DMAR_RMRR_HEADER) +
106 sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
107 sizeof(EFI_ACPI_DMAR_PCI_PATH)
108 },
109 {0}, // Reserved
110 0, // SegmentNumber
111 0x0, // ReservedMemoryRegionBaseAddress -- TO BE PATCHED
112 0x0 // ReservedMemoryRegionLimitAddress -- TO BE PATCHED
113 },
114 { // Rmrr11
115 EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT,
116 sizeof(EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER) +
117 sizeof(EFI_ACPI_DMAR_PCI_PATH),
118 0, // Reserved2
119 0, // EnumerationId
120 0 // StartBusNumber
121 },
122 { // Rmrr111
123 2, // Device
124 0 // Function
125 },
126 };
127
128 EFI_PEI_PPI_DESCRIPTOR mPlatformVTdInfoSampleDesc = {
129 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
130 &gEdkiiVTdInfoPpiGuid,
131 &mPlatformVTdSample
132 };
133
134 /**
135 Patch Graphic UMA address in RMRR and base address.
136 **/
137 VOID
138 PatchDmar (
139 VOID
140 )
141 {
142 UINT32 MchBar;
143 UINT16 IgdMode;
144 UINT16 GttMode;
145 UINT32 IgdMemSize;
146 UINT32 GttMemSize;
147
148 ///
149 /// Calculate IGD memsize
150 ///
151 IgdMode = ((PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GMS_MASK) >> N_SKL_SA_GGC_GMS_OFFSET) & 0xFF;
152 if (IgdMode < 0xF0) {
153 IgdMemSize = IgdMode * 32 * (1024) * (1024);
154 } else {
155 IgdMemSize = 4 * (IgdMode - 0xF0 + 1) * (1024) * (1024);
156 }
157
158 ///
159 /// Calculate GTT mem size
160 ///
161 GttMemSize = 0;
162 GttMode = (PciRead16 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_GGC)) & B_SKL_SA_GGC_GGMS_MASK) >> N_SKL_SA_GGC_GGMS_OFFSET;
163 if (GttMode <= V_SKL_SA_GGC_GGMS_8MB) {
164 GttMemSize = (1 << GttMode) * (1024) * (1024);
165 }
166
167 mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress = (PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_TOLUD)) & ~(0x01)) - IgdMemSize - GttMemSize;
168 mPlatformVTdSample.Rmrr1.ReservedMemoryRegionLimitAddress = mPlatformVTdSample.Rmrr1.ReservedMemoryRegionBaseAddress + IgdMemSize + GttMemSize - 1;
169
170 ///
171 /// Update DRHD structures of DmarTable
172 ///
173 MchBar = PciRead32 (PCI_LIB_ADDRESS(0, 0, 0, R_SA_MCHBAR)) & ~BIT0;
174 mPlatformVTdSample.Drhd1.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD1_OFFSET) &~1);
175 mPlatformVTdSample.Drhd2.RegisterBaseAddress = (MmioRead32 (MchBar + R_SA_MCHBAR_VTD2_OFFSET) &~1);
176 }
177
178 /**
179 Platform VTd Info sample driver.
180
181 @param[in] FileHandle Handle of the file being invoked.
182 @param[in] PeiServices Describes the list of possible PEI Services.
183
184 @retval EFI_SUCCESS if it completed successfully.
185 **/
186 EFI_STATUS
187 EFIAPI
188 PlatformVTdInfoSampleInitialize (
189 IN EFI_PEI_FILE_HANDLE FileHandle,
190 IN CONST EFI_PEI_SERVICES **PeiServices
191 )
192 {
193 EFI_STATUS Status;
194
195 PatchDmar ();
196
197 Status = PeiServicesInstallPpi (&mPlatformVTdInfoSampleDesc);
198 ASSERT_EFI_ERROR (Status);
199
200 return Status;
201 }