UefiCpuPkg: Simplify InitializeSeparateExceptionStacks
Hide the Exception implementation details in CpuExcetionHandlerLib and caller only need to provide buffer Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Leif Lindholm <quic_llindhol@quicinc.com> Cc: Dandan Bi <dandan.bi@intel.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com> Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
This commit is contained in:
committed by
mergify[bot]
parent
1da2012d93
commit
0f7bccf584
@ -151,25 +151,104 @@ InitializeCpuExceptionHandlers (
|
||||
|
||||
/**
|
||||
Setup separate stacks for certain exception handlers.
|
||||
If the input Buffer and BufferSize are both NULL, use global variable if possible.
|
||||
|
||||
InitData is optional and processor arch dependent.
|
||||
|
||||
@param[in] InitData Pointer to data optional for information about how
|
||||
to assign stacks for certain exception handlers.
|
||||
@param[in] Buffer Point to buffer used to separate exception stack.
|
||||
@param[in, out] BufferSize On input, it indicates the byte size of Buffer.
|
||||
If the size is not enough, the return status will
|
||||
be EFI_BUFFER_TOO_SMALL, and output BufferSize
|
||||
will be the size it needs.
|
||||
|
||||
@retval EFI_SUCCESS The stacks are assigned successfully.
|
||||
@retval EFI_UNSUPPORTED This function is not supported.
|
||||
|
||||
@retval EFI_BUFFER_TOO_SMALL This BufferSize is too small.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeSeparateExceptionStacks (
|
||||
IN CPU_EXCEPTION_INIT_DATA *InitData OPTIONAL
|
||||
IN VOID *Buffer,
|
||||
IN OUT UINTN *BufferSize
|
||||
)
|
||||
{
|
||||
if (InitData == NULL) {
|
||||
CPU_EXCEPTION_INIT_DATA EssData;
|
||||
IA32_DESCRIPTOR Idtr;
|
||||
IA32_DESCRIPTOR Gdtr;
|
||||
UINTN NeedBufferSize;
|
||||
UINTN StackTop;
|
||||
UINT8 *NewGdtTable;
|
||||
|
||||
//
|
||||
// X64 needs only one TSS of current task working for all exceptions
|
||||
// because of its IST feature. IA32 needs one TSS for each exception
|
||||
// in addition to current task. To simplify the code, we report the
|
||||
// needed memory for IA32 case to cover both IA32 and X64 exception
|
||||
// stack switch.
|
||||
//
|
||||
// Layout of memory needed for each processor:
|
||||
// --------------------------------
|
||||
// | Alignment | (just in case)
|
||||
// --------------------------------
|
||||
// | |
|
||||
// | Original GDT |
|
||||
// | |
|
||||
// --------------------------------
|
||||
// | Current task descriptor |
|
||||
// --------------------------------
|
||||
// | |
|
||||
// | Exception task descriptors | X ExceptionNumber
|
||||
// | |
|
||||
// --------------------------------
|
||||
// | Current task-state segment |
|
||||
// --------------------------------
|
||||
// | |
|
||||
// | Exception task-state segment | X ExceptionNumber
|
||||
// | |
|
||||
// --------------------------------
|
||||
//
|
||||
|
||||
if ((Buffer == NULL) && (BufferSize == NULL)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return ArchSetupExceptionStack (InitData);
|
||||
if (BufferSize == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AsmReadGdtr (&Gdtr);
|
||||
//
|
||||
// Total needed size includes stack size, new GDT table size, TSS size.
|
||||
// Add another DESCRIPTOR size for alignment requiremet.
|
||||
//
|
||||
NeedBufferSize = CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE +
|
||||
CPU_TSS_DESC_SIZE + Gdtr.Limit + 1 +
|
||||
CPU_TSS_SIZE +
|
||||
sizeof (IA32_TSS_DESCRIPTOR);
|
||||
if (*BufferSize < NeedBufferSize) {
|
||||
*BufferSize = NeedBufferSize;
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
StackTop = (UINTN)Buffer + CPU_STACK_SWITCH_EXCEPTION_NUMBER * CPU_KNOWN_GOOD_STACK_SIZE;
|
||||
NewGdtTable = ALIGN_POINTER (StackTop, sizeof (IA32_TSS_DESCRIPTOR));
|
||||
|
||||
AsmReadIdtr (&Idtr);
|
||||
EssData.X64.Revision = CPU_EXCEPTION_INIT_DATA_REV;
|
||||
EssData.X64.KnownGoodStackTop = StackTop;
|
||||
EssData.X64.KnownGoodStackSize = CPU_KNOWN_GOOD_STACK_SIZE;
|
||||
EssData.X64.StackSwitchExceptions = CPU_STACK_SWITCH_EXCEPTION_LIST;
|
||||
EssData.X64.StackSwitchExceptionNumber = CPU_STACK_SWITCH_EXCEPTION_NUMBER;
|
||||
EssData.X64.IdtTable = (VOID *)Idtr.Base;
|
||||
EssData.X64.IdtTableSize = Idtr.Limit + 1;
|
||||
EssData.X64.GdtTable = NewGdtTable;
|
||||
EssData.X64.GdtTableSize = CPU_TSS_DESC_SIZE + Gdtr.Limit + 1;
|
||||
EssData.X64.ExceptionTssDesc = NewGdtTable + Gdtr.Limit + 1;
|
||||
EssData.X64.ExceptionTssDescSize = CPU_TSS_DESC_SIZE;
|
||||
EssData.X64.ExceptionTss = NewGdtTable + Gdtr.Limit + 1 + CPU_TSS_DESC_SIZE;
|
||||
EssData.X64.ExceptionTssSize = CPU_TSS_SIZE;
|
||||
|
||||
return ArchSetupExceptionStack (&EssData);
|
||||
}
|
||||
|
Reference in New Issue
Block a user