From 001a663b74f03f4cb6f7285bab5d5ce363e3af96 Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Mon, 25 Nov 2024 17:35:38 +0100 Subject: [PATCH] esp32[s2|s3]: Add nxdiag without esptool wrapper --- arch/xtensa/src/common/espressif/Make.defs | 4 + arch/xtensa/src/common/espressif/esp_nxdiag.c | 341 ++++++++++++++++++ arch/xtensa/src/common/espressif/esp_nxdiag.h | 67 ++++ arch/xtensa/src/esp32/hal.mk | 3 + .../esp32/esp32-devkitc/src/esp32_bringup.c | 12 + .../esp32s2-saola-1/src/esp32s2_bringup.c | 12 + .../esp32s3-devkit/src/esp32s3_bringup.c | 12 + 7 files changed, 451 insertions(+) create mode 100644 arch/xtensa/src/common/espressif/esp_nxdiag.c create mode 100644 arch/xtensa/src/common/espressif/esp_nxdiag.h diff --git a/arch/xtensa/src/common/espressif/Make.defs b/arch/xtensa/src/common/espressif/Make.defs index 57d167166c..41de8d2bc9 100644 --- a/arch/xtensa/src/common/espressif/Make.defs +++ b/arch/xtensa/src/common/espressif/Make.defs @@ -57,6 +57,10 @@ CHIP_CSRCS += esp_spiflash_mtd.c endif endif +ifeq ($(CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL),y) +CHIP_CSRCS += esp_nxdiag.c +endif + ifeq ($(CONFIG_ESPRESSIF_WIRELESS),y) CHIP_CSRCS += esp_wireless.c ifeq ($(CONFIG_ESPRESSIF_WIFI),y) diff --git a/arch/xtensa/src/common/espressif/esp_nxdiag.c b/arch/xtensa/src/common/espressif/esp_nxdiag.c new file mode 100644 index 0000000000..c3fe946466 --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_nxdiag.c @@ -0,0 +1,341 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_nxdiag.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this args 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 +#include +#include + +#include "bootloader_flash.h" +#include "esp_mac.h" +#include "spi_flash_chip_generic.h" +#include "espressif/esp_nxdiag.h" +#include "hal/efuse_ll.h" +#include "esp_secure_boot.h" +#include "esp_flash_encrypt.h" +#include "bootloader_flash_priv.h" +#include "esp_rom_spiflash.h" +#include "soc/spi_mem_reg.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static ssize_t esp_nxdiag_read(struct file *filep, + char *buffer, + size_t buflen); +void esp_nxdiag_read_flash_id(int *mfg_id_out, int *flash_id_out); +void esp_nxdiag_read_security_info(bool *crypt_cnt, bool *secure_boot, + bool *flash_crpyt_en, int *chip_id, + int *api_version, uint32_t *key_purposes); +int esp_nxdiag_read_flash_status(uint32_t *status); +int esp_nxdiag_read_flash_status(uint32_t *status); +int esp_nxdiag_read_mac(uint8_t *mac); +static ssize_t esp_nxdiag_read(struct file *filep, + char *buffer, + size_t buflen); +static int esp_nxdiag_register(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_nxdiagops = +{ + .read = esp_nxdiag_read, /* read */ +}; + +/**************************************************************************** + * Private functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_nxdiag_read_flash_id + * + * Description: + * Read flash id value. + * + * Input Parameters: + * mfg_id_out - Manufacturer id value to return. + * flash_id_out - Flash id value to return. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_nxdiag_read_flash_id(int *mfg_id_out, int *flash_id_out) +{ + uint32_t value = bootloader_read_flash_id(); + int mfg_id = (value >> 16) & 0xff; + int flash_id = value & 0xffff; + *mfg_id_out = mfg_id; + *flash_id_out = flash_id; +} + +/**************************************************************************** + * Name: esp_nxdiag_read_security_info + * + * Description: + * Read security information. + * + * Input Parameters: + * crypt_cnt - Crypt count value to return. + * secure_boot - Secure boot value to return. + * flash_crpyt_en - Encryption enabled value to return. + * chip_id - Chip id value to return. + * api_version - API version value to return. + * key_purposes - Key values for efuses + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp_nxdiag_read_security_info(bool *crypt_cnt, bool *secure_boot, + bool *flash_crpyt_en, int *chip_id, + int *api_version, uint32_t *key_purposes) +{ +#ifdef CONFIG_ARCH_CHIP_ESP32S3 + extern int _rom_chip_id; + extern int _rom_eco_version; +#endif + + for (int i = 0; i < 7; i++) + { + key_purposes[i] = ets_efuse_get_key_purpose(ETS_EFUSE_BLOCK_KEY0 + i); + } + + *secure_boot = esp_secure_boot_enabled(); + *crypt_cnt = efuse_ll_get_flash_crypt_cnt(); + *flash_crpyt_en = esp_flash_encryption_enabled(); +#ifdef CONFIG_ARCH_CHIP_ESP32S3 + *chip_id = _rom_chip_id; + *api_version = _rom_eco_version; +#else + *chip_id = -1; + *api_version = -1; +#endif +} + +/**************************************************************************** + * Name: esp_nxdiag_read_flash_status + * + * Description: + * Read flash status value. + * + * Input Parameters: + * status - Flash status variable to fill + * + * Returned Value: + * OK on success; ERROR on failure. + * + ****************************************************************************/ + +int esp_nxdiag_read_flash_status(uint32_t *status) +{ + int ret = OK; + ret = esp_rom_spiflash_read_status(&g_rom_flashchip, status); + if (ret != OK) + { + syslog(LOG_ERR, "Failed to read flash status"); + return ERROR; + } + + ret = esp_rom_spiflash_read_statushigh(&g_rom_flashchip, status); + if (ret != OK) + { + syslog(LOG_ERR, "Failed to read flash status"); + return ERROR; + } + + return ret; +} + +/**************************************************************************** + * Name: esp_nxdiag_read_mac + * + * Description: + * Read MAC adress. + * + * Input Parameters: + * mac - Mac adress to return. + * + * Returned Value: + * OK on success; ERROR on failure. + * + ****************************************************************************/ + +int esp_nxdiag_read_mac(uint8_t *mac) +{ + int ret = esp_read_mac(mac, ESP_MAC_WIFI_STA); + return ret; +} + +/**************************************************************************** + * Name: esp_nxdiag_read + * + * Description: + * Print diagnostic information. + * + * Input Parameters: + * filep - Pointer to a file structure instance. + * buffer - Pointer to buffer to fill with random numbers. + * buflen - Length of buffer in bytes. + * + * Returned Value: + * OK on success; ERROR on failure. + * + ****************************************************************************/ + +static ssize_t esp_nxdiag_read(struct file *filep, + char *buffer, + size_t buflen) +{ + int ret; + int mfg_id; + int flash_id; + int chip_id; + int api_version; + int i; + int tmp_arr_size = 128; + char tmp[128]; + uint32_t flash_status; + uint8_t mac[6]; + uint32_t key_purposes[7]; + bool crypt_cnt; + bool secure_boot; + bool flash_crpyt_en; + + for (i = 0; i < buflen; i++) + { + buffer[i] = 0; + } + + esp_nxdiag_read_flash_id(&mfg_id, &flash_id); + snprintf(tmp, tmp_arr_size, + "Flash ID:\n\t Manufacturer: %d\n\t Device: %d\n\n", + mfg_id, flash_id); + strcat(buffer, tmp); + + ret = esp_nxdiag_read_mac(mac); + if (ret != OK) + { + printf("Failed to fetch MAC adress\n\n"); + } + else + { + snprintf(tmp, tmp_arr_size, + "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + strcat(buffer, tmp); + } + + ret = esp_nxdiag_read_flash_status(&flash_status); + if (ret != OK) + { + printf("Failed to read flash status\n\n"); + } + else + { + snprintf(tmp, tmp_arr_size, "Flash status: 0x%lx\n\n", + (long unsigned int)flash_status); + strcat(buffer, tmp); + } + + esp_nxdiag_read_security_info(&crypt_cnt, &secure_boot, + &flash_crpyt_en, &chip_id, + &api_version, key_purposes); + snprintf(tmp, tmp_arr_size, "Security information:\n\ + Key Purposes:(%ld, %ld, %ld, %ld, %ld, %ld, %ld)\n", + key_purposes[0], key_purposes[1], key_purposes[2], + key_purposes[3], key_purposes[4], key_purposes[5], + key_purposes[6]); + strcat(buffer, tmp); + + snprintf(tmp, tmp_arr_size, "\t Chip ID: %d\n", chip_id); + strcat(buffer, tmp); + + snprintf(tmp, tmp_arr_size, "\t API Version: %ld\n", + (long int)api_version); + strcat(buffer, tmp); + + snprintf(tmp, tmp_arr_size, "\t Secure Boot: %s\n", (secure_boot == 1) ? + "Enabled" : "Disabled"); + strcat(buffer, tmp); + + snprintf(tmp, tmp_arr_size, "\t Flash Encryption: %s\n", + (flash_crpyt_en == 1) ? "Enabled" : "Disabled"); + strcat(buffer, tmp); + + snprintf(tmp, tmp_arr_size, + "\t SPI Boot Crypt Count (SPI_BOOT_CRYPT_CNT): %x\n\n", + crypt_cnt); + strcat(buffer, tmp); + + return strlen(buffer); +} + +/**************************************************************************** + * Name: devrandom_register + * + * Description: + * Initialize and register the /dev/nxdiag driver. + * + * + * Input Parameters: + * None + * + * Returned Value: + * Returns OK on success; a negated errno value on failure + * + ****************************************************************************/ + +static int esp_nxdiag_register(void) +{ + return register_driver("/dev/nxdiag", &g_nxdiagops, 0444, NULL); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_nxdiag_initialize + * + * Description: + * This function initializes the internal temperature sensor with the + * provided configuration. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns OK on success; a negated errno value on failure + * + ****************************************************************************/ + +int esp_nxdiag_initialize(void) +{ + return esp_nxdiag_register(); +} diff --git a/arch/xtensa/src/common/espressif/esp_nxdiag.h b/arch/xtensa/src/common/espressif/esp_nxdiag.h new file mode 100644 index 0000000000..acba00e585 --- /dev/null +++ b/arch/xtensa/src/common/espressif/esp_nxdiag.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * arch/xtensa/src/common/espressif/esp_nxdiag.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_COMMON_ESPRESSIF_ESP_NXDIAG_H +#define __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_NXDIAG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_nxdiag_initialize + * + * Description: + * This function initializes the internal temperature sensor with the + * provided configuration. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns OK on success; a negated errno value on failure + * + ****************************************************************************/ + +int esp_nxdiag_initialize(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ARCH_XTENSA_SRC_COMMON_ESPRESSIF_ESP_NXDIAG_H */ diff --git a/arch/xtensa/src/esp32/hal.mk b/arch/xtensa/src/esp32/hal.mk index 2557353506..2cba9421b6 100644 --- a/arch/xtensa/src/esp32/hal.mk +++ b/arch/xtensa/src/esp32/hal.mk @@ -21,6 +21,8 @@ # Include header paths INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)private_include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)private_include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efuse$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -138,6 +140,7 @@ ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y) CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)esp_image_format.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)${CHIP_SERIES}$(DELIM)bootloader_soc.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)${CHIP_SERIES}$(DELIM)bootloader_sha.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)flash_encrypt.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)rtc_clk_init.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_uart.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_sys.c diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c index 9714a9f62f..326cb83a12 100644 --- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c +++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c @@ -180,6 +180,10 @@ # include "esp32_board_mcpwm.h" #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL +# include "espressif/esp_nxdiag.h" +#endif + #include "esp32-devkitc.h" /**************************************************************************** @@ -758,6 +762,14 @@ int esp32_bringup(void) } #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL + ret = esp_nxdiag_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: esp_nxdiag_initialize failed: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities. diff --git a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c index 1210355e28..cdd5b94222 100644 --- a/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c +++ b/boards/xtensa/esp32s2/esp32s2-saola-1/src/esp32s2_bringup.c @@ -102,6 +102,10 @@ # include "espressif/esp_temperature_sensor.h" #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL +# include "espressif/esp_nxdiag.h" +#endif + #include "esp32s2-saola-1.h" /**************************************************************************** @@ -424,6 +428,14 @@ int esp32s2_bringup(void) } #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL + ret = esp_nxdiag_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: esp_nxdiag_initialize failed: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities. diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c index 899479c89f..cb4b04e4aa 100644 --- a/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c +++ b/boards/xtensa/esp32s3/esp32s3-devkit/src/esp32s3_bringup.c @@ -130,6 +130,10 @@ # include "espressif/esp_temperature_sensor.h" #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL +# include "espressif/esp_nxdiag.h" +#endif + #include "esp32s3-devkit.h" /**************************************************************************** @@ -537,6 +541,14 @@ int esp32s3_bringup(void) } #endif +#ifdef CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL + ret = esp_nxdiag_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: esp_nxdiag_initialize failed: %d\n", ret); + } +#endif + /* If we got here then perhaps not all initialization was successful, but * at least enough succeeded to bring-up NSH with perhaps reduced * capabilities.