Mark shutdown_reboot() and shutdown_power_off() as NO_RETURN.
[pintos-anon] / src / devices / shutdown.c
1 #include "devices/shutdown.h"
2 #include <console.h>
3 #include <stdio.h>
4 #include "devices/kbd.h"
5 #include "devices/serial.h"
6 #include "devices/timer.h"
7 #include "threads/io.h"
8 #include "threads/thread.h"
9 #ifdef USERPROG
10 #include "userprog/exception.h"
11 #endif
12 #ifdef FILESYS
13 #include "devices/disk.h"
14 #include "filesys/filesys.h"
15 #endif
16
17 /* Keyboard control register port. */
18 #define CONTROL_REG 0x64
19
20 static void print_stats (void);
21
22 /* Reboots the machine via the keyboard controller. */
23 void
24 shutdown_reboot (void)
25 {
26   printf ("Rebooting...\n");
27
28     /* See [kbd] for details on how to program the keyboard
29      * controller. */
30   for (;;)
31     {
32       int i;
33
34       /* Poll keyboard controller's status byte until
35        * 'input buffer empty' is reported. */
36       for (i = 0; i < 0x10000; i++)
37         {
38           if ((inb (CONTROL_REG) & 0x02) == 0)
39             break;
40           timer_udelay (2);
41         }
42
43       timer_udelay (50);
44
45       /* Pulse bit 0 of the output port P2 of the keyboard controller.
46        * This will reset the CPU. */
47       outb (CONTROL_REG, 0xfe);
48       timer_udelay (50);
49     }
50 }
51
52 /* Powers down the machine we're running on,
53    as long as we're running on Bochs or QEMU. */
54 void
55 shutdown_power_off (void)
56 {
57   const char s[] = "Shutdown";
58   const char *p;
59
60 #ifdef FILESYS
61   filesys_done ();
62 #endif
63
64   print_stats ();
65
66   printf ("Powering off...\n");
67   serial_flush ();
68
69   /* This is a special power-off sequence supported by Bochs and
70      QEMU, but not by physical hardware. */
71   for (p = s; *p != '\0'; p++)
72     outb (0x8900, *p);
73
74   /* This will power off a VMware VM if "gui.exitOnCLIHLT = TRUE"
75      is set in its configuration file.  (The "pintos" script does
76      that automatically.)  */
77   asm volatile ("cli; hlt" : : : "memory");
78
79   /* None of those worked. */
80   printf ("still running...\n");
81   for (;;);
82 }
83
84 /* Print statistics about Pintos execution. */
85 static void
86 print_stats (void)
87 {
88   timer_print_stats ();
89   thread_print_stats ();
90 #ifdef FILESYS
91   disk_print_stats ();
92 #endif
93   console_print_stats ();
94   kbd_print_stats ();
95 #ifdef USERPROG
96   exception_print_stats ();
97 #endif
98 }