Skip to content

Commit

Permalink
feat: add mm-cmet and mm-ebv partition protocol for prm to access
Browse files Browse the repository at this point in the history
prm handler can access ras cmet and ebv partitions by setting partition
select

Signed-off-by: Wei Chen <weiche@nvidia.com>
Tested-by: Jake Garver <jake@nvidia.com>
Reviewed-by: Jake Garver <jake@nvidia.com>
  • Loading branch information
Wei Chen authored and jgarver committed Feb 11, 2025
1 parent b2fe155 commit c097a8f
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 26 deletions.
74 changes: 55 additions & 19 deletions Silicon/NVIDIA/Drivers/PrmRasModule/PrmRasModule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

PRM Module for CPER error dump

SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

SPDX-License-Identifier: BSD-2-Clause-Patent

Expand All @@ -20,8 +20,10 @@
#include <Protocol/FwPartitionProtocol.h>
#include "PrmRasModule.h"

STATIC NVIDIA_FW_PARTITION_PROTOCOL *mFwPartitionProtocol = NULL;
STATIC EFI_EVENT mAddressChangeEvent = NULL;
STATIC NVIDIA_FW_PARTITION_PROTOCOL *MmRasFwPartition = NULL;
STATIC NVIDIA_FW_PARTITION_PROTOCOL *MmCmetFwPartition = NULL;
STATIC NVIDIA_FW_PARTITION_PROTOCOL *MmEbvFwPartition = NULL;
STATIC EFI_EVENT mAddressChangeEvent = NULL;

STATIC
VOID
Expand All @@ -31,7 +33,14 @@ AddressChangeNotify (
IN VOID *Context
)
{
EfiConvertPointer (0x0, (VOID **)&mFwPartitionProtocol);
EfiConvertPointer (0x0, (VOID **)&MmRasFwPartition);
if (MmCmetFwPartition != NULL) {
EfiConvertPointer (0x0, (VOID **)&MmCmetFwPartition);
}

if (MmEbvFwPartition != NULL) {
EfiConvertPointer (0x0, (VOID **)&MmEbvFwPartition);
}
}

