Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
ixreboot.c
Abstract:
Provides the interface to the firmware for x86. Since there is no firmware to speak of on x86, this is just reboot support.
Author:
John Vert (jvert) 12-Aug-1991
Revision History:
--*/
//
// This module is compatible with PAE mode and therefore treats physical
// addresses as 64-bit entities.
//
#if !defined(_PHYS64_)
#define _PHYS64_
#endif
#include "halp.h"
#include "pci.h"
#ifdef ACPI_HAL
#include "acpitabl.h"
#include "xxacpi.h"
extern UCHAR HalpPiix4; #endif
//
// Defines to let us diddle the CMOS clock and the keyboard
//
#define CMOS_CTRL (PUCHAR )0x70
#define CMOS_DATA (PUCHAR )0x71
#define RESET 0xfe
#define KEYBPORT (PUCHAR )0x64
//
// Private function prototypes
//
VOID HalpWriteResetCommand( VOID ) /*++
Routine Description:
This procedure issues a reset command to the system to cause a warm boot.
It either uses the ACPI defined reset register or the keyboard controller.
N.B.
Will NOT return.
--*/ {
#ifdef ACPI_HAL
PCI_SLOT_NUMBER slot; PUCHAR ResetAddress;
//
// if the system supports the ACPI specified RESET_REG capability we
// will use that.
//
if ((HalpFixedAcpiDescTable.Header.Revision > 1) && (HalpFixedAcpiDescTable.flags & RESET_CAP) #if !defined(NT_UP)
//
// to be safer on MP systems, we will only use RESET_REG if the
// system is legacy free. On UP systems this is not necessary
// because we've already tested systems with this functionality.
// MP systems have not been tested extensively and we don't want
// false positives where systems are using this functionality and
// failing. in the next major release this change can be removed.
//
&& (!(HalpFixedAcpiDescTable.boot_arch & I8042)) #endif
) {
switch (HalpFixedAcpiDescTable.reset_reg.AddressSpaceID) { case 0: // Memory
ResetAddress = HalpMapPhysicalMemoryWriteThrough(HalpFixedAcpiDescTable.reset_reg.Address, 1); WRITE_REGISTER_UCHAR(ResetAddress, HalpFixedAcpiDescTable.reset_val); break;
case 1: // I/O
WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)HalpFixedAcpiDescTable.reset_reg.Address.LowPart, HalpFixedAcpiDescTable.reset_val); break;
case 2: // PCI Config
slot.u.AsULONG = 0; slot.u.bits.DeviceNumber = HalpFixedAcpiDescTable.reset_reg.Address.HighPart; slot.u.bits.FunctionNumber = HalpFixedAcpiDescTable.reset_reg.Address.LowPart >> 16; HalSetBusDataByOffset(PCIBus, 0, slot.u.AsULONG, &HalpFixedAcpiDescTable.reset_val, HalpFixedAcpiDescTable.reset_reg.Address.LowPart & 0xff, 1); break; } }
#endif
//
// If we return, send the reset command to the keyboard controller
//
WRITE_PORT_UCHAR(KEYBPORT, RESET);
}
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; PHYSICAL_ADDRESS zeroPhysical; //
// By sticking 0x1234 at physical location 0x472, we can bypass the
// memory check after a reboot.
//
zeroPhysical.QuadPart = 0; Magic = HalpMapPhysicalMemoryWriteThrough(zeroPhysical, 1); if (Magic) { Magic[0x472 / sizeof(USHORT)] = 0x1234; }
//
// Turn off interrupts
//
HalpAcquireCmosSpinLock(); HalpDisableInterrupts();
//
// 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();
HalpWriteResetCommand();
HalpHalt(); }
#ifndef ACPI_HAL
VOID HaliHaltSystem ( VOID )
/*++
Routine Description:
This procedure is called when the machine has crashed and is to be halted
N.B.
Will NOT return.
--*/
{ _asm { cli hlt } }
VOID HalpCheckPowerButton ( VOID ) { }
#endif
|