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