Skip to content
/ edk2 Public
forked from tianocore/edk2

Commit

Permalink
PPC64: CpuDxe with exception support
Browse files Browse the repository at this point in the history
This could be a lot better, but it's good enough for writing
a timer arch protocol that will use the HDEC. Fixes Issue tianocore#1.

Introduces Issue tianocore#11

Signed-off-by: Andrei Warkentin <[email protected]>
  • Loading branch information
andreiw committed Oct 12, 2015
1 parent 45ca7de commit 9675f52
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 50 deletions.
84 changes: 83 additions & 1 deletion MdePkg/Include/Protocol/DebugSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,86 @@ typedef struct {
} EFI_SYSTEM_CONTEXT_EBC;


///
/// PPC64 processor exception types (offsets, really).
///
#define EXCEPT_PPC64_START 0x0
#define EXCEPT_PPC64_RESET 0x100
#define EXCEPT_PPC64_MC 0x200
#define EXCEPT_PPC64_DSI 0x300
#define EXCEPT_PPC64_DSEG 0x380
#define EXCEPT_PPC64_ISI 0x400
#define EXCEPT_PPC64_ISEG 0x480
#define EXCEPT_PPC64_EXT 0x500
#define EXCEPT_PPC64_ALIGN 0x600
#define EXCEPT_PPC64_PROG 0x700
#define EXCEPT_PPC64_FPU 0x800
#define EXCEPT_PPC64_DEC 0x900
#define EXCEPT_PPC64_HDEC 0x980
#define EXCEPT_PPC64_DOOR 0xA00
#define EXCEPT_PPC64_RESV 0xB00
#define EXCEPT_PPC64_SC 0xC00
#define EXCEPT_PPC64_TRACE 0xD00
#define EXCEPT_PPC64_HDSI 0xE00
#define EXCEPT_PPC64_HISI 0xE20
#define EXCEPT_PPC64_HEA 0xE40
#define EXCEPT_PPC64_HMAINT 0xE60
#define EXCEPT_PPC64_HDOOR 0xE80
#define EXCEPT_PPC64_RESV1 0xEA0
#define EXCEPT_PPC64_RESV2 0xEC0
#define EXCEPT_PPC64_IMPL 0xEE0
#define EXCEPT_PPC64_PMU 0xF00
#define EXCEPT_PPC64_VECUN 0xF20
#define EXCEPT_PPC64_VSX 0xF40
#define EXCEPT_PPC64_FAC 0xF60
#define EXCEPT_PPC64_HFAC 0xF80
#define MAX_PPC64_EXCEPTION EXCEPT_PPC64_HFAC

///
/// PPC64 processor context definition.
///
typedef struct {
UINT64 R0;
UINT64 R1;
UINT64 R2;
UINT64 R3;
UINT64 R4;
UINT64 R5;
UINT64 R6;
UINT64 R7;
UINT64 R8;
UINT64 R9;
UINT64 R10;
UINT64 R11;
UINT64 R12;
UINT64 R13;
UINT64 R14;
UINT64 R15;
UINT64 R16;
UINT64 R17;
UINT64 R18;
UINT64 R19;
UINT64 R20;
UINT64 R21;
UINT64 R22;
UINT64 R23;
UINT64 R24;
UINT64 R25;
UINT64 R26;
UINT64 R27;
UINT64 R28;
UINT64 R29;
UINT64 R30;
UINT64 R31;
UINT64 LR;
UINT64 CTR;
UINT64 XER;
UINT64 CR;
UINT64 HSSR0;
UINT64 HSSR1;
UINT64 Vec;
} EFI_SYSTEM_CONTEXT_PPC64;


///
/// ARM processor exception types.
Expand Down Expand Up @@ -620,6 +700,7 @@ typedef union {
EFI_SYSTEM_CONTEXT_IPF *SystemContextIpf;
EFI_SYSTEM_CONTEXT_ARM *SystemContextArm;
EFI_SYSTEM_CONTEXT_AARCH64 *SystemContextAArch64;
EFI_SYSTEM_CONTEXT_PPC64 *SystemContextPPC64;
} EFI_SYSTEM_CONTEXT;

