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 | // IpfCpuCore.s\r |
14 | //\r |
15 | // Abstract:\r |
16 | // IPF Specific assembly routines\r |
17 | //\r |
18 | //-- \r |
19 | \r |
20 | .file "IpfCpuCore.s"\r |
21 | \r |
22 | #include "IpfMacro.i"\r |
23 | #include "IpfCpuCore.i"\r |
24 | \r |
25 | //----------------------------------------------------------------------------------\r |
26 | // This module supports terminating CAR (Cache As RAM) stage. It copies all the\r |
27 | // CAR data into real RAM and then makes a stack switch.\r |
28 | \r |
29 | // EFI_STATUS\r |
30 | // SwitchCoreStacks (\r |
31 | // IN VOID *EntryPoint,\r |
32 | // IN UINTN CopySize,\r |
33 | // IN VOID *OldBase,\r |
34 | // IN VOID *NewBase\r |
35 | // IN UINTN NewSP, OPTIONAL\r |
36 | // IN UINTN NewBSP OPTIONAL\r |
37 | // )\r |
38 | // EFI_STATUS\r |
39 | // SwitchCoreStacks (\r |
40 | // IN VOID *EntryPointForContinuationFunction,\r |
41 | // IN UINTN StartupDescriptor,\r |
42 | // IN VOID PEICorePointer,\r |
43 | // IN UINTN NewSP\r |
44 | // )\r |
45 | //----------------------------------------------------------------------------------\r |
46 | PROCEDURE_ENTRY (SwitchCoreStacks)\r |
47 | \r |
48 | NESTED_SETUP (4,2,0,0)\r |
49 | \r |
50 | // first save all stack registers in GPRs.\r |
51 | mov r13 = in0;; // this is a pointer to the PLABEL of the continuation function. \r |
52 | ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL\r |
53 | ld8 gp = [r13];; // gp = gp of continuation function from the PLABEL\r |
54 | mov b1 = r16;;\r |
55 | \r |
56 | // save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls\r |
57 | mov r5 = in1;; // this is the parameter1 to pass to the continuation function\r |
58 | mov r6 = in2;; // this is the parameter2 to pass to the continuation function\r |
59 | dep r6=0,r6,63,1;; // zero the bit 63.\r |
60 | \r |
61 | mov r8 = in3;; // new stack pointer.\r |
62 | \r |
63 | // r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore \r |
64 | movl r15 = PEI_BSP_STORE_SIZE;;\r |
65 | sub r8 = r8, r15;;\r |
66 | add r15 = (GuardBand),r8;; // some little buffer, now r15 will be our bspstore\r |
67 | \r |
68 | // save the bspstore value to r4, save sp value to r7\r |
69 | mov r4 = r15\r |
70 | mov r7 = r8\r |
71 | mov r16 = r8;; // will be the new sp in uncache mode\r |
72 | \r |
73 | \r |
74 | alloc r11=0,0,0,0;; // Set 0-size frame\r |
75 | flushrs;;\r |
76 | \r |
77 | mov r21 = RSC_KERNEL_DISABLED;; // for rse disable \r |
78 | mov ar.rsc = r21;; // turn off RSE \r |
79 | \r |
80 | add sp = r0, r16 // transfer to the EFI stack\r |
81 | mov ar.bspstore = r15 // switch to EFI BSP \r |
82 | invala // change of ar.bspstore needs invala. \r |
83 | \r |
84 | mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode\r |
85 | mov ar.rsc = r19;; // turn rse on, in kernel mode \r |
86 | \r |
87 | //-----------------------------------------------------------------------------------\r |
88 | // Save here the meaningful stuff for next few lines and then make the PAL call.\r |
89 | // Make PAL call to terminate the CAR status.\r |
90 | // AVL: do this only for recovery check call...\r |
91 | \r |
92 | mov r28=ar.k3;;\r |
93 | dep r2 = r28,r0,0,8;; // Extract Function bits from GR20.\r |
94 | cmp.eq p6,p7 = RecoveryFn,r2;; // Is it Recovery check \r |
95 | (p7) br.sptk.few DoneCARTermination; // if not, don't terminate car..\r |
96 | \r |
97 | TerminateCAR::\r |
98 | \r |
99 | mov r28 = ip;;\r |
100 | add r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;\r |
101 | mov b0 = r28\r |
102 | \r |
103 | mov r8 = ar.k5;;\r |
104 | mov b6 = r8\r |
105 | mov r28 = 0x208\r |
106 | \r |
107 | mov r29 = r0\r |
108 | mov r30 = r0\r |
109 | mov r31 = r0\r |
110 | mov r8 = r0;;\r |
111 | br.sptk.few b6;; // Call PAL-A call.\r |
112 | \r |
113 | DoneCARTerminationPALCall::\r |
114 | \r |
115 | // don't check error in soft sdv, it is always returning -1 for this call for some reason\r |
116 | #if SOFT_SDV\r |
117 | #else\r |
118 | ReturnToPEIMain::\r |
119 | cmp.eq p6,p7 = r8,r0;;\r |
120 | //\r |
121 | // dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory\r |
122 | //\r |
123 | (p7) br.sptk.few ReturnToPEIMain;; \r |
124 | //\r |
125 | // PAL call successed,now the stack are in memory so come into cache mode \r |
126 | // instead of uncache mode\r |
127 | //\r |
128 | \r |
129 | alloc r11=0,0,0,0;; // Set 0-size frame\r |
130 | flushrs;;\r |
131 | \r |
132 | mov r21 = RSC_KERNEL_DISABLED;; // for rse disable \r |
133 | mov ar.rsc = r21;; // turn off RSE \r |
134 | \r |
135 | dep r6 = 0,r6,63,1 // zero the bit 63 \r |
136 | dep r7 = 0,r7,63,1 // zero the bit 63 \r |
137 | dep r4 = 0,r4,63,1;; // zero the bit 63 \r |
138 | add sp = r0, r7 // transfer to the EFI stack in cache mode \r |
139 | mov ar.bspstore = r4 // switch to EFI BSP \r |
140 | invala // change of ar.bspstore needs invala. \r |
141 | \r |
142 | mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode\r |
143 | mov ar.rsc = r19;; // turn rse on, in kernel mode\r |
144 | \r |
145 | #endif\r |
146 | \r |
147 | DoneCARTermination:: \r |
148 | \r |
149 | // allocate a stack frame: \r |
150 | alloc r11=0,2,2,0 ;; // alloc outs going to ensuing DXE IPL service\r |
151 | // on the new stack\r |
152 | mov out0 = r5;;\r |
153 | mov out1 = r6;; \r |
154 | \r |
155 | mov r16 = b1;;\r |
156 | mov b6 = r16;;\r |
157 | br.call.sptk.few b0=b6;; // Call the continuation function\r |
158 | \r |
159 | NESTED_RETURN\r |
160 | \r |
161 | PROCEDURE_EXIT(SwitchCoreStacks)\r |
162 | //-----------------------------------------------------------------------------------\r |
163 | \r |
164 | //---------------------------------------------------------------------------------\r |
165 | //++\r |
166 | // GetHandOffStatus\r |
167 | //\r |
168 | // This routine is called by all processors simultaneously, to get some hand-off\r |
169 | // status that has been captured by IPF dispatcher and recorded in kernel registers.\r |
170 | //\r |
171 | // Arguments : \r |
172 | //\r |
173 | // On Entry : None.\r |
174 | //\r |
175 | // Return Value: Lid, R20Status.\r |
176 | // \r |
177 | //--\r |
178 | //----------------------------------------------------------------------------------\r |
179 | PROCEDURE_ENTRY (GetHandOffStatus)\r |
180 | \r |
181 | NESTED_SETUP (0,2+0,0,0)\r |
182 | \r |
183 | mov r8 = ar.k6 // Health Status (Self test params)\r |
184 | mov r9 = ar.k4 // LID bits\r |
185 | mov r10 = ar.k3;; // SAL_E entry state\r |
186 | mov r11 = ar.k7 // Return address to PAL\r |
187 | \r |
188 | NESTED_RETURN\r |
189 | PROCEDURE_EXIT (GetHandOffStatus)\r |
190 | //----------------------------------------------------------------------------------\r |
191 | \r |
192 | \r |