--- /dev/null
+//++\r
+// Copyright (c) 2004, Intel Corporation \r
+// All rights reserved. This program and the accompanying materials \r
+// are licensed and made available under the terms and conditions of the BSD License \r
+// which accompanies this distribution. The full text of the license may be found at \r
+// http://opensource.org/licenses/bsd-license.php \r
+// \r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+// \r
+// Module Name:\r
+//\r
+// SwitchStack.s\r
+//\r
+// Abstract:\r
+//\r
+// Contains an implementation of a stack switch for the Itanium-based architecture.\r
+//\r
+//\r
+//\r
+// Revision History:\r
+//\r
+//--\r
+\r
+ .file "SwitchStack.s"\r
+\r
+#include <asm.h>\r
+#include <ia_64gen.h>\r
+\r
+// Define hardware RSE Configuration Register\r
+//\r
+// RS Configuration (RSC) bit field positions\r
+\r
+#define RSC_MODE 0\r
+#define RSC_PL 2\r
+#define RSC_BE 4\r
+// RSC bits 5-15 reserved\r
+#define RSC_MBZ0 5\r
+#define RSC_MBZ0_V 0x3ff\r
+#define RSC_LOADRS 16\r
+#define RSC_LOADRS_LEN 14\r
+// RSC bits 30-63 reserved\r
+#define RSC_MBZ1 30\r
+#define RSC_MBZ1_V 0x3ffffffffULL\r
+\r
+// RSC modes\r
+// Lazy\r
+#define RSC_MODE_LY (0x0)\r
+// Store intensive\r
+#define RSC_MODE_SI (0x1)\r
+// Load intensive\r
+#define RSC_MODE_LI (0x2)\r
+// Eager\r
+#define RSC_MODE_EA (0x3)\r
+\r
+// RSC Endian bit values\r
+#define RSC_BE_LITTLE 0\r
+#define RSC_BE_BIG 1\r
+\r
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode\r
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode\r
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+// RSE disabled: disabled, pl = 0, little endian, eager mode\r
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))\r
+\r
+\r
+//VOID\r
+//SwitchStacks (\r
+// VOID *ContinuationFunction,\r
+// UINTN Parameter,\r
+// UINTN NewTopOfStack,\r
+// UINTN NewBSPStore OPTIONAL\r
+//)\r
+///*++\r
+//\r
+//Input Arguments\r
+//\r
+// ContinuationFunction - This is a pointer to the PLABEL of the function that should be called once the\r
+// new stack has been created. \r
+// Parameter - The parameter to pass to the continuation function\r
+// NewTopOfStack - This is the new top of the memory stack for ensuing code. This is mandatory and\r
+// should be non-zero\r
+// NewBSPStore - This is the new BSP store for the ensuing code. It is optional on IA-32 and mandatory on Itanium-based platform.\r
+//\r
+//--*/\r
+\r
+PROCEDURE_ENTRY(SwitchStacks)\r
+\r
+ mov r16 = -0x10;;\r
+ and r16 = r34, r16;; // get new stack value in R16, 0 the last nibble.\r
+ mov r15 = r35;; // Get new BspStore into R15\r
+ mov r13 = r32;; // this is a pointer to the PLABEL of the continuation function. \r
+ mov r17 = r33;; // this is the parameter to pass to the continuation function\r
+\r
+ alloc r11=0,0,0,0 // Set 0-size frame\r
+ ;;\r
+ flushrs;;\r
+\r
+ mov r21 = RSC_KERNEL_DISABLED // for rse disable \r
+ ;;\r
+ mov ar.rsc = r21 // turn off RSE \r
+\r
+ add sp = r0, r16;; // transfer to the EFI stack\r
+ mov ar.bspstore = r15 // switch to EFI BSP \r
+ invala // change of ar.bspstore needs invala. \r
+ \r
+ mov r18 = RSC_KERNEL_LAZ // RSC enabled, Lazy mode\r
+ ;;\r
+ mov ar.rsc = r18 // turn rse on, in kernel mode \r
+ ;; \r
+ alloc r11=0,0,1,0;; // alloc 0 outs going to ensuing DXE IPL service\r
+ mov out0 = r17\r
+ ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL\r
+ ld8 gp = [r13] // gp = gp of continuation function from the PLABEL\r
+ mov b6 = r16\r
+ ;;\r
+ br.call.sptk.few b0=b6;; // Call the continuation function\r
+ ;;\r
+PROCEDURE_EXIT(SwitchStacks)\r
+\r
+\r