xref: /reactos/hal/halx86/xbox/reboot.c (revision 9ba1849a)
1d4ede03eSStanislav Motylkov /*
2d4ede03eSStanislav Motylkov  * PROJECT:         Xbox HAL
3d4ede03eSStanislav Motylkov  * LICENSE:         GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4d4ede03eSStanislav Motylkov  * PURPOSE:         Xbox reboot functions
5d4ede03eSStanislav Motylkov  * COPYRIGHT:       Copyright 2004 Lehner Franz (franz@caos.at)
6d4ede03eSStanislav Motylkov  *                  Copyright 2019 Stanislav Motylkov (x86corez@gmail.com)
7d4ede03eSStanislav Motylkov  *
8d4ede03eSStanislav Motylkov  * REFERENCES:      https://xboxdevwiki.net/SMBus
9d4ede03eSStanislav Motylkov  *                  https://github.com/XboxDev/cromwell/blob/master/drivers/pci/i2cio.c
10d4ede03eSStanislav Motylkov  *                  https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-amd756.c
11d4ede03eSStanislav Motylkov  *                  https://github.com/xqemu/xqemu/blob/master/hw/xbox/smbus_xbox_smc.c
12d4ede03eSStanislav Motylkov  */
13d4ede03eSStanislav Motylkov 
14d4ede03eSStanislav Motylkov /* INCLUDES ******************************************************************/
15d4ede03eSStanislav Motylkov 
16d4ede03eSStanislav Motylkov #include "halxbox.h"
17d4ede03eSStanislav Motylkov 
18d4ede03eSStanislav Motylkov /* PRIVATE FUNCTIONS *********************************************************/
19d4ede03eSStanislav Motylkov 
20*9ba1849aSHermès Bélusca-Maïto static VOID
SMBusWriteByte(_In_ UCHAR Address,_In_ UCHAR Register,_In_ UCHAR Data)21*9ba1849aSHermès Bélusca-Maïto SMBusWriteByte(
22*9ba1849aSHermès Bélusca-Maïto     _In_ UCHAR Address,
23*9ba1849aSHermès Bélusca-Maïto     _In_ UCHAR Register,
24*9ba1849aSHermès Bélusca-Maïto     _In_ UCHAR Data)
25d4ede03eSStanislav Motylkov {
26d4ede03eSStanislav Motylkov     INT Retries = 50;
27d4ede03eSStanislav Motylkov 
28d4ede03eSStanislav Motylkov     /* Wait while bus is busy with any master traffic */
29d4ede03eSStanislav Motylkov     while (READ_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS) & 0x800)
30d4ede03eSStanislav Motylkov     {
31d4ede03eSStanislav Motylkov         NOTHING;
32d4ede03eSStanislav Motylkov     }
33d4ede03eSStanislav Motylkov 
34d4ede03eSStanislav Motylkov     while (Retries--)
35d4ede03eSStanislav Motylkov     {
36d4ede03eSStanislav Motylkov         UCHAR b;
37d4ede03eSStanislav Motylkov 
38d4ede03eSStanislav Motylkov         WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_ADDRESS, Address << 1);
39d4ede03eSStanislav Motylkov         WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_COMMAND, Register);
40d4ede03eSStanislav Motylkov 
41d4ede03eSStanislav Motylkov         WRITE_PORT_UCHAR((PUCHAR)SMB_HOST_DATA, Data);
42d4ede03eSStanislav Motylkov 
43d4ede03eSStanislav Motylkov         /* Clear down all preexisting errors */
44d4ede03eSStanislav Motylkov         WRITE_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS, READ_PORT_USHORT((PUSHORT)SMB_GLOBAL_STATUS));
45d4ede03eSStanislav Motylkov 
46d4ede03eSStanislav Motylkov         /* Let I2C SMBus know we're sending a single byte here */
47d4ede03eSStanislav Motylkov         WRITE_PORT_UCHAR((PUCHAR)SMB_GLOBAL_ENABLE, 0x1A);
48d4ede03eSStanislav Motylkov 
49d4ede03eSStanislav Motylkov         b = 0;
50d4ede03eSStanislav Motylkov 
51d4ede03eSStanislav Motylkov         while (!(b & 0x36))
52d4ede03eSStanislav Motylkov         {
53d4ede03eSStanislav Motylkov             b = READ_PORT_UCHAR((PUCHAR)SMB_GLOBAL_STATUS);
54d4ede03eSStanislav Motylkov         }
55d4ede03eSStanislav Motylkov 
56d4ede03eSStanislav Motylkov         if (b & 0x10)
57d4ede03eSStanislav Motylkov         {
58d4ede03eSStanislav Motylkov             return;
59d4ede03eSStanislav Motylkov         }
60d4ede03eSStanislav Motylkov 
61d4ede03eSStanislav Motylkov         KeStallExecutionProcessor(1);
62d4ede03eSStanislav Motylkov     }
63d4ede03eSStanislav Motylkov }
64d4ede03eSStanislav Motylkov 
65*9ba1849aSHermès Bélusca-Maïto static DECLSPEC_NORETURN
66d4ede03eSStanislav Motylkov VOID
HalpXboxPowerAction(_In_ UCHAR Action)67*9ba1849aSHermès Bélusca-Maïto HalpXboxPowerAction(
68*9ba1849aSHermès Bélusca-Maïto     _In_ UCHAR Action)
69d4ede03eSStanislav Motylkov {
70*9ba1849aSHermès Bélusca-Maïto     /* Disable interrupts */
71*9ba1849aSHermès Bélusca-Maïto     _disable();
72*9ba1849aSHermès Bélusca-Maïto 
73*9ba1849aSHermès Bélusca-Maïto     /* Send the command */
74d4ede03eSStanislav Motylkov     SMBusWriteByte(SMB_DEVICE_SMC_PIC16LC, SMC_REG_POWER, Action);
75d4ede03eSStanislav Motylkov 
76d4ede03eSStanislav Motylkov     /* Halt the CPU */
77d4ede03eSStanislav Motylkov     __halt();
78*9ba1849aSHermès Bélusca-Maïto     UNREACHABLE;
79*9ba1849aSHermès Bélusca-Maïto }
80d4ede03eSStanislav Motylkov 
81*9ba1849aSHermès Bélusca-Maïto DECLSPEC_NORETURN
82*9ba1849aSHermès Bélusca-Maïto VOID
HalpReboot(VOID)83*9ba1849aSHermès Bélusca-Maïto HalpReboot(VOID)
84*9ba1849aSHermès Bélusca-Maïto {
85*9ba1849aSHermès Bélusca-Maïto     HalpXboxPowerAction(SMC_REG_POWER_RESET);
86d4ede03eSStanislav Motylkov }
87d4ede03eSStanislav Motylkov 
88d4ede03eSStanislav Motylkov /* PUBLIC FUNCTIONS **********************************************************/
89d4ede03eSStanislav Motylkov 
90*9ba1849aSHermès Bélusca-Maïto #ifndef _MINIHAL_
91d4ede03eSStanislav Motylkov /*
92d4ede03eSStanislav Motylkov  * @implemented
93d4ede03eSStanislav Motylkov  */
94d4ede03eSStanislav Motylkov VOID
95d4ede03eSStanislav Motylkov NTAPI
HalReturnToFirmware(_In_ FIRMWARE_REENTRY Action)96*9ba1849aSHermès Bélusca-Maïto HalReturnToFirmware(
97*9ba1849aSHermès Bélusca-Maïto     _In_ FIRMWARE_REENTRY Action)
98d4ede03eSStanislav Motylkov {
99d4ede03eSStanislav Motylkov     /* Check what kind of action this is */
100d4ede03eSStanislav Motylkov     switch (Action)
101d4ede03eSStanislav Motylkov     {
102*9ba1849aSHermès Bélusca-Maïto         /* All recognized actions: call the internal power function */
103*9ba1849aSHermès Bélusca-Maïto         case HalHaltRoutine:
104d4ede03eSStanislav Motylkov         case HalPowerDownRoutine:
105d4ede03eSStanislav Motylkov         {
106d4ede03eSStanislav Motylkov             HalpXboxPowerAction(SMC_REG_POWER_SHUTDOWN);
107d4ede03eSStanislav Motylkov         }
108d4ede03eSStanislav Motylkov         case HalRestartRoutine:
109d4ede03eSStanislav Motylkov         {
110d4ede03eSStanislav Motylkov             HalpXboxPowerAction(SMC_REG_POWER_CYCLE);
111d4ede03eSStanislav Motylkov         }
112d4ede03eSStanislav Motylkov         case HalRebootRoutine:
113d4ede03eSStanislav Motylkov         {
114d4ede03eSStanislav Motylkov             HalpXboxPowerAction(SMC_REG_POWER_RESET);
115d4ede03eSStanislav Motylkov         }
116*9ba1849aSHermès Bélusca-Maïto 
117d4ede03eSStanislav Motylkov         /* Anything else */
118d4ede03eSStanislav Motylkov         default:
119d4ede03eSStanislav Motylkov         {
120d4ede03eSStanislav Motylkov             /* Print message and break */
121d4ede03eSStanislav Motylkov             DbgPrint("HalReturnToFirmware(%d) called!\n", Action);
122d4ede03eSStanislav Motylkov             DbgBreakPoint();
123d4ede03eSStanislav Motylkov         }
124d4ede03eSStanislav Motylkov     }
125d4ede03eSStanislav Motylkov }
126*9ba1849aSHermès Bélusca-Maïto #endif // _MINIHAL_
127d4ede03eSStanislav Motylkov 
128d4ede03eSStanislav Motylkov /* EOF */
129