<转载>bios 关机过程

[CSDN BIOS关机过程](https://blog.csdn.net/robinsongsog/article/details/50993333)

热启动, 冷启动,关机,这些词相信大家都很熟悉,今天就从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 填上相应的值。

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/robinsongsog/article/details/50993333

posted @ 2024-08-07 15:26  奋然  阅读(41)  评论(0编辑  收藏  举报