X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/91447636331957f3d9b5ca5b508f07c526b0074d..7ddcb079202367355dddccdfa4318e57d50318be:/osfmk/i386/acpi_wakeup.s diff --git a/osfmk/i386/acpi_wakeup.s b/osfmk/i386/acpi_wakeup.s index 931a72740..30d40507e 100644 --- a/osfmk/i386/acpi_wakeup.s +++ b/osfmk/i386/acpi_wakeup.s @@ -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 @@ -31,57 +37,10 @@ .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