0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/linkage.h>
0011 #include <asm/segment.h>
0012 #include <asm/page_types.h>
0013 #include <asm/asm-offsets.h>
0014 #include <asm/processor-flags.h>
0015 #include <asm/frame.h>
0016
0017 .text
0018
0019 SYM_FUNC_START(swsusp_arch_suspend)
0020 movl %esp, saved_context_esp
0021 movl %ebx, saved_context_ebx
0022 movl %ebp, saved_context_ebp
0023 movl %esi, saved_context_esi
0024 movl %edi, saved_context_edi
0025 pushfl
0026 popl saved_context_eflags
0027
0028
0029 movl %cr3, %eax
0030 movl %eax, restore_cr3
0031
0032 FRAME_BEGIN
0033 call swsusp_save
0034 FRAME_END
0035 RET
0036 SYM_FUNC_END(swsusp_arch_suspend)
0037
0038 SYM_CODE_START(restore_image)
0039
0040 movl restore_jump_address, %ebx
0041 movl restore_cr3, %ebp
0042
0043 movl mmu_cr4_features, %ecx
0044
0045
0046 movl relocated_restore_code, %eax
0047 jmpl *%eax
0048 SYM_CODE_END(restore_image)
0049
0050
0051 SYM_CODE_START(core_restore_code)
0052 movl temp_pgt, %eax
0053 movl %eax, %cr3
0054
0055 jecxz 1f # cr4 Pentium and higher, skip if zero
0056 andl $~(X86_CR4_PGE), %ecx
0057 movl %ecx, %cr4; # turn off PGE
0058 movl %cr3, %eax; # flush TLB
0059 movl %eax, %cr3
0060 1:
0061 movl restore_pblist, %edx
0062 .p2align 4,,7
0063
0064 copy_loop:
0065 testl %edx, %edx
0066 jz done
0067
0068 movl pbe_address(%edx), %esi
0069 movl pbe_orig_address(%edx), %edi
0070
0071 movl $(PAGE_SIZE >> 2), %ecx
0072 rep
0073 movsl
0074
0075 movl pbe_next(%edx), %edx
0076 jmp copy_loop
0077 .p2align 4,,7
0078
0079 done:
0080 jmpl *%ebx
0081 SYM_CODE_END(core_restore_code)
0082
0083
0084 .align PAGE_SIZE
0085 SYM_FUNC_START(restore_registers)
0086
0087 movl %ebp, %cr3
0088 movl mmu_cr4_features, %ecx
0089 jecxz 1f # cr4 Pentium and higher, skip if zero
0090 movl %ecx, %cr4; # turn PGE back on
0091 1:
0092
0093 movl saved_context_esp, %esp
0094 movl saved_context_ebp, %ebp
0095 movl saved_context_ebx, %ebx
0096 movl saved_context_esi, %esi
0097 movl saved_context_edi, %edi
0098
0099 pushl saved_context_eflags
0100 popfl
0101
0102
0103 movl $saved_context, %eax
0104 lgdt saved_context_gdt_desc(%eax)
0105
0106 xorl %eax, %eax
0107
0108
0109 movl %eax, in_suspend
0110
0111 RET
0112 SYM_FUNC_END(restore_registers)