public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "xianglai" <lixianglai@loongson.cn>
To: devel@edk2.groups.io, lichao@loongson.cn
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
	Bibo Mao <maobibo@loongson.cn>,
	Leif Lindholm <quic_llindhol@quicinc.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Michael D Kinney <michael.d.kinney@intel.com>
Subject: Re: [edk2-devel] [edk2-platforms][PATCH V2 3/7] Platform/Loongson: Support pflash for loongarch.
Date: Wed, 11 Jan 2023 15:16:39 +0800	[thread overview]
Message-ID: <8670ebe1-186a-a03f-30eb-3c15aa49ddac@loongson.cn> (raw)
In-Reply-To: <98699f65-39de-7c91-7ffa-6152660c4171@loongson.cn>

Ok, I'll split it in the next version.

Thanks,

xianglai


在 2023/1/10 下午3:12, Chao Li 写道:
> I suggest to splitting this patch into two, one for adding new driver, 
> and one for adjusting the code.
>
>
> Thanks,
> Chao
> 在 2023/1/10 09:16, xianglai 写道:
>> Add pflash driver for loongarch.
>>
>> Cc: Ard Biesheuvel<ardb+tianocore@kernel.org>
>> Cc: Bibo Mao<maobibo@loongson.cn>
>> Cc: Chao Li<lichao@loongson.cn>
>> Cc: Leif Lindholm<quic_llindhol@quicinc.com>
>> Cc: Liming Gao<gaoliming@byosoft.com.cn>
>> Cc: Michael D Kinney<michael.d.kinney@intel.com>
>> Signed-off-by: xianglai li<lixianglai@loongson.cn>
>> ---
>>   .../Library/NorFlashQemuLib/NorFlashQemuLib.c | 141 ++++++++++++++++++
>>   .../NorFlashQemuLib/NorFlashQemuLib.inf       |  43 ++++++
>>   .../Loongson/LoongArchQemuPkg/Loongson.dsc    |  15 +-
>>   .../Loongson/LoongArchQemuPkg/Loongson.fdf    |   3 +-
>>   .../LoongArchQemuPkg/VarStore.fdf.inc         |  67 +++++++++
>>   5 files changed, 260 insertions(+), 9 deletions(-)
>>   create mode 100644 
>> Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
>>   create mode 100644 
>> Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>>   create mode 100644 Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
>>
>> diff --git 
>> a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c 
>> b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c 
>>
>> new file mode 100644
>> index 0000000000..2e0bf3cef0
>> --- /dev/null
>> +++ 
>> b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.c
>> @@ -0,0 +1,141 @@
>> +/** @file
>> +
>> +  Copyright (c) 2023 Loongson Technology Corporation Limited. All 
>> rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/VirtNorFlashPlatformLib.h>
>> +
>> +#include <Protocol/FdtClient.h>
>> +
>> +#define QEMU_NOR_BLOCK_SIZE  SIZE_128KB
>> +
>> +EFI_STATUS
>> +VirtNorFlashPlatformInitialization (
>> +  VOID
>> +  )
>> +{
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC VIRT_NOR_FLASH_DESCRIPTION  mNorFlashDevices;
>> +
>> +EFI_STATUS
>> +VirtNorFlashPlatformGetDevices (
>> +  OUT VIRT_NOR_FLASH_DESCRIPTION  **NorFlashDescriptions,
>> +  OUT UINT32                      *Count
>> +  )
>> +{
>> +  FDT_CLIENT_PROTOCOL  *FdtClient;
>> +  INT32                Node;
>> +  EFI_STATUS           Status;
>> +  EFI_STATUS           FindNodeStatus;
>> +  CONST UINT32         *Reg;
>> +  UINT32               PropSize;
>> +  UINT64               Base;
>> +  UINT64               Size;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gFdtClientProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&FdtClient
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  FindNodeStatus = FdtClient->FindCompatibleNode (
>> +                                     FdtClient,
>> +                                     "cfi-flash",
>> +                                     &Node
>> +                                     );
>> +  ASSERT_EFI_ERROR (FindNodeStatus);
>> +
>> +  Status = FdtClient->GetNodeProperty (
>> +                        FdtClient,
>> +                        Node,
>> +                        "reg",
>> +                        (CONST VOID **)&Reg,
>> +                        &PropSize
>> +                        );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((
>> +      DEBUG_ERROR,
>> +      "%a: GetNodeProperty () failed (Status == %r)\n",
>> +      __FUNCTION__,
>> +      Status
>> +      ));
>> +    return Status;
>> +  }
>> +
>> +  ASSERT ((PropSize % (4 * sizeof (UINT32))) == 0);
>> +
>> +  if (PropSize < (4 * sizeof (UINT32))) {
>> +    DEBUG ((
>> +      DEBUG_ERROR,
>> +      "%a: reg node size(%d) is too small \n",
>> +      __FUNCTION__,
>> +      PropSize
>> +      ));
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  Base = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[0]));
>> +  Size = SwapBytes64 (ReadUnaligned64 ((VOID *)&Reg[2]));
>> +
>> +  mNorFlashDevices.DeviceBaseAddress = (UINTN)Base;
>> +  mNorFlashDevices.RegionBaseAddress = (UINTN)Base;
>> +  mNorFlashDevices.Size              = (UINTN)Size;
>> +  mNorFlashDevices.BlockSize         = QEMU_NOR_BLOCK_SIZE;
>> +
>> +  Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  /*
>> +   * Base is the value of PcdFlashNvStorageVariableBase,
>> +   * PcdFlashNvStorageFtwWorkingBase can be got by
>> +   *   PcdFlashNvStorageVariableBase + PcdFlashNvStorageVariableSize
>> +   */
>> +  Base += PcdGet32 (PcdFlashNvStorageVariableSize);
>> +  Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, Base);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  /*
>> +   * Now,Base is the value of PcdFlashNvStorageFtwWorkingBase,
>> +   * PcdFlashNvStorageFtwSpareBase can be got by
>> +   *   PcdFlashNvStorageFtwWorkingBase + 
>> PcdFlashNvStorageFtwWorkingSize.
>> +   */
>> +  Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
>> +  Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  //
>> +  // UEFI takes ownership of the NOR flash, and exposes its 
>> functionality
>> +  // through the UEFI Runtime Services GetVariable, SetVariable, 
>> etc. This
>> +  // means we need to disable it in the device tree to prevent the 
>> OS from
>> +  // attaching its device driver as well.
>> +  // Note that this also hides other flash banks, but the only other 
>> flash
>> +  // bank we expect to encounter is the one that carries the UEFI 
>> executable
>> +  // code, which is not intended to be guest updatable, and is 
>> usually backed
>> +  // in a readonly manner by QEMU anyway.
>> +  //
>> +  Status = FdtClient->SetNodeProperty (
>> +                        FdtClient,
>> +                        Node,
>> +                        "status",
>> +                        "disabled",
>> +                        sizeof ("disabled")
>> +                        );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_WARN, "Failed to set NOR flash status to 
>> 'disabled'\n"));
>> +  }
>> +
>> +  *NorFlashDescriptions = &mNorFlashDevices;
>> +  *Count                = 1;
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git 
>> a/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf 
>> b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf 
>>
>> new file mode 100644
>> index 0000000000..da05ca0898
>> --- /dev/null
>> +++ 
>> b/Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>> @@ -0,0 +1,43 @@
>> +## @file
>> +#
>> +#  Copyright (c) 2023 Loongson Technology Corporation Limited. All 
>> rights reserved.<BR>
>> +#
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x00010005
>> +  BASE_NAME                      = NorFlashQemuLib
>> +  FILE_GUID                      = 339B7829-4C5F-4EFC-B2DD-5050E530DECE
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = VirtNorFlashPlatformLib
>> +
>> +[Sources.common]
>> +  NorFlashQemuLib.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  OvmfPkg/OvmfPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  DebugLib
>> +  UefiBootServicesTableLib
>> +
>> +[Protocols]
>> +  gFdtClientProtocolGuid          ## CONSUMES
>> +
>> +[Depex]
>> +  gFdtClientProtocolGuid
>> +
>> +[Pcd]
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
>> diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc 
>> b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
>> index a9b5c8c514..05913db144 100644
>> --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
>> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.dsc
>> @@ -175,6 +175,7 @@
>>     DebugLib                         | 
>> MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
>>     PeiServicesLib                   | 
>> MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
>>     VariableFlashInfoLib             | 
>> MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf
>> +  VirtNorFlashPlatformLib          | 
>> Platform/Loongson/LoongArchQemuPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
>>     [LibraryClasses.common.SEC]
>>     PcdLib                           | 
>> MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
>> @@ -360,9 +361,9 @@
>>     #
>>   !include NetworkPkg/NetworkPcds.dsc.inc
>>   - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 
>> 0x10000
>> - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x20000
>> - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 
>> 0x10000
>> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000
>> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000
>> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 
>> 0x40000
>> ################################################################################
>>   #
>> @@ -373,6 +374,7 @@
>> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0
>> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0
>> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0
>> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0
>> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0
>> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0
>> gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved | 0
>> @@ -471,15 +473,12 @@
>>     #
>>     # Variable
>>     #
>> -
>> -  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
>> -    <LibraryClasses>
>> - PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
>> -  }
>> +  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
>> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>> MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
>>       <LibraryClasses>
>> NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
>> + 
>> NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
>> BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
>>     }
>>   diff --git a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf 
>> b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
>> index ee89097344..675d86094c 100644
>> --- a/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
>> +++ b/Platform/Loongson/LoongArchQemuPkg/Loongson.fdf
>> @@ -30,6 +30,7 @@ $(DXEFV_OFFSET)|$(DXEFV_SIZE)
>> gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvBase|gLoongArchQemuPkgTokenSpaceGuid.PcdFlashDxeFvSize
>>   FV = FVMAIN_COMPACT
>>   +!include VarStore.fdf.inc
>> #####################################################################################################
>>   [FV.SECFV]
>>   FvNameGuid         = 587d4265-5e71-41da-9c35-4258551f1e22
>> @@ -135,7 +136,7 @@ INF 
>> MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
>>   #
>>   # Variable
>>   #
>> -INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
>> +INF  OvmfPkg/VirtNorFlashDxe/VirtNorFlashDxe.inf
>>   INF 
>> MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>>   INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
>>   #
>> diff --git a/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc 
>> b/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
>> new file mode 100644
>> index 0000000000..83ce3d8008
>> --- /dev/null
>> +++ b/Platform/Loongson/LoongArchQemuPkg/VarStore.fdf.inc
>> @@ -0,0 +1,67 @@
>> +## @file
>> +#
>> +#  Copyright (c) 2023 Loongson Technology Corporation Limited. All 
>> rights reserved.<BR>
>> +#
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[FD.QEMU_VARS]
>> +BaseAddress   = 0x0
>> +Size          = 0x1000000
>> +ErasePolarity = 1
>> +BlockSize     = 0x20000
>> +NumBlocks     = 128
>> +
>> +0x00000000|0x00040000
>> +#NV_VARIABLE_STORE
>> +DATA = {
>> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
>> +  # ZeroVector []
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
>> +  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
>> +  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
>> +  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
>> +  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
>> +  # FvLength: 0xC0000
>> +  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  # Signature "_FVH"       # Attributes
>> +  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
>> +  # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
>> +  0x48, 0x00, 0x28, 0x09, 0x00, 0x00, 0x00, 0x02,
>> +  # Blockmap[0]: 0x3 Blocks * 0x40000 Bytes / Block
>> +  0x3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
>> +  # Blockmap[1]: End
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  ## This is the VARIABLE_STORE_HEADER
>> +  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
>> +  # Signature: gEfiAuthenticatedVariableGuid =
>> +  #   { 0xaaf32c78, 0x947b, 0x439a,
>> +  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
>> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
>> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
>> +  # Size: 0x40000 
>> (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
>> +  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3ffb8
>> +  # This can speed up the Variable Dispatch a bit.
>> +  0xB8, 0xFF, 0x03, 0x00,
>> +  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
>> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
>> +}
>> +
>> +0x00040000|0x00040000
>> +#NV_FTW_WORKING
>> +DATA = {
>> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = 
>> gEdkiiWorkingBlockSignatureGuid         =
>> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 
>> 0x9f, 0x1b, 0x95 }}
>> +  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
>> +  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
>> +  # Crc:UINT32            #WorkingBlockValid:1, 
>> WorkingBlockInvalid:1, Reserved
>> +  0x5b, 0xe7, 0xc6, 0x86, 0xFE, 0xFF, 0xFF, 0xFF,
>> +  # WriteQueueSize: UINT64
>> +  0xE0, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
>> +}
>> +
>> +0x00080000|0x00040000
>> +#NV_FTW_SPARE
>
>
> 
>
>
>


  reply	other threads:[~2023-01-11  7:16 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-10  1:16 [edk2-platforms][PATCH V2 0/7] loongarch add flash device xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 1/7] Platform/Loongson: add bootmode support xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 2/7] Platform/Loongson:add nvme device driver for loongarch xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 3/7] Platform/Loongson: Support pflash " xianglai
2023-01-10  7:12   ` [edk2-devel] " Chao Li
2023-01-11  7:16     ` xianglai [this message]
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 4/7] Platform/Loongson: Modify the page table entry access priority xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 5/7] Platform/Loongson: Optimize page table entry null determination xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 6/7] Platform/Loongson: Optimize the huge page and page entry conversion xianglai
2023-01-10  1:16 ` [edk2-platforms][PATCH V2 7/7] Platform/Loongson: Enable zero address protection xianglai

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=8670ebe1-186a-a03f-30eb-3c15aa49ddac@loongson.cn \
    --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