1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | .text |
3 | #include <linux/linkage.h> |
4 | #include <asm/segment.h> |
5 | #include <asm/page.h> |
6 | #include <asm/pgtable_32.h> |
7 | |
8 | .macro writepost,value |
9 | movb $0x34, %al |
10 | outb %al, $0x70 |
11 | movb $\value, %al |
12 | outb %al, $0x71 |
13 | .endm |
14 | |
15 | wakeup_start: |
16 | # OFW lands us here, running in protected mode, with a |
17 | # kernel-compatible GDT already setup. |
18 | |
19 | # Clear any dangerous flags |
20 | pushl $0 |
21 | popfl |
22 | |
23 | writepost 0x31 |
24 | |
25 | # Set up %cr3 |
26 | movl $initial_page_table - __PAGE_OFFSET, %eax |
27 | movl %eax, %cr3 |
28 | |
29 | movl saved_cr4, %eax |
30 | movl %eax, %cr4 |
31 | |
32 | movl saved_cr0, %eax |
33 | movl %eax, %cr0 |
34 | |
35 | # Control registers were modified, pipeline resync is needed |
36 | jmp 1f |
37 | 1: |
38 | |
39 | movw $__KERNEL_DS, %ax |
40 | movw %ax, %ss |
41 | movw %ax, %ds |
42 | movw %ax, %es |
43 | movw %ax, %fs |
44 | movw %ax, %gs |
45 | |
46 | lgdt saved_gdt |
47 | lidt saved_idt |
48 | lldt saved_ldt |
49 | ljmp $(__KERNEL_CS),$1f |
50 | 1: |
51 | movl %cr3, %eax |
52 | movl %eax, %cr3 |
53 | wbinvd |
54 | |
55 | # Go back to the return point |
56 | jmp ret_point |
57 | |
58 | save_registers: |
59 | sgdt saved_gdt |
60 | sidt saved_idt |
61 | sldt saved_ldt |
62 | |
63 | pushl %edx |
64 | movl %cr4, %edx |
65 | movl %edx, saved_cr4 |
66 | |
67 | movl %cr0, %edx |
68 | movl %edx, saved_cr0 |
69 | |
70 | popl %edx |
71 | |
72 | movl %ebx, saved_context_ebx |
73 | movl %ebp, saved_context_ebp |
74 | movl %esi, saved_context_esi |
75 | movl %edi, saved_context_edi |
76 | |
77 | pushfl |
78 | popl saved_context_eflags |
79 | |
80 | RET |
81 | |
82 | restore_registers: |
83 | movl saved_context_ebp, %ebp |
84 | movl saved_context_ebx, %ebx |
85 | movl saved_context_esi, %esi |
86 | movl saved_context_edi, %edi |
87 | |
88 | pushl saved_context_eflags |
89 | popfl |
90 | |
91 | RET |
92 | |
93 | SYM_CODE_START(do_olpc_suspend_lowlevel) |
94 | call save_processor_state |
95 | call save_registers |
96 | |
97 | # This is the stack context we want to remember |
98 | movl %esp, saved_context_esp |
99 | |
100 | pushl $3 |
101 | call xo1_do_sleep |
102 | |
103 | jmp wakeup_start |
104 | .p2align 4,,7 |
105 | ret_point: |
106 | movl saved_context_esp, %esp |
107 | |
108 | writepost 0x32 |
109 | |
110 | call restore_registers |
111 | call restore_processor_state |
112 | RET |
113 | SYM_CODE_END(do_olpc_suspend_lowlevel) |
114 | |
115 | .data |
116 | saved_gdt: .long 0,0 |
117 | saved_idt: .long 0,0 |
118 | saved_ldt: .long 0 |
119 | saved_cr4: .long 0 |
120 | saved_cr0: .long 0 |
121 | saved_context_esp: .long 0 |
122 | saved_context_edi: .long 0 |
123 | saved_context_esi: .long 0 |
124 | saved_context_ebx: .long 0 |
125 | saved_context_ebp: .long 0 |
126 | saved_context_eflags: .long 0 |
127 | |