Skip to content

Commit

Permalink
AmpereAltraPkg/CpuConfigDxe: Add SLC as L3$ option to CPU screen
Browse files Browse the repository at this point in the history
This adds an option for treating SLC as L3$ in the PPTT ACPI table. This
option is only active and enabled by default for 1P monolithic mode.
And, the SubNUMA mode is not changeable when the SLC as L3$ option is
enabled.

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
nhivp authored and tinhnampere committed May 24, 2022
1 parent 4f7fff1 commit 9d5203b
Showing 10 changed files with 274 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -74,6 +74,7 @@

[Guids]
gArmMpCoreInfoGuid
gCpuConfigFormSetGuid
gEfiAcpiTableGuid
gEfiEventReadyToBootGuid
gAcpiConfigFormSetGuid
42 changes: 34 additions & 8 deletions Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@
#include <IndustryStandard/ArmCache.h>
#include <Library/AmpereCpuLib.h>
#include <Library/ArmLib.h>
#include <Guid/CpuConfigHii.h>
#include <CpuConfigNVDataStruc.h>
#include "AcpiPlatform.h"

#define NUMBER_OF_RESOURCES 2 // L1I & L1D
@@ -122,11 +124,15 @@ AddSocketNode (
PpttProcessorEntryPointer->Flags.PhysicalPackage = EFI_ACPI_6_3_PPTT_PACKAGE_PHYSICAL;
PpttProcessorEntryPointer->Flags.IdenticalImplementation = EFI_ACPI_6_3_PPTT_IMPLEMENTATION_IDENTICAL;
PpttProcessorEntryPointer->Parent = ParentOffset;
PpttProcessorEntryPointer->NumberOfPrivateResources = 1;
PpttProcessorEntryPointer->Length += sizeof (UINT32) * PpttProcessorEntryPointer->NumberOfPrivateResources;
if (SlcNodeOffset > 0) {
PpttProcessorEntryPointer->NumberOfPrivateResources = 1;
PpttProcessorEntryPointer->Length += sizeof (UINT32) * PpttProcessorEntryPointer->NumberOfPrivateResources;

ResPointer = (UINT32 *)((UINT64)PpttProcessorEntryPointer + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
ResPointer[0] = SlcNodeOffset;
ResPointer = (UINT32 *)((UINT64)PpttProcessorEntryPointer + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
ResPointer[0] = SlcNodeOffset;
} else {
PpttProcessorEntryPointer->NumberOfPrivateResources = 0;
}

return PpttProcessorEntryPointer->Length;
}
@@ -290,6 +296,21 @@ AcpiInstallPpttTable (
UINTN Size;
UINTN SocketId;
VOID *PpttTablePointer;
CPU_VARSTORE_DATA CpuConfigData;
UINTN BufferSize;

BufferSize = sizeof (CPU_VARSTORE_DATA);
ZeroMem (&CpuConfigData, BufferSize);
Status = gRT->GetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
NULL,
&BufferSize,
&CpuConfigData
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a %d Can not get CPU Configuration Data \n", __FUNCTION__, __LINE__));
}

Status = gBS->LocateProtocol (
&gEfiAcpiTableProtocolGuid,
@@ -309,8 +330,10 @@ AcpiInstallPpttTable (
(sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + NUMBER_OF_RESOURCES * sizeof (UINT32)) * GetNumberOfActiveCores () + // Core node
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + // L1I node
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + // L1D node
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + // L2 node
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + sizeof (UINT32); // SLC node
sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE); // L2 node
if (CpuConfigData.CpuSlcAsL3 == CPU_SLC_AS_L3_ENABLE) {
Size += sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE) + sizeof (UINT32); // SLC node
}

PpttTablePointer = AllocateZeroPool (Size);
if (PpttTablePointer == NULL) {
@@ -322,8 +345,11 @@ AcpiInstallPpttTable (
RootNodeOffset = NextNodeOffset;
NextNodeOffset += AddRootNode (PpttTablePointer + NextNodeOffset);

SlcNodeOffset = NextNodeOffset;
NextNodeOffset += AddSlcCacheNode (PpttTablePointer + NextNodeOffset);
SlcNodeOffset = 0;
if (CpuConfigData.CpuSlcAsL3 == CPU_SLC_AS_L3_ENABLE) {
SlcNodeOffset = NextNodeOffset;
NextNodeOffset += AddSlcCacheNode (PpttTablePointer + NextNodeOffset);
}

L2NodeOffset = NextNodeOffset;
NextNodeOffset += AddL2CacheNode (PpttTablePointer + NextNodeOffset);
2 changes: 1 addition & 1 deletion Platform/Ampere/JadePkg/Jade.dsc
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@
DEFINE SECURE_BOOT_ENABLE = FALSE
DEFINE TPM2_ENABLE = TRUE
DEFINE INCLUDE_TFTP_COMMAND = TRUE
DEFINE PLATFORM_CONFIG_UUID = 52BE0815-D389-44D2-A274-2476DE2AAD2F
DEFINE PLATFORM_CONFIG_UUID = CA23E7E0-B28B-4F99-BA95-3B120D47A1B9

#
# Network definition
192 changes: 175 additions & 17 deletions Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
Original file line number Diff line number Diff line change
@@ -33,13 +33,11 @@
//
// Default settings definitions
//
#define NV_SI_SUBNUMA_MODE_DEFAULT 0x00 /* Monolithic mode */
#define NV_SI_SUBNUMA_MODE_DEFAULT CPU_SUBNUMA_MODE_MONO
#define WA_ERRATUM_1542419_DEFAULT 0x00 /* Disable I-Cache coherency */
#define NEAR_ATOMIC_DISABLE_DEFAULT 0x00 /* Enable Near Atomic */
#define CPU_SLC_REPLACE_POLICY 0x00 /* eLRU */

CHAR16 CpuVarstoreDataName[] = L"CpuConfigNVData";

EFI_HANDLE mDriverHandle = NULL;
CPU_CONFIG_PRIVATE_DATA *mPrivateData = NULL;

@@ -253,13 +251,25 @@ CpuConfigExtractConfig (
*Progress = Request;
AllocatedRequest = FALSE;

if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME)) {
return EFI_NOT_FOUND;
}

PrivateData = CPU_CONFIG_PRIVATE_FROM_THIS (This);
HiiConfigRouting = PrivateData->HiiConfigRouting;

BufferSize = sizeof (CPU_VARSTORE_DATA);
Status = gRT->GetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
NULL,
&BufferSize,
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}

//
// Get current setting from NVParam.
//
@@ -278,7 +288,7 @@ CpuConfigExtractConfig (
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
//
ConfigRequestHdr = HiiConstructConfigHdr (&gCpuConfigFormSetGuid, CpuVarstoreDataName, PrivateData->DriverHandle);
ConfigRequestHdr = HiiConstructConfigHdr (&gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME, PrivateData->DriverHandle);
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
ConfigRequest = AllocateZeroPool (Size);
ASSERT (ConfigRequest != NULL);
@@ -365,7 +375,19 @@ CpuConfigRouteConfig (
// Check routing data in <ConfigHdr>.
// Note: if only one Storage is used, then this checking could be skipped.
//
if (!HiiIsConfigHdrMatch (Configuration, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
if (!HiiIsConfigHdrMatch (Configuration, &gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME)) {
return EFI_NOT_FOUND;
}

BufferSize = sizeof (CPU_VARSTORE_DATA);
Status = gRT->GetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
NULL,
&BufferSize,
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}

@@ -392,6 +414,17 @@ CpuConfigRouteConfig (
return Status;
}

Status = gRT->SetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (CPU_VARSTORE_DATA),
&PrivateData->Configuration
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}

//
// Store configuration data back to NVParam
//
@@ -432,18 +465,68 @@ CpuConfigCallback (
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
if (Action != EFI_BROWSER_ACTION_CHANGING) {
//
// Do nothing for other UEFI Action. Only do call back when data is changed.
//
return EFI_UNSUPPORTED;
}
CPU_VARSTORE_DATA *Configuration;

if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
(ActionRequest == NULL))
{
return EFI_INVALID_PARAMETER;
}

if (Action == EFI_BROWSER_ACTION_CHANGED) {
Configuration = AllocateZeroPool (sizeof (CPU_VARSTORE_DATA));
ASSERT (Configuration != NULL);
if (!HiiGetBrowserData (&gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME, sizeof (CPU_VARSTORE_DATA), (UINT8 *)Configuration)) {
FreePool (Configuration);
return EFI_NOT_FOUND;
}

//
// Disable SLC as L3$ option if the CPU configuration is 1P monolithic mode
//
if (!IsSlaveSocketActive () && Configuration->CpuSubNumaMode == CPU_SUBNUMA_MODE_MONO) {
Configuration->CpuSlcAsL3Permitted = CPU_SLC_AS_L3_PERMITTED_YES;
} else {
Configuration->CpuSlcAsL3Permitted = CPU_SLC_AS_L3_PERMITTED_NO;
Configuration->CpuSlcAsL3 = CPU_SLC_AS_L3_DISABLE;
}

//
// Pass changed uncommitted data back to Form Browser
//
HiiSetBrowserData (&gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME, sizeof (CPU_VARSTORE_DATA), (UINT8 *)Configuration, NULL);
FreePool (Configuration);
}

return EFI_SUCCESS;
}

EFI_STATUS
CpuConfigUnload (
VOID
)
{
ASSERT (mPrivateData != NULL);

if (mDriverHandle != NULL) {
gBS->UninstallMultipleProtocolInterfaces (
mDriverHandle,
&gEfiDevicePathProtocolGuid,
&mCpuConfigHiiVendorDevicePath,
&gEfiHiiConfigAccessProtocolGuid,
&mPrivateData->ConfigAccess,
NULL
);
mDriverHandle = NULL;
}

if (mPrivateData->HiiHandle != NULL) {
HiiRemovePackages (mPrivateData->HiiHandle);
}

FreePool (mPrivateData);
mPrivateData = NULL;

return EFI_SUCCESS;
}

@@ -456,6 +539,20 @@ CpuConfigDxeEntryPoint (
EFI_STATUS Status;
EFI_HII_HANDLE HiiHandle;
EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
BOOLEAN ActionFlag;
CPU_VARSTORE_DATA *Configuration;
EFI_STRING ConfigRequestHdr;
UINTN BufferSize;

//
// With the fresh system, the NVParam value is invalid (0xFFFFFFFF).
// It causes reading from the NVParam is failed.
// So, the NVParam should be setting with default values if any params is invalid.
//
Status = SetupDefaultSettings ();
if (EFI_ERROR (Status)) {
return Status;
}

//
// Initialize driver private data
@@ -517,13 +614,74 @@ CpuConfigDxeEntryPoint (
mPrivateData->HiiHandle = HiiHandle;

//
// With the fresh system, the NVParam value is invalid (0xFFFFFFFF).
// It causes reading from the NVParam is failed.
// So, the NVParam should be setting with default values if any params is invalid.
// Initialize configuration data
//
Status = SetupDefaultSettings ();
Configuration = &mPrivateData->Configuration;
ZeroMem (Configuration, sizeof (CPU_VARSTORE_DATA));

//
// Try to read NV config EFI variable first
//
ConfigRequestHdr = HiiConstructConfigHdr (&gCpuConfigFormSetGuid, CPU_CONFIG_VARIABLE_NAME, mDriverHandle);
ASSERT (ConfigRequestHdr != NULL);

BufferSize = sizeof (CPU_VARSTORE_DATA);
Status = gRT->GetVariable (CPU_CONFIG_VARIABLE_NAME, &gCpuConfigFormSetGuid, NULL, &BufferSize, Configuration);
if (EFI_ERROR (Status)) {
return Status;
//
// Store zero data Buffer Storage to EFI variable
//
Status = gRT->SetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (CPU_VARSTORE_DATA),
Configuration
);
if (EFI_ERROR (Status)) {
CpuConfigUnload ();
return Status;
}
//
// EFI variable for NV config doesn't exit, we should build this variable
// based on default values stored in IFR
//
ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
if (!ActionFlag) {
CpuConfigUnload ();
return EFI_INVALID_PARAMETER;
}
} else {
//
// EFI variable does exist and Validate Current Setting
//
ActionFlag = HiiValidateSettings (ConfigRequestHdr);
if (!ActionFlag) {
CpuConfigUnload ();
return EFI_INVALID_PARAMETER;
}
}
FreePool (ConfigRequestHdr);

//
// Limit SLC as L3$ to only 1P monolithic mode
//
if (!IsSlaveSocketActive () && Configuration->CpuSubNumaMode == CPU_SUBNUMA_MODE_MONO) {
Configuration->CpuSlcAsL3Permitted = CPU_SLC_AS_L3_PERMITTED_YES;
} else {
Configuration->CpuSlcAsL3Permitted = CPU_SLC_AS_L3_PERMITTED_NO;
Configuration->CpuSlcAsL3 = CPU_SLC_AS_L3_DISABLE;
}

Status = gRT->SetVariable (
CPU_CONFIG_VARIABLE_NAME,
&gCpuConfigFormSetGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
sizeof (CPU_VARSTORE_DATA),
Configuration
);
if (EFI_ERROR (Status)) {
return EFI_NOT_FOUND;
}

return EFI_SUCCESS;
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
#ifndef CPU_CONFIG_H_
#define CPU_CONFIG_H_

#include "CpuConfigNVDataStruc.h"
#include <CpuConfigNVDataStruc.h>

//
// This is the generated IFR binary data for each formset defined in VFR.
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@
[Sources.common]
CpuConfigDxe.c
CpuConfigDxe.h
CpuConfigNVDataStruc.h
CpuConfigVfr.vfr
CpuConfigStrings.uni

@@ -29,6 +28,7 @@
Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec

[LibraryClasses]
AmpereCpuLib
ArmLib
BaseLib
DebugLib

This file was deleted.

Original file line number Diff line number Diff line change
@@ -15,3 +15,8 @@
#string STR_CPU_SUBNUMA_MODE_MONOLITHIC #language en-US "Monolithic"
#string STR_CPU_SUBNUMA_MODE_HEMISPHERE #language en-US "Hemisphere"
#string STR_CPU_SUBNUMA_MODE_QUADRANT #language en-US "Quadrant"

#string STR_CPU_SLC_AS_L3_PROMPT #language en-US "SLC as L3$"
#string STR_CPU_SLC_AS_L3_HELP #language en-US "This option enables / disables PPTT to indicate SLC as L3$. This is limited to only 1P Monolithic mode."
#string STR_CPU_SLC_AS_L3_ENABLE #language en-US "Enabled"
#string STR_CPU_SLC_AS_L3_DISABLE #language en-US "Disabled"
33 changes: 23 additions & 10 deletions Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigVfr.vfr
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
#include <Uefi/UefiMultiPhase.h>
#include <Guid/PlatformManagerHii.h>
#include <Guid/CpuConfigHii.h>
#include "CpuConfigNVDataStruc.h"
#include <CpuConfigNVDataStruc.h>

#define SUBNUMA_MODE_FORM_ID 1

@@ -28,15 +28,28 @@ formset
title = STRING_TOKEN(STR_CPU_FORM);
subtitle text = STRING_TOKEN(STR_CPU_FORM_HELP);

oneof
varid = CpuConfigNVData.CpuSubNumaMode,
prompt = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_PROMPT),
help = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HELP),
flags = RESET_REQUIRED,
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_MONOLITHIC), value = 0x0, flags = DEFAULT;
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HEMISPHERE), value = 0x1, flags = 0;
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_QUADRANT), value = 0x2, flags = 0;
endoneof;
grayoutif ideqval CpuConfigNVData.CpuSlcAsL3 == CPU_SLC_AS_L3_ENABLE;
oneof
varid = CpuConfigNVData.CpuSubNumaMode,
prompt = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_PROMPT),
help = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HELP),
flags = INTERACTIVE | RESET_REQUIRED,
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_MONOLITHIC), value = CPU_SUBNUMA_MODE_MONO, flags = DEFAULT;
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HEMISPHERE), value = CPU_SUBNUMA_MODE_HEMI, flags = 0;
option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_QUADRANT), value = CPU_SUBNUMA_MODE_QUAD, flags = 0;
endoneof;
endif;

