1;------------------------------------------------------------------------------
2;
3; Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.<BR>
4; This program and the accompanying materials
5; are licensed and made available under the terms and conditions of the BSD License
6; which accompanies this distribution.  The full text of the license may be found at
7; http://opensource.org/licenses/bsd-license.php
8;
9; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11;
12; Module Name:
13;   ProcessorAsms.Asm
14;
15; Abstract:
16;   This is separated from processor.c to allow this functions to be built with /O1
17;
18;
19;------------------------------------------------------------------------------
20
21text  SEGMENT
22
23
24;
25; Routine Description:
26;   This allows the caller to switch the stack and goes to the new entry point
27;
28; Arguments:
29;   EntryPoint      - Pointer to the location to enter // rcx
30;   Parameter       - Parameter to pass in             // rdx
31;   NewStack        - New Location of the stack        // r8
32;   NewBsp          - New BSP                          // r9 - not used
33;
34; Returns:
35;   Nothing. Goes to the Entry Point passing in the new parameters
36;
37SwitchStacks  PROC  PUBLIC
38
39    ; Adjust stack for
40    ;   1) leave 4 registers space
41    ;   2) let it 16 bytes aligned after call
42    sub   r8, 20h
43    and   r8w, 0fff0h    ; do not assume 16 bytes aligned
44
45    mov   rsp,  r8       ; rsp = NewStack
46    mov   r10,  rcx      ; save EntryPoint
47    mov   rcx,  rdx      ; Arg1 = Parameter
48    call  r10            ; r10 = copy of EntryPoint
49 ;
50 ; no ret as we have a new stack and we jumped to the new location
51 ;
52    ret
53
54SwitchStacks    ENDP
55
56
57EFI_SUCCESS                     equ     0
58EFI_WARN_RETURN_FROM_LONG_JUMP  equ     5
59
60;
61; Generated by h2inc run manually
62;
63_EFI_JUMP_BUFFER                STRUCT 2t
64_rbx            QWORD           ?
65_rsp            QWORD           ?
66_rbp            QWORD           ?
67_rdi            QWORD           ?
68_rsi            QWORD           ?
69_r10            QWORD           ?
70_r11            QWORD           ?
71_r12            QWORD           ?
72_r13            QWORD           ?
73_r14            QWORD           ?
74_r15            QWORD           ?
75_rip            QWORD           ?
76_MxCsr          DWORD           ?
77_XmmBuffer      DB              160 DUP (?)
78_EFI_JUMP_BUFFER                ENDS
79
80EFI_JUMP_BUFFER         TYPEDEF         _EFI_JUMP_BUFFER
81
82
83;
84;Routine Description:
85;
86;  This routine implements the x64 variant of the SetJump call.  Its
87;  responsibility is to store system state information for a possible
88;  subsequent LongJump.
89;
90;Arguments:
91;
92;  Pointer to CPU context save buffer.
93;
94;Returns:
95;
96;  EFI_SUCCESS
97;
98; EFI_STATUS
99; EFIAPI
100; TransferControlLongJump (
101;   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,
102;   IN EFI_JUMP_BUFFER                    *Jump
103;   );
104;
105; rcx - *This
106; rdx - JumpBuffer
107;
108PUBLIC  TransferControlSetJump
109TransferControlSetJump  PROC
110  mov   (EFI_JUMP_BUFFER PTR [rdx])._rbx, rbx
111  mov   (EFI_JUMP_BUFFER PTR [rdx])._rsp, rsp
112  mov   (EFI_JUMP_BUFFER PTR [rdx])._rbp, rbp
113  mov   (EFI_JUMP_BUFFER PTR [rdx])._rdi, rdi
114  mov   (EFI_JUMP_BUFFER PTR [rdx])._rsi, rsi
115  mov   (EFI_JUMP_BUFFER PTR [rdx])._r10, r10
116  mov   (EFI_JUMP_BUFFER PTR [rdx])._r11, r11
117  mov   (EFI_JUMP_BUFFER PTR [rdx])._r12, r12
118  mov   (EFI_JUMP_BUFFER PTR [rdx])._r13, r13
119  mov   (EFI_JUMP_BUFFER PTR [rdx])._r14, r14
120  mov   (EFI_JUMP_BUFFER PTR [rdx])._r15, r15
121  ; save non-volatile fp registers
122  stmxcsr    (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
123  lea   rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
124  movdqu [rax], xmm6
125  movdqu [rax + 10h], xmm7
126  movdqu [rax + 20h], xmm8
127  movdqu [rax + 30h], xmm9
128  movdqu [rax + 40h], xmm10
129  movdqu [rax + 50h], xmm11
130  movdqu [rax + 60h], xmm12
131  movdqu [rax + 70h], xmm13
132  movdqu [rax + 80h], xmm14
133  movdqu [rax + 90h], xmm15
134  mov   rax, QWORD PTR [rsp+0]
135  mov   (EFI_JUMP_BUFFER PTR [rdx])._rip, rax
136  mov   rax, EFI_SUCCESS
137  ret
138
139TransferControlSetJump      ENDP
140
141;
142; EFI_STATUS
143; EFIAPI
144; TransferControlLongJump (
145;   IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL  *This,  // rcx
146;   IN EFI_JUMP_BUFFER                    *Jump   // rdx
147;   );
148;
149;
150PUBLIC  TransferControlLongJump
151TransferControlLongJump  PROC
152  ; load non-volatile fp registers
153  ldmxcsr    (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
154  lea   rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
155  movdqu xmm6, [rax]
156  movdqu xmm7, [rax + 10h]
157  movdqu xmm8, [rax + 20h]
158  movdqu xmm9, [rax + 30h]
159  movdqu xmm10, [rax + 40h]
160  movdqu xmm11, [rax + 50h]
161  movdqu xmm12, [rax + 60h]
162  movdqu xmm13, [rax + 70h]
163  movdqu xmm14, [rax + 80h]
164  movdqu xmm15, [rax + 90h]
165  ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
166  mov   rax, EFI_WARN_RETURN_FROM_LONG_JUMP
167  mov   rbx, (EFI_JUMP_BUFFER PTR [rdx])._rbx
168  mov   rsp, (EFI_JUMP_BUFFER PTR [rdx])._rsp
169  mov   rbp, (EFI_JUMP_BUFFER PTR [rdx])._rbp
170  mov   rdi, (EFI_JUMP_BUFFER PTR [rdx])._rdi
171  mov   rsi, (EFI_JUMP_BUFFER PTR [rdx])._rsi
172  mov   r10, (EFI_JUMP_BUFFER PTR [rdx])._r10
173  mov   r11, (EFI_JUMP_BUFFER PTR [rdx])._r11
174  mov   r12, (EFI_JUMP_BUFFER PTR [rdx])._r12
175  mov   r13, (EFI_JUMP_BUFFER PTR [rdx])._r13
176  mov   r14, (EFI_JUMP_BUFFER PTR [rdx])._r14
177  mov   r15, (EFI_JUMP_BUFFER PTR [rdx])._r15
178  add   rsp, 8                                       ;pop the eip
179  jmp   QWORD PTR (EFI_JUMP_BUFFER PTR [rdx])._rip
180  ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
181  mov   rax, EFI_WARN_RETURN_FROM_LONG_JUMP
182  ret
183TransferControlLongJump  ENDP
184
185text  ENDS
186END
187