- Add some more descriptive comments to HalpReboot (and rename it from HalReboot) since some of the operations lacked comments.

- Stall the CPU after each I/O command to simulate I/O delay.
- Flush write buffers before rebooting.
- Refactor sending the reset command since it's not always a matter of using the keyboard port.
- HalReturnToFirmware does a HalpReboot no matter what parameter is sent.

svn path=/trunk/; revision=24741
This commit is contained in:
Alex Ionescu 2006-11-13 04:33:45 +00:00
parent 0e8c70ba22
commit 30c16d9652

View file

@ -1,70 +1,98 @@
/* $Id$ /*
* * PROJECT: ReactOS HAL
* COPYRIGHT: See COPYING in the top level directory * LICENSE: GPL - See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/reboot.c * FILE: ntoskrnl/hal/x86/reboot.c
* PURPOSE: Reboot functions. * PURPOSE: Reboot functions
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* UPDATE HISTORY: * Eric Kohl (ekohl@abo.rhein-zeitung.de)
* Created 11/10/99
*/ */
/* INCLUDES ******************************************************************/
#include <hal.h> #include <hal.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
static VOID VOID
HalReboot (VOID) NTAPI
HalpWriteResetCommand(VOID)
{ {
char data; /* Generate RESET signal via keyboard controller */
WRITE_PORT_UCHAR((PUCHAR)0x64, 0xFE);
};
VOID
NTAPI
HalpReboot(VOID)
{
UCHAR Data;
extern PVOID HalpZeroPageMapping; extern PVOID HalpZeroPageMapping;
/* enable warm reboot */ /* Enable warm reboot */
((PUCHAR)HalpZeroPageMapping)[0x472] = 0x34; ((PUSHORT)HalpZeroPageMapping)[0x472] = 0x1234;
((PUCHAR)HalpZeroPageMapping)[0x473] = 0x12;
/* disable interrupts */ /* FIXME: Lock CMOS Access */
Ki386DisableInterrupts();
/* Disable interrupts */
_disable();
/* disable periodic interrupt (RTC) */ /* Setup control register B */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0b); WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0B);
data = READ_PORT_UCHAR((PUCHAR)0x71); KeStallExecutionProcessor(1);
WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)(data & 0xbf));
/* */ /* Read periodic register and clear the interrupt enable */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0a); Data = READ_PORT_UCHAR((PUCHAR)0x71);
data = READ_PORT_UCHAR((PUCHAR)0x71); WRITE_PORT_UCHAR((PUCHAR)0x71, Data & 0xBF);
WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)((data & 0xf0) | 0x06)); KeStallExecutionProcessor(1);
/* */ /* Setup control register A */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0A);
KeStallExecutionProcessor(1);
/* Read divider rate and reset it */
Data = READ_PORT_UCHAR((PUCHAR)0x71);
WRITE_PORT_UCHAR((PUCHAR)0x71, (Data & 0xF0) | 0x06);
KeStallExecutionProcessor(1);
/* Reset neutral CMOS address */
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15); WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
KeStallExecutionProcessor(1);
/* generate RESET signal via keyboard controller */ /* Flush write buffers and send the reset command */
WRITE_PORT_UCHAR((PUCHAR)0x64, 0xfe); KeFlushWriteBuffer();
HalpWriteResetCommand();
/* stop the processor */ /* Halt the CPU */
#if 1
Ki386HaltProcessor(); Ki386HaltProcessor();
for(;;);
#endif
} }
/* PUBLIC FUNCTIONS **********************************************************/
VOID STDCALL /*
HalReturnToFirmware ( * @implemented
FIRMWARE_REENTRY Action */
) VOID
NTAPI
HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
{ {
if (Action == HalHaltRoutine) /* Check the kind of action this is */
switch (Action)
{ {
DbgPrint ("HalReturnToFirmware called!\n"); /* All recognized actions */
DbgBreakPoint (); case HalHaltRoutine:
} case HalRebootRoutine:
else if (Action == HalRebootRoutine)
{ /* Call the internal reboot function */
HalReboot (); HalpReboot();
/* Anything else */
default:
/* Print message and break */
DbgPrint("HalReturnToFirmware called!\n");
DbgBreakPoint();
} }
} }