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