]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/acpi_wakeup.s
xnu-1699.26.8.tar.gz
[apple/xnu.git] / osfmk / i386 / acpi_wakeup.s
index 931a72740bfb7f44d94537c1a06cb316e8064ccf..30d40507e5db68360dbe383ce82a2cf9a9b8d793 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/asm.h>
        .text
        .align  12      /* Page align for single bcopy_phys() */
 
-#define LJMP(segment, address)                  \
-       .byte   0xea                            ;\
-       .long   address - EXT(acpi_wake_start)  ;\
-       .word   segment
-
-#define        PA(addr)        ((addr)-KERNELBASE)
-
-/*
- * acpi_wake_start
- *
- * The code from acpi_wake_start to acpi_wake_end is copied to
- * memory below 1MB.  The firmware waking vector is updated to
- * point at acpi_wake_start in low memory before sleeping.
- */
-
-ENTRY(acpi_wake_start)
-       /*
-        * CPU woke up from sleep, and is back in real mode.
-        * Initialize it just enough to get back to protected mode.
-        */
-       cli
-
-       POSTCODE(ACPI_WAKE_START_ENTRY)
-
-       /* set up DS to match CS */
-       movw    %cs, %ax
-       movw    %ax, %ds
-
-       /*
-        * Must initialize GDTR before entering protected mode.
-        * Use a temporary GDT that is 0 based, 4GB limit, code and data.
-        * Restoring the actual GDT will come later.
-        */
-       addr16
-       data16
-       lgdt    EXT(acpi_gdtr) - EXT(acpi_wake_start)
-
-       /* set CR0.PE to enter protected mode */
-       mov     %cr0, %eax
-       data16
-       or      $(CR0_PE), %eax
-       mov     %eax, %cr0
-
-       /*
-        * Make intra-segment jump to flush pipeline and reload CS register.
-        * If GDT is bogus, it will blow up here.
-        */
-       data16
-       LJMP(0x8, acpi_wake_prot + ACPI_WAKE_ADDR)
+#define        PA(addr)        (addr)
 
-acpi_wake_prot:
+#if CONFIG_SLEEP
+ENTRY(acpi_wake_prot)
 
        /* protected mode, paging disabled */
 
@@ -97,36 +56,6 @@ acpi_wake_prot:
        movl    PA(saved_eip), %eax
        jmp     *%eax
 
-/*  Segment Descriptor
- *
- * 31          24         19   16                 7           0
- * ------------------------------------------------------------
- * |             | |B| |A|       | |   |1|0|E|W|A|            |
- * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
- * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
- * ------------------------------------------------------------
- * |                             |                            |
- * |        BASE 15..0           |       LIMIT 15..0          |
- * |                             |                            |
- * ------------------------------------------------------------
- */
-ENTRY(acpi_gdt)
-       .word   0, 0            /* 0x0  : null */
-       .byte   0, 0, 0, 0
-
-       .word   0xffff, 0x0000  /* 0x8  : code */
-       .byte   0, 0x9e, 0xcf, 0
-
-       .word   0xffff, 0x0000  /* 0x10 : data */
-       .byte   0, 0x92, 0xcf, 0
-
-ENTRY(acpi_gdtr)
-       .word   24              /* limit (8*3 segs) */
-       .long   EXT(acpi_gdt) - EXT(acpi_wake_start) + ACPI_WAKE_ADDR
-
-ENTRY(acpi_wake_end)
-
-
 /*
  * acpi_sleep_cpu(acpi_sleep_callback func, void * refcon)
  *
@@ -145,6 +74,10 @@ ENTRY(acpi_sleep_cpu)
        pushal
        movl    %esp, saved_esp
 
+       /* make sure tlb is flushed */
+       movl    %cr3,%eax
+       movl    %eax,%cr3
+       
        /* save control registers */
        movl    %cr0, %eax
        movl    %eax, saved_cr0
@@ -186,50 +119,34 @@ ENTRY(acpi_sleep_cpu)
        jmp     wake_restore
 
 wake_prot:
-
        /* protected mode, paging disabled */
        POSTCODE(ACPI_WAKE_PROT_ENTRY)
 
+       movl    PA(saved_cr3), %ebx
+       movl    PA(saved_cr4), %ecx
+       /*
+        * restore cr3, PAE and NXE states in an orderly fashion
+        */
+       movl    %ebx, %cr3
+       movl    %ecx, %cr4
+
+       movl    $(MSR_IA32_EFER), %ecx                  /* MSR number in ecx */
+       rdmsr                                           /* MSR value return in edx: eax */
+       orl     $(MSR_IA32_EFER_NXE), %eax              /* Set NXE bit in low 32-bits */
+       wrmsr                                           /* Update Extended Feature Enable reg */
+
        /* restore kernel GDT */
        lgdt    PA(saved_gdt)
 
-       /* restore control registers */
        movl    PA(saved_cr2), %eax
        movl    %eax, %cr2
