From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=michael.a.kubacki@intel.com; receiver=edk2-devel@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A0DCE211EDB3B for ; Sun, 31 Mar 2019 16:28:30 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Mar 2019 16:28:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,294,1549958400"; d="scan'208";a="219290857" Received: from makuback-desk1.amr.corp.intel.com ([10.7.159.144]) by orsmga001.jf.intel.com with ESMTP; 31 Mar 2019 16:28:30 -0700 From: Michael Kubacki To: edk2-devel@lists.01.org Cc: Ankit Sinha , Nate DeSimone , Chasel Chiu , Liming Gao , Michael D Kinney Date: Sun, 31 Mar 2019 16:27:40 -0700 Message-Id: <20190331232740.16872-4-michael.a.kubacki@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 In-Reply-To: <20190331232740.16872-1-michael.a.kubacki@intel.com> References: <20190331232740.16872-1-michael.a.kubacki@intel.com> Subject: [edk2-platforms][PATCH v1 3/3] ClevoOpenBoardPkg/N1xxWU: Write PEI debug messages to SPI flash X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Mar 2019 23:28:30 -0000 Adds a new SerialPortLib instance to the ClevoOpenBoardPkg to support writing debug messages to a dedicated area on SPI flash. This is to enable closed chassis debug support on the system. DXE and later phases after memory initialization are expected to use USB debug. Cc: Ankit Sinha Cc: Nate DeSimone Cc: Chasel Chiu Cc: Liming Gao Cc: Michael D Kinney Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kubacki --- Platform/Intel/ClevoOpenBoardPkg/OpenBoardPkg.dec | 5 + .../ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc | 20 +- .../ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.fdf | 4 + .../PeiSerialPortLibSpiFlash.inf | 56 ++++ .../PeiSerialPortLibSpiFlash.c | 326 +++++++++++++++++++++ 5 files changed, 407 insertions(+), 4 deletions(-) create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.inf create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c diff --git a/Platform/Intel/ClevoOpenBoardPkg/OpenBoardPkg.dec b/Platform/Intel/ClevoOpenBoardPkg/OpenBoardPkg.dec index 87bbfb2240..aa457e64db 100644 --- a/Platform/Intel/ClevoOpenBoardPkg/OpenBoardPkg.dec +++ b/Platform/Intel/ClevoOpenBoardPkg/OpenBoardPkg.dec @@ -30,6 +30,7 @@ Features\Tbt\Include [Guids] gBoardModuleTokenSpaceGuid = {0x72d1fff7, 0xa42a, 0x4219, {0xb9, 0x95, 0x5a, 0x67, 0x53, 0x6e, 0xa4, 0x2a}} gTianoLogoGuid = {0x7BB28B99, 0x61BB, 0x11D5, {0x9A, 0x5D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D}} +gSpiFlashDebugHobGuid = {0xcaaaf418, 0x38a5, 0x4d49, {0xbe, 0x74, 0xe6, 0x06, 0xe4, 0x02, 0x6d, 0x25}} gTbtInfoHobGuid = {0x74a81eaa, 0x033c, 0x4783, {0xbe, 0x2b, 0x84, 0x85, 0x74, 0xa6, 0x97, 0xb7}} gPlatformModuleTokenSpaceGuid = {0x69d13bf0, 0xaf91, 0x4d96, {0xaa, 0x9f, 0x21, 0x84, 0xc5, 0xce, 0x3b, 0xc0}} @@ -64,6 +65,10 @@ gBoardModuleTokenSpaceGuid.PcdSwSmiDTbtEnumerate|0xF7|UINT8|0x000000110 gBoardModuleTokenSpaceGuid.PcdSmcExtSmiBitPosition|0x01|UINT8|0x90000015 +gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageBase|0x00000000|UINT32|0x90000030 +gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageSize|0x00000000|UINT32|0x90000031 +gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageOffset|0x00000000|UINT32|0x90000032 + [PcdsDynamic] # Board GPIO Table diff --git a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc index 2116c48fc0..c43a30de34 100644 --- a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc +++ b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.dsc @@ -116,10 +116,18 @@ # !include $(PLATFORM_SI_PACKAGE)/SiPkgCommonLib.dsc +[LibraryClasses.IA32.SEC] + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf + SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLibNull/SecBoardInitLibNull.inf + [LibraryClasses.IA32] # # PEI phase common # + SerialPortLib|$(PLATFORM_BOARD_PACKAGE)/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.inf + DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf FspWrapperPlatformLib|$(PLATFORM_PACKAGE)/FspWrapper/Library/PeiFspWrapperPlatformLib/PeiFspWrapperPlatformLib.inf !if $(TARGET) == DEBUG TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/PeiTestPointCheckLib.inf @@ -138,10 +146,6 @@ # !include $(PLATFORM_SI_PACKAGE)/SiPkgPeiLib.dsc -[LibraryClasses.IA32.SEC] - TestPointCheckLib|$(PLATFORM_PACKAGE)/Test/Library/TestPointCheckLib/SecTestPointCheckLib.inf - SecBoardInitLib|$(PLATFORM_PACKAGE)/PlatformInit/Library/SecBoardInitLibNull/SecBoardInitLibNull.inf - [LibraryClasses.X64] # # DXE phase common @@ -185,6 +189,14 @@ # !include $(PLATFORM_PACKAGE)/Include/Dsc/CorePeiInclude.dsc + # + # Core + # + MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf { + + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + } + # # FSP wrapper SEC Core # diff --git a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.fdf b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.fdf index 95c1758ff3..7f3e965c75 100644 --- a/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.fdf +++ b/Platform/Intel/ClevoOpenBoardPkg/N1xxWU/OpenBoardPkg.fdf @@ -136,6 +136,10 @@ gMinPlatformPkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareOffset|gEfiMdeModulePkgTo gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize #NV_FTW_SPARE +gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageOffset|gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageSize +gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageBase|gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageSize +#DEBUG_MESSAGE_AREA + gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedOffset|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase|gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize FV = FvAdvanced diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.inf b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.inf new file mode 100644 index 0000000000..c22201e033 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.inf @@ -0,0 +1,56 @@ +### @file +# Component description file for Serial I/O Port library to write to SPI flash. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License which accompanies this distribution. +# The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiSerialPortLibFlash + FILE_GUID = 35A3BA89-04BE-409C-A3CA-DEF6B510F80F + VERSION_STRING = 1.1 + MODULE_TYPE = PEIM + LIBRARY_CLASS = SerialPortLib|PEIM PEI_CORE +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF +# + +[LibraryClasses] + BaseLib + BaseMemoryLib + HobLib + PcdLib + PeiServicesLib + SpiLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + KabylakeSiliconPkg/SiPkg.dec + ClevoOpenBoardPkg/OpenBoardPkg.dec + +[Sources] + PeiSerialPortLibSpiFlash.c + +[Ppis] + gPchSpiPpiGuid + +[Guids] + gSpiFlashDebugHobGuid + +[Pcd] + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES + gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageBase ## CONSUMES + gBoardModuleTokenSpaceGuid.PcdFlashNvDebugMessageSize ## CONSUMES diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c new file mode 100644 index 0000000000..e36ff8bff8 --- /dev/null +++ b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiSerialPortLibSpiFlash/PeiSerialPortLibSpiFlash.c @@ -0,0 +1,326 @@ +/** @file + Serial I/O Port library implementation for output to SPI flash + +Copyright (c) 2019, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + PCH_SPI_PPI *PchSpiPpi; + UINT32 CurrentWriteOffset; +} SPI_FLASH_DEBUG_CONTEXT; + +/** + Update reference to the most recent PCH SPI PPI installed + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS Successfully update the PCH SPI PPI reference + @retval EFI_NOT_FOUND An error occurred locating a required interface + @retval EFI_NOT_SUPPORTED + +**/ +EFI_STATUS +EFIAPI +SpiPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + PCH_SPI_PPI *PchSpiPpi; + SPI_FLASH_DEBUG_CONTEXT *Context; + + GuidHob = GetFirstGuidHob (&gSpiFlashDebugHobGuid); + if (GuidHob == NULL) { + return EFI_NOT_FOUND; + } + Context = GET_GUID_HOB_DATA (GuidHob); + + Status = PeiServicesLocatePpi ( + &gPchSpiPpiGuid, + 0, + NULL, + (VOID **) &PchSpiPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + Context->PchSpiPpi = PchSpiPpi; + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mSpiPpiNotifyList[] = { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPchSpiPpiGuid, + SpiPpiNotifyCallback + } +}; + +/** + Common function to write trace data to a chosen debug interface like + UART Serial device, USB Serial device or Trace Hub device + + @param Buffer Point of data buffer which need to be writed. + @param NumberOfBytes Number of output bytes which are cached in Buffer. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + SPI_FLASH_DEBUG_CONTEXT *Context; + UINT32 BytesWritten; + UINT32 SourceBufferOffset; + UINT32 NvMessageAreaSize; + UINT32 LinearOffset; + + BytesWritten = NumberOfBytes; + SourceBufferOffset = 0; + + NvMessageAreaSize = (UINT32) FixedPcdGet32 (PcdFlashNvDebugMessageSize); + + if (NumberOfBytes == 0 || NvMessageAreaSize == 0) { + return 0; + } + GuidHob = GetFirstGuidHob (&gSpiFlashDebugHobGuid); + if (GuidHob == NULL) { + return 0; + } + Context = GET_GUID_HOB_DATA (GuidHob); + if (Context == NULL || Context->PchSpiPpi == NULL || Context->CurrentWriteOffset >= NvMessageAreaSize) { + return 0; + } + + if ((Context->CurrentWriteOffset + NumberOfBytes) / NvMessageAreaSize > 0) { + LinearOffset = (UINT32) (FixedPcdGet32 (PcdFlashNvDebugMessageBase) - FixedPcdGet32 (PcdFlashAreaBaseAddress)); + Status = Context->PchSpiPpi->FlashErase ( + Context->PchSpiPpi, + FlashRegionBios, + LinearOffset, + NvMessageAreaSize + ); + if (!EFI_ERROR (Status)) { + Context->CurrentWriteOffset = 0; + } else { + return 0; + } + } + + if (NumberOfBytes > NvMessageAreaSize) { + BytesWritten = NvMessageAreaSize; + SourceBufferOffset = NumberOfBytes - NvMessageAreaSize; + } + + LinearOffset = (FixedPcdGet32 (PcdFlashNvDebugMessageBase) + Context->CurrentWriteOffset) - FixedPcdGet32 (PcdFlashAreaBaseAddress); + + Status = Context->PchSpiPpi->FlashWrite ( + Context->PchSpiPpi, + FlashRegionBios, + LinearOffset, + BytesWritten, + (UINT8 *) &Buffer[SourceBufferOffset] + ); + if (!EFI_ERROR (Status)) { + Context->CurrentWriteOffset += BytesWritten; + return BytesWritten; + } + + return 0; +} + +/** + Common function to Read data from UART serial device, USB serial device and save the datas in buffer. + + @param Buffer Point of data buffer which need to be writed. + @param NumberOfBytes Number of output bytes which are cached in Buffer. + + @retval 0 Read data failed, no data is to be read. + @retval >0 Actual number of bytes read from debug device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes +) +{ + return 0; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return FALSE; +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetAttributes ( + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT UINT32 *Timeout, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + EFI_STATUS Status; + SPI_FLASH_DEBUG_CONTEXT *Context; + + Context = (SPI_FLASH_DEBUG_CONTEXT *) BuildGuidHob (&gSpiFlashDebugHobGuid, sizeof (SPI_FLASH_DEBUG_CONTEXT)); + if (Context == NULL) { + return EFI_DEVICE_ERROR; + } + ZeroMem ((VOID *) Context, sizeof (SPI_FLASH_DEBUG_CONTEXT)); + + Status = PeiServicesNotifyPpi (&mSpiPpiNotifyList[0]); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // Perform silicon specific initialization required to enable write to SPI flash. + // + Status = SpiServiceInit (); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + } + + return Status; +} -- 2.16.2.windows.1