Use / as path separator
[people/mcb30/edk2.git] / edk2 / EdkModulePkg / Core / Pei / Ipf / IpfCpuCore.s
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  "Ipf/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