]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/acpi.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / osfmk / i386 / acpi.c
index e748f6161db8c3f08352fb342e973933085d4b92..a70821010ea0e07081c6d77c59589444bdb20490 100644 (file)
@@ -1,23 +1,29 @@
 /*
  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <i386/misc_protos.h>
 #include <i386/pmap.h>
 #include <i386/mtrr.h>
 #include <i386/acpi.h>
+#include <i386/fpu.h>
 #include <i386/mp.h>
+#include <i386/mp_desc.h>
+#include <i386/machine_check.h>
 
 #include <kern/cpu_data.h>
 
@@ -41,11 +50,13 @@ extern unsigned int disableSerialOuput;
 
 extern void        set_kbd_leds(int leds);
 
+extern void    fpinit(void);
+
 vm_offset_t
 acpi_install_wake_handler(void)
 {
        /* copy wake code to ACPI_WAKE_ADDR in low memory */
-       bcopy_phys((addr64_t) kvtophys((vm_offset_t)acpi_wake_start),
+       bcopy_phys(kvtophys((vm_offset_t)acpi_wake_start),
                   (addr64_t) ACPI_WAKE_ADDR,
                   acpi_wake_end - acpi_wake_start);
 
@@ -64,12 +75,28 @@ typedef struct acpi_hibernate_callback_data {
 static void
 acpi_hibernate(void *refcon)
 {
-    boolean_t hib;
+    boolean_t dohalt;
 
     acpi_hibernate_callback_data *data = (acpi_hibernate_callback_data *)refcon;
 
     if (current_cpu_datap()->cpu_hibernate) {
-        hib = hibernate_write_image();
+
+        dohalt = hibernate_write_image();
+       if (dohalt)
+       {
+           // off
+           HIBLOG("power off\n");
+           if (PE_halt_restart) 
+               (*PE_halt_restart)(kPEHaltCPU);
+       }
+       else
+       {
+           // sleep
+           HIBLOG("sleep\n");
+
+           // should we come back via regular wake, set the state in memory.
+           cpu_datap(0)->cpu_hibernate = 0;
+       }
     }
 
     (data->func)(data->refcon);
@@ -83,51 +110,85 @@ acpi_sleep_kernel(acpi_sleep_callback func, void *refcon)
     acpi_hibernate_callback_data data;
     boolean_t did_hibernate;
 
-       /* shutdown local APIC before passing control to BIOS */
-       lapic_shutdown();
+    kprintf("acpi_sleep_kernel hib=%d\n", current_cpu_datap()->cpu_hibernate);
+
+    /* shutdown local APIC before passing control to BIOS */
+    lapic_shutdown();
 
     data.func = func;
     data.refcon = refcon;
 
-       /*
-        * Save master CPU state and sleep platform.
-        * Will not return until platform is woken up,
-        * or if sleep failed.
-        */
+    /* Save HPET state */
+    hpet_save();
+
+    /*
+     * If we're in 64-bit mode, drop back into legacy mode during sleep.
+     */
+    if (cpu_mode_is64bit()) {
+       cpu_IA32e_disable(current_cpu_datap());
+       kprintf("acpi_sleep_kernel legacy mode re-entered\n");
+    }
+
+    /*
+     * Save master CPU state and sleep platform.
+     * Will not return until platform is woken up,
+     * or if sleep failed.
+     */
     acpi_sleep_cpu(acpi_hibernate, &data);
 
-       /* reset UART if kprintf is enabled */
-       if (FALSE == disableSerialOuput)
-               serial_init();
+    /* reset UART if kprintf is enabled */
+    if (FALSE == disableSerialOuput)
+           serial_init();
+
+    kprintf("ret from acpi_sleep_cpu hib=%d\n", current_cpu_datap()->cpu_hibernate);
 
     if (current_cpu_datap()->cpu_hibernate) {
-        * (int *) CM1 = 0;
-        * (int *) CM2 = 0;
-        * (int *) CM3 = 0;
+       int i;
+       for (i=0; i<PMAP_NWINDOWS; i++) {
+           *current_cpu_datap()->cpu_pmap->mapwindow[i].prv_CMAP = 0;
+       }
+       current_cpu_datap()->cpu_hibernate = 0;
+       did_hibernate = TRUE;
 
-        current_cpu_datap()->cpu_hibernate = 0;
+    } else {
+       did_hibernate = FALSE;
+    }
 
-        did_hibernate = TRUE;
+    /* Re-enable 64-bit mode if necessary. */
+    if (cpu_mode_is64bit()) {
+       cpu_IA32e_enable(current_cpu_datap());
+       cpu_desc_load64(current_cpu_datap());
+       kprintf("acpi_sleep_kernel 64-bit mode re-enabled\n");
+       fast_syscall_init64();
     } else {
-        did_hibernate = FALSE;
+       fast_syscall_init();
     }
 
-       /* restore MTRR settings */
-       mtrr_update_cpu();
+    /* Re-enable machine check handling */
+    mca_cpu_init();
 
-       /* set up PAT following boot processor power up */
-       pat_init();
+    /* restore MTRR settings */
+    mtrr_update_cpu();
+
+    /* set up PAT following boot processor power up */
+    pat_init();
 
     if (did_hibernate) {
         hibernate_machine_init();
     }
         
-       /* re-enable and re-init local apic */
-       if (lapic_probe())
-               lapic_init();
+    /* re-enable and re-init local apic */
+    if (lapic_probe())
+       lapic_init();
+
+    /* Restore HPET state */
+    hpet_restore();
+
+    /* let the realtime clock reset */
+    rtc_sleep_wakeup();
 
-       /* let the realtime clock reset */
-       rtc_sleep_wakeup();
+    fpinit();
+    clear_fpu();
 
     if (did_hibernate) {
         enable_preemption();