220 lines
4.1 KiB
C
220 lines
4.1 KiB
C
/*++
|
||
|
||
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
|
||
}
|
||
}
|