Skip to content

Commit

Permalink
OcLegacyThunkLib: Consolidate 16-bit thunking interface into library
Browse files Browse the repository at this point in the history
  • Loading branch information
Goldfish64 committed Aug 8, 2023
1 parent 3b6d8b8 commit c9abfda
Show file tree
Hide file tree
Showing 17 changed files with 189 additions and 510 deletions.
70 changes: 70 additions & 0 deletions Include/Acidanthera/Library/OcLegacyThunkLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/** @file
This library implements thunking to legacy 16-bit environment.
Copyright (c) 2023, Goldfish64. All rights reserved.<BR>
Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause
**/

#ifndef OC_LEGACY_THUNK_LIB_H
#define OC_LEGACY_THUNK_LIB_H

#include <Protocol/Legacy8259.h>

//
// Legacy region base is 0x0C0000.
//
#define LEGACY_REGION_BASE 0x0C0000
#define LEGACY_REGION_SIZE 0x10000

#define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)
#define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)

/**
Initialize legacy environment for BIOS INI caller.
@param ThunkContext the instance pointer of THUNK_CONTEXT
**/
VOID
OcLegacyThunkInitializeBiosIntCaller (
IN OUT THUNK_CONTEXT *ThunkContext
);

/**
Initialize interrupt redirection code and entries, because
IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.
Or the interrupt will lost when we do thunk.
NOTE: We do not reset 8259 vector base, because it will cause pending
interrupt lost.
@param Legacy8259 Instance pointer for EFI_LEGACY_8259_PROTOCOL.
**/
VOID
OcLegacyThunkInitializeInterruptRedirection (
IN EFI_LEGACY_8259_PROTOCOL *Legacy8259
);

/**
Thunk to 16-bit real mode and execute a software interrupt with a vector
of BiosInt. Regs will contain the 16-bit register context on entry and
exit.
@param This Protocol instance pointer.
@param BiosInt Processor interrupt vector to invoke
@param Reg Register contexted passed into (and returned) from thunk to 16-bit mode
@retval TRUE Thunk completed, and there were no BIOS errors in the target code.
See Regs for status.
@retval FALSE There was a BIOS erro in the target code.
**/
BOOLEAN
EFIAPI
OcLegacyThunkBiosInt86 (
IN THUNK_CONTEXT *ThunkContext,
IN EFI_LEGACY_8259_PROTOCOL *Legacy8259,
IN UINT8 BiosInt,
IN IA32_REGISTER_SET *Regs
);

#endif // OC_LEGACY_THUNK_LIB_H
26 changes: 13 additions & 13 deletions Legacy/BootPlatform/BiosVideo/BiosVideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ BiosVideoDriverBindingStart (
goto Done;
}

InitializeBiosIntCaller (&mThunkContext);
InitializeInterruptRedirection (mLegacy8259);
OcLegacyThunkInitializeBiosIntCaller (&mThunkContext);
OcLegacyThunkInitializeInterruptRedirection (mLegacy8259);
}

//
Expand Down Expand Up @@ -622,12 +622,12 @@ BiosVideoChildHandleUninstall (
//
Regs.H.AH = 0x00;
Regs.H.AL = 0x03;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

Regs.H.AH = 0x11;
Regs.H.AL = 0x14;
Regs.H.BL = 0;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

//
// Do not disable IO/memory decode since that would prevent legacy ROM from working
Expand Down Expand Up @@ -712,7 +712,7 @@ BiosVideoGetVbeData (
Regs.E.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeInformationBlock);
Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeInformationBlock);

LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

Status = EFI_DEVICE_ERROR;

Expand Down Expand Up @@ -772,7 +772,7 @@ BiosVideoGetVbeData (
Regs.E.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);
Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeModeInformationBlock);

LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

//
// See if the call succeeded. If it didn't, then try the next mode.
Expand Down Expand Up @@ -984,7 +984,7 @@ BiosVideoGetVbeData (
Regs.E.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeEdidDataBlock);
Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeEdidDataBlock);

LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

