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