github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/cpvmm/vmm/include/hw/hw_utils.h (about)

     1  /*
     2   * Copyright (c) 2013 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *     http://www.apache.org/licenses/LICENSE-2.0
     8   * Unless required by applicable law or agreed to in writing, software
     9   * distributed under the License is distributed on an "AS IS" BASIS,
    10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11   * See the License for the specific language governing permissions and
    12   * limitations under the License.
    13   */
    14  
    15  #ifndef _HW_UTILS_H_
    16  #define _HW_UTILS_H_
    17  
    18  #include "vmm_defs.h"
    19  #include "gdt.h"
    20  
    21  BOOLEAN hw_rdmsr_safe(UINT32 msr_id, UINT64 *value, VECTOR_ID *fault_vector, UINT32 *error_code);
    22  BOOLEAN hw_wrmsr_safe(UINT32 msr_id, UINT64 value, VECTOR_ID *fault_vector, UINT32 *error_code);
    23  
    24  #ifdef __GNUC__
    25  
    26  UINT8 hw_read_port_8( UINT16 port );
    27  UINT16 hw_read_port_16( UINT16 port );
    28  UINT32 hw_read_port_32( UINT16 port );
    29  void hw_write_port_8( UINT16 port, UINT8 val8 );
    30  void hw_write_port_16( UINT16 port, UINT16 val16 );
    31  void hw_write_port_32( UINT16 port, UINT32 val32 );
    32  
    33  void hw_lidt(void *Source);
    34  void hw_sidt(void *Destination);
    35  void hw_write_msr( UINT32 msr_id, UINT64 Value );
    36  UINT64 hw_read_msr( UINT32 msr_id );
    37  
    38  // find first bit set
    39  //  forward: LSB->MSB
    40  //  backward: MSB->LSB
    41  // Return 0 if no bits set
    42  // Fills "bit_number" with the set bit position zero based
    43  // BOOLEAN hw_scan_bit_forward( UINT32& bit_number, UINT32 bitset );
    44  // BOOLEAN hw_scan_bit_backward( UINT32& bit_number, UINT32 bitset );
    45  // BOOLEAN hw_scan_bit_forward64( UINT32& bit_number, UINT64 bitset );
    46  // BOOLEAN hw_scan_bit_backward64( UINT32& bit_number, UINT64 bitset );
    47  
    48  BOOLEAN hw_scan_bit_forward( UINT32 *bit_number_ptr, UINT32 bitset );
    49  BOOLEAN hw_scan_bit_backward( UINT32 *bit_number_ptr, UINT32 bitset );
    50  BOOLEAN hw_scan_bit_forward64( UINT32 *bit_number_ptr, UINT64 bitset );
    51  BOOLEAN hw_scan_bit_backward64( UINT32 *bit_number_ptr, UINT64 bitset );
    52  
    53  UINT64 hw_rdtsc(void);
    54  UINT64 hw_read_cr0(void);
    55  UINT64 hw_read_cr2(void);
    56  UINT64 hw_read_cr3(void);
    57  UINT64 hw_read_cr4(void);
    58  UINT64 hw_read_cr8(void);
    59  void   hw_write_cr0(UINT64 Data);
    60  void   hw_write_cr3(UINT64 Data);
    61  void   hw_write_cr4(UINT64 Data);
    62  void   hw_write_cr8(UINT64 Data);
    63  
    64  UINT64 hw_read_dr0(void);
    65  UINT64 hw_read_dr1(void);
    66  UINT64 hw_read_dr2(void);
    67  UINT64 hw_read_dr3(void);
    68  UINT64 hw_read_dr4(void);
    69  UINT64 hw_read_dr5(void);
    70  UINT64 hw_read_dr6(void);
    71  UINT64 hw_read_dr7(void);
    72  
    73  void hw_write_dr0(UINT64 value);
    74  void hw_write_dr1(UINT64 value);
    75  void hw_write_dr2(UINT64 value);
    76  void hw_write_dr3(UINT64 value);
    77  void hw_write_dr4(UINT64 value);
    78  void hw_write_dr5(UINT64 value);
    79  void hw_write_dr6(UINT64 value);
    80  void hw_write_dr7(UINT64 value);
    81  #define hw_read_dr(__dbg_reg) hw_read_dr##__dbg_reg()
    82  #define hw_write_dr(__dbg_reg, __value) hw_write_dr##__dbg_reg(__value)
    83  
    84  void hw_invlpg(void *address);
    85  void hw_wbinvd(void);
    86  void hw_halt( void );
    87  
    88  #else
    89  
    90  extern unsigned char __inbyte( unsigned short Port );
    91  extern unsigned short _inpw( unsigned short port );
    92  extern unsigned long _inpd( unsigned short port );
    93  extern void __outbyte( unsigned short Port, unsigned char Data );
    94  extern unsigned short _outpw( unsigned short port, unsigned short dataword );
    95  extern unsigned long _outpd( unsigned short port, unsigned long dataword );
    96  extern void __lidt(void *Source);
    97  extern void __sidt(void *Destination);
    98  extern void __writemsr( unsigned long Register, unsigned __int64 Value );
    99  extern unsigned __int64 __readmsr( int msr_id );
   100  extern unsigned char _BitScanForward( unsigned long * Index, unsigned long Mask );
   101  extern unsigned char _BitScanReverse( unsigned long * Index, unsigned long Mask );
   102  extern unsigned char _BitScanForward64( unsigned long * Index, unsigned __int64 Mask );
   103  extern unsigned char _BitScanReverse64( unsigned long * Index, unsigned __int64 Mask );
   104  extern unsigned __int64 __rdtsc(void);
   105  extern unsigned __int64 __readcr0(void);
   106  extern unsigned __int64 __readcr2(void);
   107  extern unsigned __int64 __readcr3(void);
   108  extern unsigned __int64 __readcr4(void);
   109  extern unsigned __int64 __readcr8(void);
   110  extern void __writecr0(unsigned __int64 Data);
   111  extern void __writecr3(unsigned __int64 Data);
   112  extern void __writecr4(unsigned __int64 Data);
   113  extern void __writecr8(unsigned __int64 Data);
   114  extern unsigned __int64 __readdr(unsigned int DebugRegister);
   115  extern void __writedr(unsigned DebugRegister, unsigned __int64 DebugValue);
   116  extern void __invlpg(void* Address);
   117  extern void __wbinvd(void);
   118  extern void __halt( void );
   119  
   120  #define hw_read_port_8( port )  (UINT8)__inbyte( (unsigned short)(port))
   121  #define hw_read_port_16( port )  (UINT16)_inpw( (unsigned short)(port))
   122  #define hw_read_port_32( port )  (UINT32)_inpd( (unsigned short)(port))
   123  #define hw_write_port_8( port, data )  __outbyte( (unsigned short)(port),       \
   124                                                    (unsigned char)(data))
   125  #define hw_write_port_16( port, data )  _outpw( (unsigned short)(port),       \
   126                                                  (unsigned short)(data))
   127  #define hw_write_port_32( port, data )  _outpd( (unsigned short)(port),\
   128                                                  (unsigned long)(data))
   129  
   130  #define hw_lidt( _idtr ) __lidt( _idtr )
   131  #define hw_sidt( _idtr ) __sidt( _idtr )
   132  
   133  #define hw_read_msr( _register )           __readmsr( _register )
   134  #define hw_write_msr( _register, _value )   __writemsr( _register, _value )
   135  
   136  #define hw_scan_bit_forward( _bit_number_ptr, _bitset )                         \
   137                             (UINT8)_BitScanForward( (unsigned long *) _bit_number_ptr, _bitset )
   138  #define hw_scan_bit_backward( _bit_number_ptr, _bitset )                        \
   139                             (UINT8)_BitScanReverse( (unsigned long *) _bit_number_ptr, _bitset )
   140  
   141  #define hw_scan_bit_forward64( _bit_number_ptr, _bitset )                       \
   142                             (UINT8)_BitScanForward64( (unsigned long *) _bit_number_ptr, _bitset )
   143  #define hw_scan_bit_backward64( _bit_number_ptr, _bitset )                      \
   144                             (UINT8)_BitScanReverse64( (unsigned long *) _bit_number_ptr, _bitset )
   145  
   146  #define hw_rdtsc() __rdtsc()
   147  #define hw_read_cr0()           __readcr0()
   148  #define hw_write_cr0( _value )  __writecr0( _value )
   149  #define hw_read_cr2()           __readcr2()
   150  #define hw_read_cr3()           __readcr3()
   151  #define hw_write_cr3( _value )  __writecr3( _value )
   152  #define hw_read_cr4()           __readcr4()
   153  #define hw_write_cr4( _value )  __writecr4( _value )
   154  #define hw_read_cr8()           __readcr8()
   155  #define hw_write_cr8( _value )  __writecr8( _value )
   156  #define hw_read_dr( _index )            __readdr( _index )
   157  #define hw_write_dr( _index, _value )   __writedr( _index, _value )
   158  #define hw_invlpg(addr) __invlpg((void*)addr)
   159  #define hw_wbinvd() __wbinvd()
   160  #define hw_halt() __halt()
   161  
   162  #endif // ! __GNUC__
   163  
   164  
   165  typedef struct {
   166      UINT64   m_rax;
   167      UINT64   m_rbx;
   168      UINT64   m_rcx;
   169      UINT64   m_rdx;
   170  } PACKED CPUID_PARAMS;
   171  
   172  void hw_cpuid(CPUID_PARAMS *);
   173  
   174  typedef struct _CPUID_INFO_STRUCT {
   175      int data[4];
   176  } CPUID_INFO_STRUCT;
   177  
   178  
   179  // CPUID leaf and ext leaf definitions
   180  #define CPUID_LEAF_1H       0x1
   181  #define CPUID_LEAF_3H       0x3
   182  #define CPUID_LEAF_7H       0x7
   183  
   184  #define CPUID_SUB_LEAF_0H   0x0  //sub leaf input ECX = 0
   185  
   186  #define CPUID_EXT_LEAF_1H   0x80000001
   187  #define CPUID_EXT_LEAF_2H   0x80000002
   188  
   189  
   190  // CPUID bit support for h/w features
   191  #define CPUID_LEAF_1H_ECX_VMX_SUPPORT        5  // ecx bit 5 for VMX 
   192  #define CPUID_LEAF_1H_ECX_SMX_SUPPORT        6  // ecx bit 6 for SMX
   193  #define CPUID_LEAF_1H_ECX_PCID_SUPPORT       17 // ecx bit 17 for PCID (CR4.PCIDE)
   194  
   195  #define CPUID_EXT_LEAF_1H_EDX_SYSCALL_SYSRET 11 // edx bit 11 for syscall/ret
   196  #define CPUID_EXT_LEAF_1H_EDX_RDTSCP_BIT     27 // edx bit 27 for rdtscp
   197  
   198  // ebx bit 10 for INVPCID (INPUT leaf EAX=07H, ECX=0H)
   199  #define CPUID_LEAF_7H_0H_EBX_INVPCID_BIT     10 
   200  
   201  // ebx bit 0 for supporting RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE
   202  #define CPUID_LEAF_7H_0H_EBX_FSGSBASE_BIT     0
   203  
   204  #define CPUID_VALUE_EAX( cpuid_info ) ((UINT32)((cpuid_info).data[0]))
   205  #define CPUID_VALUE_EBX( cpuid_info ) ((UINT32)((cpuid_info).data[1]))
   206  #define CPUID_VALUE_ECX( cpuid_info ) ((UINT32)((cpuid_info).data[2]))
   207  #define CPUID_VALUE_EDX( cpuid_info ) ((UINT32)((cpuid_info).data[3]))
   208  
   209  #define cpuid( p_cpuid_info, type )                                            \
   210  {                                                                              \
   211      CPUID_PARAMS __cpuid_params;                                               \
   212      __cpuid_params.m_rax = type;                                               \
   213      hw_cpuid(&__cpuid_params);                                                 \
   214                                                                                 \
   215      (p_cpuid_info)->data[0] = (UINT32)__cpuid_params.m_rax;                      \
   216      (p_cpuid_info)->data[1] = (UINT32)__cpuid_params.m_rbx;                      \
   217      (p_cpuid_info)->data[2] = (UINT32)__cpuid_params.m_rcx;                      \
   218      (p_cpuid_info)->data[3] = (UINT32)__cpuid_params.m_rdx;                      \
   219  }
   220  
   221  INLINE UINT32 hw_read_address_size(void)
   222  {
   223      CPUID_INFO_STRUCT cpu_info;
   224      cpuid(&cpu_info, 0x80000008);
   225      return CPUID_VALUE_EAX(cpu_info);
   226  }
   227  
   228  INLINE BOOLEAN is_rdtscp_supported(void)
   229  {
   230      CPUID_PARAMS cpuid_params = {0,0,0,0};
   231      cpuid_params.m_rax = CPUID_EXT_LEAF_1H; 
   232      hw_cpuid(&cpuid_params);  
   233      return BIT_GET64( cpuid_params.m_rdx, CPUID_EXT_LEAF_1H_EDX_RDTSCP_BIT)? TRUE:FALSE;
   234  }
   235  
   236  
   237  INLINE BOOLEAN is_invpcid_supported(void)
   238  {
   239      CPUID_PARAMS cpuid_params = {0,0,0,0};
   240      cpuid_params.m_rax = CPUID_LEAF_7H; 
   241      cpuid_params.m_rcx = CPUID_SUB_LEAF_0H; 
   242      hw_cpuid(&cpuid_params);  
   243      return BIT_GET64(cpuid_params.m_rbx, CPUID_LEAF_7H_0H_EBX_INVPCID_BIT)? 
   244                       TRUE:FALSE;
   245  }
   246  
   247  INLINE BOOLEAN is_fsgsbase_supported(void)
   248  {
   249      CPUID_PARAMS cpuid_params = {0,0,0,0};
   250      cpuid_params.m_rax = CPUID_LEAF_7H; 
   251      cpuid_params.m_rcx = CPUID_SUB_LEAF_0H; 
   252      hw_cpuid(&cpuid_params);  
   253      return BIT_GET64(cpuid_params.m_rbx, CPUID_LEAF_7H_0H_EBX_FSGSBASE_BIT)? 
   254                TRUE:FALSE;
   255  }
   256  
   257  
   258  INLINE BOOLEAN is_pcid_supported(void)
   259  {
   260      CPUID_PARAMS cpuid_params = {0,0,0,0};
   261      cpuid_params.m_rax = CPUID_LEAF_1H; 
   262      hw_cpuid(&cpuid_params);  
   263      return BIT_GET64( cpuid_params.m_rcx, CPUID_LEAF_1H_ECX_PCID_SUPPORT)? TRUE:FALSE;
   264  }
   265  
   266  void    hw_perform_asm_iret(void);
   267  void    hw_lgdt(void * gdtr);
   268  void    hw_sgdt(void * gdtr);
   269  UINT16  hw_read_cs(void);
   270  void    hw_write_cs(UINT16);
   271  UINT16  hw_read_ds(void);
   272  void    hw_write_ds(UINT16);
   273  UINT16  hw_read_es(void);
   274  void    hw_write_es(UINT16);
   275  UINT16  hw_read_ss(void);
   276  void    hw_write_ss(UINT16);
   277  UINT16  hw_read_fs(void);
   278  void    hw_write_fs(UINT16);
   279  UINT16   hw_read_gs(void);
   280  void     hw_write_gs(UINT16);
   281  UINT16   hw_read_tr(void);
   282  void     hw_write_tr(UINT16);
   283  UINT16   hw_read_ldtr(void);
   284  void     hw_write_ldtr(UINT16);
   285  
   286  typedef void (*main_continue_fn)(void* params);
   287  void hw_set_stack_pointer(HVA new_stack_pointer,
   288                            main_continue_fn func, void* params);
   289  UINT64 hw_read_rsp(void);
   290  void hw_cpuid(CPUID_PARAMS *);
   291  void hw_write_cr2( UINT64 value );
   292  
   293  
   294  #define hw_flash_tlb()      hw_write_cr3(hw_read_cr3())
   295  
   296  void hw_reset_platform(void);
   297  void hw_stall(UINT32 stall_usec);
   298  void hw_calibrate_tsc_ticks_per_second(void);
   299  UINT64 hw_get_tsc_ticks_per_second(void);
   300  void hw_stall_using_tsc(UINT32 stall_usec);
   301  
   302  
   303  // Test for ready-to-be-accepted fixed interrupts.
   304  BOOLEAN hw_is_ready_interrupt_exist(void);
   305  
   306  void hw_write_to_smi_port(
   307      UINT64 * p_rax,     // rcx
   308      UINT64 * p_rbx,     // rdx
   309      UINT64 * p_rcx,     // r8
   310      UINT64 * p_rdx,     // r9
   311      UINT64 * p_rsi,     // on the stack
   312      UINT64 * p_rdi,     // on the stack
   313      UINT64 * p_rflags); // on the stack
   314  void hw_enable_interrupts(void);
   315  void hw_disable_interrupts(void);
   316  void hw_fxsave( void* buffer );
   317  void hw_fxrestore( void* buffer );
   318  
   319  INLINE UINT32 hw_read_memory_mapped_register(ADDRESS base, ADDRESS offset)
   320  {
   321      return *((volatile UINT32 *) (base + offset));
   322  }
   323  
   324  INLINE UINT32 hw_write_memory_mapped_register(ADDRESS base, ADDRESS offset, UINT32 value)
   325  {
   326      return *((volatile UINT32 *) (base + offset)) = value;
   327  }
   328  
   329  INLINE UINT64 hw_read_memory_mapped_register64(ADDRESS base, ADDRESS offset)
   330  {
   331      return *((volatile UINT64 *) (base + offset));
   332  }
   333  
   334  INLINE UINT64 hw_write_memory_mapped_register64(ADDRESS base, ADDRESS offset, UINT64 value)
   335  {
   336      return *((volatile UINT64 *) (base + offset)) = value;
   337  }
   338  
   339  #endif // _HW_UTILS_H_
   340