1// Copyright 2017 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6//
7
8#include <asm.h>
9
10/*
11struct x86_realmode_entry_data_registers {
12    uint64_t rdi, rsi, rbp, rbx, rdx, rcx, rax;
13    uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
14    uint64_t rsp, rip;
15};
16*/
17.code64
18.section .text
19// ACPI_STATUS x86_acpi_transition_s_state(struct x86_realmode_entry_data_registers* reg,
20//                                         uint8_t target_s_state, uint8_t sleep_type_a,
21//                                         uint8_t sleep_type_b)
22FUNCTION_LABEL(x86_acpi_transition_s_state)
23    // We do not need to save floating point registers, since this method must be called
24    // by a kernel thread if the system is expected to return from the S-state.
25    mov %rdi, (%rdi)
26    mov %rsi, 8(%rdi)
27    mov %rbp, 16(%rdi)
28    mov %rbx, 24(%rdi)
29    mov %rdx, 32(%rdi)
30    mov %rcx, 40(%rdi)
31    // Stash 0 as rax, so we return AE_OK if we do suspend
32    movq $0, 48(%rdi)
33    mov %r8, 56(%rdi)
34    mov %r9, 64(%rdi)
35    mov %r10, 72(%rdi)
36    mov %r11, 80(%rdi)
37    mov %r12, 88(%rdi)
38    mov %r13, 96(%rdi)
39    mov %r14, 104(%rdi)
40    mov %r15, 112(%rdi)
41    mov %rsp, 120(%rdi)
42
43    // Set up our return IP, in case the S-state needs it (jumped to by _x86_suspend_wakeup())
44    leaq .Lafter_sleep(%rip), %rax
45    movq %rax, 128(%rdi)
46
47    // Enter the sleep state
48    sub $8, %rsp
49    mov %rsi, %rdi
50    mov %rdx, %rsi
51    mov %rcx, %rdx
52    call AcpiHwLegacySleepFinal
53    add $8, %rsp
54.Lafter_sleep:
55    ret
56