summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/X64/ProcessorAsms.S
blob: 2d464488cc2fea7593cf0a140752a0425f99a650 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#------------------------------------------------------------------------------
#
# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials                          
# are licensed and made available under the terms and conditions of the BSD License         
# which accompanies this distribution.  The full text of the license may be found at        
# http://opensource.org/licenses/bsd-license.php                                            
#                                                                                           
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
# 
# Module Name:
#   ProcessorAsms.S
#
# Abstract:
#   This is separated from processor.c to allow this functions to be built with /O1
#
#
#------------------------------------------------------------------------------
#include <EfiBind.h>

    .text

.globl ASM_PFX(SwitchStacks)
.globl ASM_PFX(TransferControlSetJump)
.globl ASM_PFX(TransferControlLongJump)

#
# Routine Description:
#   This allows the caller to switch the stack and goes to the new entry point
#
# Arguments:
#   EntryPoint      - Pointer to the location to enter // rcx
#   Parameter       - Parameter to pass in             // rdx
#   NewStack        - New Location of the stack        // r8
#   NewBsp          - New BSP                          // r9 - not used
#
# Returns:
#   Nothing. Goes to the Entry Point passing in the new parameters
#
ASM_PFX(SwitchStacks):

    # Adjust stack for
    #   1) leave 4 registers space
    #   2) let it 16 bytes aligned after call
    sub    $0x20,%r8
    and    -0x10,%r8w   # do not assume 16 bytes aligned

  	mov    %r8,%rsp
  	mov    %rcx,%r10
  	mov    %rdx,%rcx
  	callq  *%r10

 #
 # no ret as we have a new stack and we jumped to the new location
 #     
    ret

#SwitchStacks ENDP


.equ                            EFI_SUCCESS, 0
.equ                            EFI_WARN_RETURN_FROM_LONG_JUMP, 5

#
#Routine Description:
#
#  This routine implements the x64 variant of the SetJump call.  Its
#  responsibility is to store system state information for a possible
#  subsequent LongJump.
#
#Arguments:
#
#  Pointer to CPU context save buffer.
#
#Returns:
#
#  EFI_SUCCESS
#
# EFI_STATUS
# EFIAPI
# TransferControlLongJump (
#   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,
#   IN EFI_JUMP_BUFFER                    *Jump
#   );
#
# rcx - *This
# rdx - JumpBuffer
#
ASM_PFX(TransferControlSetJump):
      mov    %rbx,(%rdx)
      mov    %rsp,0x8(%rdx)
      mov    %rbp,0x10(%rdx)
      mov    %rdi,0x18(%rdx)
      mov    %rsi,0x20(%rdx)
      mov    %r10,0x28(%rdx)
      mov    %r11,0x30(%rdx)
      mov    %r12,0x38(%rdx)
      mov    %r13,0x40(%rdx)
      mov    %r14,0x48(%rdx)
      mov    %r15,0x50(%rdx)
      #; save non-volatile fp registers
      stmxcsr 0x60(%rdx)
      lea     0x68(%rdx), %rax
      movdqu  %xmm6, (%rax) 
      movdqu  %xmm7, 0x10(%rax)
      movdqu  %xmm8, 0x20(%rax)
      movdqu  %xmm9, 0x30(%rax)
      movdqu  %xmm10, 0x40(%rax)
      movdqu  %xmm11, 0x50(%rax)
      movdqu  %xmm12, 0x60(%rax)
      movdqu  %xmm13, 0x70(%rax)
      movdqu  %xmm14, 0x80(%rax)
      movdqu  %xmm15, 0x90(%rax)
      mov    (%rsp),%rax
      mov    %rax,0x58(%rdx)
      mov    $0x0,%rax
      retq   


#
# EFI_STATUS
# EFIAPI
# TransferControlLongJump (
#   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,  // rcx
#   IN EFI_JUMP_BUFFER                    *Jump   // rdx
#   );
#
#
ASM_PFX(TransferControlLongJump):
      # set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
      #; load non-volatile fp registers
      ldmxcsr 0x60(%rdx)
      lea     0x68(%rdx), %rax
      movdqu  (%rax), %xmm6
      movdqu  0x10(%rax), %xmm7
      movdqu  0x20(%rax), %xmm8
      movdqu  0x30(%rax), %xmm9
      movdqu  0x40(%rax), %xmm10
      movdqu  0x50(%rax), %xmm11
      movdqu  0x60(%rax), %xmm12
      movdqu  0x70(%rax), %xmm13
      movdqu  0x80(%rax), %xmm14
      movdqu  0x90(%rax), %xmm15
      mov    $0x5,%rax
      mov    (%rdx),%rbx
      mov    0x8(%rdx),%rsp
      mov    0x10(%rdx),%rbp
      mov    0x18(%rdx),%rdi
      mov    0x20(%rdx),%rsi
      mov    0x28(%rdx),%r10
      mov    0x30(%rdx),%r11
      mov    0x38(%rdx),%r12
      mov    0x40(%rdx),%r13
      mov    0x48(%rdx),%r14
      mov    0x50(%rdx),%r15
      add    $0x8,%rsp
      jmpq   *0x58(%rdx)
      mov    $0x5,%rax
      retq