1/* 2 * Copyright (C) 2018-2022 Intel Corporation. 3 * SPDX-License-Identifier: BSD-3-Clause 4 */ 5 6/* NOTE: 7 * 8 * MISRA C requires that all unsigned constants should have the suffix 'U' 9 * (e.g. 0xffU), but the assembler may not accept such C-style constants. For 10 * example, binutils 2.26 fails to compile assembly in that case. To work this 11 * around, all unsigned constants must be explicitly spells out in assembly 12 * with a comment tracking the original expression from which the magic 13 * number is calculated. As an example: 14 * 15 * /* 0x00000668 = 16 * * (CR4_DE | CR4_PAE | CR4_MCE | CR4_OSFXSR | CR4_OSXMMEXCPT) *\/ 17 * movl $0x00000668, %eax 18 * 19 * Make sure that these numbers are updated accordingly if the definition of 20 * the macros involved are changed. 21 */ 22 .text 23 .align 8 24 .code64 25 .extern restore_msrs 26 .extern cpu_ctx 27 .extern load_gdtr_and_tr 28 .extern do_acpi_sx 29 30 .global asm_enter_s3 31asm_enter_s3: 32 /* 33 * 0U=0x0=CPU_CONTEXT_OFFSET_RAX 34 * 8U=0x8=CPU_CONTEXT_OFFSET_RCX 35 * 16U=0x10=CPU_CONTEXT_OFFSET_RDX 36 * 24U=0x18=CPU_CONTEXT_OFFSET_RBX 37 * 32U=0x20=CPU_CONTEXT_OFFSET_RSP 38 * 40U=0x28=CPU_CONTEXT_OFFSET_RBP 39 * 48U=0x30=CPU_CONTEXT_OFFSET_RSI 40 * 56U=0x38=CPU_CONTEXT_OFFSET_RDI 41 * 64U=0x40=CPU_CONTEXT_OFFSET_R8 42 * 72U=0x48=CPU_CONTEXT_OFFSET_R9 43 * 80U=0x50=CPU_CONTEXT_OFFSET_R10 44 * 88U=0x58=CPU_CONTEXT_OFFSET_R11 45 * 96U=0x60=CPU_CONTEXT_OFFSET_R12 46 * 104U=0x68=CPU_CONTEXT_OFFSET_R13 47 * 112U=0x70=CPU_CONTEXT_OFFSET_R14 48 * 120U=0x78=CPU_CONTEXT_OFFSET_R15 49 */ 50 movq %rax, 0x0 + cpu_ctx(%rip) 51 movq %rcx, 0x8 + cpu_ctx(%rip) 52 movq %rdx, 0x10 + cpu_ctx(%rip) 53 movq %rbx, 0x18 + cpu_ctx(%rip) 54 movq %rsp, 0x20 + cpu_ctx(%rip) 55 movq %rbp, 0x28 + cpu_ctx(%rip) 56 movq %rsi, 0x30 + cpu_ctx(%rip) 57 movq %rdi, 0x38 + cpu_ctx(%rip) 58 movq %r8, 0x40 + cpu_ctx(%rip) 59 movq %r9, 0x48 + cpu_ctx(%rip) 60 movq %r10, 0x50 + cpu_ctx(%rip) 61 movq %r11, 0x58 + cpu_ctx(%rip) 62 movq %r12, 0x60 + cpu_ctx(%rip) 63 movq %r13, 0x68 + cpu_ctx(%rip) 64 movq %r14, 0x70 + cpu_ctx(%rip) 65 movq %r15, 0x78 + cpu_ctx(%rip) 66 67 pushfq 68 /*160U=0xa0=CPU_CONTEXT_OFFSET_RFLAGS*/ 69 popq 0xa0 + cpu_ctx(%rip) 70 71 /*192U=0xc0=CPU_CONTEXT_OFFSET_IDTR*/ 72 sidt 0xc0 + cpu_ctx(%rip) 73 /*216U=0xd8=CPU_CONTEXT_OFFSET_LDTR*/ 74 sldt 0xd8 + cpu_ctx(%rip) 75 76 mov %cr0, %rax 77 /*128U=0x80=CPU_CONTEXT_OFFSET_CR0*/ 78 mov %rax, 0x80 + cpu_ctx(%rip) 79 80 mov %cr3, %rax 81 /*184U=0xb8=CPU_CONTEXT_OFFSET_CR3*/ 82 mov %rax, 0xb8 + cpu_ctx(%rip) 83 84 mov %cr4, %rax 85 /*144U=0x90=CPU_CONTEXT_OFFSET_CR4*/ 86 mov %rax, 0x90 + cpu_ctx(%rip) 87 88 wbinvd 89 90 /*16U=0x10=CPU_CONTEXT_OFFSET_RDX*/ 91 movq 0x10 + cpu_ctx(%rip), %rdx /* pm1b_cnt_val */ 92 /*56U=0x38=CPU_CONTEXT_OFFSET_RDI*/ 93 movq 0x38 + cpu_ctx(%rip), %rdi /* pm sstate_data */ 94 /*48U=0x30=CPU_CONTEXT_OFFSET_RSI*/ 95 movq 0x30 + cpu_ctx(%rip), %rsi /* pm1a_cnt_val */ 96 97 call do_acpi_sx 98 99/* 100 * When system resume from S3, trampoline_start64 will 101 * jump to restore_s3_context after setup temporary stack. 102 */ 103.global restore_s3_context 104restore_s3_context: 105 /*144U=0x90=CPU_CONTEXT_OFFSET_CR4*/ 106 mov 0x90 + cpu_ctx(%rip), %rax 107 mov %rax, %cr4 108 109 /*184U=0xb8=CPU_CONTEXT_OFFSET_CR3*/ 110 mov 0xb8 + cpu_ctx(%rip), %rax 111 mov %rax, %cr3 112 113 /*128U=0x80=CPU_CONTEXT_OFFSET_CR0*/ 114 mov 0x80 + cpu_ctx(%rip), %rax 115 mov %rax, %cr0 116 117 /*192U=0xc0=CPU_CONTEXT_OFFSET_IDTR*/ 118 lidt 0xc0 + cpu_ctx(%rip) 119 /*216U=0xd8=CPU_CONTEXT_OFFSET_LDTR*/ 120 lldt 0xd8 + cpu_ctx(%rip) 121 122 /*32=0x20=CPU_CONTEXT_OFFSET_RSP*/ 123 movq 0x20 + cpu_ctx(%rip), %rsp 124 125 /*160U=0xa0=CPU_CONTEXT_OFFSET_RFLAGS*/ 126 pushq 0xa0 + cpu_ctx(%rip) 127 popfq 128 129 stac 130 call load_gdtr_and_tr 131 clac 132 call restore_msrs 133 134 /* 135 * 0U=0x0=CPU_CONTEXT_OFFSET_RAX 136 * 8U=0x8=CPU_CONTEXT_OFFSET_RCX 137 * 16U=0x10=CPU_CONTEXT_OFFSET_RDX 138 * 24U=0x18=CPU_CONTEXT_OFFSET_RBX 139 * 40U=0x28=CPU_CONTEXT_OFFSET_RBP 140 * 48U=0x30=CPU_CONTEXT_OFFSET_RSI 141 * 56U=0x38=CPU_CONTEXT_OFFSET_RDI 142 * 64U=0x40=CPU_CONTEXT_OFFSET_R8 143 * 72U=0x48=CPU_CONTEXT_OFFSET_R9 144 * 80U=0x50=CPU_CONTEXT_OFFSET_R10 145 * 88U=0x58=CPU_CONTEXT_OFFSET_R11 146 * 96U=0x60=CPU_CONTEXT_OFFSET_R12 147 * 104U=0x68=CPU_CONTEXT_OFFSET_R13 148 * 112U=0x70=CPU_CONTEXT_OFFSET_R14 149 * 120U=0x79=CPU_CONTEXT_OFFSET_R15 150 */ 151 movq 0x0 + cpu_ctx(%rip), %rax 152 movq 0x8 + cpu_ctx(%rip), %rcx 153 movq 0x10 + cpu_ctx(%rip), %rdx 154 movq 0x18 + cpu_ctx(%rip), %rbx 155 movq 0x28 + cpu_ctx(%rip), %rbp 156 movq 0x30 + cpu_ctx(%rip), %rsi 157 movq 0x38 + cpu_ctx(%rip), %rdi 158 movq 0x40 + cpu_ctx(%rip), %r8 159 movq 0x48 + cpu_ctx(%rip), %r9 160 movq 0x50 + cpu_ctx(%rip), %r10 161 movq 0x58 + cpu_ctx(%rip), %r11 162 movq 0x60 + cpu_ctx(%rip), %r12 163 movq 0x68 + cpu_ctx(%rip), %r13 164 movq 0x70 + cpu_ctx(%rip), %r14 165 movq 0x78 + cpu_ctx(%rip), %r15 166 167 retq 168