bios 关机过程

热启动, 冷启动,关机,这些词相信大家都很熟悉,今天就从BIOS 的角度,说说这三种reset 具体是怎么实现的。


/**
  Reset the system.

  @param ResetType       warm or cold
  @param ResetStatus     possible cause of reset
  @param DataSize        Size of ResetData in bytes
  @param ResetData       Optional Unicode string

**/
VOID
EFIAPI
KbcResetSystem (
  IN EFI_RESET_TYPE   ResetType,
  IN EFI_STATUS       ResetStatus,
  IN UINTN            DataSize,
  IN VOID             *ResetData OPTIONAL
  )
{
  switch (ResetType) {
  case EfiResetWarm:
    ResetWarm ();
    break;
  case EfiResetCold:
    ResetCold ();
    break;
  case EfiResetShutdown:
    ResetShutdown ();
    break;
  default:
    return;
  }

  //
  // Given we should have reset getting here would be bad
  //
  ASSERT (FALSE);
}


热启动的代码就这个样子的:

/**
  Calling this function causes a system-wide initialization. The processors
  are set to their initial state, and pending cycles are not corrupted.

  System reset should not return, if it returns, it means the system does
  not support warm reset.
**/
VOID
EFIAPI
ResetWarm (
  VOID
  )
{
  IoWrite8 (R_PCH_RST_CNT, 0x0);
  IoWrite8 (R_PCH_RST_CNT, 0x4);
}

#define R_PCH_RST_CNT                             0xCF9


所以它的实现就是往IO先填0, 然后填4.

下面看看CF9 具体有哪些作用:



简单解读一下:

第2位: 当这一位由0变为1的时候,它将触发一次hard 或者soft reset. 至于是hard 还是soft 则由第一位决定。



冷启动的代码是这个样子的:

/**
  Calling this function causes a system-wide reset. This sets
  all circuitry within the system to its initial state. This type of reset
  is asynchronous to system operation and operates without regard to
  cycle boundaries.

  System reset should not return, if it returns, it means the system does
  not support cold reset.
**/
VOID
EFIAPI
ResetCold (
  VOID
  )
{
  IoWrite8 (R_PCH_RST_CNT, 0x2);
  IoWrite8 (R_PCH_RST_CNT, 0x6);
}


关机是这样的:

/**
  Calling this function causes the system to enter a power state equivalent
  to the ACPI G2/S5 or G3 states.

  System shutdown should not return, if it returns, it means the system does
  not support shut down reset.
**/
VOID
EFIAPI
ResetShutdown (
  VOID
  )
{
  UINT16  PchPmioBase;
  UINT16  Data16;
  UINT32  Data32;

  //
  // Firstly, ACPI decode must be enabled
  //
  PciOr8 (
    PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PMC, PCI_FUNCTION_NUMBER_PCH_PMC, R_PCH_PMC_ACPI_CNT),
    (UINT8) (B_PCH_PMC_ACPI_CNT_ACPI_EN)
    );

  PchPmioBase = (UINT16) (PciRead16 (PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_PMC, PCI_FUNCTION_NUMBER_PCH_PMC, R_PCH_PMC_ACPI_BASE)) & ~BIT0);

  //
  // Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
  //
  Data16 = 0;
  IoWrite16 (
    (UINTN)(PchPmioBase + R_PCH_ACPI_GPE0_EN_127_96),
    (UINT16)Data16
    );

  //
  // Secondly, PwrSts register must be cleared
  //
  // Write a "1" to bit[8] of power button status register at
  // (PM_BASE + PM1_STS_OFFSET) to clear this bit
  //
  Data16 = B_PCH_ACPI_PM1_STS_PWRBTN;
  IoWrite16 (
    (UINTN)(PchPmioBase + R_PCH_ACPI_PM1_STS),
    (UINT16)Data16
    );

  //
  // Finally, transform system into S5 sleep state
  //
  Data32 = IoRead32 ((UINTN) (PchPmioBase + R_PCH_ACPI_PM1_CNT));

  Data32 = (UINT32) ((Data32 & ~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S5);

  IoWrite32 (
    (UINTN)(PchPmioBase + R_PCH_ACPI_PM1_CNT),
    (UINT32)Data32
    );

  Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN;

  IoWrite32 (
    (UINTN)(PchPmioBase + R_PCH_ACPI_PM1_CNT),
    (UINT32)Data32
    );

  return;
}

这里的关机指的是系统进S5. 

很容易,我们可以找到 R_PCH_ACPI_PM1_CNT 的值:

#define R_PCH_ACPI_PM1_CNT                    0x04

即关机的过程是往pmiobase+04的位置填上相应的值。

这个位置,具体是这样描述的:



即在第12:10 填上111b.



summary:

一言以蔽之, 重启就是往CF9里面填相应的值,关机就是往PMBASE + 04h 填上相应的值。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值