/**
Expand All @@ -46,6 +55,7 @@ AddressChangeNotify (
**/
PRM_HANDLER_EXPORT (RasPrmHandler) {
EFI_STATUS Status;
NVIDIA_FW_PARTITION_PROTOCOL *mFwPartitionProtocol;
PRM_RAS_MODULE_STATIC_DATA_CONTEXT_BUFFER *RasDataBuffer;
UINTN ReadOffset;
UINTN ReadSize;
Expand All @@ -70,6 +80,28 @@ PRM_HANDLER_EXPORT (RasPrmHandler) {
return EFI_NOT_FOUND;
}

RasDataBuffer = (PRM_RAS_MODULE_STATIC_DATA_CONTEXT_BUFFER *)&ContextBuffer->StaticDataBuffer->Data[0];

// Use the highest byte (bit60~63) for partition selection
switch (RasDataBuffer->PartitionCommand.Select) {
case PRM_MM_RAS_PARTITION_OFFSET:
mFwPartitionProtocol = MmRasFwPartition;
break;

case PRM_MM_CMET_PARTITION_OFFSET:
mFwPartitionProtocol = MmCmetFwPartition;
break;

case PRM_MM_EARLY_BOOT_VARS_OFFSET:
mFwPartitionProtocol = MmEbvFwPartition;
break;

default:
DEBUG ((DEBUG_ERROR, "%a: FW Partition protocol %x not support\n", __FUNCTION__, RasDataBuffer->PartitionCommand.Select));
mFwPartitionProtocol = NULL;
break;
}

if (mFwPartitionProtocol == NULL) {
DEBUG ((DEBUG_ERROR, "%a: FW Partition protocol not found\n", __FUNCTION__));
return EFI_NOT_FOUND;
Expand All @@ -80,21 +112,19 @@ PRM_HANDLER_EXPORT (RasPrmHandler) {
return EFI_UNSUPPORTED;
}

RasDataBuffer = (PRM_RAS_MODULE_STATIC_DATA_CONTEXT_BUFFER *)&ContextBuffer->StaticDataBuffer->Data[0];

// 64K alignment
RasDataBuffer->PartitionOffset &= 0xFFFFFFFFFFFF0000;
RasDataBuffer->PartitionCommand.Offset &= 0xFFFFFFFFFFF0000;

if (RasDataBuffer->PartitionOffset + PRM_SPI_ACCESS_DATA_SIZE > Attributes.Bytes) {
DEBUG ((DEBUG_ERROR, "%a: Wrong partition offset input\n", __FUNCTION__));
if (RasDataBuffer->PartitionCommand.Offset + PRM_SPI_ACCESS_DATA_SIZE > Attributes.Bytes) {
DEBUG ((DEBUG_ERROR, "%a: Partition offset %lx is larger than %lx\n", __FUNCTION__, RasDataBuffer->PartitionCommand.Offset, Attributes.Bytes));
return EFI_INVALID_PARAMETER;
}

RasDataBuffer->PartitionSize = Attributes.Bytes;
RasDataBuffer->DataSize = PRM_SPI_ACCESS_DATA_SIZE;

// Read SPI data
ReadOffset = RasDataBuffer->PartitionOffset;
ReadOffset = RasDataBuffer->PartitionCommand.Offset;
ReadSize = RasDataBuffer->DataSize;
ReadData = RasDataBuffer->CperData;

Expand Down Expand Up @@ -139,10 +169,11 @@ PrmRasModuleInit (
EFI_HANDLE *Handles;
UINTN HandleCount;
NVIDIA_FW_PARTITION_PROTOCOL *FwPartitionProtocol;
BOOLEAN IsProtocolFound;

IsProtocolFound = FALSE;
HandleCount = 0;
MmRasFwPartition = NULL;
MmCmetFwPartition = NULL;
MmEbvFwPartition = NULL;
HandleCount = 0;

//
// Get MM-NorFlash FwPartitionProtocol
Expand All @@ -169,14 +200,21 @@ PrmRasModuleInit (
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: PartitionName = %s\n", __FUNCTION__, FwPartitionProtocol->PartitionName));
if (StrCmp (FwPartitionProtocol->PartitionName, L"MM-RAS") == 0) {
IsProtocolFound = TRUE;
break;
MmRasFwPartition = FwPartitionProtocol;
}

if (StrCmp (FwPartitionProtocol->PartitionName, L"MM-CMET") == 0) {
MmCmetFwPartition = FwPartitionProtocol;
}

if (StrCmp (FwPartitionProtocol->PartitionName, L"MM-EBV") == 0) {
MmEbvFwPartition = FwPartitionProtocol;
}
}
} while (HandleCount > 0);

if (!IsProtocolFound) {
DEBUG ((DEBUG_ERROR, "%a: Cannot find FW Partition.\n", __FUNCTION__));
if (MmRasFwPartition == NULL) {
DEBUG ((DEBUG_ERROR, "%a: Cannot find MM-RAS FW Partition.\n", __FUNCTION__));
return EFI_NOT_FOUND;
}

Expand All @@ -193,7 +231,5 @@ PrmRasModuleInit (
return Status;
}

mFwPartitionProtocol = FwPartitionProtocol;

return EFI_SUCCESS;
}
24 changes: 18 additions & 6 deletions Silicon/NVIDIA/Drivers/PrmRasModule/PrmRasModule.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @file
PRM Module Static Data

SPDX-FileCopyrightText: Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

SPDX-License-Identifier: BSD-2-Clause-Patent

Expand All @@ -18,13 +18,25 @@
// {ad16d36e-1933-480e-9b52-d17de5b4e632}
#define NVIDIA_RAS_PRM_HANDLER_GUID {0xad16d36e, 0x1933, 0x480e, {0x9b, 0x52, 0xd1, 0x7d, 0xe5, 0xb4, 0xe6, 0x32}}

#define PRM_SPI_ACCESS_DATA_SIZE (64 * 1024)
#define PRM_SPI_ACCESS_DATA_SIZE (64 * 1024)
#define PRM_MM_RAS_PARTITION_OFFSET 0x00
#define PRM_MM_CMET_PARTITION_OFFSET 0x01
#define PRM_MM_EARLY_BOOT_VARS_OFFSET 0x02

#pragma pack(1)

typedef struct {
UINT64 Offset : 56;
UINT64 Select : 8;
} PARTITION_COMMAND;

typedef struct {
UINT64 PartitionSize;
UINT64 PartitionOffset;
UINT32 DataSize;
UINT8 CperData[PRM_SPI_ACCESS_DATA_SIZE];
UINT64 PartitionSize;
PARTITION_COMMAND PartitionCommand;
UINT32 DataSize;
UINT8 CperData[PRM_SPI_ACCESS_DATA_SIZE];
} PRM_RAS_MODULE_STATIC_DATA_CONTEXT_BUFFER;

#pragma pack()

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

FW Partition Device Library

SPDX-FileCopyrightText: Copyright (c) 2021-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

SPDX-License-Identifier: BSD-2-Clause-Patent

Expand Down Expand Up @@ -581,6 +581,48 @@ FwDeviceAddAsPartition (
DEBUG ((DEBUG_ERROR, "%a: Can't find partition MM-RAS: %r\n", __FUNCTION__, Status));
}

Status = GetPartitionInfoStMm (
(UINTN)CpuBlParamsAddr,
TEGRABL_CMET,
&DeviceInstance,
&PartitionOffset,
&PartitionSize
);
if (!EFI_ERROR (Status)) {
Status = FwPartitionAdd (
L"MM-CMET",
DeviceInfo,
PartitionOffset,
PartitionSize
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Can't add partition MM-CMET\n", __FUNCTION__));
}
} else {
DEBUG ((DEBUG_ERROR, "%a: Can't find partition MM-CMET: %r\n", __FUNCTION__, Status));
}

Status = GetPartitionInfoStMm (
(UINTN)CpuBlParamsAddr,
TEGRABL_EARLY_BOOT_VARS,
&DeviceInstance,
&PartitionOffset,
&PartitionSize
);
if (!EFI_ERROR (Status)) {
Status = FwPartitionAdd (
L"MM-EBV",
DeviceInfo,
PartitionOffset,
PartitionSize
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Can't add partition EARLY_BOOT_VARS\n", __FUNCTION__));
}
} else {
DEBUG ((DEBUG_ERROR, "%a: Can't find partition EARLY_BOOT_VARS: %r\n", __FUNCTION__, Status));
}

Status = GetPartitionInfoStMm (
(UINTN)CpuBlParamsAddr,
TEGRAUEFI_CAPSULE,
Expand Down

0 comments on commit c097a8f

Please sign in to comment.