grayoutif ideqval CpuConfigNVData.CpuSlcAsL3Permitted == CPU_SLC_AS_L3_PERMITTED_NO;
oneof
varid = CpuConfigNVData.CpuSlcAsL3,
prompt = STRING_TOKEN(STR_CPU_SLC_AS_L3_PROMPT),
help = STRING_TOKEN(STR_CPU_SLC_AS_L3_HELP),
flags = RESET_REQUIRED,
option text = STRING_TOKEN(STR_CPU_SLC_AS_L3_ENABLE), value = CPU_SLC_AS_L3_ENABLE, flags = DEFAULT;
option text = STRING_TOKEN(STR_CPU_SLC_AS_L3_DISABLE), value = CPU_SLC_AS_L3_DISABLE, flags = 0;
endoneof;
endif;

endform;

33 changes: 33 additions & 0 deletions Silicon/Ampere/AmpereAltraPkg/Include/CpuConfigNVDataStruc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/** @file
Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#ifndef CPU_CONFIG_NV_DATA_STRUC_H_
#define CPU_CONFIG_NV_DATA_STRUC_H_

#define CPU_SUBNUMA_MODE_MONO 0x00
#define CPU_SUBNUMA_MODE_HEMI 0x01
#define CPU_SUBNUMA_MODE_QUAD 0x02

#define CPU_SLC_AS_L3_ENABLE 0x00
#define CPU_SLC_AS_L3_DISABLE 0x01

#define CPU_SLC_AS_L3_PERMITTED_YES 0x00
#define CPU_SLC_AS_L3_PERMITTED_NO 0x01

#pragma pack(1)
typedef struct {
UINT32 CpuSubNumaMode;
UINT32 CpuSlcAsL3Permitted;
UINT32 CpuSlcAsL3;
} CPU_VARSTORE_DATA;

#pragma pack()

#define CPU_CONFIG_VARIABLE_NAME L"CpuConfigNVData"

#endif /* CPU_CONFIG_NV_DATA_STRUC_H_ */

0 comments on commit 9d5203b

Please sign in to comment.