terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
阅读:2700回复:1

有src的xd们,帮忙看看HalReturnToFirmware这个函数怎么实现的?

楼主#
更多 发布于:2005-03-16 10:26
特别是HalRebootRoutine,能帮忙贴上来最好
tiamo
VIP专家组
VIP专家组
  • 注册日期2002-02-26
  • 最后登录2018-01-09
  • 粉丝17
  • 关注4
  • 积分50分
  • 威望142点
  • 贡献值1点
  • 好评度40点
  • 原创分2分
  • 专家分15分
  • 原创先锋奖
  • 社区居民
沙发#
发布于:2005-03-19 18:25
reboot啊

2k以上操作系统
如果不支持acpi的reboot方式
就用键盘上的micro controller的传统方法reboot
否则用acpi的reboot方式了
但是没有这个代码...你跟踪下就知道了

而nt本身不支持acpi
nt的实现就是使用键盘..代码有
#define CMOS_CTRL   (PUCHAR )0x70
#define CMOS_DATA   (PUCHAR )0x71

#define RESET       0xfe
#define KEYBPORT    (PUCHAR )0x64

//
// Private function prototypes
//

VOID
HalpReboot (
    VOID
    );

VOID
HalpReboot (
    VOID
    )

/*++

Routine Description:

    This procedure resets the CMOS clock to the standard timer settings
    so the bios will work, and then issues a reset command to the keyboard
    to cause a warm boot.

    It is very machine dependent, this implementation is intended for
    PC-AT like machines.

    This code copied from the \"old debugger\" sources.

    N.B.

        Will NOT return.

--*/

{
    UCHAR   Scratch;
    PUSHORT   Magic;

    //
    // By sticking 0x1234 at physical location 0x472, we can bypass the
    // memory check after a reboot.
    //

    Magic = HalpMapPhysicalMemory(0, 1);
    Magic[0x472 / sizeof(USHORT)] = 0x1234;

    //
    // Turn off interrupts
    //

    HalpAcquireCmosSpinLock();

    _asm {
        cli
    }

    //
    // Reset the cmos clock to a standard value
    // (We are setting the periodic interrupt control on the MC147818)
    //

    //
    // Disable periodic interrupt
    //

    WRITE_PORT_UCHAR(CMOS_CTRL, 0x0b);      // Set up for control reg B.
    KeStallExecutionProcessor(1);

    Scratch = READ_PORT_UCHAR(CMOS_DATA);
    KeStallExecutionProcessor(1);

    Scratch &= 0xbf;                        // Clear periodic interrupt enable

    WRITE_PORT_UCHAR(CMOS_DATA, Scratch);
    KeStallExecutionProcessor(1);

    //
    // Set \"standard\" divider rate
    //

    WRITE_PORT_UCHAR(CMOS_CTRL, 0x0a);      // Set up for control reg A.
    KeStallExecutionProcessor(1);

    Scratch = READ_PORT_UCHAR(CMOS_DATA);
    KeStallExecutionProcessor(1);

    Scratch &= 0xf0;                        // Clear rate setting
    Scratch |= 6;                           // Set default rate and divider

    WRITE_PORT_UCHAR(CMOS_DATA, Scratch);
    KeStallExecutionProcessor(1);

    //
    // Set a \"neutral\" cmos address to prevent weirdness
    // (Why is this needed? Source this was copied from doesn\'t say)
    //

    WRITE_PORT_UCHAR(CMOS_CTRL, 0x15);
    KeStallExecutionProcessor(1);

    HalpResetAllProcessors();

    //
    // If we return, send the reset command to the keyboard controller
    //

    WRITE_PORT_UCHAR(KEYBPORT, RESET);

    _asm {
        hlt
    }
}
游客

返回顶部