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