PKUOS - Pintos
Pintos source browser for PKU Operating System course
shutdown.c
Go to the documentation of this file.
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/block.h"
14#include "filesys/filesys.h"
15#endif
16
17/** Keyboard control register port. */
18#define CONTROL_REG 0x64
19
20/** How to shut down when shutdown() is called. */
22
23static void print_stats (void);
24
25/** Shuts down the machine in the way configured by
26 shutdown_configure(). If the shutdown type is SHUTDOWN_NONE
27 (which is the default), returns without doing anything. */
28void
30{
31 switch (how)
32 {
35 break;
36
37 case SHUTDOWN_REBOOT:
39 break;
40
41 default:
42 /* Nothing to do. */
43 break;
44 }
45}
46
47/** Sets TYPE as the way that machine will shut down when Pintos
48 execution is complete. */
49void
51{
52 how = type;
53}
54
55/** Reboots the machine via the keyboard controller. */
56void
58{
59 printf ("Rebooting...\n");
60
61 /* See [kbd] for details on how to program the keyboard
62 * controller. */
63 for (;;)
64 {
65 int i;
66
67 /* Poll keyboard controller's status byte until
68 * 'input buffer empty' is reported. */
69 for (i = 0; i < 0x10000; i++)
70 {
71 if ((inb (CONTROL_REG) & 0x02) == 0)
72 break;
73 timer_udelay (2);
74 }
75
76 timer_udelay (50);
77
78 /* Pulse bit 0 of the output port P2 of the keyboard controller.
79 * This will reset the CPU. */
80 outb (CONTROL_REG, 0xfe);
81 timer_udelay (50);
82 }
83}
84
85/** Powers down the machine we're running on,
86 as long as we're running on Bochs or QEMU. */
87void
89{
90 const char s[] = "Shutdown";
91 const char *p;
92
93#ifdef FILESYS
94 filesys_done ();
95#endif
96
97 print_stats ();
98
99 printf ("Powering off...\n");
100 serial_flush ();
101
102 /* ACPI power-off */
103 outw (0xB004, 0x2000);
104
105 /* This is a special power-off sequence supported by Bochs and
106 QEMU, but not by physical hardware. */
107 for (p = s; *p != '\0'; p++)
108 outb (0x8900, *p);
109
110 /* For newer versions of qemu, you must run with -device
111 * isa-debug-exit, which exits on any write to an IO port (by
112 * default 0x501). Qemu's exit code is double the value plus one,
113 * so there is no way to exit cleanly. We use 0x31 which should
114 * result in a qemu exit code of 0x63. */
115 outb (0x501, 0x31);
116
117 /* This will power off a VMware VM if "gui.exitOnCLIHLT = TRUE"
118 is set in its configuration file. (The "pintos" script does
119 that automatically.) */
120 asm volatile ("cli; hlt" : : : "memory");
121
122 /* None of those worked. */
123 printf ("still running...\n");
124 for (;;);
125}
126
127/** Print statistics about Pintos execution. */
128static void
130{
133#ifdef FILESYS
135#endif
138#ifdef USERPROG
140#endif
141}
void block_print_stats(void)
Prints statistics for each block device used for a Pintos role.
Definition: block.c:165
void exception_print_stats(void)
Prints exception statistics.
Definition: exception.c:65
void filesys_done(void)
Shuts down the file system module, writing any unwritten data to disk.
Definition: filesys.c:36
static uint8_t inb(uint16_t port)
Reads and returns a byte from PORT.
Definition: io.h:9
static void outw(uint16_t port, uint16_t data)
Writes the 16-bit DATA to PORT.
Definition: io.h:83
static void outb(uint16_t port, uint8_t data)
Writes byte DATA to PORT.
Definition: io.h:66
void kbd_print_stats(void)
Prints keyboard statistics.
Definition: kbd.c:38
void console_print_stats(void)
Prints console statistics.
Definition: console.c:81
int printf(const char *format,...)
Writes formatted output to the console.
Definition: stdio.c:79
static uint8_t s[256]
RC4-based pseudo-random number generator (PRNG).
Definition: random.c:17
void serial_flush(void)
Flushes anything in the serial buffer out the port in polling mode.
Definition: serial.c:135
void shutdown(void)
Shuts down the machine in the way configured by shutdown_configure().
Definition: shutdown.c:29
#define CONTROL_REG
Keyboard control register port.
Definition: shutdown.c:18
void shutdown_configure(enum shutdown_type type)
Sets TYPE as the way that machine will shut down when Pintos execution is complete.
Definition: shutdown.c:50
void shutdown_power_off(void)
Powers down the machine we're running on, as long as we're running on Bochs or QEMU.
Definition: shutdown.c:88
void shutdown_reboot(void)
Reboots the machine via the keyboard controller.
Definition: shutdown.c:57
static void print_stats(void)
Print statistics about Pintos execution.
Definition: shutdown.c:129
static enum shutdown_type how
How to shut down when shutdown() is called.
Definition: shutdown.c:21
shutdown_type
How to shut down when Pintos has nothing left to do.
Definition: shutdown.h:8
@ SHUTDOWN_POWER_OFF
Power off the machine (if possible).
Definition: shutdown.h:10
@ SHUTDOWN_NONE
Loop forever.
Definition: shutdown.h:9
@ SHUTDOWN_REBOOT
Reboot the machine (if possible).
Definition: shutdown.h:11
void thread_print_stats(void)
Prints thread statistics.
Definition: thread.c:144
void timer_print_stats(void)
Prints timer statistics.
Definition: timer.c:164
void timer_udelay(int64_t us)
Sleeps for approximately US microseconds.
Definition: timer.c:144