//
// If the call succeed, populate EDID Discovered protocol.
Expand Down Expand Up @@ -1533,7 +1533,7 @@ BiosVideoSetModeWorker (
// Set VGA Mode
//
Regs.X.AX = ModeData->VbeModeNumber;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);
} else {
//
// Allocate a working buffer for BLT operations to the VBE frame buffer
Expand All @@ -1554,7 +1554,7 @@ BiosVideoSetModeWorker (
Regs.E.ES = EFI_SEGMENT ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);
Regs.X.DI = EFI_OFFSET ((UINTN)BiosVideoPrivate->VbeCrtcInformationBlock);

LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

//
// Check to see if the call succeeded
Expand Down Expand Up @@ -2652,12 +2652,12 @@ BiosVideoVgaMiniPortSetMode (
//
Regs.H.AH = 0x00;
Regs.H.AL = 0x83;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

Regs.H.AH = 0x11;
Regs.H.AL = 0x14;
Regs.H.BL = 0;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

break;

Expand All @@ -2667,12 +2667,12 @@ BiosVideoVgaMiniPortSetMode (
//
Regs.H.AH = 0x00;
Regs.H.AL = 0x83;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);

Regs.H.AH = 0x11;
Regs.H.AL = 0x12;
Regs.H.BL = 0;
LegacyBiosInt86 (BiosVideoPrivate, 0x10, &Regs);
OcLegacyThunkBiosInt86 (BiosVideoPrivate->ThunkContext, BiosVideoPrivate->Legacy8259, 0x10, &Regs);
break;

default:
Expand Down
57 changes: 1 addition & 56 deletions Legacy/BootPlatform/BiosVideo/BiosVideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/MemoryAllocationLib.h>
#include <Library/DevicePathLib.h>

#include <Library/OcLegacyThunkLib.h>
#include <Library/OcMemoryLib.h>
#include <Library/OcMiscLib.h>

Expand All @@ -55,13 +56,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

#include "VesaBiosExtensions.h"

//
// ** CHANGE **
// Legacy region base is now 0x0C0000 instead of 0x100000.
//
#define LEGACY_REGION_BASE 0x0C0000
#define LEGACY_REGION_SIZE 0x10000

//
// Vendor IDs.
//
Expand Down Expand Up @@ -171,9 +165,6 @@ typedef struct {

#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff

#define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)
#define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)

//
// Global Variables
//
Expand Down Expand Up @@ -553,52 +544,6 @@ BiosVideoIsVga (

#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08

/**
Initialize legacy environment for BIOS INI caller.
@param ThunkContext the instance pointer of THUNK_CONTEXT
**/
VOID
InitializeBiosIntCaller (
THUNK_CONTEXT *ThunkContext
);

/**
Initialize interrupt redirection code and entries, because
IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.
Or the interrupt will lost when we do thunk.
NOTE: We do not reset 8259 vector base, because it will cause pending
interrupt lost.
@param Legacy8259 Instance pointer for EFI_LEGACY_8259_PROTOCOL.
**/
VOID
InitializeInterruptRedirection (
IN EFI_LEGACY_8259_PROTOCOL *Legacy8259
);

/**
Thunk to 16-bit real mode and execute a software interrupt with a vector
of BiosInt. Regs will contain the 16-bit register context on entry and
exit.
@param This Protocol instance pointer.
@param BiosInt Processor interrupt vector to invoke
@param Reg Register contexted passed into (and returned) from thunk to 16-bit mode
@retval TRUE Thunk completed, and there were no BIOS errors in the target code.
See Regs for status.
@retval FALSE There was a BIOS erro in the target code.
**/
BOOLEAN
EFIAPI
LegacyBiosInt86 (
IN BIOS_VIDEO_DEV *BiosDev,
IN UINT8 BiosInt,
IN IA32_REGISTER_SET *Regs
);

/**
Force the specified resolution and reconnect the controller.
Specifying zero for Width and Height will pull the maximum
Expand Down
2 changes: 1 addition & 1 deletion Legacy/BootPlatform/BiosVideo/BiosVideo.inf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
MemoryAllocationLib
UefiDriverEntryPoint
DevicePathLib
OcLegacyThunkLib
OcMemoryLib
OcMiscLib

Expand All @@ -45,7 +46,6 @@
BiosVideo.c
ComponentName.c
VesaBiosExtensions.h
LegacyBiosThunk.c
VideoBiosPatch.c

[Protocols]
Expand Down
4 changes: 2 additions & 2 deletions Legacy/BootPlatform/BlockIoDxe/BiosBlkIo.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ BiosBlockIoDriverBindingStart (
goto Error;
}

InitializeBiosIntCaller (&mThunkContext);
InitializeInterruptRedirection (Legacy8259);
OcLegacyThunkInitializeBiosIntCaller (&mThunkContext);
OcLegacyThunkInitializeInterruptRedirection (Legacy8259);

//
// Open the IO Abstraction(s) needed
Expand Down
49 changes: 1 addition & 48 deletions Legacy/BootPlatform/BlockIoDxe/BiosBlkIo.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcLegacyThunkLib.h>

#include <IndustryStandard/Pci.h>

#include "Edd.h"

#define LEGACY_REGION_BASE 0x0C0000

//
// Global Variables
//
Expand Down Expand Up @@ -423,50 +422,4 @@ SetBiosInitBlockIoDevicePath (
OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
);

/**
Initialize legacy environment for BIOS INI caller.
@param ThunkContext the instance pointer of THUNK_CONTEXT
**/
VOID
InitializeBiosIntCaller (
THUNK_CONTEXT *ThunkContext
);

/**
Initialize interrupt redirection code and entries, because
IDT Vectors 0x68-0x6f must be redirected to IDT Vectors 0x08-0x0f.
Or the interrupt will lost when we do thunk.
NOTE: We do not reset 8259 vector base, because it will cause pending
interrupt lost.
@param Legacy8259 Instance pointer for EFI_LEGACY_8259_PROTOCOL.
**/
VOID
InitializeInterruptRedirection (
IN EFI_LEGACY_8259_PROTOCOL *Legacy8259
);

/**
Thunk to 16-bit real mode and execute a software interrupt with a vector
of BiosInt. Regs will contain the 16-bit register context on entry and
exit.
@param This Protocol instance pointer.
@param BiosInt Processor interrupt vector to invoke
@param Reg Register contexted passed into (and returned) from thunk to 16-bit mode
@retval TRUE Thunk completed, and there were no BIOS errors in the target code.
See Regs for status.
@retval FALSE There was a BIOS erro in the target code.
**/
BOOLEAN
EFIAPI
LegacyBiosInt86 (
IN BIOS_BLOCK_IO_DEV *BiosDev,
IN UINT8 BiosInt,
IN IA32_REGISTER_SET *Regs
);

#endif
Loading

0 comments on commit c9abfda

Please sign in to comment.