//
Expand Down Expand Up @@ -661,7 +742,8 @@ typedef enum {
IsaIpf = IMAGE_FILE_MACHINE_IA64, ///< 0x0200
IsaEbc = IMAGE_FILE_MACHINE_EBC, ///< 0x0EBC
IsaArm = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED, ///< 0x01c2
IsaAArch64 = IMAGE_FILE_MACHINE_ARM64 ///< 0xAA64
IsaAArch64 = IMAGE_FILE_MACHINE_ARM64, ///< 0xAA64
IsaPPC64 = IMAGE_FILE_MACHINE_PPC64 ///< 0x1F0
} EFI_INSTRUCTION_SET_ARCHITECTURE;


Expand Down
142 changes: 104 additions & 38 deletions PPC64Pkg/Drivers/CpuDxe/CpuDxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
//

#include "CpuDxe.h"
#include <Guid/IdleLoopEvent.h>
#include <Pcr.h>
#include <Library/OpalLib.h>
#include <Chipset/PPC64Intrinsics.h>

BOOLEAN mInterruptState = FALSE;
#define UNRECOVERABLE_EXCEPTION_STACK_PAGES 2

EFI_CPU_INTERRUPT_HANDLER mHDECHandler = NULL;


/**
Expand Down Expand Up @@ -83,7 +87,7 @@ CpuEnableInterrupt (
IN EFI_CPU_ARCH_PROTOCOL *This
)
{
mInterruptState = TRUE;
mtmsrd(mfmsr() | MSR_EE, 1);
return EFI_SUCCESS;
}

Expand All @@ -103,7 +107,7 @@ CpuDisableInterrupt (
IN EFI_CPU_ARCH_PROTOCOL *This
)
{
mInterruptState = FALSE;
mtmsrd(mfmsr() & ~MSR_EE, 1);
return EFI_SUCCESS;
}

Expand Down Expand Up @@ -132,7 +136,8 @@ CpuGetInterruptState (
return EFI_INVALID_PARAMETER;
}

*State = mInterruptState;

*State = ((mfmsr() & MSR_EE) != 0);
return EFI_SUCCESS;
}

Expand Down Expand Up @@ -171,6 +176,16 @@ CpuRegisterInterruptHandler (
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
{
if (InterruptType != EXCEPT_PPC64_HDEC) {
return EFI_UNSUPPORTED;
}

if (InterruptHandler != NULL &&
mHDECHandler != NULL) {
return EFI_ALREADY_STARTED;
}

mHDECHandler = InterruptHandler;
return EFI_SUCCESS;
}

Expand All @@ -186,23 +201,6 @@ CpuGetTimerValue (
return EFI_UNSUPPORTED;
}

/**
Callback function for idle events.
@param Event Event whose notification function is being invoked.
@param Context The pointer to the notification function's context,
which is implementation-dependent.
**/
VOID
EFIAPI
IdleLoopEventCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
}

