Changed SwitchStack() to _SwitchStack()
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ipf / SwitchStack.s
1 //++
2 // Copyright (c) 2006, Intel Corporation
3 // All rights reserved. This program and the accompanying materials
4 // are licensed and made available under the terms and conditions of the BSD License
5 // which accompanies this distribution. The full text of the license may be found at
6 // http://opensource.org/licenses/bsd-license.php
7 //
8 // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 //
11 // Module Name:
12 //
13 // SwitchStack.s
14 //
15 // Abstract:
16 //
17 // Contains an implementation of a stack switch for the Itanium-based architecture.
18 //
19 //
20 //
21 // Revision History:
22 //
23 //--
24
25 .file "SwitchStack.s"
26
27 #include "asm.h"
28 #include "ia_64gen.h"
29
30 // Define hardware RSE Configuration Register
31 //
32 // RS Configuration (RSC) bit field positions
33
34 #define RSC_MODE 0
35 #define RSC_PL 2
36 #define RSC_BE 4
37 // RSC bits 5-15 reserved
38 #define RSC_MBZ0 5
39 #define RSC_MBZ0_V 0x3ff
40 #define RSC_LOADRS 16
41 #define RSC_LOADRS_LEN 14
42 // RSC bits 30-63 reserved
43 #define RSC_MBZ1 30
44 #define RSC_MBZ1_V 0x3ffffffffULL
45
46 // RSC modes
47 // Lazy
48 #define RSC_MODE_LY (0x0)
49 // Store intensive
50 #define RSC_MODE_SI (0x1)
51 // Load intensive
52 #define RSC_MODE_LI (0x2)
53 // Eager
54 #define RSC_MODE_EA (0x3)
55
56 // RSC Endian bit values
57 #define RSC_BE_LITTLE 0
58 #define RSC_BE_BIG 1
59
60 // RSC while in kernel: enabled, little endian, pl = 0, eager mode
61 #define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
62 // Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
63 #define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
64 // RSE disabled: disabled, pl = 0, little endian, eager mode
65 #define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
66
67
68 //VOID
69 //_SwitchStack (
70 // VOID *ContinuationFunction,
71 // UINTN Parameter,
72 // UINTN NewTopOfStack,
73 // UINTN NewBSPStore OPTIONAL
74 //)
75 ///*++
76 //
77 //Input Arguments
78 //
79 // ContinuationFunction - This is a pointer to the PLABEL of the function that should be called once the
80 // new stack has been created.
81 // Parameter - The parameter to pass to the continuation function
82 // NewTopOfStack - This is the new top of the memory stack for ensuing code. This is mandatory and
83 // should be non-zero
84 // NewBSPStore - This is the new BSP store for the ensuing code. It is optional on IA-32 and mandatory on Itanium-based platform.
85 //
86 //--*/
87
88 PROCEDURE_ENTRY(_SwitchStack)
89
90 mov r16 = -0x10;;
91 and r16 = r34, r16;; // get new stack value in R16, 0 the last nibble.
92 mov r15 = r35;; // Get new BspStore into R15
93 mov r13 = r32;; // this is a pointer to the PLABEL of the continuation function.
94 mov r17 = r33;; // this is the parameter to pass to the continuation function
95
96 alloc r11=0,0,0,0 // Set 0-size frame
97 ;;
98 flushrs;;
99
100 mov r21 = RSC_KERNEL_DISABLED // for rse disable
101 ;;
102 mov ar.rsc = r21 // turn off RSE
103
104 add sp = r0, r16;; // transfer to the EFI stack
105 mov ar.bspstore = r15 // switch to EFI BSP
106 invala // change of ar.bspstore needs invala.
107
108 mov r18 = RSC_KERNEL_LAZ // RSC enabled, Lazy mode
109 ;;
110 mov ar.rsc = r18 // turn rse on, in kernel mode
111 ;;
112 alloc r11=0,0,1,0;; // alloc 0 outs going to ensuing DXE IPL service
113 mov out0 = r17
114 ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
115 ld8 gp = [r13] // gp = gp of continuation function from the PLABEL
116 mov b6 = r16
117 ;;
118 br.call.sptk.few b0=b6;; // Call the continuation function
119 ;;
120 PROCEDURE_EXIT(_SwitchStack)
121
122