Updates for new version of qemu
[pintos-anon] / src / devices / shutdown.c
index fbc662b01c095edc25741ea265e5a01fe52e0c78..da94c5294f339c1d81eb0950f83e53f9f703b1dc 100644 (file)
 #include "userprog/exception.h"
 #endif
 #ifdef FILESYS
-#include "devices/disk.h"
+#include "devices/block.h"
 #include "filesys/filesys.h"
 #endif
 
 /* Keyboard control register port. */
 #define CONTROL_REG 0x64
 
+/* How to shut down when shutdown() is called. */
+static enum shutdown_type how = SHUTDOWN_NONE;
+
 static void print_stats (void);
 
+/* Shuts down the machine in the way configured by
+   shutdown_configure().  If the shutdown type is SHUTDOWN_NONE
+   (which is the default), returns without doing anything. */
+void
+shutdown (void)
+{
+  switch (how)
+    {
+    case SHUTDOWN_POWER_OFF:
+      shutdown_power_off ();
+      break;
+
+    case SHUTDOWN_REBOOT:
+      shutdown_reboot ();
+      break;
+
+    default:
+      /* Nothing to do. */
+      break;
+    }
+}
+
+/* Sets TYPE as the way that machine will shut down when Pintos
+   execution is complete. */
+void
+shutdown_configure (enum shutdown_type type)
+{
+  how = type;
+}
+
 /* Reboots the machine via the keyboard controller. */
 void
 shutdown_reboot (void)
 {
-  int i;
-
   printf ("Rebooting...\n");
 
     /* See [kbd] for details on how to program the keyboard
      * controller. */
-  for (i = 0; i < 100; i++)
+  for (;;)
     {
-      int j;
+      int i;
 
       /* Poll keyboard controller's status byte until
        * 'input buffer empty' is reported. */
-      for (j = 0; j < 0x10000; j++)
+      for (i = 0; i < 0x10000; i++)
         {
           if ((inb (CONTROL_REG) & 0x02) == 0)
             break;
@@ -68,11 +99,21 @@ shutdown_power_off (void)
   printf ("Powering off...\n");
   serial_flush ();
 
+  /* ACPI power-off */
+  outw (0xB004, 0x2000);
+
   /* This is a special power-off sequence supported by Bochs and
      QEMU, but not by physical hardware. */
   for (p = s; *p != '\0'; p++)
     outb (0x8900, *p);
 
+  /* For newer versions of qemu, you must run with -device
+   * isa-debug-exit, which exits on any write to an IO port (by
+   * default 0x501).  Qemu's exit code is double the value plus one,
+   * so there is no way to exit cleanly.  We use 0x31 which should
+   * result in a qemu exit code of 0x63.  */
+  outb (0x501, 0x31);
+
   /* This will power off a VMware VM if "gui.exitOnCLIHLT = TRUE"
      is set in its configuration file.  (The "pintos" script does
      that automatically.)  */
@@ -90,7 +131,7 @@ print_stats (void)
   timer_print_stats ();
   thread_print_stats ();
 #ifdef FILESYS
-  disk_print_stats ();
+  block_print_stats ();
 #endif
   console_print_stats ();
   kbd_print_stats ();