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