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
|