public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Abdul Lateef Attar" <abdattar@amd.com>
To: <devel@edk2.groups.io>
Cc: Abdul Lateef Attar <abdattar@amd.com>, Abner Chang <abner.chang@amd.com>
Subject: [PATCH v2 2/2] AMD/AmdMinBoardkPkg: Implements PeiReportFvLib Library
Date: Mon, 22 May 2023 14:58:51 +0530	[thread overview]
Message-ID: <19efba7e1a2883cbc9607c81d018d08c2ea734a8.1684747555.git.abdattar@amd.com> (raw)
In-Reply-To: <cover.1684747555.git.abdattar@amd.com>

Customize PeiReportFvLib library for AMD platforms by
adding below changes.
  Installs Advanced Security FV.
  Adds facility to install FV above 4GB address space.

Cc: Abner Chang <abner.chang@amd.com>

Signed-off-by: Abdul Lateef Attar <abdattar@amd.com>
---
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec     |   8 +
 .../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc     |   2 +
 .../Library/PeiReportFvLib/PeiReportFvLib.inf |  57 +++++
 .../Library/PeiReportFvLib/PeiReportFvLib.c   | 239 ++++++++++++++++++
 4 files changed, 306 insertions(+)
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
 create mode 100644 Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c

diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
index 65ba08545021..03d1d77c34eb 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
@@ -33,3 +33,11 @@ [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
   # PreFetch Memory padding in bytes, default 2MB
   gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadPMem|0x00200000|UINT32|0x10000001
 
+  # PCDs to support loading of FV above 4GB address space
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedBase            |0x0000000000000000|UINT64|0x10000004
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvOsBootBase              |0x0000000000000000|UINT64|0x10000005
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvUefiBootBase            |0x0000000000000000|UINT64|0x10000006
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedSecurityBase    |0x0000000000000000|UINT64|0x10000007
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedSecuritySize    |0x00000000|UINT32|0x10000008
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedSecurityOffset  |0x00000000|UINT32|0x10000009
+
diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index 1a8407250c56..be33089a45ef 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -24,6 +24,7 @@ [Packages]
 
 [LibraryClasses]
   SpcrDeviceLib|AmdMinBoardPkg/Library/SpcrDeviceLib/SpcrDeviceLib.inf
+  ReportFvLib|AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
 
 [LibraryClasses.common]
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -43,6 +44,7 @@ [Components]
 
 [Components.IA32]
   AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
+  AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
 
 [Components.X64]
   AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
new file mode 100644
index 000000000000..23ee503c42be
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.inf
@@ -0,0 +1,57 @@
+### @file
+# Component information file for the Report Firmware Volume (FV) library.
+#
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+[Defines]
+  INF_VERSION                    = 1.29
+  BASE_NAME                      = PeiReportFvLib
+  FILE_GUID                      = 3C207C28-DC43-4A3A-B572-6794C77AB519
+  VERSION_STRING                 = 1.0
+  MODULE_TYPE                    = PEIM
+  LIBRARY_CLASS                  = ReportFvLib
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  PeiServicesLib
+
+[Packages]
+  AmdMinBoardPkg/AmdMinBoardPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  MinPlatformPkg/MinPlatformPkg.dec
+
+[Sources]
+  PeiReportFvLib.c
+
+[Pcd]
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedBase         ## CONSUMES
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedSecurityBase ## CONSUMES
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvAdvancedSecuritySize ## CONSUMES
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvOsBootBase           ## CONSUMES
+  gAmdMinBoardPkgTokenSpaceGuid.PcdAmdFlashFvUefiBootBase         ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdBootStage                      ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress           ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize                  ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemoryBase   ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedPreMemorySize   ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvAdvancedSize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTBase                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvFspTSize                ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootBase              ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvOsBootSize              ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemoryBase          ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvPostMemorySize          ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecurityBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvSecuritySize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootBase            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFlashFvUefiBootSize            ## CONSUMES
+  gMinPlatformPkgTokenSpaceGuid.PcdFspWrapperBootMode             ## CONSUMES
diff --git a/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
new file mode 100644
index 000000000000..f0b2abef611b
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/Library/PeiReportFvLib/PeiReportFvLib.c
@@ -0,0 +1,239 @@
+/** @file
+  Source code file for Report Firmware Volume (FV) library for AMD platforms.
+
+  @par Note:
+    This source has the reference of MinPlatformPkgs's PeriReportFvLib.c module.
+
+  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/ReportFvLib.h>
+#include <Guid/FirmwareFileSystem2.h>
+#include <Ppi/FirmwareVolumeInfo.h>
+
+VOID
+ReportPreMemFv (
+  VOID
+  )
+{
+  ///
+  /// Note : FSP FVs except FSP-T FV are installed in IntelFsp2WrapperPkg in Dispatch mode.
+  ///
+  if (PcdGetBool (PcdFspWrapperBootMode)) {
+    DEBUG ((DEBUG_INFO, "Install FlashFvFspT - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvFspTBase), PcdGet32 (PcdFlashFvFspTSize)));
+    PeiServicesInstallFvInfo2Ppi (
+      &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFlashFvFspTBase))->FileSystemGuid),
+      (VOID *)(UINTN)PcdGet32 (PcdFlashFvFspTBase),
+      PcdGet32 (PcdFlashFvFspTSize),
+      NULL,
+      NULL,
+      0
+      );
+  }
+
+  DEBUG ((DEBUG_INFO, "Install FlashFvSecurity - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvSecurityBase), PcdGet32 (PcdFlashFvSecuritySize)));
+  PeiServicesInstallFvInfo2Ppi (
+    &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFlashFvSecurityBase))->FileSystemGuid),
+    (VOID *)(UINTN)PcdGet32 (PcdFlashFvSecurityBase),
+    PcdGet32 (PcdFlashFvSecuritySize),
+    NULL,
+    NULL,
+    0
+    );
+  if (PcdGet8 (PcdBootStage) >= 6) {
+    DEBUG ((
+      DEBUG_INFO,
+      "Install FlashFvAdvancedPreMemory - 0x%x, 0x%x\n",
+      PcdGet32 (PcdFlashFvAdvancedPreMemoryBase),
+      PcdGet32 (PcdFlashFvAdvancedPreMemorySize)
+      ));
+    PeiServicesInstallFvInfo2Ppi (
+      &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFlashFvAdvancedPreMemoryBase))->FileSystemGuid),
+      (VOID *)(UINTN)PcdGet32 (PcdFlashFvAdvancedPreMemoryBase),
+      PcdGet32 (PcdFlashFvAdvancedPreMemorySize),
+      NULL,
+      NULL,
+      0
+      );
+  }
+}
+
+VOID
+ReportPostMemFv (
+  VOID
+  )
+{
+  EFI_STATUS                Status;
+  EFI_BOOT_MODE             BootMode;
+  EFI_HOB_FIRMWARE_VOLUME3  *Hob3;
+  EFI_HOB_FIRMWARE_VOLUME   *Hob;
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  ///
+  /// Note : FSP FVs except FSP-T FV are installed in IntelFsp2WrapperPkg in Dispatch mode.
+  ///
+
+  ///
+  /// Build HOB for DXE
+  ///
+  if (BootMode == BOOT_IN_RECOVERY_MODE) {
+    ///
+    /// Prepare the recovery service
+    ///
+  } else {
+    DEBUG ((DEBUG_INFO, "Install FlashFvPostMemory - 0x%x, 0x%x\n", PcdGet32 (PcdFlashFvPostMemoryBase), PcdGet32 (PcdFlashFvPostMemorySize)));
+    PeiServicesInstallFvInfo2Ppi (
+      &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdFlashFvPostMemoryBase))->FileSystemGuid),
+      (VOID *)(UINTN)PcdGet32 (PcdFlashFvPostMemoryBase),
+      PcdGet32 (PcdFlashFvPostMemorySize),
+      NULL,
+      NULL,
+      0
+      );
+
+    if (PcdGet64 (PcdAmdFlashFvUefiBootBase) >= BASE_4GB) {
+      Hob  = NULL;
+      Hob3 = NULL;
+      DEBUG ((DEBUG_INFO, "Found FvUefiBoot FV above 4GB, creating FV HOBs.\n"));
+      Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME), (VOID **)&Hob);
+      if (!EFI_ERROR (Status)) {
+        Hob->BaseAddress = PcdGet64 (PcdAmdFlashFvUefiBootBase);
+        Hob->Length      = PcdGet32 (PcdFlashFvUefiBootSize);
+      }
+
+      Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3), (VOID **)&Hob3);
+      if (!EFI_ERROR (Status)) {
+        Hob3->BaseAddress          = PcdGet64 (PcdAmdFlashFvUefiBootBase);
+        Hob3->Length               = PcdGet32 (PcdFlashFvUefiBootSize);
+        Hob3->AuthenticationStatus = 0;
+        Hob3->ExtractedFv          = FALSE;
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "Install FlashFvUefiBoot - 0x%lx, 0x%x\n", PcdGet64 (PcdAmdFlashFvUefiBootBase), PcdGet32 (PcdFlashFvUefiBootSize)));
+      PeiServicesInstallFvInfo2Ppi (
+        &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdAmdFlashFvUefiBootBase))->FileSystemGuid),
+        (VOID *)(UINTN)PcdGet64 (PcdAmdFlashFvUefiBootBase),
+        PcdGet32 (PcdFlashFvUefiBootSize),
+        NULL,
+        NULL,
+        0
+        );
+    }
+
+    if (PcdGet64 (PcdAmdFlashFvOsBootBase) >= BASE_4GB) {
+      Hob  = NULL;
+      Hob3 = NULL;
+      DEBUG ((DEBUG_INFO, "Found FvOsBoot FV above 4GB, creating FV HOBs.\n"));
+      Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME), (VOID **)&Hob);
+      if (!EFI_ERROR (Status)) {
+        Hob->BaseAddress = PcdGet64 (PcdAmdFlashFvOsBootBase);
+        Hob->Length      = PcdGet32 (PcdFlashFvOsBootSize);
+      }
+
+      Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3), (VOID **)&Hob3);
+      if (!EFI_ERROR (Status)) {
+        Hob3->BaseAddress          = PcdGet64 (PcdAmdFlashFvOsBootBase);
+        Hob3->Length               = PcdGet32 (PcdFlashFvOsBootSize);
+        Hob3->AuthenticationStatus = 0;
+        Hob3->ExtractedFv          = FALSE;
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "Install FlashFvOsBoot - 0x%lx, 0x%x\n", PcdGet64 (PcdAmdFlashFvOsBootBase), PcdGet32 (PcdFlashFvOsBootSize)));
+      PeiServicesInstallFvInfo2Ppi (
+        &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdAmdFlashFvOsBootBase))->FileSystemGuid),
+        (VOID *)(UINTN)PcdGet64 (PcdAmdFlashFvOsBootBase),
+        PcdGet32 (PcdFlashFvOsBootSize),
+        NULL,
+        NULL,
+        0
+        );
+    }
+
+    if (PcdGet8 (PcdBootStage) >= 6) {
+      if (PcdGet64 (PcdAmdFlashFvAdvancedBase) >= BASE_4GB) {
+        Hob  = NULL;
+        Hob3 = NULL;
+        DEBUG ((DEBUG_INFO, "Found FvAdvanced FV above 4GB, creating FV HOBs.\n"));
+        Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME), (VOID **)&Hob);
+        if (!EFI_ERROR (Status)) {
+          Hob->BaseAddress = PcdGet64 (PcdAmdFlashFvAdvancedBase);
+          Hob->Length      = PcdGet32 (PcdFlashFvAdvancedSize);
+        }
+
+        Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3), (VOID **)&Hob3);
+        if (!EFI_ERROR (Status)) {
+          Hob3->BaseAddress          = PcdGet64 (PcdAmdFlashFvAdvancedBase);
+          Hob3->Length               = PcdGet32 (PcdFlashFvAdvancedSize);
+          Hob3->AuthenticationStatus = 0;
+          Hob3->ExtractedFv          = FALSE;
+        }
+      } else {
+        DEBUG ((DEBUG_INFO, "Install FlashFvAdvanced - 0x%lx, 0x%x\n", PcdGet64 (PcdAmdFlashFvAdvancedBase), PcdGet32 (PcdFlashFvAdvancedSize)));
+        PeiServicesInstallFvInfo2Ppi (
+          &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdAmdFlashFvAdvancedBase))->FileSystemGuid),
+          (VOID *)(UINTN)PcdGet64 (PcdAmdFlashFvAdvancedBase),
+          PcdGet32 (PcdFlashFvAdvancedSize),
+          NULL,
+          NULL,
+          0
+          );
+      }
+    }
+  }
+
+  if (PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase) >= BASE_4GB) {
+    Hob  = NULL;
+    Hob3 = NULL;
+    DEBUG ((DEBUG_INFO, "Found FvAdvancedSecurity FV above 4GB, creating FV HOBs.\n"));
+    Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME), (VOID **)&Hob);
+    if (!EFI_ERROR (Status)) {
+      Hob->BaseAddress = PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase);
+      Hob->Length      = PcdGet32 (PcdAmdFlashFvAdvancedSecuritySize);
+    }
+
+    Status = PeiServicesCreateHob (EFI_HOB_TYPE_FV3, sizeof (EFI_HOB_FIRMWARE_VOLUME3), (VOID **)&Hob3);
+    if (!EFI_ERROR (Status)) {
+      Hob3->BaseAddress          = PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase);
+      Hob3->Length               = PcdGet32 (PcdAmdFlashFvAdvancedSecuritySize);
+      Hob3->AuthenticationStatus = 0;
+      Hob3->ExtractedFv          = FALSE;
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "Install FvAdvancedSecurity - 0x%lx, 0x%x\n", PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase), PcdGet32 (PcdAmdFlashFvAdvancedSecuritySize)));
+    PeiServicesInstallFvInfo2Ppi (
+      &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase))->FileSystemGuid),
+      (VOID *)(UINTN)PcdGet64 (PcdAmdFlashFvAdvancedSecurityBase),
+      PcdGet32 (PcdAmdFlashFvAdvancedSecuritySize),
+      NULL,
+      NULL,
+      0
+      );
+  }
+
+  //
+  // Report resource HOB for flash FV
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+    (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
+     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+    (UINTN)PcdGet32 (PcdFlashAreaBaseAddress),
+    (UINTN)PcdGet32 (PcdFlashAreaSize)
+    );
+  BuildMemoryAllocationHob (
+    (UINTN)PcdGet32 (PcdFlashAreaBaseAddress),
+    (UINTN)PcdGet32 (PcdFlashAreaSize),
+    EfiMemoryMappedIO
+    );
+}
-- 
2.25.1


  parent reply	other threads:[~2023-05-22  9:29 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-22  9:28 [PATCH v2 0/2] AMD/AmdMinBoardPkg: ReportFvLib library and Abdul Lateef Attar
2023-05-22  9:28 ` [PATCH v2 1/2] AMD/AmdMinBoardPkg: Implements PCI hotplug init protocol Abdul Lateef Attar
2023-05-26  1:36   ` Chang, Abner
2023-05-29 14:35     ` Attar, AbdulLateef (Abdul Lateef)
2023-05-29 14:40   ` Chang, Abner
2023-05-22  9:28 ` Abdul Lateef Attar [this message]
2023-05-29 14:40   ` [PATCH v2 2/2] AMD/AmdMinBoardkPkg: Implements PeiReportFvLib Library Chang, Abner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=19efba7e1a2883cbc9607c81d018d08c2ea734a8.1684747555.git.abdattar@amd.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox