1 /** @file
2   Register CPU Features Library to register and manage CPU features.
3 
4   Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #ifndef __REGISTER_CPU_FEATURES_LIB_H__
10 #define __REGISTER_CPU_FEATURES_LIB_H__
11 
12 #include <AcpiCpuData.h>
13 #include <Register/Intel/Cpuid.h>
14 #include <Protocol/MpService.h>
15 
16 ///
17 /// Defines used to identify a CPU feature.  The lower 16-bits are used to
18 /// identify a unique CPU feature and the value represents a bit number in
19 /// a bit mask.  The upper 16-bits are bit mask values that are used as
20 /// modifiers of a CPU feature.  When used in a list, the define value
21 /// CPU_FEATURE_END is used to terminate a list of CPU feature values.
22 /// @{
23 #define CPU_FEATURE_AESNI                           0
24 #define CPU_FEATURE_TURBO_MODE                      1
25 #define CPU_FEATURE_MWAIT                           2
26 #define CPU_FEATURE_ACPI                            3
27 #define CPU_FEATURE_EIST                            4
28 #define CPU_FEATURE_RESERVED_5                      5
29 #define CPU_FEATURE_FASTSTRINGS                     6
30 #define CPU_FEATURE_VMX                             7
31 #define CPU_FEATURE_SMX                             8
32 #define CPU_FEATURE_LMCE                            9
33 #define CPU_FEATURE_LOCK_FEATURE_CONTROL_REGISTER   10
34 #define CPU_FEATURE_LIMIT_CPUID_MAX_VAL             11
35 #define CPU_FEATURE_MCE                             12
36 #define CPU_FEATURE_MCA                             13
37 #define CPU_FEATURE_MCG_CTL                         14
38 #define CPU_FEATURE_PENDING_BREAK                   15
39 #define CPU_FEATURE_C1E                             16
40 #define CPU_FEATURE_C1_AUTO_DEMOTION                17
41 #define CPU_FEATURE_C3_AUTO_DEMOTION                18
42 #define CPU_FEATURE_C1_UNDEMOTION                   19
43 #define CPU_FEATURE_C3_UNDEMOTION                   20
44 #define CPU_FEATURE_C_STATE                         21
45 #define CPU_FEATURE_TM                              22
46 #define CPU_FEATURE_TM2                             23
47 #define CPU_FEATURE_X2APIC                          24
48 #define CPU_FEATURE_RESERVED_25                     25
49 #define CPU_FEATURE_RESERVED_26                     26
50 #define CPU_FEATURE_RESERVED_27                     27
51 #define CPU_FEATURE_RESERVED_28                     28
52 #define CPU_FEATURE_RESERVED_29                     29
53 #define CPU_FEATURE_RESERVED_30                     30
54 #define CPU_FEATURE_RESERVED_31                     31
55 
56 #define CPU_FEATURE_L2_PREFETCHER                   (32+0)
57 #define CPU_FEATURE_L1_DATA_PREFETCHER              (32+1)
58 #define CPU_FEATURE_HARDWARE_PREFETCHER             (32+2)
59 #define CPU_FEATURE_ADJACENT_CACHE_LINE_PREFETCH    (32+3)
60 #define CPU_FEATURE_DCU_PREFETCHER                  (32+4)
61 #define CPU_FEATURE_IP_PREFETCHER                   (32+5)
62 #define CPU_FEATURE_MLC_STREAMER_PREFETCHER         (32+6)
63 #define CPU_FEATURE_MLC_SPATIAL_PREFETCHER          (32+7)
64 #define CPU_FEATURE_THREE_STRIKE_COUNTER            (32+8)
65 #define CPU_FEATURE_APIC_TPR_UPDATE_MESSAGE         (32+9)
66 #define CPU_FEATURE_ENERGY_PERFORMANCE_BIAS         (32+10)
67 #define CPU_FEATURE_PPIN                            (32+11)
68 #define CPU_FEATURE_PROC_TRACE                      (32+12)
69 
70 #define CPU_FEATURE_BEFORE_ALL                      BIT23
71 #define CPU_FEATURE_AFTER_ALL                       BIT24
72 #define CPU_FEATURE_THREAD_BEFORE                   BIT25
73 #define CPU_FEATURE_THREAD_AFTER                    BIT26
74 #define CPU_FEATURE_CORE_BEFORE                     BIT27
75 #define CPU_FEATURE_CORE_AFTER                      BIT28
76 #define CPU_FEATURE_PACKAGE_BEFORE                  BIT29
77 #define CPU_FEATURE_PACKAGE_AFTER                   BIT30
78 #define CPU_FEATURE_END                             MAX_UINT32
79 /// @}
80 
81 ///
82 /// The bit field to indicate whether the processor is the first in its parent scope.
83 ///
84 typedef struct {
85   //
86   // Set to 1 when current processor is the first thread in the core it resides in.
87   //
88   UINT32 Thread   : 1;
89   //
90   // Set to 1 when current processor is a thread of the first core in the module it resides in.
91   //
92   UINT32 Core     : 1;
93   //
94   // Set to 1 when current processor is a thread of the first module in the tile it resides in.
95   //
96   UINT32 Module   : 1;
97   //
98   // Set to 1 when current processor is a thread of the first tile in the die it resides in.
99   //
100   UINT32 Tile     : 1;
101   //
102   // Set to 1 when current processor is a thread of the first die in the package it resides in.
103   //
104   UINT32 Die      : 1;
105   //
106   // Set to 1 when current processor is a thread of the first package in the system.
107   //
108   UINT32 Package  : 1;
109   UINT32 Reserved : 26;
110 } REGISTER_CPU_FEATURE_FIRST_PROCESSOR;
111 
112 ///
113 /// CPU Information passed into the SupportFunc and InitializeFunc of the
114 /// RegisterCpuFeature() library function.  This structure contains information
115 /// that is commonly used during CPU feature detection and initialization.
116 ///
117 typedef struct {
118   ///
119   /// The package that the CPU resides
120   ///
121   EFI_PROCESSOR_INFORMATION            ProcessorInfo;
122 
123   ///
124   /// The bit flag indicating whether the CPU is the first Thread/Core/Module/Tile/Die/Package in its parent scope.
125   ///
126   REGISTER_CPU_FEATURE_FIRST_PROCESSOR First;
127   ///
128   /// The Display Family of the CPU computed from CPUID leaf CPUID_VERSION_INFO
129   ///
130   UINT32                               DisplayFamily;
131   ///
132   /// The Display Model of the CPU computed from CPUID leaf CPUID_VERSION_INFO
133   ///
134   UINT32                               DisplayModel;
135   ///
136   /// The Stepping ID of the CPU computed from CPUID leaf CPUID_VERSION_INFO
137   ///
138   UINT32                               SteppingId;
139   ///
140   /// The Processor Type of the CPU computed from CPUID leaf CPUID_VERSION_INFO
141   ///
142   UINT32                               ProcessorType;
143   ///
144   /// Bit field structured returned in ECX from CPUID leaf CPUID_VERSION_INFO
145   ///
146   CPUID_VERSION_INFO_ECX               CpuIdVersionInfoEcx;
147   ///
148   /// Bit field structured returned in EDX from CPUID leaf CPUID_VERSION_INFO
149   ///
150   CPUID_VERSION_INFO_EDX               CpuIdVersionInfoEdx;
151 } REGISTER_CPU_FEATURE_INFORMATION;
152 
153 /**
154   Determines if a CPU feature is enabled in PcdCpuFeaturesSupport bit mask.
155   If a CPU feature is disabled in PcdCpuFeaturesSupport then all the code/data
156   associated with that feature should be optimized away if compiler
157   optimizations are enabled.
158 
159   @param[in]  Feature  The bit number of the CPU feature to check in the PCD
160                        PcdCpuFeaturesSupport.
161 
162   @retval  TRUE   The CPU feature is set in PcdCpuFeaturesSupport.
163   @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesSupport.
164 
165   @note This service could be called by BSP only.
166 **/
167 BOOLEAN
168 EFIAPI
169 IsCpuFeatureSupported (
170   IN UINT32              Feature
171   );
172 
173 /**
174   Determines if a CPU feature is set in PcdCpuFeaturesSetting bit mask.
175 
176   @param[in]  Feature  The bit number of the CPU feature to check in the PCD
177                        PcdCpuFeaturesSetting.
178 
179   @retval  TRUE   The CPU feature is set in PcdCpuFeaturesSetting.
180   @retval  FALSE  The CPU feature is not set in PcdCpuFeaturesSetting.
181 
182   @note This service could be called by BSP only.
183 **/
184 BOOLEAN
185 EFIAPI
186 IsCpuFeatureInSetting (
187   IN UINT32              Feature
188   );
189 
190 /**
191   Prepares for the data used by CPU feature detection and initialization.
192 
193   @param[in]  NumberOfProcessors  The number of CPUs in the platform.
194 
195   @return  Pointer to a buffer of CPU related configuration data.
196 
197   @note This service could be called by BSP only.
198 **/
199 typedef
200 VOID *
201 (EFIAPI *CPU_FEATURE_GET_CONFIG_DATA)(
202   IN UINTN               NumberOfProcessors
203   );
204 
205 /**
206   Detects if CPU feature supported on current processor.
207 
208   @param[in]  ProcessorNumber  The index of the CPU executing this function.
209   @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
210                                structure for the CPU executing this function.
211   @param[in]  ConfigData       A pointer to the configuration buffer returned
212                                by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
213                                CPU_FEATURE_GET_CONFIG_DATA was not provided in
214                                RegisterCpuFeature().
215 
216   @retval TRUE     CPU feature is supported.
217   @retval FALSE    CPU feature is not supported.
218 
219   @note This service could be called by BSP/APs.
220 **/
221 typedef
222 BOOLEAN
223 (EFIAPI *CPU_FEATURE_SUPPORT)(
224   IN UINTN                             ProcessorNumber,
225   IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
226   IN VOID                              *ConfigData  OPTIONAL
227   );
228 
229 /**
230   Initializes CPU feature to specific state.
231 
232   This service does not initialize hardware and only produces entries in the
233   Register Table for specified processor. Hardware initialization on BSP/APs
234   will be done in CpuFeaturesInitialize().
235 
236   @param[in]  ProcessorNumber  The index of the CPU executing this function.
237   @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
238                                structure for the CPU executing this function.
239   @param[in]  ConfigData       A pointer to the configuration buffer returned
240                                by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
241                                CPU_FEATURE_GET_CONFIG_DATA was not provided in
242                                RegisterCpuFeature().
243   @param[in]  State            If TRUE, then the CPU feature must be enabled.
244                                If FALSE, then the CPU feature must be disabled.
245 
246   @retval RETURN_SUCCESS       CPU feature is initialized.
247 
248   @note This service could be called by BSP only.
249 **/
250 typedef
251 RETURN_STATUS
252 (EFIAPI *CPU_FEATURE_INITIALIZE)(
253   IN UINTN                             ProcessorNumber,
254   IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
255   IN VOID                              *ConfigData,  OPTIONAL
256   IN BOOLEAN                           State
257   );
258 
259 /**
260   Registers a CPU Feature.
261 
262   @param[in]  FeatureName        A Null-terminated Ascii string indicates CPU feature
263                                  name.
264   @param[in]  GetConfigDataFunc  CPU feature get configuration data function.  This
265                                  is an optional parameter that may be NULL.  If NULL,
266                                  then the most recently registered function for the
267                                  CPU feature is used.  If no functions are registered
268                                  for a CPU feature, then the CPU configuration data
269                                  for the registered feature is NULL.
270   @param[in]  SupportFunc        CPU feature support function.  This is an optional
271                                  parameter that may be NULL.  If NULL, then the most
272                                  recently registered function for the CPU feature is
273                                  used. If no functions are registered for a CPU
274                                  feature, then the CPU feature is assumed to be
275                                  supported by all CPUs.
276   @param[in]  InitializeFunc     CPU feature initialize function.  This is an optional
277                                  parameter that may be NULL.  If NULL, then the most
278                                  recently registered function for the CPU feature is
279                                  used. If no functions are registered for a CPU
280                                  feature, then the CPU feature initialization is
281                                  skipped.
282   @param[in]  ...                Variable argument list of UINT32 CPU feature value.
283                                  Values with no modifiers are the features provided
284                                  by the registered functions.
285                                  Values with CPU_FEATURE_BEFORE modifier are features
286                                  that must be initialized after the features provided
287                                  by the registered functions are used.
288                                  Values with CPU_FEATURE_AFTER modifier are features
289                                  that must be initialized before the features provided
290                                  by the registered functions are used.
291                                  The last argument in this variable argument list must
292                                  always be CPU_FEATURE_END.
293 
294   @retval  RETURN_SUCCESS           The CPU feature was successfully registered.
295   @retval  RETURN_OUT_OF_RESOURCES  There are not enough resources to register
296                                     the CPU feature.
297   @retval  RETURN_UNSUPPORTED       Registration of the CPU feature is not
298                                     supported due to a circular dependency between
299                                     BEFORE and AFTER features.
300 
301   @note This service could be called by BSP only.
302 **/
303 RETURN_STATUS
304 EFIAPI
305 RegisterCpuFeature (
306   IN CHAR8                             *FeatureName,       OPTIONAL
307   IN CPU_FEATURE_GET_CONFIG_DATA       GetConfigDataFunc,  OPTIONAL
308   IN CPU_FEATURE_SUPPORT               SupportFunc,        OPTIONAL
309   IN CPU_FEATURE_INITIALIZE            InitializeFunc,     OPTIONAL
310   ...
311   );
312 
313 /**
314   Performs CPU features detection.
315 
316   This service will invoke MP service to check CPU features'
317   capabilities on BSP/APs.
318 
319   @note This service could be called by BSP only.
320 **/
321 VOID
322 EFIAPI
323 CpuFeaturesDetect (
324   VOID
325   );
326 
327 /**
328   Performs CPU features Initialization.
329 
330   This service will invoke MP service to perform CPU features
331   initialization on BSP/APs per user configuration.
332 
333   @note This service could be called by BSP only.
334 **/
335 VOID
336 EFIAPI
337 CpuFeaturesInitialize (
338   VOID
339   );
340 
341 /**
342   Switches to assigned BSP after CPU features initialization.
343 
344   @param[in]  ProcessorNumber  The index of the CPU executing this function.
345 
346   @note This service could be called by BSP only.
347 **/
348 VOID
349 EFIAPI
350 SwitchBspAfterFeaturesInitialize (
351   IN UINTN               ProcessorNumber
352   );
353 
354 /**
355   Adds an entry in specified register table.
356 
357   This function adds an entry in specified register table, with given register type,
358   register index, bit section and value.
359 
360   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
361   @param[in]  RegisterType     Type of the register to program
362   @param[in]  Index            Index of the register to program
363   @param[in]  ValueMask        Mask of bits in register to write
364   @param[in]  Value            Value to write
365 
366   @note This service could be called by BSP only.
367 **/
368 VOID
369 EFIAPI
370 CpuRegisterTableWrite (
371   IN UINTN               ProcessorNumber,
372   IN REGISTER_TYPE       RegisterType,
373   IN UINT64              Index,
374   IN UINT64              ValueMask,
375   IN UINT64              Value
376   );
377 
378 /**
379   Adds an entry in specified register table.
380 
381   This function adds an entry in specified register table, with given register type,
382   register index, bit section and value.
383 
384   Driver will  test the current value before setting new value.
385 
386   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry
387   @param[in]  RegisterType     Type of the register to program
388   @param[in]  Index            Index of the register to program
389   @param[in]  ValueMask        Mask of bits in register to write
390   @param[in]  Value            Value to write
391 
392   @note This service could be called by BSP only.
393 **/
394 VOID
395 EFIAPI
396 CpuRegisterTableTestThenWrite (
397   IN UINTN               ProcessorNumber,
398   IN REGISTER_TYPE       RegisterType,
399   IN UINT64              Index,
400   IN UINT64              ValueMask,
401   IN UINT64              Value
402   );
403 
404 /**
405   Adds an entry in specified Pre-SMM register table.
406 
407   This function adds an entry in specified register table, with given register type,
408   register index, bit section and value.
409 
410   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
411   @param[in]  RegisterType     Type of the register to program
412   @param[in]  Index            Index of the register to program
413   @param[in]  ValueMask        Mask of bits in register to write
414   @param[in]  Value            Value to write
415 
416   @note This service could be called by BSP only.
417 **/
418 VOID
419 EFIAPI
420 PreSmmCpuRegisterTableWrite (
421   IN UINTN               ProcessorNumber,
422   IN REGISTER_TYPE       RegisterType,
423   IN UINT64              Index,
424   IN UINT64              ValueMask,
425   IN UINT64              Value
426   );
427 
428 /**
429   Adds a 32-bit register write entry in specified register table.
430 
431   This macro adds an entry in specified register table, with given register type,
432   register index, and value.
433 
434   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
435   @param[in]  RegisterType     Type of the register to program
436   @param[in]  Index            Index of the register to program
437   @param[in]  Value            Value to write
438 
439   @note This service could be called by BSP only.
440 **/
441 #define CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value)       \
442   do {                                                                                \
443     CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value);  \
444   } while(FALSE);
445 
446 /**
447   Adds a 32-bit register write entry in specified register table.
448 
449   This macro adds an entry in specified register table, with given register type,
450   register index, and value.
451 
452   Driver will  test the current value before setting new value.
453 
454   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
455   @param[in]  RegisterType     Type of the register to program
456   @param[in]  Index            Index of the register to program
457   @param[in]  Value            Value to write
458 
459   @note This service could be called by BSP only.
460 **/
461 #define CPU_REGISTER_TABLE_TEST_THEN_WRITE32(ProcessorNumber, RegisterType, Index, Value)     \
462   do {                                                                                        \
463     CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value);  \
464   } while(FALSE);
465 
466 /**
467   Adds a 64-bit register write entry in specified register table.
468 
469   This macro adds an entry in specified register table, with given register type,
470   register index, and value.
471 
472   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
473   @param[in]  RegisterType     Type of the register to program
474   @param[in]  Index            Index of the register to program
475   @param[in]  Value            Value to write
476 
477   @note This service could be called by BSP only.
478 **/
479 #define CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value)       \
480   do {                                                                                \
481     CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value);  \
482   } while(FALSE);
483 
484 /**
485   Adds a 64-bit register write entry in specified register table.
486 
487   This macro adds an entry in specified register table, with given register type,
488   register index, and value.
489 
490   Driver will  test the current value before setting new value.
491 
492   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
493   @param[in]  RegisterType     Type of the register to program
494   @param[in]  Index            Index of the register to program
495   @param[in]  Value            Value to write
496 
497   @note This service could be called by BSP only.
498 **/
499 #define CPU_REGISTER_TABLE_TEST_THEN_WRITE64(ProcessorNumber, RegisterType, Index, Value)     \
500   do {                                                                                        \
501     CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value);  \
502   } while(FALSE);
503 
504 /**
505   Adds a bit field write entry in specified register table.
506 
507   This macro adds an entry in specified register table, with given register type,
508   register index, bit field section, and value.
509 
510   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
511   @param[in]  RegisterType     Type of the register to program.
512   @param[in]  Index            Index of the register to program.
513   @param[in]  Type             The data type name of a register structure.
514   @param[in]  Field            The bit fiel name in register structure to write.
515   @param[in]  Value            Value to write to the bit field.
516 
517   @note This service could be called by BSP only.
518 **/
519 #define CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \
520   do {                                                                                           \
521     UINT64  ValueMask;                                                                           \
522     ValueMask = MAX_UINT64;                                                                      \
523     ((Type *)(&ValueMask))->Field = 0;                                                           \
524     CpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value);             \
525   } while(FALSE);
526 
527 /**
528   Adds a bit field write entry in specified register table.
529 
530   This macro adds an entry in specified register table, with given register type,
531   register index, bit field section, and value.
532 
533   Driver will  test the current value before setting new value.
534 
535   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
536   @param[in]  RegisterType     Type of the register to program.
537   @param[in]  Index            Index of the register to program.
538   @param[in]  Type             The data type name of a register structure.
539   @param[in]  Field            The bit fiel name in register structure to write.
540   @param[in]  Value            Value to write to the bit field.
541 
542   @note This service could be called by BSP only.
543 **/
544 #define CPU_REGISTER_TABLE_TEST_THEN_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \
545   do {                                                                                                     \
546     UINT64  ValueMask;                                                                                     \
547     ValueMask = MAX_UINT64;                                                                                \
548     ((Type *)(&ValueMask))->Field = 0;                                                                     \
549     CpuRegisterTableTestThenWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value);               \
550   } while(FALSE);
551 
552 /**
553   Adds a 32-bit register write entry in specified register table.
554 
555   This macro adds an entry in specified register table, with given register type,
556   register index, and value.
557 
558   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
559   @param[in]  RegisterType     Type of the register to program
560   @param[in]  Index            Index of the register to program
561   @param[in]  Value            Value to write
562 
563   @note This service could be called by BSP only.
564 **/
565 #define PRE_SMM_CPU_REGISTER_TABLE_WRITE32(ProcessorNumber, RegisterType, Index, Value)    \
566   do {                                                                                     \
567     PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT32, Value); \
568   } while(FALSE);
569 
570 /**
571   Adds a 64-bit register write entry in specified register table.
572 
573   This macro adds an entry in specified register table, with given register type,
574   register index, and value.
575 
576   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
577   @param[in]  RegisterType     Type of the register to program
578   @param[in]  Index            Index of the register to program
579   @param[in]  Value            Value to write
580 
581   @note This service could be called by BSP only.
582 **/
583 #define PRE_SMM_CPU_REGISTER_TABLE_WRITE64(ProcessorNumber, RegisterType, Index, Value)    \
584   do {                                                                                     \
585     PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, MAX_UINT64, Value); \
586   } while(FALSE);
587 
588 /**
589   Adds a bit field write entry in specified register table.
590 
591   This macro adds an entry in specified register table, with given register type,
592   register index, bit field section, and value.
593 
594   @param[in]  ProcessorNumber  The index of the CPU to add a register table entry.
595   @param[in]  RegisterType     Type of the register to program.
596   @param[in]  Index            Index of the register to program.
597   @param[in]  Type             The data type name of a register structure.
598   @param[in]  Field            The bit fiel name in register structure to write.
599   @param[in]  Value            Value to write to the bit field.
600 
601   @note This service could be called by BSP only.
602 **/
603 #define PRE_SMM_CPU_REGISTER_TABLE_WRITE_FIELD(ProcessorNumber, RegisterType, Index, Type, Field, Value) \
604   do {                                                                                                   \
605     UINT64  ValueMask;                                                                                   \
606     ValueMask = MAX_UINT64;                                                                              \
607     ((Type *)(&ValueMask))->Field = 0;                                                                   \
608     PreSmmCpuRegisterTableWrite (ProcessorNumber, RegisterType, Index, ~ValueMask, Value);                \
609   } while(FALSE);
610 
611 #endif
612