diff options
Diffstat (limited to 'arch/x86/power/hibernate_asm_32.S')
| -rw-r--r-- | arch/x86/power/hibernate_asm_32.S | 37 | 
1 files changed, 31 insertions, 6 deletions
| diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S index 6e56815e13a0..6fe383002125 100644 --- a/arch/x86/power/hibernate_asm_32.S +++ b/arch/x86/power/hibernate_asm_32.S @@ -12,6 +12,7 @@  #include <asm/page_types.h>  #include <asm/asm-offsets.h>  #include <asm/processor-flags.h> +#include <asm/frame.h>  .text @@ -24,13 +25,30 @@ ENTRY(swsusp_arch_suspend)  	pushfl  	popl saved_context_eflags +	/* save cr3 */ +	movl	%cr3, %eax +	movl	%eax, restore_cr3 + +	FRAME_BEGIN  	call swsusp_save +	FRAME_END  	ret +ENDPROC(swsusp_arch_suspend)  ENTRY(restore_image) +	/* prepare to jump to the image kernel */ +	movl	restore_jump_address, %ebx +	movl	restore_cr3, %ebp +  	movl	mmu_cr4_features, %ecx -	movl	resume_pg_dir, %eax -	subl	$__PAGE_OFFSET, %eax + +	/* jump to relocated restore code */ +	movl	relocated_restore_code, %eax +	jmpl	*%eax + +/* code below has been relocated to a safe page */ +ENTRY(core_restore_code) +	movl	temp_pgt, %eax  	movl	%eax, %cr3  	jecxz	1f	# cr4 Pentium and higher, skip if zero @@ -49,7 +67,7 @@ copy_loop:  	movl	pbe_address(%edx), %esi  	movl	pbe_orig_address(%edx), %edi -	movl	$1024, %ecx +	movl	$(PAGE_SIZE >> 2), %ecx  	rep  	movsl @@ -58,10 +76,13 @@ copy_loop:  	.p2align 4,,7  done: +	jmpl	*%ebx + +	/* code below belongs to the image kernel */ +	.align PAGE_SIZE +ENTRY(restore_registers)  	/* go back to the original page tables */ -	movl	$swapper_pg_dir, %eax -	subl	$__PAGE_OFFSET, %eax -	movl	%eax, %cr3 +	movl	%ebp, %cr3  	movl	mmu_cr4_features, %ecx  	jecxz	1f	# cr4 Pentium and higher, skip if zero  	movl	%ecx, %cr4;  # turn PGE back on @@ -82,4 +103,8 @@ done:  	xorl	%eax, %eax +	/* tell the hibernation core that we've just restored the memory */ +	movl	%eax, in_suspend +  	ret +ENDPROC(restore_registers) |