1 /** @file
2   MTRR setting library
3 
4   Copyright (c) 2008 - 2018, 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 will get the raw value in variable MTRRs
190 
191   @param[out]  VariableSettings   A buffer to hold variable MTRRs content.
192 
193   @return The buffer point to MTRR_VARIABLE_SETTINGS in which holds the content of the variable MTRR
194 
195 **/
196 MTRR_VARIABLE_SETTINGS*
197 EFIAPI
198 MtrrGetVariableMtrr (
199   OUT MTRR_VARIABLE_SETTINGS         *VariableSettings
200   );
201 
202 
203 /**
204   This function sets variable MTRRs
205 
206   @param[in]  VariableSettings   A buffer to hold variable MTRRs content.
207 
208   @return The pointer of VariableSettings
209 
210 **/
211 MTRR_VARIABLE_SETTINGS*
212 EFIAPI
213 MtrrSetVariableMtrr (
214   IN MTRR_VARIABLE_SETTINGS         *VariableSettings
215   );
216 
217 
218 /**
219   This function gets the content in fixed MTRRs
220 
221   @param[out]  FixedSettings      A buffer to hold fixed MTRRs content.
222 
223   @return The pointer of FixedSettings
224 
225 **/
226 MTRR_FIXED_SETTINGS*
227 EFIAPI
228 MtrrGetFixedMtrr (
229   OUT MTRR_FIXED_SETTINGS         *FixedSettings
230   );
231 
232 
233 /**
234   This function sets fixed MTRRs
235 
236   @param[in]   FixedSettings      A buffer holding fixed MTRRs content.
237 
238   @return  The pointer of FixedSettings
239 
240 **/
241 MTRR_FIXED_SETTINGS*
242 EFIAPI
243 MtrrSetFixedMtrr (
244   IN MTRR_FIXED_SETTINGS          *FixedSettings
245   );
246 
247 
248 /**
249   This function gets the content in all MTRRs (variable and fixed)
250 
251   @param[out]  MtrrSetting   A buffer to hold all MTRRs content.
252 
253   @return The pointer of MtrrSetting
254 
255 **/
256 MTRR_SETTINGS *
257 EFIAPI
258 MtrrGetAllMtrrs (
259   OUT MTRR_SETTINGS                *MtrrSetting
260   );
261 
262 
263 /**
264   This function sets all MTRRs (variable and fixed)
265 
266   @param[in]  MtrrSetting   A buffer to hold all MTRRs content.
267 
268   @return The pointer of MtrrSetting
269 
270 **/
271 MTRR_SETTINGS *
272 EFIAPI
273 MtrrSetAllMtrrs (
274   IN MTRR_SETTINGS                *MtrrSetting
275   );
276 
277 
278 /**
279   Get the attribute of variable MTRRs.
280 
281   This function shadows the content of variable MTRRs into
282   an internal array: VariableMtrr
283 
284   @param[in]   MtrrValidBitsMask    The mask for the valid bit of the MTRR
285   @param[in]   MtrrValidAddressMask The valid address mask for MTRR since the base address in
286                                     MTRR must align to 4K, so valid address mask equal to
287                                     MtrrValidBitsMask & 0xfffffffffffff000ULL
288   @param[out]  VariableMtrr         The array to shadow variable MTRRs content
289 
290   @return                       The return value of this parameter indicates the number of
291                                 MTRRs which has been used.
292 **/
293 UINT32
294 EFIAPI
295 MtrrGetMemoryAttributeInVariableMtrr (
296   IN  UINT64                    MtrrValidBitsMask,
297   IN  UINT64                    MtrrValidAddressMask,
298   OUT VARIABLE_MTRR             *VariableMtrr
299   );
300 
301 
302 /**
303   This function prints all MTRRs for debugging.
304 **/
305 VOID
306 EFIAPI
307 MtrrDebugPrintAllMtrrs (
308   VOID
309   );
310 
311 /**
312   Checks if MTRR is supported.
313 
314   @retval TRUE  MTRR is supported.
315   @retval FALSE MTRR is not supported.
316 
317 **/
318 BOOLEAN
319 EFIAPI
320 IsMtrrSupported (
321   VOID
322   );
323 
324 /**
325   Returns the default MTRR cache type for the system.
326 
327   @return  The default MTRR cache type.
328 
329 **/
330 MTRR_MEMORY_CACHE_TYPE
331 EFIAPI
332 MtrrGetDefaultMemoryType (
333   VOID
334   );
335 
336 /**
337   This function attempts to set the attributes into MTRR setting buffer for a memory range.
338 
339   @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
340   @param[in]       BaseAddress  The physical address that is the start address
341                                 of a memory region.
342   @param[in]       Length       The size in bytes of the memory region.
343   @param[in]       Attribute    The bit mask of attributes to set for the
344                                 memory region.
345 
346   @retval RETURN_SUCCESS            The attributes were set for the memory region.
347   @retval RETURN_INVALID_PARAMETER  Length is zero.
348   @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
349                                     memory resource range specified by BaseAddress and Length.
350   @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
351                                     range specified by BaseAddress and Length.
352   @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
353                                     BaseAddress and Length cannot be modified.
354   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
355                                     the memory resource range.
356                                     Multiple memory range attributes setting by calling this API multiple
357                                     times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean
358                                     the number of CPU MTRRs are too small to set such memory attributes.
359                                     Pass the multiple memory range attributes to one call of
360                                     MtrrSetMemoryAttributesInMtrrSettings() may succeed.
361   @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.
362                                     Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify
363                                     external scratch buffer.
364 **/
365 RETURN_STATUS
366 EFIAPI
367 MtrrSetMemoryAttributeInMtrrSettings (
368   IN OUT MTRR_SETTINGS       *MtrrSetting,
369   IN PHYSICAL_ADDRESS        BaseAddress,
370   IN UINT64                  Length,
371   IN MTRR_MEMORY_CACHE_TYPE  Attribute
372   );
373 
374 /**
375   This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges.
376 
377   @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
378   @param[in]       Scratch      A temporary scratch buffer that is used to perform the calculation.
379   @param[in, out]  ScratchSize  Pointer to the size in bytes of the scratch buffer.
380                                 It may be updated to the actual required size when the calculation
381                                 needs more scratch buffer.
382   @param[in]       Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
383                                 When range overlap happens, the last one takes higher priority.
384                                 When the function returns, either all the attributes are set successfully,
385                                 or none of them is set.
386   @param[in]      RangeCount    Count of MTRR_MEMORY_RANGE.
387 
388   @retval RETURN_SUCCESS            The attributes were set for all the memory ranges.
389   @retval RETURN_INVALID_PARAMETER  Length in any range is zero.
390   @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
391                                     memory resource range specified by BaseAddress and Length in any range.
392   @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
393                                     range specified by BaseAddress and Length in any range.
394   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
395                                     the memory resource ranges.
396   @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
397                                     BaseAddress and Length cannot be modified.
398   @retval RETURN_BUFFER_TOO_SMALL   The scratch buffer is too small for MTRR calculation.
399 **/
400 RETURN_STATUS
401 EFIAPI
402 MtrrSetMemoryAttributesInMtrrSettings (
403   IN OUT MTRR_SETTINGS           *MtrrSetting,
404   IN     VOID                    *Scratch,
405   IN OUT UINTN                   *ScratchSize,
406   IN     CONST MTRR_MEMORY_RANGE *Ranges,
407   IN     UINTN                   RangeCount
408   );
409 #endif // _MTRR_LIB_H_
410