-       
-#ifdef PAE
-       movl    PA(EXT(IdlePDPT)), %eax
-       movl    (%eax), %esi            /* save orig */
-       movl    24(%eax), %ebx
-       movl    %ebx, (%eax)    /* identity map low mem */
-       movl    %eax, %cr3
-
-       movl    PA(saved_cr4), %eax
-       movl    %eax, %cr4
-#else
-       movl    PA(saved_cr4), %eax
-       movl    %eax, %cr4
-
-       /*
-        * Temporarily use the page tables at IdlePTD
-        * to enable paging.  Copy the KPTDI entry to
-        * entry 0 in the PTD to identity map the kernel.
-        */
-       movl    PA(EXT(IdlePTD)), %eax
-       movl    %eax, %ebx
-       addl    $(KPTDI << PTEINDX), %ebx  /* bytes per PDE */
-       movl    (%ebx), %ebx            /* IdlePTD[KPTDI]  */
-       movl    (%eax), %esi            /* save original IdlePTD[0] */
-       movl    %ebx, (%eax)            /* update IdlePTD[0] */   
-       movl    %eax, %cr3              /* CR3 = IdlePTD */
-#endif
 
        /* restore CR0, paging enabled */
        movl    PA(saved_cr0), %eax
        movl    %eax, %cr0
 
        /* switch to kernel code segment */
-       ljmpl   $(KERNEL_CS), $wake_paged
+       ljmpl   $(KERNEL32_CS), $wake_paged
 
 wake_paged:
 
@@ -240,20 +157,6 @@ wake_paged:
        movw    $(KERNEL_DS), %ax
        movw    %ax, %ds
 
-       /* undo changes to IdlePTD */
-#ifdef PAE
-       movl    EXT(IdlePDPT), %eax
-#else  
-       movl    EXT(IdlePTD), %eax
-#endif
-       addl    $(KERNELBASE), %eax     /* make virtual */
-       movl    %esi, (%eax)
-
-       /* restore real PDE base */
-       movl    saved_cr3, %eax
-       movl    %eax, %cr3
-
-
        /* restore local and interrupt descriptor tables */
        lldt    saved_ldt
        lidt    saved_idt
@@ -292,30 +195,60 @@ wake_restore:
         
         .globl EXT(acpi_wake_prot_entry)
 ENTRY(acpi_wake_prot_entry)
+       mov             %cr0, %eax
+       and             $(~CR0_PG), %eax
+       mov             %eax, %cr0
+       mov             $EXT(IdlePDPT), %eax
+       mov             EXT(IdlePTD), %ecx
+       or              $(INTEL_PTE_VALID), %ecx
+       mov     $0x0, %edx
+       mov             %ecx, (0*8+0)(%eax)
+       mov     %edx, (0*8+4)(%eax)
+       add             $(PAGE_SIZE), %ecx
+       mov     %ecx, (1*8+0)(%eax)
+       mov     %edx, (1*8+4)(%eax)
+       add             $(PAGE_SIZE), %ecx
+       mov     %ecx, (2*8+0)(%eax)
+       mov     %edx, (2*8+4)(%eax)
+       add             $(PAGE_SIZE), %ecx
+       mov     %ecx, (3*8+0)(%eax)
+       mov     %edx, (3*8+4)(%eax)
+       mov     %eax, %cr3
+       mov             %cr0, %eax
+       or              $(CR0_PG), %eax
+       mov             %eax, %cr0
+
        /* protected mode, paging enabled */
+
        POSTCODE(ACPI_WAKE_PAGED_ENTRY)
 
        /* restore kernel GDT */
-       lgdt    PA(saved_gdt)
-       
+       lgdt    saved_gdt
+
        POSTCODE(0x40)
+
        /* restore control registers */
+
+       movl    saved_cr0, %eax
+       movl    %eax, %cr0
+
        movl    saved_cr2, %eax
        movl    %eax, %cr2
 
         POSTCODE(0x3E)
-       /* switch to kernel data segment */
-       movw    $(KERNEL_DS), %ax
-       movw    %ax, %ds
 
-        POSTCODE(0x3D)
        /* restore real PDE base */
        movl    saved_cr3, %eax
        movl    saved_cr4, %edx
        movl    %eax, %cr3
        movl    %edx, %cr4
+       movl    %eax, %cr3
 
-        POSTCODE(0x3C)
+       /* switch to kernel data segment */
+       movw    $(KERNEL_DS), %ax
+       movw    %ax, %ds
+
+       POSTCODE(0x3C)
        /* restore local and interrupt descriptor tables */
        lldt    saved_ldt
        lidt    saved_idt
@@ -351,17 +284,18 @@ ENTRY(acpi_wake_prot_entry)
         movl   $2, %eax
 
         leave
-       ret
 
-        
-       .data
-        .section __HIB, __data
-       .align  2
+       ret
+#endif /* CONFIG_SLEEP */
 
+.data
+.section __SLEEP, __data
+.align 2
 
 /*
  * CPU registers saved across sleep/wake.
  */
+
 saved_esp:     .long 0
 saved_es:      .word 0
 saved_fs:      .word 0