+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-Module Name:\r
-\r
-\r
- Dimm.c\r
-\r
-Abstract:\r
-\r
- PPI for reading SPD modules on DIMMs.\r
-\r
---*/\r
-\r
-\r
-//\r
-// Header Files\r
-//\r
-#include "Platformearlyinit.h"\r
-\r
-#define DIMM_SOCKETS 4 // Total number of DIMM sockets allowed on\r
- // the platform\r
-#define DIMM_SEGMENTS 1 // Total number of Segments Per DIMM.\r
-#define MEMORY_CHANNELS 2 // Total number of memory channels\r
- // populated on the system board\r
-//\r
-// Prototypes\r
-//\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-GetDimmState (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- OUT PEI_PLATFORM_DIMM_STATE *State\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SetDimmState (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- IN PEI_PLATFORM_DIMM_STATE *State\r
- );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ReadSpd (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- IN UINT8 Offset,\r
- IN UINTN Count,\r
- IN OUT UINT8 *Buffer\r
- );\r
-\r
-static PEI_PLATFORM_DIMM_PPI mGchDimmPpi = {\r
- DIMM_SOCKETS,\r
- DIMM_SEGMENTS,\r
- MEMORY_CHANNELS,\r
- GetDimmState,\r
- SetDimmState,\r
- ReadSpd\r
-};\r
-\r
-static EFI_PEI_PPI_DESCRIPTOR mPpiPlatformDimm = {\r
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gPeiPlatformDimmPpiGuid,\r
- &mGchDimmPpi\r
-};\r
-\r
-\r
-//\r
-// Functions\r
-//\r
-\r
-/**\r
- This function returns the current state of a single DIMM. Present indicates\r
- that the DIMM slot is physically populated. Disabled indicates that the DIMM\r
- should not be used.\r
-\r
- @param PeiServices PEI services table pointer\r
- @param This PPI pointer\r
- @param Dimm DIMM to read from\r
- @param State Pointer to a return buffer to be updated with the current state\r
- of the DIMM\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDimmState (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- OUT PEI_PLATFORM_DIMM_STATE *State\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT8 Buffer;\r
-\r
- PEI_ASSERT (PeiServices, (Dimm < This->DimmSockets));\r
-\r
- //\r
- // A failure here does not necessarily mean that no DIMM is present.\r
- // Read a single byte. All we care about is the return status.\r
- //\r
- Status = ReadSpd (\r
- PeiServices,\r
- This,\r
- Dimm,\r
- 0,\r
- 1,\r
- &Buffer\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- State->Present = 0;\r
- } else {\r
- State->Present = 1;\r
- }\r
-\r
- //\r
- // BUGBUG: Update to check platform variable when it is available\r
- //\r
- State->Disabled = 0;\r
- State->Reserved = 0;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-\r
- This function updates the state of a single DIMM.\r
-\r
- @param PeiServices PEI services table pointer\r
- @param This PPI pointer\r
- @param Dimm DIMM to set state for\r
- @param State Pointer to the state information to set.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_UNSUPPORTED The function is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetDimmState (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- IN PEI_PLATFORM_DIMM_STATE *State\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- This function reads SPD information from a DIMM.\r
-\r
- PeiServices PEI services table pointer\r
- This PPI pointer\r
- Dimm DIMM to read from\r
- Offset Offset in DIMM\r
- Count Number of bytes\r
- Buffer Return buffer\r
-\r
- @param EFI_SUCCESS The function completed successfully.\r
- @param EFI_DEVICE_ERROR The DIMM being accessed reported a device error,\r
- does not have an SPD module, or is not installed in\r
- the system.\r
- @retval EFI_TIMEOUT Time out trying to read the SPD module.\r
- @retval EFI_INVALID_PARAMETER A parameter was outside the legal limits.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ReadSpd (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN PEI_PLATFORM_DIMM_PPI *This,\r
- IN UINT8 Dimm,\r
- IN UINT8 Offset,\r
- IN UINTN Count,\r
- IN OUT UINT8 *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- PEI_SMBUS_PPI *Smbus;\r
- UINTN Index;\r
- UINTN Index1;\r
- EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;\r
- EFI_SMBUS_DEVICE_COMMAND Command;\r
- UINTN Length;\r
-\r
- Status = (**PeiServices).LocatePpi (\r
- PeiServices,\r
- &gPeiSmbusPpiGuid, // GUID\r
- 0, // INSTANCE\r
- NULL, // EFI_PEI_PPI_DESCRIPTOR\r
- &Smbus // PPI\r
- );\r
- ASSERT_PEI_ERROR (PeiServices, Status);\r
-\r
- switch (Dimm) {\r
- case 0:\r
- SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_1 >> 1;\r
- break;\r
- case 1:\r
- SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_A_2 >> 1;\r
- break;\r
- case 2:\r
- SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_1 >> 1;\r
- break;\r
- case 3:\r
- SlaveAddress.SmbusDeviceAddress = SMBUS_ADDR_CH_B_2 >> 1;\r
- break;\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Index = Count % 4;\r
- if (Index != 0) {\r
- //\r
- // read the first serveral bytes to speed up following reading\r
- //\r
- for (Index1 = 0; Index1 < Index; Index1++) {\r
- Length = 1;\r
- Command = Offset + Index1;\r
- Status = Smbus->Execute (\r
- PeiServices,\r
- Smbus,\r
- SlaveAddress,\r
- Command,\r
- EfiSmbusReadByte,\r
- FALSE,\r
- &Length,\r
- &Buffer[Index1]\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Now collect all the remaining bytes on 4 bytes block\r
- //\r
- for (; Index < Count; Index += 2) {\r
- Command = Index + Offset;\r
- Length = 2;\r
- Status = Smbus->Execute (\r
- PeiServices,\r
- Smbus,\r
- SlaveAddress,\r
- Command,\r
- EfiSmbusReadWord,\r
- FALSE,\r
- &Length,\r
- &Buffer[Index]\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
-\r
- Index += 2;\r
- Command = Index + Offset;\r
- Length = 2;\r
- Status = Smbus->Execute (\r
- PeiServices,\r
- Smbus,\r
- SlaveAddress,\r
- Command,\r
- EfiSmbusReadWord,\r
- FALSE,\r
- &Length,\r
- &Buffer[Index]\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return Status;\r
- }\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function initializes the PEIM. It simply installs the DIMM PPI.\r
-\r
- @param FfsHeader Not used by this function\r
- @param PeiServices Pointer to PEI services table\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PeimInitializeDimm (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *SmbusPpi\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- Status = (**PeiServices).InstallPpi (\r
- PeiServices,\r
- &mPpiPlatformDimm\r
- );\r
- ASSERT_PEI_ERROR (PeiServices, Status);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r