pkarashchenko commented on a change in pull request #5827:
URL: https://github.com/apache/incubator-nuttx/pull/5827#discussion_r833007801



##########
File path: arch/xtensa/src/esp32s2/rom/esp32s2_spiflash.h
##########
@@ -0,0 +1,1020 @@
+/*****************************************************************************
+ * arch/xtensa/src/esp32s2/rom/esp32s2_spiflash.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ *****************************************************************************/
+
+#ifndef _ROM_SPI_FLASH_H_

Review comment:
       ```suggestion
   #ifndef __ARCH_XTENSA_SRC_ESP32S2_ROM_ESP32S2_SPIFLASH_H
   ```

##########
File path: arch/xtensa/src/esp32s2/esp32s2_spiram.c
##########
@@ -0,0 +1,450 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32s2/esp32s2_spiram.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <debug.h>
+#include <string.h>
+#include <sys/param.h>
+#include <nuttx/config.h>
+#include <nuttx/spinlock.h>
+
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "esp32s2_psram.h"
+#include "esp32s2_spiram.h"
+#include "hardware/esp32s2_soc.h"
+#include "hardware/esp32s2_cache_memory.h"
+#include "hardware/esp32s2_extmem.h"
+#include "hardware/esp32s2_iomux.h"
+
+/****************************************************************************
+ * Pre-processor Prototypes
+ ****************************************************************************/
+
+#define PSRAM_MODE PSRAM_VADDR_MODE_NORMAL
+
+#if defined(CONFIG_ESP32S2_SPIRAM)
+
+#define MMU_PAGE_TO_BYTES(page_id)      ((page_id) << 16)
+#define BYTES_TO_MMU_PAGE(bytes)        ((bytes) / MMU_PAGE_SIZE)
+
+#if defined(CONFIG_ESP32S2_SPIRAM_SPEED_40M)
+#  define PSRAM_SPEED PSRAM_CACHE_S40M
+#else  /* #if CONFIG_ESP32S2_SPIRAM_SPEED_80M */
+#  define PSRAM_SPEED PSRAM_CACHE_S80M
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+static bool g_spiram_inited;
+
+/* These variables are in bytes */
+
+static uint32_t g_allocable_vaddr_start;
+static uint32_t g_allocable_vaddr_end;
+static DRAM_ATTR uint32_t g_mapped_vaddr_start;
+
+static uint32_t g_instruction_in_spiram;
+static uint32_t g_rodata_in_spiram;
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS)
+static int      g_instr_flash2spiram_offs;
+static uint32_t g_instr_start_page;
+static uint32_t g_instr_end_page;
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_RODATA)
+static int      g_rodata_flash2spiram_offs;
+static uint32_t g_rodata_start_page;
+static uint32_t g_rodata_end_page;
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS) || \
+    defined(CONFIG_ES32S3_SPIRAM_RODATA)
+static uint32_t page0_mapped;
+static uint32_t page0_page = INVALID_PHY_PAGE;
+#endif
+
+/* Let's export g_mapped_size to export heap */
+
+DRAM_ATTR uint32_t g_mapped_size;
+
+/****************************************************************************
+ * ROM Function Prototypes
+ ****************************************************************************/
+
+extern void cache_writeback_all(void);
+extern uint32_t cache_suspend_dcache(void);
+extern void cache_resume_dcache(uint32_t val);
+extern int cache_dbus_mmu_set(uint32_t ext_ram, uint32_t vaddr,
+                              uint32_t paddr, uint32_t psize,
+                              uint32_t num, uint32_t fixed);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mmu_map_psram
+ *
+ * Description:
+ *   Map the PSRAM to MMU
+ *
+ * Input Parameters:
+ *   start_paddr - start of physical PSRAM address
+ *   end_paddr   - end of physical PSRAM address
+ *   out_start_vaddr - start of virtual address
+ *
+ * Returned Value:
+ *   Zero value (OK) on success or a negative error.
+ *
+ ****************************************************************************/
+
+int mmu_map_psram(uint32_t start_paddr, uint32_t end_paddr,
+                  uint32_t *out_start_vaddr)
+{
+  /* For now, this function should only run when virtual address is enough
+   * Decide these logics when there's a real PSRAM with larger size
+   */
+
+  uint32_t map_length = end_paddr - start_paddr;
+
+  if (map_length > SOC_EXTRAM_DATA_SIZE)
+    {
+      /* Decide these logics when there's a real PSRAM with larger size */
+
+      merr("PSRAM physical size is too large, not support mapping it yet!");
+      return -ENOMEM;
+    }
+
+  /* should be MMU page aligned */
+
+  assert((start_paddr % MMU_PAGE_SIZE) == 0);
+
+  uint32_t start_vaddr = DPORT_CACHE_ADDRESS_LOW;
+  uint32_t end_vaddr = start_vaddr + map_length;
+  uint32_t cache_bus_mask = 0;
+
+  cache_bus_mask |= (end_vaddr > 0) ? EXTMEM_PRO_DCACHE_MASK_DPORT : 0;
+  cache_bus_mask |= (end_vaddr >= DPORT_ADDRESS_HIGH) ?
+                    EXTMEM_PRO_DCACHE_MASK_DRAM1 : 0;
+  cache_bus_mask |= (end_vaddr >= DRAM1_ADDRESS_HIGH) ?
+                    EXTMEM_PRO_DCACHE_MASK_DRAM0 : 0;
+
+  assert(end_vaddr <= DRAM0_CACHE_ADDRESS_HIGH);
+
+  minfo("start_paddr is %x, map_length is %xB, %d pages",
+        start_paddr, map_length, BYTES_TO_MMU_PAGE(map_length));
+
+  /* No need to disable cache, this file is put in Internal RAM */
+
+  cache_dbus_mmu_set(MMU_ACCESS_SPIRAM, start_vaddr, start_paddr, 64,
+                     BYTES_TO_MMU_PAGE(map_length), 0);
+
+  REG_CLR_BIT(EXTMEM_PRO_DCACHE_CTRL1_REG, cache_bus_mask);
+
+  *out_start_vaddr = start_vaddr;
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: mmu_map_psram
+ *
+ * Description:
+ *   Initialize the CACHE to use with PSRAM
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp_spiram_init_cache(void)
+{
+  int ret;
+  static DRAM_ATTR uint32_t vaddr_start = 0;
+  uint32_t start_page = 0;
+  uint32_t psram_available_size = esp_spiram_get_size();
+
+  /* Map the PSRAM physical range to MMU */
+
+  ret = mmu_map_psram(MMU_PAGE_TO_BYTES(start_page),
+                      MMU_PAGE_TO_BYTES(start_page) +
+                      psram_available_size, &vaddr_start);
+  if (ret < 0)
+    {
+      merr("MMU PSRAM mapping wrong!");
+      abort();
+    }
+
+  /* After mapping, we DON'T care about the PSRAM PHYSICAL
+   * ADDRESSS ANYMORE!
+   */
+
+  g_allocable_vaddr_start = vaddr_start;
+  g_allocable_vaddr_end   = vaddr_start + psram_available_size;
+}
+
+/****************************************************************************
+ * Name: esp_spiram_test
+ *
+ * Description:
+ *   Simple RAM test. Writes a word every 32 bytes. Takes about a second
+ *   to complete for 4MiB. Returns true when RAM seems OK, false when test
+ *   fails. WARNING: Do not run this before the 2nd cpu has been initialized
+ *   (in a two-core system) or after the heap allocator has taken ownership
+ *   of the memory.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   True on success or False on failure
+ *
+ ****************************************************************************/
+
+bool esp_spiram_test(void)
+{
+  volatile int *spiram = (volatile int *)g_mapped_vaddr_start;
+
+  size_t s = g_mapped_size;
+  size_t p;
+  int errct = 0;
+  int initial_err = -1;
+
+  for (p = 0; p < (s / sizeof(int)); p += 8)
+    {
+      spiram[p] = p ^ 0xaaaaaaaa;
+    }
+
+  for (p = 0; p < (s / sizeof(int)); p += 8)
+    {
+      if (spiram[p] != (p ^ 0xaaaaaaaa))
+        {
+          errct++;
+          if (errct == 1)
+            {
+              initial_err = p * sizeof(int);
+            }
+
+          if (errct < 4)
+            {
+              merr("SPI SRAM error @ %08x:%08x/%08x \n", &spiram[p],
+                   spiram[p], p ^ 0xaaaaaaaa);
+            }
+        }
+    }
+
+  if (errct != 0)
+    {
+      merr("SPI SRAM memory test fail. %d/%d writes failed, first @ %X\n",
+           errct, s / 32, initial_err + SOC_EXTRAM_DATA_LOW);
+      return false;
+    }
+  else
+    {
+      minfo("SPI SRAM memory test OK!");
+      return true;
+    }
+}
+
+uint32_t esp_spiram_instruction_access_enabled(void)
+{
+  return g_instruction_in_spiram;
+}
+
+uint32_t esp_spiram_rodata_access_enabled(void)
+{
+  return g_rodata_in_spiram;
+}
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS)
+int esp_spiram_enable_instruction_access(void)
+{
+  /* `pages_for_flash` will be overwritten, however it influences the psram
+   * size to be added to the heap allocator.
+   */
+
+  abort();
+}
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_RODATA)
+int esp_spiram_enable_rodata_access(void)
+{
+  /* `pages_for_flash` will be overwritten, however it influences the psram
+   * size to be added to the heap allocator.
+   */
+
+  abort();
+}
+#endif
+
+#if defined(CONFIG_ESP32S2_SPIRAM_FETCH_INSTRUCTIONS)
+void instruction_flash_page_info_init(void)
+{
+  uint32_t instr_page_cnt = ((uint32_t)&_instruction_reserved_end -
+                            SOC_IROM_LOW + MMU_PAGE_SIZE - 1) /
+                            MMU_PAGE_SIZE;
+
+  g_instr_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE +
+                                              CACHE_IROM_MMU_START);
+  g_instr_start_page &= MMU_ADDRESS_MASK;
+  g_instr_end_page = g_instr_start_page + instr_page_cnt - 1;
+}
+
+uint32_t IRAM_ATTR instruction_flash_start_page_get(void)
+{
+  return g_instr_start_page;
+}
+
+uint32_t IRAM_ATTR instruction_flash_end_page_get(void)
+{
+  return g_instr_end_page;
+}
+
+int IRAM_ATTR instruction_flash2spiram_offset(void)
+{
+  return g_instr_flash2spiram_offs;
+}
+#endif
+
+#if defined(CONFIG_ESP32_SPIRAM_RODATA)
+void rodata_flash_page_info_init(void)
+{
+  uint32_t rodata_page_cnt = ((uint32_t)&_rodata_reserved_end -
+                              ((uint32_t)&_rodata_reserved_start &
+                              ~ (MMU_PAGE_SIZE - 1)) + MMU_PAGE_SIZE - 1) /
+                              MMU_PAGE_SIZE;
+
+  g_rodata_start_page = *(volatile uint32_t *)(DR_REG_MMU_TABLE +
+                                               CACHE_DROM_MMU_START);
+  g_rodata_start_page &= MMU_ADDRESS_MASK;
+  g_rodata_end_page = g_rodata_start_page + rodata_page_cnt - 1;
+}
+
+uint32_t IRAM_ATTR rodata_flash_start_page_get(void)
+{
+  return g_rodata_start_page;
+}
+
+uint32_t IRAM_ATTR rodata_flash_end_page_get(void)
+{
+  return g_rodata_end_page;
+}
+
+int IRAM_ATTR g_rodata_flash2spiram_offset(void)
+{
+  return g_rodata_flash2spiram_offs;
+}
+#endif
+
+int esp_spiram_init(void)
+{
+  int r;
+  size_t spiram_size;
+
+  r = psram_enable(PSRAM_SPEED, PSRAM_MODE);
+  if (r != OK)
+    {
+      merr("SPI RAM enabled but initialization failed. Bailing out.\n");
+      return r;
+    }
+
+  g_spiram_inited = true;
+
+  spiram_size = esp_spiram_get_size();
+
+#if defined(CONFIG_ESP32S2_SPIRAM_SIZE) && (CONFIG_ESP32S2_SPIRAM_SIZE != -1)
+  if (spiram_size != CONFIG_ESP32S2_SPIRAM_SIZE)
+    {
+      merr("Expected %dMB chip but found %dMB chip. Bailing out..",
+           (CONFIG_ESP32S2_SPIRAM_SIZE / 1024 / 1024),
+           (spiram_size / 1024 / 1024));
+      return ;

Review comment:
       ```suggestion
         return;
   ```

##########
File path: arch/xtensa/src/esp32s2/rom/esp32s2_opi_flash.h
##########
@@ -0,0 +1,367 @@
+/*****************************************************************************
+ * arch/xtensa/src/esp32s2/rom/esp32s2_opi_flash.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ *****************************************************************************/
+
+#ifndef __ARCH_XTENSA_SRC_ESP32S2_ROM_ESP32S2_OPI_FLASH_H
+#define __ARCH_XTENSA_SRC_ESP32S2_ROM_ESP32S2_OPI_FLASH_H
+
+/*****************************************************************************
+ * Included Files
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct
+{
+  uint16_t cmd;                /* !< Command value */
+  uint16_t cmd_bit_len;        /* !< Command byte length */
+  uint32_t *addr;              /* !< Point to address value */
+  uint32_t addr_bit_len;       /* !< Address byte length */
+  uint32_t *tx_data;           /* !< Point to send data buffer */
+  uint32_t tx_data_bit_len;    /* !< Send data byte length. */
+  uint32_t *rx_data;           /* !< Point to recevie data buffer */
+  uint32_t rx_data_bit_len;    /* !< Recevie Data byte length. */
+  uint32_t dummy_bit_len;
+} esp_rom_spi_cmd_t;
+
+#define ESP_ROM_OPIFLASH_MUX_TAKE()
+#define ESP_ROM_OPIFLASH_MUX_GIVE()
+#define ESP_ROM_OPIFLASH_SEL_CS0     (BIT(0))
+#define ESP_ROM_OPIFLASH_SEL_CS1     (BIT(1))
+
+/* Definition of MX25UM25645G Octa Flash
+ * SPI status register
+ */
+
+#define ESP_ROM_SPIFLASH_BUSY_FLAG     BIT0
+#define ESP_ROM_SPIFLASH_WRENABLE_FLAG BIT1
+#define ESP_ROM_SPIFLASH_BP0           BIT2
+#define ESP_ROM_SPIFLASH_BP1           BIT3
+#define ESP_ROM_SPIFLASH_BP2           BIT4
+#define ESP_ROM_SPIFLASH_QE            BIT9
+
+#define FLASH_OP_MODE_RDCMD_DOUT       0x3B
+#define ESP_ROM_FLASH_SECTOR_SIZE      0x1000
+#define ESP_ROM_FLASH_BLOCK_SIZE_64K   0x10000
+#define ESP_ROM_FLASH_PAGE_SIZE        256
+
+/* FLASH commands */
+
+#define ROM_FLASH_CMD_RDID             0x9F
+#define ROM_FLASH_CMD_WRSR             0x01
+#define ROM_FLASH_CMD_WRSR2            0x31 /* Not all SPI flash uses this 
command */
+#define ROM_FLASH_CMD_WREN             0x06
+#define ROM_FLASH_CMD_WRDI             0x04
+#define ROM_FLASH_CMD_RDSR             0x05
+#define ROM_FLASH_CMD_RDSR2            0x35 /* Not all SPI flash uses this 
command */
+#define ROM_FLASH_CMD_ERASE_SEC        0x20
+#define ROM_FLASH_CMD_ERASE_BLK_32K    0x52
+#define ROM_FLASH_CMD_ERASE_BLK_64K    0xD8
+#define ROM_FLASH_CMD_OTPEN            0x3A /* Enable OTP mode, not all SPI 
flash uses this command */
+#define ROM_FLASH_CMD_RSTEN            0x66
+#define ROM_FLASH_CMD_RST              0x99
+
+#define ROM_FLASH_CMD_SE4B             0x21
+#define ROM_FLASH_CMD_SE4B_OCT         0xDE21
+#define ROM_FLASH_CMD_BE4B             0xDC
+#define ROM_FLASH_CMD_BE4B_OCT         0x23DC
+#define ROM_FLASH_CMD_RSTEN_OCT        0x9966
+#define ROM_FLASH_CMD_RST_OCT          0x6699
+
+#define ROM_FLASH_CMD_FSTRD4B_STR      0x13EC
+#define ROM_FLASH_CMD_FSTRD4B_DTR      0x11EE
+#define ROM_FLASH_CMD_FSTRD4B          0x0C
+#define ROM_FLASH_CMD_PP4B             0x12
+#define ROM_FLASH_CMD_PP4B_OCT         0xED12
+
+#define ROM_FLASH_CMD_RDID_OCT         0x609F
+#define ROM_FLASH_CMD_WREN_OCT         0xF906
+#define ROM_FLASH_CMD_RDSR_OCT         0xFA05
+#define ROM_FLASH_CMD_RDCR2            0x71
+#define ROM_FLASH_CMD_RDCR2_OCT        0x8E71
+#define ROM_FLASH_CMD_WRCR2            0x72
+#define ROM_FLASH_CMD_WRCR2_OCT        0x8D72
+
+/* Definitions for GigaDevice GD25LX256E Flash */
+
+#define ROM_FLASH_CMD_RDFSR_GD            0x70
+#define ROM_FLASH_CMD_RD_GD               0x03
+#define ROM_FLASH_CMD_RD4B_GD             0x13
+#define ROM_FLASH_CMD_FSTRD_GD            0x0B
+#define ROM_FLASH_CMD_FSTRD4B_GD          0x0C
+#define ROM_FLASH_CMD_FSTRD_OOUT_GD       0x8B
+#define ROM_FLASH_CMD_FSTRD4B_OOUT_GD     0x7C
+#define ROM_FLASH_CMD_FSTRD_OIOSTR_GD     0xCB
+#define ROM_FLASH_CMD_FSTRD4B_OIOSTR_GD   0xCC
+#define ROM_FLASH_CMD_FSTRD4B_OIODTR_GD   0xFD
+
+#define ROM_FLASH_CMD_PP_GD               0x02
+#define ROM_FLASH_CMD_PP4B_GD             0x12
+#define ROM_FLASH_CMD_PP_OOUT_GD          0x82
+#define ROM_FLASH_CMD_PP4B_OOUT_GD        0x84
+#define ROM_FLASH_CMD_PP_OIO_GD           0xC2
+#define ROM_FLASH_CMD_PP4B_OIOSTR_GD      0x8E
+
+#define ROM_FLASH_CMD_SE_GD               0x20
+#define ROM_FLASH_CMD_SE4B_GD             0x21
+#define ROM_FLASH_CMD_BE32K_GD            0x52
+#define ROM_FLASH_CMD_BE32K4B_GD          0x5C
+#define ROM_FLASH_CMD_BE64K_GD            0xD8
+#define ROM_FLASH_CMD_BE64K4B_GD          0xDC
+
+#define ROM_FLASH_CMD_EN4B_GD             0xB7
+#define ROM_FLASH_CMD_DIS4B_GD            0xE9
+
+/* spi user mode command config */
+
+/**
+ * @brief Config the spi user command
+ * @param spi_num spi port
+ * @param pcmd pointer to accept the spi command struct
+ */
+
+void esp_rom_spi_cmd_config(int spi_num, esp_rom_spi_cmd_t *pcmd);
+
+/**
+ * @brief Start a spi user command sequence
+ * @param spi_num spi port
+ * @param rx_buf buffer pointer to receive data
+ * @param rx_len receive data length in byte
+ * @param cs_en_mask decide which cs to use, 0 for cs0, 1 for cs1
+ * @param is_write_erase to indicate whether this is a write or erase
+ * operation, since the CPU would check permission
+ */
+
+void esp_rom_spi_cmd_start(int spi_num, uint8_t *rx_buf, uint16_t rx_len,
+                           uint8_t cs_en_mask, bool is_write_erase);
+
+/**
+ * @brief Config opi flash pads according to efuse settings.
+ */
+
+void esp_rom_opiflash_pin_config(void);
+
+/**
+ * @brief Set SPI operation mode
+ * @param spi_num spi port
+ * @param mode Flash Read Mode
+ */
+
+void esp_rom_spi_set_op_mode(int spi_num, esp_rom_spiflash_read_mode_t mode);
+
+/**
+ * @brief Set data swap mode in DTR(DDR) mode
+ * @param spi_num spi port
+ * @param wr_swap to decide whether to swap fifo data in dtr write operation
+ * @param rd_swap to decide whether to swap fifo data in dtr read operation
+ */
+
+void esp_rom_spi_set_dtr_swap_mode(int spi, bool wr_swap, bool rd_swap);
+
+/**
+ * @brief to send reset command in spi/opi-str/opi-dtr mode(for MX25UM25645G)
+ * @param spi_num spi port
+ */
+
+void esp_rom_opiflash_mode_reset(int spi_num);
+
+#if 0

Review comment:
       should we keep this all `#if 0` block?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to