/**
This function modifies the attributes for the memory region specified by BaseAddress and
Length from their current attributes to the attributes specified by Attributes.
Expand Down Expand Up @@ -253,35 +251,103 @@ EFI_CPU_ARCH_PROTOCOL mCpu = {
4, // DmaBufferAlignment
};

VOID
CpuDxeVectorHandler (
IN EFI_SYSTEM_CONTEXT_PPC64 *Context
)
{
if (Context->Vec == EXCEPT_PPC64_HDEC) {
if (mHDECHandler != NULL) {
mHDECHandler(Context->Vec, (EFI_SYSTEM_CONTEXT) Context);
CpuDxeRFI(Context);
}
}

DEBUG((EFI_D_ERROR, "Unknown exception 0x%x for 0x%016lx!\n",
Context->Vec, Context->LR));
ASSERT(FALSE);
while (1);
}

EFI_PHYSICAL_ADDRESS
CpuDxeMyTOC (
VOID
)
{
register UINT64 R2 asm("r2");
return R2;
}

EFI_STATUS
CpuDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT IdleLoopEvent;
EFI_STATUS Status;
OPAL_STATUS OpalStatus;
EFI_PHYSICAL_ADDRESS UnrecStack;
EFI_PHYSICAL_ADDRESS Vectors;

PcrGet()->CpuDxeTOC = CpuDxeMyTOC();
DEBUG((EFI_D_ERROR, "My TOC is at 0x%lx\n", PcrGet()->CpuDxeTOC));

/*
* MSR.ILE controls supervisor exception endianness. OPAL
* takes care of setting the hypervisor exception endianness
* bit in an implementation-neutral fashion. Mambo systemsim
* doesn't seem to report a PVR version that Skiboot recognises
* as supporting HID0.HILE, so we'll manually set it until
* the skiboot patch goes in.
*/
OpalStatus = OpalReinitCPUs(OPAL_REINIT_CPUS_HILE_LE);
if (OpalStatus != OPAL_SUCCESS) {
DEBUG((EFI_D_INFO, "OPAL claims no HILE supported, pretend to know better...\n"));
UINT64 HID0 = GET_HID0();
SET_HID0(HID0 | HID0_HILE);
}

/*
* Force external interrupts to HV mode.
*/
SET_LPCR((GET_LPCR() & ~LPCR_LPES) | LPCR_ILE);

/*
* Allocate the stack we'll use when servicing exceptions
* with MSR_RI 0.
*/
Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData,
UNRECOVERABLE_EXCEPTION_STACK_PAGES,
&UnrecStack);
ASSERT_EFI_ERROR (Status);
PcrGet()->CpuDxeUnrecSP = UnrecStack;

Vectors = 0;
Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode,
EFI_SIZE_TO_PAGES((UINTN) &CpuDxeVectorsEnd -
(UINTN) &CpuDxeVectorsStart),
&Vectors);
ASSERT_EFI_ERROR (Status);
CopyMem((void *) Vectors, (VOID *) &CpuDxeVectorsStart,
((UINTN) &CpuDxeVectorsEnd - (UINTN) &CpuDxeVectorsStart));

/*
* Vectors expect HSPRG0 to contain the pointer to KPCR,
* HSPRG1 is scratch.
*/
SET_HSPRG0((UINTN) PcrGet());

/*
* Context is now recoverable.
*/
mtmsrd(MSR_RI, 1);

Status = gBS->InstallMultipleProtocolInterfaces (
&mCpuHandle,
&gEfiCpuArchProtocolGuid, &mCpu,
&gEfiCpuArchProtocolGuid, &mCpu,
NULL
);
ASSERT_EFI_ERROR (Status);

//
// Setup a callback for idle events
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
IdleLoopEventCallback,
NULL,
&gIdleLoopEventGuid,
&IdleLoopEvent
);
ASSERT_EFI_ERROR (Status);

return Status;
}
4 changes: 4 additions & 0 deletions PPC64Pkg/Drivers/CpuDxe/CpuDxe.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@
#include <Protocol/DebugSupportPeriodicCallback.h>
#include <Protocol/LoadedImage.h>

extern VOID *CpuDxeVectorsStart;
extern VOID *CpuDxeVectorsEnd;
VOID CpuDxeRFI(EFI_SYSTEM_CONTEXT_PPC64 *Context);

#endif // __CPU_DXE_H__
4 changes: 4 additions & 0 deletions PPC64Pkg/Drivers/CpuDxe/CpuDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
CpuDxe.c
CpuDxe.h

[Sources.PPC64]
PPC64/Vectors.S

[Packages]
PPC64Pkg/PPC64Pkg.dec
EmbeddedPkg/EmbeddedPkg.dec
Expand All @@ -42,6 +45,7 @@
PeCoffGetEntryPointLib
UefiDriverEntryPoint
UefiLib
OpalLib

[Protocols]
gEfiCpuArchProtocolGuid
Expand Down
Loading

0 comments on commit 9675f52

Please sign in to comment.