1 /** @file
2   MTRR setting library
3 
4   Copyright (c) 2008 - 2020, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef  _MTRR_LIB_H_
10 #define  _MTRR_LIB_H_
11 
12 //
13 // According to IA32 SDM, MTRRs number and MSR offset are always consistent
14 // for IA32 processor family
15 //
16 
17 //
18 // The semantics of below macro is MAX_MTRR_NUMBER_OF_VARIABLE_MTRR, the real number can be read out from MTRR_CAP register.
19 //
20 #define  MTRR_NUMBER_OF_VARIABLE_MTRR  32
21 //
22 // Firmware need reserve 2 MTRR for OS
23 // Note: It is replaced by PCD PcdCpuNumberOfReservedVariableMtrrs
24 //
25 #define  RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER  2
26 
27 #define  MTRR_NUMBER_OF_FIXED_MTRR      11
28 
29 //
30 // Structure to describe a fixed MTRR
31 //
32 typedef struct {
33   UINT32  Msr;
34   UINT32  BaseAddress;
35   UINT32  Length;
36 } FIXED_MTRR;
37 
38 //
39 // Structure to describe a variable MTRR
40 //
41 typedef struct {
42   UINT64  BaseAddress;
43   UINT64  Length;
44   UINT64  Type;
45   UINT32  Msr;
46   BOOLEAN Valid;
47   BOOLEAN Used;
48 } VARIABLE_MTRR;
49 
50 //
51 // Structure to hold base and mask pair for variable MTRR register
52 //
53 typedef struct _MTRR_VARIABLE_SETTING_ {
54   UINT64    Base;
55   UINT64    Mask;
56 } MTRR_VARIABLE_SETTING;
57 
58 //
59 // Array for variable MTRRs
60 //
61 typedef struct _MTRR_VARIABLE_SETTINGS_ {
62   MTRR_VARIABLE_SETTING   Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
63 } MTRR_VARIABLE_SETTINGS;
64 
65 //
66 // Array for fixed MTRRs
67 //
68 typedef  struct  _MTRR_FIXED_SETTINGS_ {
69   UINT64       Mtrr[MTRR_NUMBER_OF_FIXED_MTRR];
70 } MTRR_FIXED_SETTINGS;
71 
72 //
73 // Structure to hold all MTRRs
74 //
75 typedef struct _MTRR_SETTINGS_ {
76   MTRR_FIXED_SETTINGS       Fixed;
77   MTRR_VARIABLE_SETTINGS    Variables;
78   UINT64                    MtrrDefType;
79 } MTRR_SETTINGS;
80 
81 //
82 // Memory cache types
83 //
84 typedef enum {
85   CacheUncacheable    = 0,
86   CacheWriteCombining = 1,
87   CacheWriteThrough   = 4,
88   CacheWriteProtected = 5,
89   CacheWriteBack      = 6,
90   CacheInvalid        = 7
91 } MTRR_MEMORY_CACHE_TYPE;
92 
93 #define  MTRR_CACHE_UNCACHEABLE      0
94 #define  MTRR_CACHE_WRITE_COMBINING  1
95 #define  MTRR_CACHE_WRITE_THROUGH    4
96 #define  MTRR_CACHE_WRITE_PROTECTED  5
97 #define  MTRR_CACHE_WRITE_BACK       6
98 #define  MTRR_CACHE_INVALID_TYPE     7
99 
100 typedef struct {
101   UINT64                 BaseAddress;
102   UINT64                 Length;
103   MTRR_MEMORY_CACHE_TYPE Type;
104 } MTRR_MEMORY_RANGE;
105 
106 /**
107   Returns the variable MTRR count for the CPU.
108 
109   @return Variable MTRR count
110 
111 **/
112 UINT32
113 EFIAPI
114 GetVariableMtrrCount (
115   VOID
116   );
117 
118 /**
119   Returns the firmware usable variable MTRR count for the CPU.
120 
121   @return Firmware usable variable MTRR count
122 
123 **/
124 UINT32
125 EFIAPI
126 GetFirmwareVariableMtrrCount (
127   VOID
128   );
129 
130 /**
131   This function attempts to set the attributes for a memory range.
132 
133   @param[in]       BaseAddress       The physical address that is the start
134                                      address of a memory region.
135   @param[in]       Length            The size in bytes of the memory region.
136   @param[in]       Attribute         The bit mask of attributes to set for the
137                                      memory region.
138 
139   @retval RETURN_SUCCESS            The attributes were set for the memory
140                                     region.
141   @retval RETURN_INVALID_PARAMETER  Length is zero.
142   @retval RETURN_UNSUPPORTED        The processor does not support one or
143                                     more bytes of the memory resource range
144                                     specified by BaseAddress and Length.
145   @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
146                                     for the memory resource range specified
147                                     by BaseAddress and Length.
148   @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
149                                     range specified by BaseAddress and Length
150                                     cannot be modified.
151   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
152                                     modify the attributes of the memory
153                                     resource range.
154                                     Multiple memory range attributes setting by calling this API multiple
155                                     times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean
156                                     the number of CPU MTRRs are too small to set such memory attributes.
157                                     Pass the multiple memory range attributes to one call of
158                                     MtrrSetMemoryAttributesInMtrrSettings() may succeed.
159   @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.
160                                     Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify
161                                     external scratch buffer.
162 **/
163 RETURN_STATUS
164 EFIAPI
165 MtrrSetMemoryAttribute (
166   IN PHYSICAL_ADDRESS        BaseAddress,
167   IN UINT64                  Length,
168   IN MTRR_MEMORY_CACHE_TYPE  Attribute
169   );
170 
171 
172 /**
173   This function will get the memory cache type of the specific address.
174   This function is mainly for debugging purposes.
175 
176   @param[in]  Address            The specific address
177 
178   @return The memory cache type of the specific address
179 
180 **/
181 MTRR_MEMORY_CACHE_TYPE
182 EFIAPI
183 MtrrGetMemoryAttribute (
184   IN PHYSICAL_ADDRESS   Address
185   );
186 
187 
188 /**
189   This function gets the content in fixed MTRRs
190 
191   @param[out]  FixedSettings      A buffer to hold fixed MTRRs content.
192 
193   @return The pointer of FixedSettings
194 
195 **/
196 MTRR_FIXED_SETTINGS*
197 EFIAPI
198 MtrrGetFixedMtrr (
199   OUT MTRR_FIXED_SETTINGS         *FixedSettings
200   );
201 
202 
203 /**
204   This function gets the content in all MTRRs (variable and fixed)
205 
206   @param[out]  MtrrSetting   A buffer to hold all MTRRs content.
207 
208   @return The pointer of MtrrSetting
209 
210 **/
211 MTRR_SETTINGS *
212 EFIAPI
213 MtrrGetAllMtrrs (
214   OUT MTRR_SETTINGS                *MtrrSetting
215   );
216 
217 
218 /**
219   This function sets all MTRRs (variable and fixed)
220 
221   @param[in]  MtrrSetting   A buffer to hold all MTRRs content.
222 
223   @return The pointer of MtrrSetting
224 
225 **/
226 MTRR_SETTINGS *
227 EFIAPI
228 MtrrSetAllMtrrs (
229   IN MTRR_SETTINGS                *MtrrSetting
230   );
231 
232 
233 /**
234   Get the attribute of variable MTRRs.
235 
236   This function shadows the content of variable MTRRs into
237   an internal array: VariableMtrr
238 
239   @param[in]   MtrrValidBitsMask    The mask for the valid bit of the MTRR
240   @param[in]   MtrrValidAddressMask The valid address mask for MTRR since the base address in
241                                     MTRR must align to 4K, so valid address mask equal to
242                                     MtrrValidBitsMask & 0xfffffffffffff000ULL
243   @param[out]  VariableMtrr         The array to shadow variable MTRRs content
244 
245   @return                       The return value of this parameter indicates the number of
246                                 MTRRs which has been used.
247 **/
248 UINT32
249 EFIAPI
250 MtrrGetMemoryAttributeInVariableMtrr (
251   IN  UINT64                    MtrrValidBitsMask,
252   IN  UINT64                    MtrrValidAddressMask,
253   OUT VARIABLE_MTRR             *VariableMtrr
254   );
255 
256 
257 /**
258   This function prints all MTRRs for debugging.
259 **/
260 VOID
261 EFIAPI
262 MtrrDebugPrintAllMtrrs (
263   VOID
264   );
265 
266 /**
267   Checks if MTRR is supported.
268 
269   @retval TRUE  MTRR is supported.
270   @retval FALSE MTRR is not supported.
271 
272 **/
273 BOOLEAN
274 EFIAPI
275 IsMtrrSupported (
276   VOID
277   );
278 
279 /**
280   Returns the default MTRR cache type for the system.
281 
282   @return  The default MTRR cache type.
283 
284 **/
285 MTRR_MEMORY_CACHE_TYPE
286 EFIAPI
287 MtrrGetDefaultMemoryType (
288   VOID
289   );
290 
291 /**
292   This function attempts to set the attributes into MTRR setting buffer for a memory range.
293 
294   @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
295   @param[in]       BaseAddress  The physical address that is the start address
296                                 of a memory region.
297   @param[in]       Length       The size in bytes of the memory region.
298   @param[in]       Attribute    The bit mask of attributes to set for the
299                                 memory region.
300 
301   @retval RETURN_SUCCESS            The attributes were set for the memory region.
302   @retval RETURN_INVALID_PARAMETER  Length is zero.
303   @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
304                                     memory resource range specified by BaseAddress and Length.
305   @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
306                                     range specified by BaseAddress and Length.
307   @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
308                                     BaseAddress and Length cannot be modified.
309   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
310                                     the memory resource range.
311                                     Multiple memory range attributes setting by calling this API multiple
312                                     times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean
313                                     the number of CPU MTRRs are too small to set such memory attributes.
314                                     Pass the multiple memory range attributes to one call of
315                                     MtrrSetMemoryAttributesInMtrrSettings() may succeed.
316   @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.
317                                     Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify
318                                     external scratch buffer.
319 **/
320 RETURN_STATUS
321 EFIAPI
322 MtrrSetMemoryAttributeInMtrrSettings (
323   IN OUT MTRR_SETTINGS       *MtrrSetting,
324   IN PHYSICAL_ADDRESS        BaseAddress,
325   IN UINT64                  Length,
326   IN MTRR_MEMORY_CACHE_TYPE  Attribute
327   );
328 
329 /**
330   This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges.
331 
332   @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
333   @param[in]       Scratch      A temporary scratch buffer that is used to perform the calculation.
334   @param[in, out]  ScratchSize  Pointer to the size in bytes of the scratch buffer.
335                                 It may be updated to the actual required size when the calculation
336                                 needs more scratch buffer.
337   @param[in]       Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
338                                 When range overlap happens, the last one takes higher priority.
339                                 When the function returns, either all the attributes are set successfully,
340                                 or none of them is set.
341   @param[in]      RangeCount    Count of MTRR_MEMORY_RANGE.
342 
343   @retval RETURN_SUCCESS            The attributes were set for all the memory ranges.
344   @retval RETURN_INVALID_PARAMETER  Length in any range is zero.
345   @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
346                                     memory resource range specified by BaseAddress and Length in any range.
347   @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
348                                     range specified by BaseAddress and Length in any range.
349   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
350                                     the memory resource ranges.
351   @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
352                                     BaseAddress and Length cannot be modified.
353   @retval RETURN_BUFFER_TOO_SMALL   The scratch buffer is too small for MTRR calculation.
354 **/
355 RETURN_STATUS
356 EFIAPI
357 MtrrSetMemoryAttributesInMtrrSettings (
358   IN OUT MTRR_SETTINGS           *MtrrSetting,
359   IN     VOID                    *Scratch,
360   IN OUT UINTN                   *ScratchSize,
361   IN     CONST MTRR_MEMORY_RANGE *Ranges,
362   IN     UINTN                   RangeCount
363   );
364 #endif // _MTRR_LIB_H_
365