1 /** @file
2   Execute Disable feature.
3 
4   Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5   SPDX-License-Identifier: BSD-2-Clause-Patent
6 
7 **/
8 
9 #include "CpuCommonFeatures.h"
10 
11 /**
12   Detects if Execute Disable feature supported on current processor.
13 
14   @param[in]  ProcessorNumber  The index of the CPU executing this function.
15   @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
16                                structure for the CPU executing this function.
17   @param[in]  ConfigData       A pointer to the configuration buffer returned
18                                by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
19                                CPU_FEATURE_GET_CONFIG_DATA was not provided in
20                                RegisterCpuFeature().
21 
22   @retval TRUE     Execute Disable feature is supported.
23   @retval FALSE    Execute Disable feature is not supported.
24 
25   @note This service could be called by BSP/APs.
26 **/
27 BOOLEAN
28 EFIAPI
ExecuteDisableSupport(IN UINTN ProcessorNumber,IN REGISTER_CPU_FEATURE_INFORMATION * CpuInfo,IN VOID * ConfigData OPTIONAL)29 ExecuteDisableSupport (
30   IN UINTN                             ProcessorNumber,
31   IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
32   IN VOID                              *ConfigData  OPTIONAL
33   )
34 {
35   UINT32                         Eax;
36   CPUID_EXTENDED_CPU_SIG_EDX     Edx;
37 
38   AsmCpuid (CPUID_EXTENDED_FUNCTION, &Eax, NULL, NULL, NULL);
39   if (Eax <= CPUID_EXTENDED_FUNCTION) {
40     //
41     // Extended CPUID functions are not supported on this processor.
42     //
43     return FALSE;
44   }
45 
46   AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &Edx.Uint32);
47   return (Edx.Bits.NX != 0);
48 }
49 
50 /**
51   Initializes Execute Disable feature to specific state.
52 
53   @param[in]  ProcessorNumber  The index of the CPU executing this function.
54   @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
55                                structure for the CPU executing this function.
56   @param[in]  ConfigData       A pointer to the configuration buffer returned
57                                by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
58                                CPU_FEATURE_GET_CONFIG_DATA was not provided in
59                                RegisterCpuFeature().
60   @param[in]  State            If TRUE, then the Execute Disable feature must be enabled.
61                                If FALSE, then the Execute Disable feature must be disabled.
62 
63   @retval RETURN_SUCCESS       Execute Disable feature is initialized.
64 
65   @note This service could be called by BSP only.
66 **/
67 RETURN_STATUS
68 EFIAPI
ExecuteDisableInitialize(IN UINTN ProcessorNumber,IN REGISTER_CPU_FEATURE_INFORMATION * CpuInfo,IN VOID * ConfigData,OPTIONAL IN BOOLEAN State)69 ExecuteDisableInitialize (
70   IN UINTN                             ProcessorNumber,
71   IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
72   IN VOID                              *ConfigData,  OPTIONAL
73   IN BOOLEAN                           State
74   )
75 {
76   //
77   // The scope of the MSR_IA32_EFER is core for below processor type, only program
78   // MSR_IA32_EFER for thread 0 in each core.
79   //
80   if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {
81     if (CpuInfo->ProcessorInfo.Location.Thread != 0) {
82       return RETURN_SUCCESS;
83     }
84   }
85 
86   CPU_REGISTER_TABLE_WRITE_FIELD (
87     ProcessorNumber,
88     Msr,
89     MSR_IA32_EFER,
90     MSR_IA32_EFER_REGISTER,
91     Bits.NXE,
92     (State) ? 1 : 0
93     );
94   return RETURN_SUCCESS;
95 }
96