public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: zwei4 <david.wei@intel.com>
To: edk2-devel@lists.01.org
Cc: David Wei <david.wei@intel.com>,
	Kelly Steele <kelly.steele@intel.com>,
	Mike Wu <mike.wu@intel.com>, Mang Guo <mang.guo@intel.com>
Subject: [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 5/5] EEPROM header files.
Date: Mon, 23 Jul 2018 10:39:19 +0800	[thread overview]
Message-ID: <20180723023919.19796-5-david.wei@intel.com> (raw)
In-Reply-To: <20180723023919.19796-1-david.wei@intel.com>

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Kelly Steele <kelly.steele@intel.com>
CC: Mike Wu  <mike.wu@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
 .../Common/Features/Eeprom/Include/EepromStruct.h  | 189 +++++++++++++++++++++
 .../Features/Eeprom/Include/Guid/EepromVariable.h  |  26 +++
 .../Eeprom/Include/Library/EepromDataLib.h         | 158 +++++++++++++++++
 .../Features/Eeprom/Include/Library/EepromLib.h    | 110 ++++++++++++
 .../Common/Features/Eeprom/ReadMe.txt              |  62 +++++++
 5 files changed, 545 insertions(+)
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt

diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
new file mode 100644
index 0000000000..e3d0fa6199
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/EepromStruct.h
@@ -0,0 +1,189 @@
+/** @file
+  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _EEPROM_LAYOUT_H_
+#define _EEPROM_LAYOUT_H_
+
+#pragma pack(1)
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+}GENERIC_HEADER;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    UINT32  structlength;
+    UINT32  crc32;
+    UINT32  crclength;
+    UINT32  version;
+    CHAR8   reserved[16];
+}EEPROM_HEADER;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   acpitbl[0];
+}ACPI_TABLE;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   manuname[16];
+    CHAR8   brdname[16];
+    CHAR8   brdserial[16];
+    UINT32  boardid;
+    UINT32  fabid;
+    UINT32  ecid;
+    UINT8   boardtype;
+    CHAR8   reserved[19];
+}BOARD_INFO_TABLE;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   partlabel[16];
+    UINT32  blklength;
+    UINT16  pagesize;
+    UINT32  partsize;
+    UINT8   busnumber;
+    UINT8   master;
+    UINT8   speed;
+    CHAR8   reserved[3];
+//  UINT8   mapdata[0];
+}EEPROM_MAP;
+
+
+typedef struct {
+    CHAR8   maplabel[16];
+    UINT32  length;
+    UINT32  offset;
+    UINT8   address;
+    CHAR8   reserved[7];
+}EEPROM_MAP_RECORD;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   gpiodata[0];
+}GPIO_DATA_HEADER;
+
+
+typedef struct {
+    CHAR8   gpiolabel[16];
+    UINT32  length;
+    UINT32  offset;
+    UINT32  anddata;
+    UINT32  ordata;
+    UINT8   datasize;
+    UINT8   datatype;
+    CHAR8   reserved[14];
+}GPIO_DATA_RECORD;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   hdacodec[0];
+}HDA_CODEC;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    UINT16  spdslot;
+    CHAR8   reserved[14];
+//  UINT8   spddata[0];
+}MEMORY_SPD;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   nicid[8];
+    CHAR8   macaddr[6];
+    UINT16  nicnum;
+    CHAR8   reserved[16];
+//  UINT8   nicdata[0];
+}NIC_INFO;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    UINT16  hashtype;
+    CHAR8   reserved[14];
+//  UINT8   eepromsig[0];
+}SIGNATURE_DATA;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   ucodedata[0];
+}MICROCODE;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   videodata[0];
+}VIDEO_DATA;
+
+
+typedef struct {
+    CHAR8   signature[8];
+    UINT16  vermajor;
+    UINT16  verminor;
+    UINT32  length;
+    CHAR8   reserved[16];
+//  UINT8   logodata[0];
+}LOGO_DATA;
+
+#pragma pack()
+#endif
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
new file mode 100644
index 0000000000..47b0590467
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Guid/EepromVariable.h
@@ -0,0 +1,26 @@
+/** @file
+  GUIDs used for EEPROM variable code.
+
+  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _EEPROM_VARIABLE_H_
+#define _EEPROM_VARIABLE_H_
+
+
+#define EEPROM_VARIABLE_GUID \
+{ 0xEE96CA33, 0x5F59, 0x4594, 0x98, 0x69, 0x07, 0xF7, 0x9A, 0xA3, 0xC0, 0x6F }
+
+extern EFI_GUID gEepromVariableGuid;
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
new file mode 100644
index 0000000000..0d71b3d1bc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromDataLib.h
@@ -0,0 +1,158 @@
+/** @file
+  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _EEPROM_DATA_LIB_
+#define _EEPROM_DATA_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+
+////
+//// Defines
+////
+
+////
+//// Enums
+////
+typedef enum {
+  EEPROM_NULL                   = 0,
+  EEPROM_EEPROM                 = 1,
+  EEPROM_FV                     = 2,
+  EEPROM_MEMORY                 = 3,
+  EEPROM_DATA_LIBRARY_INDEX_MAX = 4
+} EEPROM_DATA_LIBRARY_TYPE;
+
+
+////
+//// Externs
+////
+extern BOOLEAN    mEepromDataLibDebugFlag;
+extern CHAR8     *mEepromLibraryString[EEPROM_DATA_LIBRARY_INDEX_MAX];
+
+
+////
+//// Structures
+////
+typedef struct {
+  UINT8                   LibraryIndex;
+  UINT8                   Address;
+  UINT8                   Bus;
+  UINT32                  Size;         // NOTE: Set this to 0x00.
+  UINT8                  *Buffer;       // NOTE: Set this to NULL.
+  UINT8                  *ScanBuffer;   // NOTE: Should be NULL unless requesting a scan on that I2C bus
+  UINT8                  *ScanSize;     // NOTE: Should be NULL unless requesting a scan on that I2C bus
+} EEPROM_FUNCTION_INFO;
+
+//
+// Should only use this if you need to get a different file from the FV.
+//
+typedef struct {
+  UINT8                   LibraryIndex;
+  EFI_GUID               *FvFileGuid;
+} FV_FUNCTION_INFO;
+
+
+////
+//// Functions
+////
+//
+// Desc:        Copies the contents of an existing memory pool into a new memory pool of equal or greater size.
+// Variables:   Size           Size of the pool to copy existing pool into
+//              SourcePointer  Pointer to the source buffer to copy
+// Return:      Pointer        Pointer to your copy of the pool
+//
+VOID*
+EFIAPI
+EepromAllocateCopyPool (
+  IN  UINTN    Size,
+  IN  VOID    *SourcePointer
+  );
+
+//
+// Desc:        Creates a new memory pool.
+// Variables:   Size           Size of the pool requested
+// Return:      Pointer        Pointer the new pool
+//
+VOID*
+EFIAPI
+EepromAllocatePool (
+  IN  UINTN   Size
+  );
+
+EFI_STATUS
+EFIAPI
+EepromDataLibNemToMemory (VOID);
+
+//
+// Desc:        Frees a memory pool.
+// Variables:   Pointer        Pointer to the beginning of the pool to be freed
+// Return:      Pointer        NULL
+//
+VOID*
+EFIAPI
+EepromFreePool (
+  IN  VOID  *Pointer
+  );
+
+//
+// Desc:        Reads from the EEPROM and copies to the passed in buffer.
+// Variables:   LibraryIndex   Determines which raw data library to use
+//              Offset         Start copying from the offset
+//              Size           Size of the buffer and the number of bytes to copy
+//                             - If set to 0, then return size of EEPROM binary
+//              Buffer         Storage buffer for the copied data from the EEPROM
+//              FunctionInfo   Pointer to function specific data
+// Return:      EFI_SUCCESS             Data copied successfully
+//              EFI_UNSUPPORTED         This function is not supported
+//              EFI_INVALID_PARAMETER   One of the parameters is invalid
+//              EFI_NOT_READY           Called before all necessary library available
+//              EFI_DEVICE_ERROR        Communication error with device
+//
+EFI_STATUS
+EFIAPI
+ReadEeprom (
+  IN       UINT8     LibraryIndex,
+  IN       UINT32    Offset,
+  IN OUT   UINT32   *Size,
+  IN OUT   UINT8    *Buffer,
+  IN OUT   VOID     *FunctionInfo
+  );
+
+//
+// Desc:        Writes to the EEPROM and copies to the passed in buffer.
+// Variables:   LibraryIndex   Determines which raw data library to use
+//              Offset         Start copying from the offset
+//              Size           Size of the buffer and the number of bytes to copy
+//                             - If set to 0, then return size of EEPROM binary
+//              Buffer         Data to be copied to the EEPROM
+//              FunctionInfo   Pointer to function specific data
+// Return:      EFI_SUCCESS             Data copied successfully
+//              EFI_UNSUPPORTED         This function is not supported
+//              EFI_INVALID_PARAMETER   One of the parameters is invalid
+//              EFI_NOT_READY           Called before all necessary library available
+//              EFI_DEVICE_ERROR        Communication error with device
+//
+EFI_STATUS
+EFIAPI
+WriteEeprom (
+  IN       UINT8     LibraryIndex,
+  IN       UINT32    Offset,
+  IN OUT   UINT32   *Size,
+  IN OUT   UINT8    *Buffer,
+  IN OUT   VOID     *FunctionInfo
+  );
+
+#endif // _EEPROM_DATA_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
new file mode 100644
index 0000000000..b386e8c7bc
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/Include/Library/EepromLib.h
@@ -0,0 +1,110 @@
+/** @file
+  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _EEPROM_LIB_
+#define _EEPROM_LIB_
+////
+//// Header files
+////
+#include <Uefi.h>
+
+#include <EepromStruct.h>
+
+
+////
+//// defines
+////
+#define EEPROM_SIGNATURE_SIZE   9
+
+
+////
+//// Enums
+////
+typedef enum {
+  HASH_NONE        = 0,
+  HASH_MD5         = 1,
+  HASH_SHA1        = 2,
+  HASH_SHA256      = 3,
+  HASH_SHA384      = 4,
+  HASH_SHA512      = 5
+} EEPROM_HASH_TYPE;
+
+
+////
+//// Functions
+////
+UINTN
+EFIAPI
+DisplayStackPointer (
+  IN   CHAR8    *Function,
+  IN   UINTN     LineNumber
+  );
+
+EFI_STATUS
+EFIAPI
+EraseEeprom (
+  IN       UINT8     LibraryIndex
+  );
+
+EFI_STATUS
+EFIAPI
+GetEepromStructure (
+  IN       UINT8      LibraryIndex,
+  IN OUT   CHAR8      Signature[EEPROM_SIGNATURE_SIZE],
+  IN OUT   UINT8    **Buffer,
+  IN OUT   UINT32    *Size
+  );
+
+UINT32
+EFIAPI
+GetImageSize (
+  IN       UINT8      LibraryIndex
+  );
+
+EFI_STATUS
+EFIAPI
+GetNextEepromStructure (
+  IN       UINT8      LibraryIndex,
+  IN OUT   UINT32    *Index,
+  IN OUT   UINT8    **Buffer,
+  IN OUT   UINT32    *Size
+  );
+
+UINT8
+EFIAPI
+GetValidEepromLibrary (
+  IN       BOOLEAN   CopyToMemory,
+  IN       BOOLEAN   MemoryInitialized
+  );
+
+BOOLEAN
+EFIAPI
+InPeiPhase (VOID);
+
+EFI_STATUS
+EFIAPI
+ValidateEeprom (
+  IN       UINT8     LibraryIndex
+  );
+
+//
+// Desc:        Registers the raw data libraries
+// Variables:   None
+// Return:      EFI_SUCCESS
+//
+EFI_STATUS
+EFIAPI
+EepromInitConstructor (VOID);
+
+#endif // _EEPROM_LIB_
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt
new file mode 100644
index 0000000000..5179b97e3d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/Eeprom/ReadMe.txt
@@ -0,0 +1,62 @@
+## @file
+#  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+#  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.
+#
+##
+
+==========================================================================================
+                                   EEPROM PCDs
+==========================================================================================
+[PcdsFixedAtBuild]
+  ## I2C bus the master EEPROM is hanging on
+  gPlatformModuleTokenSpaceGuid.PcdEepromBus|0x06|UINT8|0xEEEE2000
+  ## 7-bit address of the master EEPROM
+  gPlatformModuleTokenSpaceGuid.PcdEepromAddress|0x53|UINT8|0xEEEE2001
+  ## Priority order of EEPROM data libraries
+  ## 00 - Null; 01 - EEPROM; 02 - FV; 03 - Memory; FF - End of list
+  ## Memory should be first
+  gPlatformModuleTokenSpaceGuid.PcdEepromAutoPriority|{0x03, 0x01, 0x02, 0x00, 0xFF}|VOID*|0xEEEE2002
+  ## Public key file GUID - 5D8A38A3-FBBD-4077-8105-11170C2AF54D
+  gPlatformModuleTokenSpaceGuid.PcdEepromPublicKeyFile|{0xA3, 0x38, 0x8A, 0x5D, 0xBD, 0xFB, 0x77, 0x40, 0x81, 0x05, 0x11, 0x17, 0x0C, 0x2A, 0xF5, 0x4D}|VOID*|0xEEEE2003
+  ## FV EEPROM Image file GUID - BFBD3DAC-01EB-4FEB-A9DE-BCC9D1BA5531
+  gPlatformModuleTokenSpaceGuid.PcdEepromFvImageFile|{0xAC, 0x3D, 0xBD, 0xBF, 0xEB, 0x01, 0xEB, 0x4F, 0xA9, 0xDE, 0xBC, 0xC9, 0xD1, 0xBA, 0x55, 0x31}|VOID*|0xEEEE2004
+
+[PcdsDynamic, PcdsDynamicEx]
+  ## Used to store the EEPROM memory buffer pointer
+  gPlatformModuleTokenSpaceGuid.PcdEepromMemoryPointer|0|UINT64|0xEEEE0000
+  ## Used to store the EEPROM memory buffer size
+  gPlatformModuleTokenSpaceGuid.PcdEepromMemorySize|0|UINT32|0xEEEE0001
+  ## Used to store the EEPROM data library valid flags
+  gPlatformModuleTokenSpaceGuid.PcdEepromLibraryValid|{0x00, 0x00, 0x00, 0x00}|VOID*|0xEEEE0002
+  ## Flag to indicate that a HOB exists with EEPROM_MEMORY data
+  gPlatformModuleTokenSpaceGuid.PcdEepromMemoryHobPresent|FALSE|BOOLEAN|0xEEEE0003
+  ## Pointer to the Part head link
+  gPlatformModuleTokenSpaceGuid.PcdEepromPartsHeadLink|0|UINT64|0xEEEE0004
+  ## Pointer to the Parts table
+  gPlatformModuleTokenSpaceGuid.PcdEepromParts|0|UINT64|0xEEEE0005
+  ## Flag to tell if EEPROM Map is in memory
+  gPlatformModuleTokenSpaceGuid.PcdEepromInMemoryFlag|0|BOOLEAN|0xEEEE0006
+  ## Flag to tell if EEPROM Map is in HOB
+  gPlatformModuleTokenSpaceGuid.PcdEepromMapHobValid|0|BOOLEAN|0xEEEE0007
+
+
+==========================================================================================
+                                   EEPROM GUIDs
+==========================================================================================
+[Guids]
+  # GUID for EEPROM variables - {EE96CA33-5F59-4594-9869-07F79AA3C06F}
+  gEepromVariableGuid = { 0xEE96CA33, 0x5F59, 0x4594, { 0x98, 0x69, 0x07, 0xF7, 0x9A, 0xA3, 0xC0, 0x6F }}
+
+
+==========================================================================================
+                                   Generating EEPROM binary
+==========================================================================================
+ Use the GenerateBinary.py script as a guide on how to create the EEPROM binary.
+
-- 
2.14.1.windows.1



      parent reply	other threads:[~2018-07-23  2:39 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-23  2:39 [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 1/5] Add EepromApp zwei4
2018-07-23  2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 3/5] Library producing EEPROM raw data functionality zwei4
2018-07-23  2:39 ` [Patch][edk2-platforms/devel-IntelAtomProcessorE3900 4/5] Common EEPROM library instance zwei4
2018-07-23  2:39 ` zwei4 [this message]

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=20180723023919.19796-5-david.wei@intel.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