当前位置: 代码迷 >> 综合 >> bios 关机过程
  详细解决方案

bios 关机过程

热度:35   发布时间:2023-12-14 22:37:09.0

热启动, 冷启动,关机,这些词相信大家都很熟悉,今天就从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 processorsare set to their initial state, and pending cycles are not corrupted.System reset should not return, if it returns, it means the system doesnot 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 setsall circuitry within the system to its initial state. This type of resetis asynchronous to system operation and operates without regard tocycle boundaries.System reset should not return, if it returns, it means the system doesnot 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 equivalentto the ACPI G2/S5 or G3 states.System shutdown should not return, if it returns, it means the system doesnot 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 填上相应的值。