int.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 237 行
C
237 行
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
int.c
Abstract:
Main SAL interface routine for IA-64 calls.
Revision History
--*/
#include "efi.h"
#include "efilib.h"
#include "SalEfi.h"
#include "SalProc.h"
#include "PlSal.h"
#include "Int86.h"
//
// BugBug: Move me to a more common place
//
#define INT86_STACK_PAGES 4
#define INTERRUPT_FLAG 0x09
STATIC VOID *GlobalInt86Stack;
BOOLEAN
Int86 (
IN UINT8 BiosInt,
IN IA32_RegisterSet_t *Regs
)
// returns carry flag
{
rArg Return;
IA32_BIOS_REGISTER_STATE SAL_Regs;
UINTN ModBiosInt;
EFI_TPL Tpl;
Tpl = BS->RaiseTPL (TPL_NOTIFY);
//
// BugBug: cs is being hard coded. This is bad.
// may need to capture these value at hand off time.
//
SAL_Regs.eax = Regs->x.AX;
SAL_Regs.ecx = Regs->x.CX;
SAL_Regs.edx = Regs->x.DX;
SAL_Regs.ebx = Regs->x.BX;
SAL_Regs.ebp = Regs->x.BP;
SAL_Regs.esi = Regs->x.SI;
SAL_Regs.edi = Regs->x.DI;
SAL_Regs.eflags = 1 << INTERRUPT_FLAG;
SAL_Regs.eip = 0;
SAL_Regs.cs = 0xf000;
SAL_Regs.ds = Regs->x.DS;
SAL_Regs.es = Regs->x.ES;
SAL_Regs.fs = 0x0;
SAL_Regs.gs = 0x0;
SAL_Regs.ss = _FP_SEG(GlobalInt86Stack);
SAL_Regs.esp = _FP_OFF(GlobalInt86Stack);
ModBiosInt = ID_SALCB_BIOSCALL(BiosInt);
SalCallBack(
(UINT64)ModBiosInt, (UINT64)&SAL_Regs,
0, 0, 0, 0, 0, 0,
&Return
);
Regs->x.AX = (UINT16)SAL_Regs.eax;
Regs->x.CX = (UINT16)SAL_Regs.ecx;
Regs->x.DX = (UINT16)SAL_Regs.edx;
Regs->x.BX = (UINT16)SAL_Regs.ebx;
Regs->x.SI = (UINT16)SAL_Regs.esi;
Regs->x.DI = (UINT16)SAL_Regs.edi;
Regs->x.Flags.CF = ((UINT16)SAL_Regs.eflags >> 0) & 1;
Regs->x.Flags.PF = ((UINT16)SAL_Regs.eflags >> 2) & 1;
Regs->x.Flags.AF = ((UINT16)SAL_Regs.eflags >> 4) & 1;
Regs->x.Flags.ZF = ((UINT16)SAL_Regs.eflags >> 6) & 1;
Regs->x.Flags.SF = ((UINT16)SAL_Regs.eflags >> 7) & 1;
Regs->x.Flags.DF = ((UINT16)SAL_Regs.eflags >> 10) & 1;
Regs->x.Flags.OF = ((UINT16)SAL_Regs.eflags >> 11) & 1;
Regs->x.DS = SAL_Regs.ds;
Regs->x.ES = SAL_Regs.es;
Regs->x.BP = (UINT16)SAL_Regs.ebp;
BS->RestoreTPL(Tpl);
return Regs->x.Flags.CF ? TRUE : FALSE;
}
VOID
InitializeBiosIntCaller (
VOID
)
{
UINTN PageSize;
EFI_PHYSICAL_ADDRESS MemPage;
EFI_STATUS Status;
//
// Allocate 16K bellow 1MB.
//
PageSize = INT86_STACK_PAGES;
MemPage = 0xfffff;
Status = BS->AllocatePages (AllocateMaxAddress, EfiBootServicesData, PageSize, &MemPage);
ASSERT (!EFI_ERROR(Status));
//
// Stack Grows down, so point to the end of the device. Make it - 0x10 from the
// top of the buffer. The 0x10 is safty margin.
//
GlobalInt86Stack = (VOID *)(MemPage + (INT86_STACK_PAGES*EFI_PAGE_SIZE) - 0x10);
}
BOOLEAN
Int86Available (
VOID
)
{
//
// Assume if the SAL_B SAL API's exist that we can make a SAL Callback to do Int86
// Note: We really use the SalCallBack() to do this, but we may use SalCallBack()
// even if we do not support Int86 callbacks.
//
return RtGlobalSalProcEntry.ProcEntryPoint != 0x00;
}
BOOLEAN
FarCall86 (
IN UINT16 Segment,
IN UINT16 Offset,
IN IA32_RegisterSet_t *Regs,
IN OUT VOID *Stack, // we need to retrieve our stack state
IN UINTN StackSize
)
// returns carry flag
{
rArg Return;
IA32_BIOS_REGISTER_STATE SAL_Regs;
UINT8 *S16; // possibly byte-aligned Real-mode stack
EFI_TPL Tpl;
Tpl = BS->RaiseTPL (TPL_NOTIFY);
// build the arguments to call in
SAL_Regs.eax = Regs->x.AX;
SAL_Regs.ecx = Regs->x.CX;
SAL_Regs.edx = Regs->x.DX;
SAL_Regs.ebx = Regs->x.BX;
SAL_Regs.ebp = Regs->x.BP;
SAL_Regs.esi = Regs->x.SI;
SAL_Regs.edi = Regs->x.DI;
SAL_Regs.eflags = 1 << INTERRUPT_FLAG;
SAL_Regs.eip = Offset;
SAL_Regs.cs = Segment;
SAL_Regs.ds = Regs->x.DS;
SAL_Regs.es = Regs->x.ES;
SAL_Regs.fs = 0x0;
SAL_Regs.gs = 0x0;
SAL_Regs.ss = _FP_SEG(GlobalInt86Stack);
SAL_Regs.esp = _FP_OFF(GlobalInt86Stack);
if (Stack!=NULL && StackSize!=0) {
//
// Copy Stack to low memory stack
//
S16 = GlobalInt86Stack;
S16 -= StackSize / sizeof(UINT8);
CopyMem (S16, Stack, StackSize);
SAL_Regs.ss = _FP_SEG(S16);
SAL_Regs.esp = _FP_OFF(S16);
}
SalCallBack(
ID_SALCB_REALMODE, // ID_SALCB_REALMODE
(UINT64)&SAL_Regs,
INT86_STACK_PAGES * EFI_PAGE_SIZE, // Right now, this will be 16KB. This will allow the SAL to perform some checking for stack overflows if that became important,
StackSize, // OPTIONAL - Will be 0 for INT calls. Will be 0 for FAR CALLs that do not require a stack frame.
0,
0,
0,
0,
&Return
);
// retrieve the stack in order to parse any return arguments
Regs->x.AX = (UINT16)SAL_Regs.eax ;
Regs->x.BX = (UINT16)SAL_Regs.ebx;
Regs->x.CX = (UINT16)SAL_Regs.ecx ;
Regs->x.DX = (UINT16)SAL_Regs.edx;
Regs->x.BP = (UINT16)SAL_Regs.ebp;
Regs->x.SI = (UINT16)SAL_Regs.esi;
Regs->x.DI = (UINT16)SAL_Regs.edi;
Regs->x.DS = (UINT16)SAL_Regs.ds;
Regs->x.ES = (UINT16)SAL_Regs.es;
if (Stack!=NULL && StackSize!=0) {
S16 = (UINT8 *)((SAL_Regs.ss << 4) | (SAL_Regs.esp & 0xffff));
// Put the data back for the caller
CopyMem (Stack, S16, StackSize);
}
BS->RestoreTPL(Tpl);
return SAL_Regs.eflags & CARRY_FLAG ? TRUE : FALSE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?