blob: 31172977b9d03aa8f39c9960e72443a741bc7321 (
plain) (
tree)
|
|
/*++
Copyright (c) 1992 NCR Corporation
Module Name:
ncrstop.c
Abstract:
Provides the interface to the firmware for x86.
Author:
Richard R. Barton (o-richb) 04-Feb-1992
Revision History:
--*/
#include "halp.h"
#include "ncr.h"
/*
* Some plagarism from ixreboot.c
*/
//
// Defines to let us diddle the CMOS clock and the keyboard
//
#define CMOS_CTRL (PUCHAR )0x70
#define CMOS_DATA (PUCHAR )0x71
// below 2 defines are for 3450/3550 machines
#define SHUT_DOWN 0x8F
#define SHUT5 0x05
#define RESET 0xfe
#define KEYBPORT (PUCHAR )0x64
extern ULONG NCRPlatform;
extern BOOLEAN NCRPowerOffSystem;
//
// Private function prototypes
//
VOID
HalpReboot (
VOID
);
VOID
HalReturnToFirmware(
IN FIRMWARE_ENTRY Routine
)
/*++
Routine Description:
Returns control to the firmware routine specified.
BUGBUG This can probably do useful things (like rebooting) for some
values of Routine.
Arguments:
Routine - Supplies a value indicating which firmware routine to invoke.
Return Value:
Does not return.
--*/
{
switch (Routine) {
case HalPowerDownRoutine:
if (NCRPlatform != NCR3360) {
HalpCatPowerOffSystem();
}
case HalHaltRoutine:
case HalRestartRoutine:
case HalRebootRoutine:
//
// Never returns
//
if ((NCRPlatform != NCR3360) && (NCRPowerOffSystem == TRUE)) {
HalpCatPowerOffSystem();
} else {
HalpVideoReboot();
HalpReboot();
}
break;
default:
DBGMSG(("HalReturnToFirmware called\n"));
DbgBreakPoint();
break;
}
}
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);
//
// for 3450/3550 machines - Set shutdown flag to reset
//
if ((NCRPlatform == NCR3450) || (NCRPlatform == NCR3550)) {
WRITE_PORT_UCHAR(CMOS_CTRL, SHUT_DOWN);
WRITE_PORT_UCHAR(CMOS_DATA, SHUT5);
}
//
// Send the reset command to the keyboard controller
//
WRITE_PORT_UCHAR(KEYBPORT, RESET);
_asm {
hlt
}
}
|