/** @file
  Real Mode Thunk Functions for IA32 and X64.

  Copyright (c) 2006, Intel Corporation<BR>
  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:  x86Thunk.c

**/

//
// Byte packed structure for a segment descriptor in a GDT/LDT
//
typedef union {
  struct {
    UINT32  LimitLow:16;
    UINT32  BaseLow:16;
    UINT32  BaseMid:8;
    UINT32  Type:4;
    UINT32  S:1;
    UINT32  DPL:2;
    UINT32  P:1;
    UINT32  LimitHigh:4;
    UINT32  AVL:1;
    UINT32  L:1;
    UINT32  DB:1;
    UINT32  G:1;
    UINT32  BaseHigh:8;
  } Bits;
  UINT64  Uint64;
} IA32_SEGMENT_DESCRIPTOR;

extern CONST UINT8                  m16Start;
extern CONST UINT16                 m16Size;
extern CONST UINT16                 mThunk16Attr;
extern CONST UINT16                 m16Gdt;
extern CONST UINT16                 m16GdtrBase;
extern CONST UINT16                 mTransition;

/**
  Invokes 16-bit code in big real mode and returns the updated register set.

  This function transfers control to the 16-bit code specified by CS:EIP using
  the stack specified by SS:ESP in RegisterSet. The updated registers are saved
  on the real mode stack and the starting address of the save area is returned.

  @param  RegisterSet Values of registers before invocation of 16-bit code.
  @param  Transition  Pointer to the transition code under 1MB.

  @return The pointer to a IA32_REGISTER_SET structure containing the updated
          register values.

**/
IA32_REGISTER_SET *
InternalAsmThunk16 (
  IN      IA32_REGISTER_SET         *RegisterSet,
  IN OUT  VOID                      *Transition
  );

/**
  Retrieves the properties for 16-bit thunk functions.

  Computes the size of the buffer and stack below 1MB required to use the
  AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This
  buffer size is returned in RealModeBufferSize, and the stack size is returned
  in ExtraStackSize. If parameters are passed to the 16-bit real mode code,
  then the actual minimum stack size is ExtraStackSize plus the maximum number
  of bytes that need to be passed to the 16-bit real mode code.

  If RealModeBufferSize is NULL, then ASSERT().
  If ExtraStackSize is NULL, then ASSERT().

  @param  RealModeBufferSize  A pointer to the size of the buffer below 1MB
                              required to use the 16-bit thunk functions.
  @param  ExtraStackSize      A pointer to the extra size of stack below 1MB
                              that the 16-bit thunk functions require for
                              temporary storage in the transition to and from
                              16-bit real mode.

**/
VOID
EFIAPI
AsmGetThunk16Properties (
  OUT     UINT32                    *RealModeBufferSize,
  OUT     UINT32                    *ExtraStackSize
  )
{
  ASSERT (RealModeBufferSize != NULL);
  ASSERT (ExtraStackSize != NULL);

  *RealModeBufferSize = m16Size;

  //
  // Extra 4 bytes for return address, and another 4 bytes for mode transition
  //
  *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8;
}

/**
  Prepares all structures a code required to use AsmThunk16().

  Prepares all structures and code required to use AsmThunk16().

  If ThunkContext is NULL, then ASSERT().

  @param  ThunkContext  A pointer to the context structure that describes the
                        16-bit real mode code to call.

**/
VOID
EFIAPI
AsmPrepareThunk16 (
  OUT     THUNK_CONTEXT             *ThunkContext
  )
{
  IA32_SEGMENT_DESCRIPTOR           *RealModeGdt;

  ASSERT (ThunkContext != NULL);
  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);
  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);
  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

  CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size);

  //
  // Point RealModeGdt to the GDT to be used in transition
  //
  // RealModeGdt[0]: Reserved as NULL descriptor
  // RealModeGdt[1]: Code Segment
  // RealModeGdt[2]: Data Segment
  // RealModeGdt[3]: Call Gate
  //
  RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)(
                  (UINTN)ThunkContext->RealModeBuffer + m16Gdt);

  //
  // Update Code & Data Segment Descriptor
  //
  RealModeGdt[1].Bits.BaseLow =
    (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf;
  RealModeGdt[1].Bits.BaseMid =
    (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16;

  //
  // Update transition code entry point offset
  //
  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) +=
    (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf;

  //
  // Update Segment Limits for both Code and Data Segment Descriptors
  //
  if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) {
    //
    // Set segment limits to 64KB
    //
    RealModeGdt[1].Bits.LimitHigh = 0;
    RealModeGdt[1].Bits.G = 0;
    RealModeGdt[2].Bits.LimitHigh = 0;
    RealModeGdt[2].Bits.G = 0;
  }

  //
  // Update GDTBASE for this thunk context
  //
  *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt;

  //
  // Update Thunk Attributes
  //
  *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) =
    ThunkContext->ThunkAttributes;
}

/**
  Transfers control to a 16-bit real mode entry point and returns the results.

  Transfers control to a 16-bit real mode entry point and returns the results.
  AsmPrepareThunk16() must be called with ThunkContext before this function is
  used. This function must be called with interrupts disabled.

  If ThunkContext is NULL, then ASSERT().
  If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().

  @param  ThunkContext  A pointer to the context structure that describes the
                        16-bit real mode code to call.

**/
VOID
EFIAPI
AsmThunk16 (
  IN OUT  THUNK_CONTEXT             *ThunkContext
  )
{
  IA32_REGISTER_SET                 *UpdatedRegs;

  ASSERT (ThunkContext != NULL);
  ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000);
  ASSERT (ThunkContext->RealModeBufferSize >= m16Size);
  ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000);

  UpdatedRegs = InternalAsmThunk16 (
                  ThunkContext->RealModeState,
                  ThunkContext->RealModeBuffer
                  );

  CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs));
}

/**
  Prepares all structures and code for a 16-bit real mode thunk, transfers
  control to a 16-bit real mode entry point, and returns the results.

  Prepares all structures and code for a 16-bit real mode thunk, transfers
  control to a 16-bit real mode entry point, and returns the results. If the
  caller only need to perform a single 16-bit real mode thunk, then this
  service should be used. If the caller intends to make more than one 16-bit
  real mode thunk, then it is more efficient if AsmPrepareThunk16() is called
  once and AsmThunk16() can be called for each 16-bit real mode thunk. This
  function must be called with interrupts disabled.

  If ThunkContext is NULL, then ASSERT().

  @param  ThunkContext  A pointer to the context structure that describes the
                        16-bit real mode code to call.

**/
VOID
EFIAPI
AsmPrepareAndThunk16 (
  IN OUT  THUNK_CONTEXT             *ThunkContext
  )
{
  AsmPrepareThunk16 (ThunkContext);
  AsmThunk16 (ThunkContext);
}
