1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  |     .text 
 |  #include <linux/linkage.h> 
 |  #include <asm/segment.h> 
 |  #include <asm/page_types.h> 
 |    
 |  # Copyright 2003, 2008 Pavel Machek <pavel@suse.cz>, distribute under GPLv2 
 |    
 |      .code32 
 |      ALIGN 
 |    
 |  ENTRY(wakeup_pmode_return) 
 |  wakeup_pmode_return: 
 |      movw    $__KERNEL_DS, %ax 
 |      movw    %ax, %ss 
 |      movw    %ax, %fs 
 |      movw    %ax, %gs 
 |    
 |      movw    $__USER_DS, %ax 
 |      movw    %ax, %ds 
 |      movw    %ax, %es 
 |    
 |      # reload the gdt, as we need the full 32 bit address 
 |      lidt    saved_idt 
 |      lldt    saved_ldt 
 |      ljmp    $(__KERNEL_CS), $1f 
 |  1: 
 |      movl    %cr3, %eax 
 |      movl    %eax, %cr3 
 |      wbinvd 
 |    
 |      # and restore the stack ... but you need gdt for this to work 
 |      movl    saved_context_esp, %esp 
 |    
 |      movl    %cs:saved_magic, %eax 
 |      cmpl    $0x12345678, %eax 
 |      jne    bogus_magic 
 |    
 |      # jump to place where we left off 
 |      movl    saved_eip, %eax 
 |      jmp    *%eax 
 |    
 |  bogus_magic: 
 |      jmp    bogus_magic 
 |    
 |    
 |    
 |  save_registers: 
 |      sidt    saved_idt 
 |      sldt    saved_ldt 
 |      str    saved_tss 
 |    
 |      leal    4(%esp), %eax 
 |      movl    %eax, saved_context_esp 
 |      movl    %ebx, saved_context_ebx 
 |      movl    %ebp, saved_context_ebp 
 |      movl    %esi, saved_context_esi 
 |      movl    %edi, saved_context_edi 
 |      pushfl 
 |      popl    saved_context_eflags 
 |    
 |      movl    $ret_point, saved_eip 
 |      ret 
 |    
 |    
 |  restore_registers: 
 |      movl    saved_context_ebp, %ebp 
 |      movl    saved_context_ebx, %ebx 
 |      movl    saved_context_esi, %esi 
 |      movl    saved_context_edi, %edi 
 |      pushl    saved_context_eflags 
 |      popfl 
 |      ret 
 |    
 |  ENTRY(do_suspend_lowlevel) 
 |      call    save_processor_state 
 |      call    save_registers 
 |      pushl    $3 
 |      call    x86_acpi_enter_sleep_state 
 |      addl    $4, %esp 
 |    
 |  #    In case of S3 failure, we'll emerge here.  Jump 
 |  #     to ret_point to recover 
 |      jmp    ret_point 
 |      .p2align 4,,7 
 |  ret_point: 
 |      call    restore_registers 
 |      call    restore_processor_state 
 |      ret 
 |    
 |  .data 
 |  ALIGN 
 |  ENTRY(saved_magic)    .long    0 
 |  ENTRY(saved_eip)    .long    0 
 |    
 |  # saved registers 
 |  saved_idt:    .long    0,0 
 |  saved_ldt:    .long    0 
 |  saved_tss:    .long    0 
 |  
  |