SMM 详解

 当处理器的SMM 中断pin(SMI#) 被激活,或者收到一个从APIC( advanced programmable interrupt controller)发来的SMI,处理器就会进入SMM,

 SMM 模式下的执行程序被称作SMM处理程序,所有的SMM处理程序只能在称作系统管理内存(System Management RAM, SRAM)的空间内运行。

 在SMM中,当保存好当前程序的内容后,CPU会去另外一个地址空间执行程序,SMM相关代码会在后台悄悄的执行。当从SMM返回的时候,CPU回到中断前的状态。

1. SMM Service

      SMM service 是高优先级的system management interrupt(SMI), 在runtime的时候

仍然可接管系统。下面分成三个特性及两个service特点来介绍。 characteristics

1. 在smi的时候, CPU 执行pre-defined starting vector.

2. smm的code放在 SMRAM中,在SMM初始化后会lock 起来。

3 . smi 是由hardware event 或system interrupt所产生的。它可以被侦测,清除或disable.

Services

1. SMM service是一个handers 的list.并且都是DXE foundation service的subset.

 

2. SMM service和DXE foundation services 提供同样的functionality,但不同的是smm locate在smram中。

3. SMI 是由hardware event 或 system interrupt 所产生的。它可以被侦测,清除或disable.

 在UEFI的架构中,SMM Driver是一个独立的driver, efi 会有dispatcher 来负责执行driver,当执行过

程中发现是driver 是smm driver时,这时会调用Kernel的function.将此driver搬到 SMM RAM里面。

SMM driver 可以从entry point 发现与DXE Driver 的不同,SMM的Entry point 会先去Locate一下叫

efi_smm_base_protocol Protocol, 透过此protocol 来知道目前是否在smm mode下,如果不是在

smm mode下的话,程序会先去注册(register), 将这支smm driver的FV地址以及大小register起来,

如此一来系统就会依照这些信息将此smm dirver 搬到smm ram里面去,搬完之后系统产生一次smi,

此时会再进入一次smm driver的entry point.第二次进入entry point 通过 efi_smm_base_protocol.insmm() 就会知道目前是在SMM MODE下,

第二次就要通过efis_smm_base_protocol.registercallback() 注册callback function.等下一次smi触发

时,就可以进入到callback function去执行。

// Procedure:   InSmmFunction
//
// Description: Installs North Bridge SMM Child Dispatcher Handler.
//
// Input:       ImageHandle  - Image handle
//              *SystemTable - Pointer to the system table
//
// Output:      EFI_STATUS
//----------------------------------------------------------------------------
EFI_STATUS InSmmFunction (
    IN EFI_HANDLE           ImageHandle,
    IN EFI_SYSTEM_TABLE     *SystemTable )
{
    EFI_STATUS Status;
    EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
    EFI_SMM_SW_DISPATCH_CONTEXT AcpiS3Context = {SB_SWSMI_ACPI_S3};
    EFI_SMM_SW_DISPATCH_CONTEXT SwContext = {SB_SWSMI};
    EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *pPowerButton;
    EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PowerButtonContext = {PowerButtonEntry};
    EFI_HANDLE Handle;

    Status = pBS->LocateProtocol( &gEfiSmmSwDispatchProtocolGuid,
                                   NULL,
                                   &pSwDispatch );
    if (!EFI_ERROR(Status))
    {
        Status  = pSwDispatch->Register(
                        pSwDispatch,
                        SbS3PatchSmiHandler,
                        &AcpiS3Context,
                        &Handle );

        Status  = pSwDispatch->Register(
                        pSwDispatch,
                        SbSwSmiHandler,
                        &SwContext,
                        &Handle );
    }

    Status = pBS->LocateProtocol( &gEfiSmmPowerButtonDispatchProtocolGuid,
                                   NULL,
                                   &pPowerButton );
    if (!EFI_ERROR(Status))
    {
        Status = pPowerButton->Register(
                        pPowerButton,
                        PowerButtonHandler,
                        &PowerButtonContext,
                        &Handle);
    }

    pBS->InstallMultipleProtocolInterfaces(
                    &ImageHandle,
                    &gAmiSbSmiProtocolGuid,
                    &SbSmiProtocol,
                    NULL);
    ASSERT_EFI_ERROR(Status);

    return EFI_SUCCESS;
}



SMM Q & A


1.如何进入SMM?

当收到SMI(system management interput)的时候,就会进入SMM, SMI 可以下面几种方式触发:

Motherboard hardware or chipset signaling via a designated pin SMI# of the processor chip.[10] This signal can be an independent event.
Software SMI triggered by the system software via an I/O access to a location considered special by the motherboard logic (port 0B2h is common).[11][12]
An I/O write to a location which the firmware has requested that the processor chip act on.

2,smi 产生的时候,是不是所有核都得进 SMM ? 

SMI 产生的时候,现行BIOS 同时进SMM ,是考虑到冲突的问题,写BIOS 的人,觉得这样写比较安全,如果一个处理器A陷入了smm 里面,其他处理器在normal 模式,当处理器A 改变了某个寄存器的值,处于normal 状态的可能会有某个动作去override 这个值.

如果这个SMI是南桥产生的,那么所有核都进SMM, 如果是CPU生成的,他是可以指定具体哪个cpu进smm的(通过APIC ID)。


上面这段话,有争议,skylake 除了smi ipi 是可以指定具体发给那个core, 其他都是broadcast

Various causes of SMI are routed through the system agent and PCH and signaled to
each processor via an SMI message. Other SMIs are generated by a processor. SMIIPIs
can be sent to directed threads, all other SMIs are broadcast to all thread.


发送 INIT IPI  的时候,调用的SendInterrupt ,并且第一个参数为BROADCAST_MODE_ALL_EXCLUDING_SELF  ,字面意思发给其他所有的,除了自己。

  ///
  /// Send INIT IPI - SIPI to all APs
  ///
  SendInterrupt (
    BROADCAST_MODE_ALL_EXCLUDING_SELF,
    0,
    0,
    DELIVERY_MODE_INIT,
    TRIGGER_MODE_EDGE,
    TRUE
    );

第一个参数是 BroadcastMode       即中断广播模式,它有三个取值:

#define BROADCAST_MODE_SPECIFY_CPU            0x00
#define BROADCAST_MODE_ALL_INCLUDING_SELF     0x01
#define BROADCAST_MODE_ALL_EXCLUDING_SELF     0x02


即发给特定的,所有,包括自己,所有,但不包括自己。

其相应的处理方式为:

  switch (BroadcastMode) {
    case BROADCAST_MODE_SPECIFY_CPU:
      if (X2apicEnabled) {
        IcrHigh = (UINT32) ApicID;
      } else {
        IcrHigh = ApicID << 24;
      }
      break;

    case BROADCAST_MODE_ALL_INCLUDING_SELF:
      IcrLow |= 0x80000;
      break;

    case BROADCAST_MODE_ALL_EXCLUDING_SELF:
      IcrLow |= 0xC0000;
      break;

    default:
      return EFI_INVALID_PARAMETER;
  }




3. SMRAM 可以有哪几种状态? 具体是怎么实现的?

可以是lock, close, open,  lock

  mSmmAccess.SmmAccess.Open             = Open;
  mSmmAccess.SmmAccess.Close            = Close;
  mSmmAccess.SmmAccess.Lock             = Lock;
在CPU里面,有个叫System Management RAM Control 的寄存器,负责对SMRAM 这段空间访问权限的设定
<img src="https://img-blog.csdn.net/20150917200316684" alt="" />
</pre><pre class="cpp" name="code">下面以lock 为例。


 277: 将合适的值写到smram这个变量里。

282: 最生写这个这个寄存器里面,完成lock.

对于open, close, 搞法一样,先把相应的值读出来,在正确的bit上填入相应的值,最后将这个变量写到寄存器里面。



3. 产生smi 之后,谁最先进入smm ,即成为smm bsp?

原则就是谁先将手头的事情(原子操作)做完,谁就先进去。


Reference:
Intel®64 and IA-32 Architectures Software Developer’s Manual Volume 3 Chapter 29System Management Mode.
Platform Initialization SpecificationVolume 4: System Management Mode Core Interface .

4. 如何产生一个software SMI
触发一个software SMI 是由这个函数做的:


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值