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