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