https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d4ede03e192ae492b796e…
commit d4ede03e192ae492b796ee7c8d6c9c71409ec56a
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Fri Oct 4 22:04:51 2019 +0300
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Oct 5 17:42:28 2019 +0200
[HALXBOX] Implement shutdown, reboot, and power cycle routines
CORE-16216
---
hal/halx86/xbox.cmake | 2 +-
hal/halx86/xbox/halxbox.h | 28 +++++++++--
hal/halx86/xbox/reboot.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 139 insertions(+), 6 deletions(-)
diff --git a/hal/halx86/xbox.cmake b/hal/halx86/xbox.cmake
index a259df7a57c..c3604e70dfe 100644
--- a/hal/halx86/xbox.cmake
+++ b/hal/halx86/xbox.cmake
@@ -15,7 +15,6 @@ list(APPEND HAL_XBOX_SOURCE
generic/memory.c
generic/misc.c
generic/pic.c
- generic/reboot.c
generic/sysinfo.c
generic/usage.c
generic/bios.c
@@ -34,6 +33,7 @@ list(APPEND HAL_XBOX_SOURCE
generic/timer.c
xbox/part_xbox.c
xbox/halinit_xbox.c
+ xbox/reboot.c
up/pic.c)
add_asm_files(lib_hal_xbox_asm ${HAL_XBOX_ASM_SOURCE})
diff --git a/hal/halx86/xbox/halxbox.h b/hal/halx86/xbox/halxbox.h
index b27c6e31c23..5e4a5228800 100644
--- a/hal/halx86/xbox/halxbox.h
+++ b/hal/halx86/xbox/halxbox.h
@@ -1,11 +1,14 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
* PROJECT: Xbox HAL
- * FILE: hal/halx86/xbox/halxbox.h
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Xbox specific routines
- * PROGRAMMER: Ge van Geldorp (gvg(a)reactos.com)
- * UPDATE HISTORY:
- * Created 2004/12/02
+ * COPYRIGHT: Copyright 2004 Gé van Geldorp (gvg(a)reactos.com)
+ * Copyright 2019 Stanislav Motylkov (x86corez(a)gmail.com)
+ *
+ * REFERENCES:
https://xboxdevwiki.net/SMBus
+ *
https://github.com/XboxDev/cromwell/blob/master/drivers/pci/i2cio.c
+ *
https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-amd756…
+ *
https://github.com/xqemu/xqemu/blob/master/hw/xbox/smbus_xbox_smc.c
*/
#ifndef HALXBOX_H_INCLUDED
@@ -14,6 +17,21 @@
#include <hal.h>
#include <ntdddisk.h>
+#define SMB_IO_BASE 0xC000
+
+#define SMB_GLOBAL_STATUS (0 + SMB_IO_BASE)
+#define SMB_GLOBAL_ENABLE (2 + SMB_IO_BASE)
+#define SMB_HOST_ADDRESS (4 + SMB_IO_BASE)
+#define SMB_HOST_DATA (6 + SMB_IO_BASE)
+#define SMB_HOST_COMMAND (8 + SMB_IO_BASE)
+
+#define SMB_DEVICE_SMC_PIC16LC 0x10
+
+#define SMC_REG_POWER 0x02
+#define SMC_REG_POWER_RESET 0x01
+#define SMC_REG_POWER_CYCLE 0x40
+#define SMC_REG_POWER_SHUTDOWN 0x80
+
VOID HalpXboxInitPciBus(PBUS_HANDLER BusHandler);
VOID HalpXboxInitPartIo(VOID);
diff --git a/hal/halx86/xbox/reboot.c b/hal/halx86/xbox/reboot.c
new file mode 100644
index 00000000000..1f2dec387c1
--- /dev/null
+++ b/hal/halx86/xbox/reboot.c
@@ -0,0 +1,115 @@
+/*
+ * PROJECT: Xbox HAL
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Xbox reboot functions
+ * COPYRIGHT: Copyright 2004 Lehner Franz (franz(a)caos.at)
+ * Copyright 2019 Stanislav Motylkov (x86corez(a)gmail.com)
+ *
+ * REFERENCES:
https://xboxdevwiki.net/SMBus
+ *
https://github.com/XboxDev/cromwell/blob/master/drivers/pci/i2cio.c
+ *
https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-amd756…
+ *
https://github.com/xqemu/xqemu/blob/master/hw/xbox/smbus_xbox_smc.c
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "halxbox.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+SMBusWriteByte(UCHAR Address, UCHAR Register, UCHAR Data)
+{
+ INT Retries = 50;
+
+ /* Wait while bus is busy with any master traffic */
+ while (READ_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS) & 0x800)
+ {
+ NOTHING;
+ }
+
+ while (Retries--)
+ {
+ UCHAR b;
+
+ WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_ADDRESS, Address << 1);
+ WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_COMMAND, Register);
+
+ WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_DATA, Data);
+
+ /* Clear down all preexisting errors */
+ WRITE_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS,
READ_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS));
+
+ /* Let I2C SMBus know we're sending a single byte here */
+ WRITE_PORT_UCHAR((PUCHAR)SMB_GLOBAL_ENABLE, 0x1A);
+
+ b = 0;
+
+ while (!(b & 0x36))
+ {
+ b = READ_PORT_UCHAR((PUCHAR)SMB_GLOBAL_STATUS);
+ }
+
+ if (b & 0x10)
+ {
+ return;
+ }
+
+ KeStallExecutionProcessor(1);
+ }
+}
+
+VOID
+DECLSPEC_NORETURN
+NTAPI
+HalpXboxPowerAction(IN UCHAR Action)
+{
+ SMBusWriteByte(SMB_DEVICE_SMC_PIC16LC, SMC_REG_POWER, Action);
+
+ /* Halt the CPU */
+ __halt();
+
+ while (TRUE); /* 'noreturn' function */
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
+{
+ /* Check what kind of action this is */
+ switch (Action)
+ {
+ /* All recognized actions */
+ case HalPowerDownRoutine:
+ {
+ /* Call the internal power function */
+ HalpXboxPowerAction(SMC_REG_POWER_SHUTDOWN);
+ }
+ case HalRestartRoutine:
+ {
+ HalpXboxPowerAction(SMC_REG_POWER_CYCLE);
+ }
+ case HalRebootRoutine:
+ {
+ HalpXboxPowerAction(SMC_REG_POWER_RESET);
+ }
+ /* Anything else */
+ default:
+ {
+ /* Print message and break */
+ DbgPrint("HalReturnToFirmware(%d) called!\n", Action);
+ DbgBreakPoint();
+ }
+ }
+}
+
+/* EOF */