Skip to content

Instantly share code, notes, and snippets.

@173210
Created July 2, 2016 23:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 173210/00d3bb13256a13f886c208e6d6c6d00b to your computer and use it in GitHub Desktop.
Save 173210/00d3bb13256a13f886c208e6d6c6d00b to your computer and use it in GitHub Desktop.
    <register name="IA32_SMRR_PHYSBASE"   type="msr" msr="0x1F2" desc="SMRR Base Address MSR">
      <field name="Type"     bit="0"  size="8"  desc="SMRR memory type" />
      <field name="PhysBase" bit="12" size="20" desc="SMRR physical base address" />
    </register>
    <register name="IA32_SMRR_PHYSMASK"   type="msr" msr="0x1F3" desc="SMRR Range Mask MSR">
      <field name="Valid"    bit="11" size="1"  desc="SMRR valid" />
      <field name="PhysMask" bit="12" size="20" desc="SMRR address range mask" />
    </register>
;------------------------------------------------------------------------------
;  void _rdmsr( 
;    unsigned int msr_num, // rdi
;    unsigned int* msr_lo, // rsi
;    unsigned int* msr_hi  // rdx
;    )
;------------------------------------------------------------------------------
_rdmsr: 
    push r10
    push r11
    push rax
    push rdx


    mov rcx, rdi
    mov r10, rsi ; msr_lo
    mov r11, rdx ; msr_hi

    ; rcx has msr_num
    rdmsr

    ; Write MSR results in edx:eax
    mov [r10], eax

    mov [r11], edx

    pop rdx
    pop rax
    pop r11
    pop r10

    ret
	case IOCTL_RDMSR:
	{
		//IN  params: threadid, msr_addr
		//OUT params: edx, eax
#ifdef CONFIG_X86

		numargs = 4;
		if(copy_from_user((void*)ptrbuf, (void*)ioctl_param, (sizeof(long) * numargs)) > 0)
			return -EFAULT;

		_rdmsr(ptr[1],&ptr[3],&ptr[2]);

		if(copy_to_user((void*)ioctl_param, (void*)ptrbuf, (sizeof(long) * numargs)) > 0)
			return -EFAULT;
		break;
#else
		return -EFAULT;
#endif
	}
    def read_msr(self, thread_id, msr_addr):
        self.set_affinity(thread_id)
        edx = eax = 0
        in_buf = struct.pack( "4"+self._pack, thread_id, msr_addr, edx, eax)
        unbuf = struct.unpack("4"+self._pack, self.ioctl(IOCTL_RDMSR, in_buf))
        return (unbuf[3], unbuf[2])
    def read_msr( self, cpu_thread_id, msr_addr ):
        (eax, edx) = self.helper.read_msr( cpu_thread_id, msr_addr )
        if logger().VERBOSE: logger().log( "[cpu%d] RDMSR( 0x%x ): EAX = 0x%08X, EDX = 0x%08X" % (cpu_thread_id, msr_addr, eax, edx) )
        return (eax, edx)
def read_register( _cs, reg_name, cpu_thread=0 ):
    reg = _cs.Cfg.REGISTERS[ reg_name ]
    rtype = reg['type']
    reg_value = 0
    if RegisterType.PCICFG == rtype:
        b = int(reg['bus'],16)
        d = int(reg['dev'],16)
        f = int(reg['fun'],16)
        o = int(reg['offset'],16)
        size = int(reg['size'],16)
        if   1 == size: reg_value = _cs.pci.read_byte ( b, d, f, o )
        elif 2 == size: reg_value = _cs.pci.read_word ( b, d, f, o )
        elif 4 == size: reg_value = _cs.pci.read_dword( b, d, f, o )
        elif 8 == size: reg_value = (_cs.pci.read_dword( b, d, f, o+4 ) << 32) | _cs.pci.read_dword( b, d, f, o )
    elif RegisterType.MMCFG == rtype:
        reg_value = mmio.read_mmcfg_reg( _cs, int(reg['bus'],16), int(reg['dev'],16), int(reg['fun'],16), int(reg['offset'],16), int(reg['size'],16) )
    elif RegisterType.MMIO == rtype:
        reg_value = mmio.read_MMIO_BAR_reg( _cs, reg['bar'], int(reg['offset'],16), int(reg['size'],16) )
    elif RegisterType.MSR == rtype:
        (eax, edx) = _cs.msr.read_msr( cpu_thread, int(reg['msr'],16) )
        reg_value = (edx << 32) | eax
    elif RegisterType.PORTIO == rtype:
        port = int(reg['port'],16)
        size = int(reg['size'],16)
        reg_value = _cs.io._read_port( port, size )
    elif RegisterType.IOBAR == rtype:
        iobar = chipsec.hal.iobar.iobar( _cs )
        reg_value = iobar.read_IO_BAR_reg( reg['bar'], int(reg['offset'],16), int(reg['size'],16) ) 
    return reg_value
def get_register_def( _cs, reg_name ):
    return _cs.Cfg.REGISTERS[ reg_name ]
def get_register_field( _cs, reg_name, reg_value, field_name, preserve_field_position=False ):
    field_attrs = get_register_def( _cs, reg_name )['FIELDS'][field_name]
    field_bit   = int(field_attrs['bit'])
    field_mask  = (1 << int(field_attrs['size'])) - 1
    if preserve_field_position: return reg_value & (field_mask << field_bit)
    else:                       return (reg_value >> field_bit) & field_mask
def read_register_field( _cs, reg_name, field_name, preserve_field_position=False, cpu_thread=0 ):
    reg_value = read_register( _cs, reg_name )
    return get_register_field( _cs, reg_name, reg_value, field_name, preserve_field_position )
    #
    # Return SMRR MSR physical base and mask
    #
    def get_SMRR( self ):
        smrambase = chipsec.chipset.read_register_field( self.cs, 'IA32_SMRR_PHYSBASE', 'PhysBase', True )
        smrrmask  = chipsec.chipset.read_register_field( self.cs, 'IA32_SMRR_PHYSMASK', 'PhysMask', True )
        return (smrambase, smrrmask)

    #
    # Return SMRAM region base, limit and size as defined by SMRR
    #
    def get_SMRR_SMRAM( self ):
        (smram_base, smrrmask) = self.get_SMRR()
        smram_base &= smrrmask
        smram_size = ((~smrrmask)&0xFFFFFFFF) + 1
        smram_limit = smram_base + smram_size - 1
        return (smram_base, smram_limit, smram_size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment