diff --git a/boot/espressif/CMakeLists.txt b/boot/espressif/CMakeLists.txt index 3bfb367f2..3c732db6e 100644 --- a/boot/espressif/CMakeLists.txt +++ b/boot/espressif/CMakeLists.txt @@ -22,6 +22,7 @@ if ("${MCUBOOT_TARGET}" STREQUAL "esp32" OR set(MCUBOOT_ARCH "xtensa") elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR "${MCUBOOT_TARGET}" STREQUAL "esp32c6" OR + "${MCUBOOT_TARGET}" STREQUAL "esp32c2" OR "${MCUBOOT_TARGET}" STREQUAL "esp32h2") set(MCUBOOT_ARCH "riscv") endif() @@ -37,6 +38,8 @@ elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c3") set(ESP_MIN_REVISION 3) elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c6") set(ESP_MIN_REVISION 0) +elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c2") + set(ESP_MIN_REVISION 0) elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2") set(ESP_MIN_REVISION 0) else() @@ -118,6 +121,8 @@ if (NOT DEFINED ESP_FLASH_FREQ) "${MCUBOOT_TARGET}" STREQUAL "esp32c3" OR "${MCUBOOT_TARGET}" STREQUAL "esp32c6") set(ESP_FLASH_FREQ "40m") + elseif("${MCUBOOT_TARGET}" STREQUAL "esp32c2") + set(ESP_FLASH_FREQ "60m") elseif("${MCUBOOT_TARGET}" STREQUAL "esp32h2") set(ESP_FLASH_FREQ "24m") endif() diff --git a/boot/espressif/hal/include/esp32c2/esp32c2.cmake b/boot/espressif/hal/include/esp32c2/esp32c2.cmake new file mode 100644 index 000000000..b859f9f9d --- /dev/null +++ b/boot/espressif/hal/include/esp32c2/esp32c2.cmake @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: Apache-2.0 + +list(APPEND hal_srcs + ${esp_hal_dir}/components/esp_hw_support/port/${MCUBOOT_TARGET}/rtc_init.c + ${esp_hal_dir}/components/hal/cache_hal.c + ${esp_hal_dir}/components/efuse/${MCUBOOT_TARGET}/esp_efuse_table.c + ${esp_hal_dir}/components/efuse/src/efuse_controller/keys/without_key_purposes/one_key_block/esp_efuse_api_key.c +) + +if (DEFINED CONFIG_ESP_CONSOLE_UART_CUSTOM) + list(APPEND hal_srcs + ${src_dir}/${MCUBOOT_TARGET}/console_uart_custom.c + ) +endif() + +list(APPEND LINKER_SCRIPTS + -T${esp_hal_dir}/components/esp_rom/${MCUBOOT_TARGET}/ld/${MCUBOOT_TARGET}.rom.newlib.ld +) + +set_source_files_properties( + ${esp_hal_dir}/components/bootloader_support/src/esp_image_format.c + ${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash.c + ${esp_hal_dir}/components/bootloader_support/bootloader_flash/src/bootloader_flash_config_${MCUBOOT_TARGET}.c + ${esp_hal_dir}/components/hal/mmu_hal.c + ${esp_hal_dir}/components/hal/cache_hal.c + PROPERTIES COMPILE_FLAGS + "-Wno-logical-op") diff --git a/boot/espressif/hal/include/esp32c2/sdkconfig.h b/boot/espressif/hal/include/esp32c2/sdkconfig.h new file mode 100644 index 000000000..f71490b2b --- /dev/null +++ b/boot/espressif/hal/include/esp32c2/sdkconfig.h @@ -0,0 +1,30 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define BOOTLOADER_BUILD 1 +#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x000C +#define CONFIG_IDF_TARGET_ESP32C2 1 +#define CONFIG_ESP32C2_REV_MIN_0 1 +#define CONFIG_ESP32C2_REV_MIN_FULL 3 +#define CONFIG_ESP_REV_MIN_FULL CONFIG_ESP32C2_REV_MIN_FULL +#define CONFIG_ESP32C2_REV_MIN 3 +#define CONFIG_ESP32C2_REV_MAX_FULL 99 +#define CONFIG_ESP_REV_MAX_FULL CONFIG_ESP32C2_REV_MAX_FULL +#define CONFIG_IDF_TARGET_ARCH_RISCV 1 +#define CONFIG_MMU_PAGE_SIZE 0x10000 +#define CONFIG_XTAL_FREQ_26 1 +#define CONFIG_XTAL_FREQ 26 +#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 +#define CONFIG_MCUBOOT 1 +#define NDEBUG 1 +#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000 +#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200 +#define CONFIG_BOOTLOADER_OFFSET_IN_FLASH 0x0000 +#define CONFIG_PARTITION_TABLE_OFFSET 0x10000 +#define CONFIG_EFUSE_VIRTUAL_OFFSET 0x250000 +#define CONFIG_EFUSE_VIRTUAL_SIZE 0x2000 +#define CONFIG_EFUSE_MAX_BLK_LEN 256 +#define CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT 1 diff --git a/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h index 680bc7997..d6197729c 100644 --- a/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h +++ b/boot/espressif/hal/include/mcuboot_config/mcuboot_logging.h @@ -27,6 +27,8 @@ extern int ets_printf(const char *fmt, ...); #define TARGET "[esp32c3]" #elif CONFIG_IDF_TARGET_ESP32C6 #define TARGET "[esp32c6]" +#elif CONFIG_IDF_TARGET_ESP32C2 +#define TARGET "[esp32c2]" #elif CONFIG_IDF_TARGET_ESP32H2 #define TARGET "[esp32h2]" #else diff --git a/boot/espressif/hal/src/esp32c2/console_uart_custom.c b/boot/espressif/hal/src/esp32c2/console_uart_custom.c new file mode 100644 index 000000000..e0067098d --- /dev/null +++ b/boot/espressif/hal/src/esp32c2/console_uart_custom.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if CONFIG_ESP_CONSOLE_UART_CUSTOM +static uart_dev_t *alt_console_uart_dev = (CONFIG_ESP_CONSOLE_UART_NUM == 0) ? + &UART0 : + &UART1; + +void IRAM_ATTR esp_rom_uart_putc(char c) +{ + while (uart_ll_get_txfifo_len(alt_console_uart_dev) == 0); + uart_ll_write_txfifo(alt_console_uart_dev, (const uint8_t *) &c, 1); +} +#endif diff --git a/boot/espressif/port/esp32c2/bootloader.conf b/boot/espressif/port/esp32c2/bootloader.conf new file mode 100644 index 000000000..5c5307c9c --- /dev/null +++ b/boot/espressif/port/esp32c2/bootloader.conf @@ -0,0 +1,88 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ESP_FLASH_SIZE=4MB +CONFIG_ESP_BOOTLOADER_SIZE=0xF000 +CONFIG_ESP_BOOTLOADER_OFFSET=0x0000 +CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000 +CONFIG_ESP_APPLICATION_SIZE=0x100000 +CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x110000 +CONFIG_ESP_MCUBOOT_WDT_ENABLE=y +CONFIG_ESP_SCRATCH_OFFSET=0x210000 +CONFIG_ESP_SCRATCH_SIZE=0x40000 + +# When enabled, prevents updating image to an older version +# CONFIG_ESP_DOWNGRADE_PREVENTION=y +# This option makes downgrade prevention rely also on security +# counter (defined using imgtool) instead of only image version +# CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y + +# Enables the MCUboot Serial Recovery, that allows the use of +# MCUMGR to upload a firmware through the serial port +# CONFIG_ESP_MCUBOOT_SERIAL=y +# Use Serial through USB JTAG Serial port for Serial Recovery +# CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y +# Use sector erasing (recommended) instead of entire image size +# erasing when uploading through Serial Recovery +# CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y + +# GPIO used to boot on Serial Recovery +# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5 +# GPIO input type (0 for Pull-down, 1 for Pull-up) +# CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0 +# GPIO signal value +# CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1 +# Delay time for identify the GPIO signal +# CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5 +# UART port used for serial communication (not needed when using USB) +# CONFIG_ESP_SERIAL_BOOT_UART_NUM=1 +# GPIO for Serial RX signal +# CONFIG_ESP_SERIAL_BOOT_GPIO_RX=8 +# GPIO for Serial TX signal +# CONFIG_ESP_SERIAL_BOOT_GPIO_TX=9 + +# Use UART0 for console printing (use either UART or USB alone) +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +# Configures alternative UART port for console printing +# (UART_NUM=0 must not be changed) +# CONFIG_ESP_CONSOLE_UART_CUSTOM=y +# CONFIG_ESP_CONSOLE_UART_TX_GPIO=9 +# CONFIG_ESP_CONSOLE_UART_RX_GPIO=8 +# Use USB JTAG Serial for console printing +# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y + +# CONFIG_ESP_SIGN_EC256=y +# CONFIG_ESP_SIGN_ED25519=n +# CONFIG_ESP_SIGN_RSA=n +# CONFIG_ESP_SIGN_RSA_LEN=2048 + +# Use Tinycrypt lib for EC256 or ED25519 signing +# CONFIG_ESP_USE_TINYCRYPT=y +# Use Mbed TLS lib for RSA image signing +# CONFIG_ESP_USE_MBEDTLS=n + +# It is strongly recommended to generate a new signing key +# using imgtool instead of use the existent sample +# CONFIG_ESP_SIGN_KEY_FILE=root-ec-p256.pem + +# Hardware Secure Boot related options +# CONFIG_SECURE_SIGNED_ON_BOOT=1 +# CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1 +# CONFIG_SECURE_BOOT=1 +# CONFIG_SECURE_BOOT_V2_ENABLED=1 +# CONFIG_SECURE_BOOT_SUPPORTS_RSA=1 + +# Hardware Flash Encryption related options +# CONFIG_SECURE_FLASH_ENC_ENABLED=1 +# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1 +# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1 +# CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1 +# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1 +# CONFIG_SECURE_BOOT_ALLOW_JTAG=1 +# CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=1 + +# Options for enabling eFuse emulation in Flash +# CONFIG_EFUSE_VIRTUAL=1 +# CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1 diff --git a/boot/espressif/port/esp32c2/ld/bootloader.ld b/boot/espressif/port/esp32c2/ld/bootloader.ld new file mode 100644 index 000000000..bb9479f09 --- /dev/null +++ b/boot/espressif/port/esp32c2/ld/bootloader.ld @@ -0,0 +1,214 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C2 ROM static data usage is as follows: + * - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fcdcb70). + */ + +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x6e0000; + +/* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fcdcb70; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x3000; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x403aeb70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/* Default entry point: */ +ENTRY(main); + +SECTIONS +{ + .iram_loader.text : + { + . = ALIGN (16); + _loader_text_start = ABSOLUTE(.); + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ + *libhal.a:bootloader_flash.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_flash_config_esp32c2.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_init.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_common.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_random.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) + *libhal.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) + *libhal.a:bootloader_efuse.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_utility.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_sha.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_console.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_panic.*(.literal .text .literal.* .text.*) + *libhal.a:bootloader_soc.*(.literal .text .literal.* .text.*) + *libhal.a:esp_image_format.*(.literal .text .literal.* .text.*) + *libhal.a:flash_encrypt.*(.literal .text .literal.* .text.*) + *libhal.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) + *libhal.a:flash_partitions.*(.literal .text .literal.* .text.*) + *libhal.a:secure_boot.*(.literal .text .literal.* .text.*) + *libhal.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) + *libhal.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) + *libhal.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) + *libhal.a:esp_efuse_table.*(.literal .text .literal.* .text.*) + *libhal.a:esp_efuse_fields.*(.literal .text .literal.* .text.*) + *libhal.a:esp_efuse_api.*(.literal .text .literal.* .text.*) + *libhal.a:esp_efuse_utility.*(.literal .text .literal.* .text.*) + *libhal.a:esp_efuse_api_key.*(.literal .text .literal.* .text.*) + *libhal.a:rtc_clk.*(.literal .text .literal.* .text.*) + *libhal.a:rtc_time.*(.literal .text .literal.* .text.*) + *libhal.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) + *esp_mcuboot.*(.literal .text .literal.* .text.*) + *esp_loader.*(.literal .text .literal.* .text.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _loader_text_end = ABSOLUTE(.); + } > iram_loader_seg + + .iram.text : + { + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + } > iram_seg + + + /* Shared RAM */ + .dram0.bss (NOLOAD) : + { + . = ALIGN (8); + _dram_start = ABSOLUTE(.); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + } >dram_seg + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } >dram_seg + + .dram0.rodata : + { + _rodata_start = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + . = (. + 3) & ~ 3; + /* C++ constructor and destructor tables, properly ordered: */ + __init_array_start = ABSOLUTE(.); + KEEP (*crtbegin.*(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __init_array_end = ABSOLUTE(.); + KEEP (*crtbegin.*(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + _rodata_end = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + _dram_end = ABSOLUTE(.); + } >dram_seg + + .iram.text : + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.iram .iram.*) /* catch stray IRAM_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } > iram_seg + +} diff --git a/boot/espressif/port/esp32c2/serial_adapter.c b/boot/espressif/port/esp32c2/serial_adapter.c new file mode 100644 index 000000000..f40fa41f1 --- /dev/null +++ b/boot/espressif/port/esp32c2/serial_adapter.c @@ -0,0 +1,226 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT +#define SERIAL_BOOT_GPIO_DETECT CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT +#else +#define SERIAL_BOOT_GPIO_DETECT GPIO_NUM_5 +#endif + +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL +#define SERIAL_BOOT_GPIO_DETECT_VAL CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL +#else +#define SERIAL_BOOT_GPIO_DETECT_VAL 1 +#endif + +#ifdef CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S +#define SERIAL_BOOT_DETECT_DELAY_S CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S +#else +#define SERIAL_BOOT_DETECT_DELAY_S 5 +#endif + +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE +#define SERIAL_BOOT_GPIO_INPUT_TYPE CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE +#else +// pull-down +#define SERIAL_BOOT_GPIO_INPUT_TYPE 0 +#endif + +#ifndef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG + +#ifdef CONFIG_ESP_SERIAL_BOOT_UART_NUM +#define SERIAL_BOOT_UART_NUM CONFIG_ESP_SERIAL_BOOT_UART_NUM +#else +#define SERIAL_BOOT_UART_NUM ESP_ROM_UART_1 +#endif + +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_RX +#define SERIAL_BOOT_GPIO_RX CONFIG_ESP_SERIAL_BOOT_GPIO_RX +#else +#define SERIAL_BOOT_GPIO_RX GPIO_NUM_8 +#endif + +#ifdef CONFIG_ESP_SERIAL_BOOT_GPIO_TX +#define SERIAL_BOOT_GPIO_TX CONFIG_ESP_SERIAL_BOOT_GPIO_TX +#else +#define SERIAL_BOOT_GPIO_TX GPIO_NUM_9 +#endif + +static uart_dev_t *serial_boot_uart_dev = (SERIAL_BOOT_UART_NUM == 0) ? + &UART0 : + &UART1; + +#endif + +void console_write(const char *str, int cnt) +{ +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG + usb_serial_jtag_ll_txfifo_flush(); + while (!usb_serial_jtag_ll_txfifo_writable()) { + MCUBOOT_WATCHDOG_FEED(); + } + usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, cnt); + usb_serial_jtag_ll_txfifo_flush(); +#else + uint32_t tx_len; + uint32_t write_len; + + do { + tx_len = uart_ll_get_txfifo_len(serial_boot_uart_dev); + if (tx_len > 0) { + write_len = tx_len < cnt ? tx_len : cnt; + uart_ll_write_txfifo(serial_boot_uart_dev, (const uint8_t *)str, write_len); + cnt -= write_len; + } + MCUBOOT_WATCHDOG_FEED(); + esp_rom_delay_us(1000); + } while (cnt > 0); +#endif +} + +int console_read(char *str, int cnt, int *newline) +{ +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG + uint32_t read_len = 0; + + esp_rom_delay_us(1000); + do { + if (usb_serial_jtag_ll_rxfifo_data_available()) { + usb_serial_jtag_ll_read_rxfifo((uint8_t *)&str[read_len], 1); + read_len++; + } + MCUBOOT_WATCHDOG_FEED(); + esp_rom_delay_us(1000); + } while (!(read_len == cnt || str[read_len - 1] == '\n')); + *newline = (str[read_len - 1] == '\n') ? 1 : 0; + + return read_len; +#else + uint32_t len = 0; + uint32_t read_len = 0; + bool stop = false; + + do { + len = uart_ll_get_rxfifo_len(serial_boot_uart_dev); + + if (len > 0) { + for (uint32_t i = 0; i < len; i++) { + /* Read the character from the RX FIFO */ + uart_ll_read_rxfifo(serial_boot_uart_dev, (uint8_t *)&str[read_len], 1); + read_len++; + if (read_len == cnt - 1|| str[read_len - 1] == '\n') { + stop = true; + break; + } + } + } + MCUBOOT_WATCHDOG_FEED(); + esp_rom_delay_us(1000); + } while (!stop); + + *newline = (str[read_len - 1] == '\n') ? 1 : 0; + return read_len; +#endif +} + +int boot_console_init(void) +{ + BOOT_LOG_INF("Initializing serial boot pins"); + +#ifdef CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG + usb_serial_jtag_ll_txfifo_flush(); + esp_rom_uart_tx_wait_idle(0); +#else + /* Enable GPIO for UART RX */ + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_RX); + esp_rom_gpio_connect_in_signal(SERIAL_BOOT_GPIO_RX, + UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_RX_PIN_IDX), + 0); + gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_RX); + esp_rom_gpio_pad_pullup_only(SERIAL_BOOT_GPIO_RX); + + + /* Enable GPIO for UART TX */ + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_TX); + esp_rom_gpio_connect_out_signal(SERIAL_BOOT_GPIO_TX, + UART_PERIPH_SIGNAL(SERIAL_BOOT_UART_NUM, SOC_UART_TX_PIN_IDX), + 0, 0); + gpio_ll_output_enable(&GPIO, SERIAL_BOOT_GPIO_TX); + + uart_ll_set_sclk(serial_boot_uart_dev, UART_SCLK_APB); + uart_ll_set_mode_normal(serial_boot_uart_dev); + uart_ll_set_baudrate(serial_boot_uart_dev, 115200, UART_SCLK_APB); + uart_ll_set_stop_bits(serial_boot_uart_dev, 1u); + uart_ll_set_parity(serial_boot_uart_dev, UART_PARITY_DISABLE); + uart_ll_set_rx_tout(serial_boot_uart_dev, 16); + uart_ll_set_data_bit_num(serial_boot_uart_dev, UART_DATA_8_BITS); + uart_ll_set_tx_idle_num(serial_boot_uart_dev, 0); + uart_ll_set_hw_flow_ctrl(serial_boot_uart_dev, UART_HW_FLOWCTRL_DISABLE, 100); + periph_ll_enable_clk_clear_rst(PERIPH_UART0_MODULE + SERIAL_BOOT_UART_NUM); + + uart_ll_txfifo_rst(serial_boot_uart_dev); + uart_ll_rxfifo_rst(serial_boot_uart_dev); + esp_rom_delay_us(50000); +#endif + + return 0; +} + +bool boot_serial_detect_pin(void) +{ + bool detected = false; + int pin_value = 0; + + esp_rom_gpio_pad_select_gpio(SERIAL_BOOT_GPIO_DETECT); + gpio_ll_input_enable(&GPIO, SERIAL_BOOT_GPIO_DETECT); + switch (SERIAL_BOOT_GPIO_INPUT_TYPE) { + // Pull-down + case 0: + gpio_ll_pulldown_en(&GPIO, SERIAL_BOOT_GPIO_DETECT); + break; + // Pull-up + case 1: + gpio_ll_pullup_en(&GPIO, SERIAL_BOOT_GPIO_DETECT); + break; + } + esp_rom_delay_us(50000); + + pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT); + detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL); + esp_rom_delay_us(50000); + + if (detected) { + if (SERIAL_BOOT_DETECT_DELAY_S > 0) { + /* The delay time is an approximation */ + for (int i = 0; i < (SERIAL_BOOT_DETECT_DELAY_S * 100); i++) { + esp_rom_delay_us(10000); + pin_value = gpio_ll_get_level(&GPIO, SERIAL_BOOT_GPIO_DETECT); + detected = (pin_value == SERIAL_BOOT_GPIO_DETECT_VAL); + if (!detected) { + break; + } + } + } + } + return detected; +} diff --git a/boot/espressif/tools/toolchain-esp32c2.cmake b/boot/espressif/tools/toolchain-esp32c2.cmake new file mode 100644 index 000000000..0982a85e4 --- /dev/null +++ b/boot/espressif/tools/toolchain-esp32c2.cmake @@ -0,0 +1,13 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# +# SPDX-License-Identifier: Apache-2.0 + +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_C_COMPILER riscv32-esp-elf-gcc) +set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++) +set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc) + +set(CMAKE_C_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS "-march=rv32imc_zicsr_zifencei" CACHE STRING "C++ Compiler Base Flags") +set(CMAKE_EXE_LINKER_FLAGS "-nostartfiles -march=rv32imc_zicsr_zifencei --specs=nosys.specs" CACHE STRING "Linker Base Flags")