IDF master c69f0ec32 (#5449)

esp-dsp: master f4d7d6e
esp-face: master 420fc7e
esp-rainmaker: f1b82c7
esp32-camera: master 6a9497b
esp_littlefs: master b58f00c
This commit is contained in:
Me No Dev
2021-07-26 15:56:05 +03:00
committed by GitHub
parent e0e5c88658
commit 6972695d95
588 changed files with 15433 additions and 1657 deletions

View File

@ -54,8 +54,10 @@ typedef bool (*async_memcpy_isr_cb_t)(async_memcpy_t mcp_hdl, async_memcpy_event
*
*/
typedef struct {
uint32_t backlog; /*!< Maximum number of streams that can be handled simultaneously */
uint32_t flags; /*!< Extra flags to control async memcpy feature */
uint32_t backlog; /*!< Maximum number of streams that can be handled simultaneously */
size_t sram_trans_align; /*!< DMA transfer alignment (both in size and address) for SRAM memory */
size_t psram_trans_align; /*!< DMA transfer alignment (both in size and address) for PSRAM memory */
uint32_t flags; /*!< Extra flags to control async memcpy feature */
} async_memcpy_config_t;
/**
@ -63,9 +65,11 @@ typedef struct {
*
*/
#define ASYNC_MEMCPY_DEFAULT_CONFIG() \
{ \
.backlog = 8, \
.flags = 0, \
{ \
.backlog = 8, \
.sram_trans_align = 0, \
.psram_trans_align = 0, \
.flags = 0, \
}
/**

View File

@ -60,7 +60,9 @@ typedef enum {
* @note If not using a valid OUI, set the "locally administered" bit
* (bit value 0x02 in the first byte) to avoid collisions.
*
* @param mac base MAC address, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
*
* @return ESP_OK on success
* ESP_ERR_INVALID_ARG If mac is NULL or is not a unicast MAC
@ -72,7 +74,9 @@ esp_err_t esp_base_mac_addr_set(const uint8_t *mac);
*
* @note If no custom Base MAC has been set, this returns the pre-programmed Espressif base MAC address.
*
* @param mac base MAC address, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
*
* @return ESP_OK on success
* ESP_ERR_INVALID_MAC base MAC address has not been set
@ -91,7 +95,9 @@ esp_err_t esp_base_mac_addr_get(uint8_t *mac);
*
* @note This function is currently only supported on ESP32.
*
* @param mac base MAC address, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
*
* @return ESP_OK on success
* ESP_ERR_INVALID_VERSION An invalid MAC version field was read from BLK3 of EFUSE
@ -102,7 +108,9 @@ esp_err_t esp_efuse_mac_get_custom(uint8_t *mac);
/**
* @brief Return base MAC address which is factory-programmed by Espressif in EFUSE.
*
* @param mac base MAC address, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
*
* @return ESP_OK on success
*/
@ -115,12 +123,14 @@ esp_err_t esp_efuse_mac_get_default(uint8_t *mac);
* Then calculates the MAC address of the specific interface requested,
* refer to ESP-IDF Programming Guide for the algorithm.
*
* @param mac MAC address of the interface, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
* @param type Type of MAC address to return
*
* @return ESP_OK on success
*/
esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type);
esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type);
/**
* @brief Derive local MAC address from universal MAC address.
@ -133,12 +143,14 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type);
* address, then the first octet is XORed with 0x4 in order to create a different
* locally administered MAC address.
*
* @param local_mac Derived local MAC address, length: 6 bytes.
* @param mac base MAC address, length: 6 bytes/8 bytes.
* length: 6 bytes for MAC-48
* 8 bytes for EUI-64(used for IEEE 802.15.4)
* @param universal_mac Source universal MAC address, length: 6 bytes.
*
* @return ESP_OK on success
*/
esp_err_t esp_derive_local_mac(uint8_t* local_mac, const uint8_t* universal_mac);
esp_err_t esp_derive_local_mac(uint8_t *local_mac, const uint8_t *universal_mac);
#ifdef __cplusplus
}

View File

@ -17,7 +17,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "soc/cpu.h"
#include "soc/soc_memory_layout.h"
#include "soc/soc_memory_types.h"
#if __XTENSA__
#include "xtensa/xtruntime.h"

View File

@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: 2010-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <sdkconfig.h>
#ifndef _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include "xtensa/xtruntime.h"
#ifdef __cplusplus
extern "C" {
#endif
void esp_dport_access_stall_other_cpu_start(void);
void esp_dport_access_stall_other_cpu_end(void);
void esp_dport_access_int_init(void);
void esp_dport_access_int_pause(void);
void esp_dport_access_int_resume(void);
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
uint32_t esp_dport_access_reg_read(uint32_t reg);
uint32_t esp_dport_access_sequence_reg_read(uint32_t reg);
//This routine does not stop the dport routines in any way that is recoverable. Please
//only call in case of panic().
void esp_dport_access_int_abort(void);
#if defined(BOOTLOADER_BUILD) || !defined(CONFIG_ESP32_DPORT_WORKAROUND) || !defined(ESP_PLATFORM)
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#else
#define DPORT_STALL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start()
#define DPORT_STALL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end()
#define DPORT_INTERRUPT_DISABLE() unsigned int intLvl = XTOS_SET_INTLEVEL(CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL)
#define DPORT_INTERRUPT_RESTORE() XTOS_RESTORE_JUST_INTLEVEL(intLvl)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,143 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
//Opaque pointers as handles for ram/range data
typedef struct esp_himem_ramdata_t *esp_himem_handle_t;
typedef struct esp_himem_rangedata_t *esp_himem_rangehandle_t;
//ESP32 MMU block size
#define ESP_HIMEM_BLKSZ (0x8000)
#define ESP_HIMEM_MAPFLAG_RO 1 /*!< Indicates that a mapping will only be read from. Note that this is unused for now. */
/**
* @brief Allocate a block in high memory
*
* @param size Size of the to-be-allocated block, in bytes. Note that this needs to be
* a multiple of the external RAM mmu block size (32K).
* @param[out] handle_out Handle to be returned
* @returns - ESP_OK if succesful
* - ESP_ERR_NO_MEM if out of memory
* - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K
*/
esp_err_t esp_himem_alloc(size_t size, esp_himem_handle_t *handle_out);
/**
* @brief Allocate a memory region to map blocks into
*
* This allocates a contiguous CPU memory region that can be used to map blocks
* of physical memory into.
*
* @param size Size of the range to be allocated. Note this needs to be a multiple of
* the external RAM mmu block size (32K).
* @param[out] handle_out Handle to be returned
* @returns - ESP_OK if succesful
* - ESP_ERR_NO_MEM if out of memory or address space
* - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K
*/
esp_err_t esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t *handle_out);
/**
* @brief Map a block of high memory into the CPUs address space
*
* This effectively makes the block available for read/write operations.
*
* @note The region to be mapped needs to have offsets and sizes that are aligned to the
* SPI RAM MMU block size (32K)
*
* @param handle Handle to the block of memory, as given by esp_himem_alloc
* @param range Range handle to map the memory in
* @param ram_offset Offset into the block of physical memory of the block to map
* @param range_offset Offset into the address range where the block will be mapped
* @param len Length of region to map
* @param flags One of ESP_HIMEM_MAPFLAG_*
* @param[out] out_ptr Pointer to variable to store resulting memory pointer in
* @returns - ESP_OK if the memory could be mapped
* - ESP_ERR_INVALID_ARG if offset, range or len aren't MMU-block-aligned (32K)
* - ESP_ERR_INVALID_SIZE if the offsets/lengths don't fit in the allocated memory or range
* - ESP_ERR_INVALID_STATE if a block in the selected ram offset/length is already mapped, or
* if a block in the selected range offset/length already has a mapping.
*/
esp_err_t esp_himem_map(esp_himem_handle_t handle, esp_himem_rangehandle_t range, size_t ram_offset, size_t range_offset, size_t len, int flags, void **out_ptr);
/**
* @brief Free a block of physical memory
*
* This clears out the associated handle making the memory available for re-allocation again.
* This will only succeed if none of the memory blocks currently have a mapping.
*
* @param handle Handle to the block of memory, as given by esp_himem_alloc
* @returns - ESP_OK if the memory is succesfully freed
* - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped
*/
esp_err_t esp_himem_free(esp_himem_handle_t handle);
/**
* @brief Free a mapping range
*
* This clears out the associated handle making the range available for re-allocation again.
* This will only succeed if none of the range blocks currently are used for a mapping.
*
* @param handle Handle to the range block, as given by esp_himem_alloc_map_range
* @returns - ESP_OK if the memory is succesfully freed
* - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped to
*/
esp_err_t esp_himem_free_map_range(esp_himem_rangehandle_t handle);
/**
* @brief Unmap a region
*
* @param range Range handle
* @param ptr Pointer returned by esp_himem_map
* @param len Length of the block to be unmapped. Must be aligned to the SPI RAM MMU blocksize (32K)
* @returns - ESP_OK if the memory is succesfully unmapped,
* - ESP_ERR_INVALID_ARG if ptr or len are invalid.
*/
esp_err_t esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr, size_t len);
/**
* @brief Get total amount of memory under control of himem API
*
* @returns Amount of memory, in bytes
*/
size_t esp_himem_get_phys_size(void);
/**
* @brief Get free amount of memory under control of himem API
*
* @returns Amount of free memory, in bytes
*/
size_t esp_himem_get_free_size(void);
/**
* @brief Get amount of SPI memory address space needed for bankswitching
*
* @note This is also weakly defined in esp32/spiram.c and returns 0 there, so
* if no other function in this file is used, no memory is reserved.
*
* @returns Amount of reserved area, in bytes
*/
size_t esp_himem_reserved_area_size(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp32/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,115 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_SPIRAM_H
#define __ESP_SPIRAM_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ESP_SPIRAM_SIZE_16MBITS = 0, /*!< SPI RAM size is 16 MBits */
ESP_SPIRAM_SIZE_32MBITS = 1, /*!< SPI RAM size is 32 MBits */
ESP_SPIRAM_SIZE_64MBITS = 2, /*!< SPI RAM size is 64 MBits */
ESP_SPIRAM_SIZE_INVALID, /*!< SPI RAM size is invalid */
} esp_spiram_size_t;
/**
* @brief get SPI RAM size
* @return
* - ESP_SPIRAM_SIZE_INVALID if SPI RAM not enabled or not valid
* - SPI RAM size
*/
esp_spiram_size_t esp_spiram_get_chip_size(void);
/**
* @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
*
* @return ESP_OK on success
*/
esp_err_t esp_spiram_init(void);
/**
* @brief Configure Cache/MMU for access to external SPI RAM.
*
* Normally this function is called from cpu_start, if CONFIG_SPIRAM_BOOT_INIT
* option is enabled. Applications which need to enable SPI RAM at run time
* can disable CONFIG_SPIRAM_BOOT_INIT, and call this function later.
*
* @attention this function must be called with flash cache disabled.
*/
void esp_spiram_init_cache(void);
/**
* @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
* (in case of a dual-core system) the app CPU is online. This test overwrites the
* memory with crap, so do not call after e.g. the heap allocator has stored important
* stuff in SPI RAM.
*
* @return true on success, false on failed memory test
*/
bool esp_spiram_test(void);
/**
* @brief Add the initialized SPI RAM to the heap allocator.
*/
esp_err_t esp_spiram_add_to_heapalloc(void);
/**
* @brief Get the size of the attached SPI RAM chip selected in menuconfig
*
* @return Size in bytes, or 0 if no external RAM chip support compiled in.
*/
size_t esp_spiram_get_size(void);
/**
* @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
* cache is disabled, because disabling cache on the ESP32 discards the data in the SPI
* RAM cache.
*
* This is meant for use from within the SPI flash code.
*/
void esp_spiram_writeback_cache(void);
/**
* @brief Reserve a pool of internal memory for specific DMA/internal allocations
*
* @param size Size of reserved pool in bytes
*
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM when no memory available for pool
*/
esp_err_t esp_spiram_reserve_dma_pool(size_t size);
/**
* @brief If SPI RAM(PSRAM) has been initialized
*
* @return
* - true SPI RAM has been initialized successfully
* - false SPI RAM hasn't been initialized or initialized failed
*/
bool esp_spiram_is_initialized(void);
#ifdef __cplusplus
}
#endif
#endif // __ESP_SPIRAM_H

View File

@ -0,0 +1,42 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read a sequence of DPORT registers to the buffer.
*
* @param[out] buff_out Contains the read data.
* @param[in] address Initial address for reading registers.
* @param[in] num_words The number of words.
*/
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,76 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Acquire lock for HMAC cryptography peripheral
*
* Internally also locks the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_acquire(void);
/**
* @brief Release lock for HMAC cryptography peripheral
*
* Internally also releases the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_release(void);
/**
* @brief Acquire lock for DS cryptography peripheral
*
* Internally also locks the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_acquire(void);
/**
* @brief Release lock for DS cryptography peripheral
*
* Internally also releases the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_release(void);
/**
* @brief Acquire lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_acquire(void);
/**
* @brief Release lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_release(void);
/**
* @brief Acquire lock for the mpi cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* @brief Release lock for the mpi/rsa cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,218 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include "esp_hmac.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP32C3_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
HMAC peripheral problem */
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
result is invalid */
#define ESP32C3_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
is produced anyway and can be read*/
#define ESP_DS_IV_BIT_LEN 128
#define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8)
#define ESP_DS_SIGNATURE_MAX_BIT_LEN 3072
#define ESP_DS_SIGNATURE_MD_BIT_LEN 256
#define ESP_DS_SIGNATURE_M_PRIME_BIT_LEN 32
#define ESP_DS_SIGNATURE_L_BIT_LEN 32
#define ESP_DS_SIGNATURE_PADDING_BIT_LEN 64
/* Length of parameter 'C' stored in flash, in bytes
- Operands Y, M and r_bar; each 3072 bits
- Operand MD (message digest); 256 bits
- Operands M' and L; each 32 bits
- Operand beta (padding value; 64 bits
*/
#define ESP_DS_C_LEN (((ESP_DS_SIGNATURE_MAX_BIT_LEN * 3 \
+ ESP_DS_SIGNATURE_MD_BIT_LEN \
+ ESP_DS_SIGNATURE_M_PRIME_BIT_LEN \
+ ESP_DS_SIGNATURE_L_BIT_LEN \
+ ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8))
typedef struct esp_ds_context esp_ds_context_t;
typedef enum {
ESP_DS_RSA_1024 = (1024 / 32) - 1,
ESP_DS_RSA_2048 = (2048 / 32) - 1,
ESP_DS_RSA_3072 = (3072 / 32) - 1
} esp_digital_signature_length_t;
/**
* Encrypted private key data. Recommended to store in flash in this format.
*
* @note This struct has to match to one from the ROM code! This documentation is mostly taken from there.
*/
typedef struct esp_digital_signature_data {
/**
* RSA LENGTH register parameters
* (number of words in RSA key & operands, minus one).
*
* Max value 127 (for RSA 3072).
*
* This value must match the length field encrypted and stored in 'c',
* or invalid results will be returned. (The DS peripheral will
* always use the value in 'c', not this value, so an attacker can't
* alter the DS peripheral results this way, it will just truncate or
* extend the message and the resulting signature in software.)
*
* @note In IDF, the enum type length is the same as of type unsigned, so they can be used interchangably.
* See the ROM code for the original declaration of struct \c ets_ds_data_t.
*/
esp_digital_signature_length_t rsa_length;
/**
* IV value used to encrypt 'c'
*/
uint32_t iv[ESP_DS_IV_BIT_LEN / 32];
/**
* Encrypted Digital Signature parameters. Result of AES-CBC encryption
* of plaintext values. Includes an encrypted message digest.
*/
uint8_t c[ESP_DS_C_LEN];
} esp_ds_data_t;
/**
* Plaintext parameters used by Digital Signature.
*
* This is only used for encrypting the RSA parameters by calling esp_ds_encrypt_params().
* Afterwards, the result can be stored in flash or in other persistent memory.
* The encryption is a prerequisite step before any signature operation can be done.
*/
typedef struct {
uint32_t Y[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA exponent
uint32_t M[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA modulus
uint32_t Rb[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA r inverse operand
uint32_t M_prime; //!< RSA M prime operand
uint32_t length; //!< RSA length in words (32 bit)
} esp_ds_p_data_t;
/**
* @brief Sign the message with a hardware key from specific key slot.
*
* This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them
* in parallel.
* It blocks until the signing is finished and then returns the signature.
*
* @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
*
* @return
* - ESP_OK if successful, the signature was written to the parameter \c signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches.
*/
esp_err_t esp_ds_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
void *signature);
/**
* @brief Start the signing process.
*
* This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
* process.
*
* @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call
* \c esp_ds_finish_sign() in a timely manner.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param esp_ds_ctx the context object which is needed for finishing the signing process later
*
* @return
* - ESP_OK if successful, the ds operation was started now and has to be finished with \c esp_ds_finish_sign()
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
*/
esp_err_t esp_ds_start_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
esp_ds_context_t **esp_ds_ctx);
/**
* Return true if the DS peripheral is busy, otherwise false.
*
* @note Only valid if \c esp_ds_start_sign() was called before.
*/
bool esp_ds_is_busy(void);
/**
* @brief Finish the signing process.
*
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
* @param esp_ds_ctx the context object retreived by \c esp_ds_start_sign()
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* This means that the encrypted RSA key parameters are invalid, indicating that they may have been tampered
* with or indicating a flash error, etc.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches (see TRM for more details).
*/
esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
/**
* @brief Encrypt the private key parameters.
*
* The encryption is a prerequisite step before any signature operation can be done.
* It is not strictly necessary to use this encryption function, the encryption could also happen on an external
* device.
*
* @param data Output buffer to store encrypted data, suitable for later use generating signatures.
* The allocated memory must be in internal memory and word aligned since it's filled by DMA. Both is asserted
* at run time.
* @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time.
* @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
* is done and 'data' is stored.
* @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
* corresponding HMAC key will be stored to efuse and then permanently erased.
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
*/
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,67 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_HMAC_H_
#define _ESP_HMAC_H_
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
HMAC_KEY_MAX
} hmac_key_id_t;
/**
* @brief
* Calculate the HMAC of a given message.
*
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
* SHA256 is used for the calculation (fixed on ESP32S2).
*
* @note Uses the HMAC peripheral in "upstream" mode.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
* @param message the message for which to calculate the HMAC
* @param message_len message length
* return ESP_ERR_INVALID_STATE if unsuccessful
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be 32 bytes long
*
* @return
* * ESP_OK, if the calculation was successful,
* * ESP_FAIL, if the hmac calculation failed
*/
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac);
#ifdef __cplusplus
}
#endif
#endif // _ESP_HMAC_H_

View File

@ -0,0 +1,457 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
/* INTERNAL API
* generic interface to PMS memory protection features
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IRAM_SRAM_START
#define IRAM_SRAM_START 0x4037C000
#endif
#ifndef DRAM_SRAM_START
#define DRAM_SRAM_START 0x3FC7C000
#endif
#ifndef MAP_DRAM_TO_IRAM
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + IRAM_SRAM_START)
#endif
#ifndef MAP_IRAM_TO_DRAM
#define MAP_IRAM_TO_DRAM(addr) (addr - IRAM_SRAM_START + DRAM_SRAM_START)
#endif
typedef enum {
MEMPROT_NONE = 0x00000000,
MEMPROT_IRAM0_SRAM = 0x00000001,
MEMPROT_DRAM0_SRAM = 0x00000002,
MEMPROT_ALL = 0xFFFFFFFF
} mem_type_prot_t;
typedef enum {
MEMPROT_SPLITLINE_NONE = 0,
MEMPROT_IRAM0_DRAM0_SPLITLINE,
MEMPROT_IRAM0_LINE_0_SPLITLINE,
MEMPROT_IRAM0_LINE_1_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE
} split_line_t;
typedef enum {
MEMPROT_PMS_AREA_NONE = 0,
MEMPROT_IRAM0_PMS_AREA_0,
MEMPROT_IRAM0_PMS_AREA_1,
MEMPROT_IRAM0_PMS_AREA_2,
MEMPROT_IRAM0_PMS_AREA_3,
MEMPROT_DRAM0_PMS_AREA_0,
MEMPROT_DRAM0_PMS_AREA_1,
MEMPROT_DRAM0_PMS_AREA_2,
MEMPROT_DRAM0_PMS_AREA_3
} pms_area_t;
typedef enum
{
MEMPROT_PMS_WORLD_0 = 0,
MEMPROT_PMS_WORLD_1,
MEMPROT_PMS_WORLD_2,
MEMPROT_PMS_WORLD_INVALID = 0xFFFFFFFF
} pms_world_t;
typedef enum
{
MEMPROT_PMS_OP_READ = 0,
MEMPROT_PMS_OP_WRITE,
MEMPROT_PMS_OP_FETCH,
MEMPROT_PMS_OP_INVALID = 0xFFFFFFFF
} pms_operation_type_t;
/**
* @brief Converts Memory protection type to string
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type);
/**
* @brief Converts Split line type to string
*
* @param line_type Split line type (see split_line_t enum)
*/
const char *esp_memprot_split_line_to_str(split_line_t line_type);
/**
* @brief Converts PMS Area type to string
*
* @param area_type PMS Area type (see pms_area_t enum)
*/
const char *esp_memprot_pms_to_str(pms_area_t area_type);
/**
* @brief Returns PMS splitting address for given Split line type
*
* The value is taken from PMS configuration registers (IRam0 range)
* For details on split lines see 'esp_memprot_set_prot_int' function description
*
* @param line_type Split line type (see split_line_t enum)
*
* @return appropriate split line address
*/
uint32_t *esp_memprot_get_split_addr(split_line_t line_type);
/**
* @brief Returns default main IRAM/DRAM splitting address
*
* The address value is given by _iram_text_end global (IRam0 range)
* @return Main I/D split line (IRam0_DRam0_Split_Addr)
*/
void *esp_memprot_get_default_main_split_addr(void);
/**
* @brief Sets a lock for the main IRAM/DRAM splitting address
*
* Locks can be unlocked only by digital system reset
*/
void esp_memprot_set_split_line_lock(void);
/**
* @brief Gets a lock status for the main IRAM/DRAM splitting address
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_split_line_lock(void);
/**
* @brief Sets required split line address
*
* @param line_type Split line type (see split_line_t enum)
* @param line_addr target address from a memory range relevant to given line_type (IRAM/DRAM)
*/
void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr);
/**
* @brief Sets a lock for PMS Area settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS Area settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Sets permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
* @param x Execute permission flag
*/
void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x);
/**
* @brief Gets current permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
* @param x Execute permission flag holder
*/
void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x);
/**
* @brief Sets permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
*/
void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w);
/**
* @brief Gets current permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
*/
void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w);
/**
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Enable PMS violation interrupt monitoring of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
* @param enable/disable
*/
void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable);
/**
* @brief Gets enable/disable status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (enabled/disabled)
*/
bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type);
/**
* @brief Gets CPU ID for currently active PMS violation interrupt
*
* @return CPU ID (CPU_PRO for ESP32C3)
*/
int IRAM_ATTR esp_memprot_intr_get_cpuid(void);
/**
* @brief Clears current interrupt ON flag for given Memory type
*
* Interrupt clearing happens in two steps:
* 1. Interrupt CLR flag is set (to clear the interrupt ON status)
* 2. Interrupt CLR flag is reset (to allow further monitoring)
* This operation is non-atomic by PMS module design
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void IRAM_ATTR esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type);
/**
* @brief Returns active PMS violation interrupt (if any)
*
* This function iterates through supported Memory type status registers
* and returns the first interrupt-on flag. If none is found active,
* MEMPROT_NONE is returned.
* Order of checking (in current version):
* 1. MEMPROT_IRAM0_SRAM
* 2. MEMPROT_DRAM0_SRAM
*
* @return mem_type Memory protection type related to active interrupt found (see mem_type_prot_t enum)
*/
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
/**
* @brief Checks whether any violation interrupt is active
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_locked_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_intr_ena_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type);
/**
* @brief Returns the address which caused the violation interrupt (if any)
*
* The address is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return faulting address
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_addr(mem_type_prot_t mem_type);
/**
* @brief Returns the World identifier of the code causing the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return World identifier (see pms_world_t enum)
*/
pms_world_t IRAM_ATTR esp_memprot_get_violate_world(mem_type_prot_t mem_type);
/**
* @brief Returns Read or Write operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return PMS operation type relevant to mem_type parameter (se pms_operation_type_t)
*/
pms_operation_type_t IRAM_ATTR esp_memprot_get_violate_wr(mem_type_prot_t mem_type);
/**
* @brief Returns LoadStore flag of the operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
* Effective only on IRam0 access
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (LoadStore bit on/off)
*/
bool IRAM_ATTR esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type);
/**
* @brief Returns byte-enables for the address which caused the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return byte-enables
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type);
/**
* @brief Returns raw contents of DRam0 status register 1
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_1(void);
/**
* @brief Returns raw contents of DRam0 status register 2
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_2(void);
/**
* @brief Returns raw contents of IRam0 status register
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_iram_status_reg(void);
/**
* @brief Register PMS violation interrupt in global interrupt matrix for given Memory type
*
* Memory protection components uses specific interrupt number, see ETS_MEMPROT_ERR_INUM
* The registration makes the panic-handler routine being called when the interrupt appears
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type);
/**
* @brief Convenient routine for setting the PMS defaults
*
* Called on application startup, depending on CONFIG_ESP_SYSTEM_MEMPROT_FEATURE Kconfig settings
* For implementation details see 'esp_memprot_set_prot_int' description
*
* @param invoke_panic_handler register all interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (see 'esp_memprot_set_prot_int')
*/
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
/**
* @brief Internal routine for setting the PMS defaults
*
* Called on application startup from within 'esp_memprot_set_prot'. Allows setting a specific splitting address
* (main I/D split line) - see the parameter 'split_addr'. If the 'split_addr' equals to NULL, default I/D split line
* is used (&_iram_text_end) and all the remaining lines share the same address.
* The function sets all the split lines and PMS areas to the same space,
* ie there is a single instruction space and single data space at the end.
* The PMS split lines and permission areas scheme described below:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* ... | IRam0_PMS_0 |
* DRam0_PMS_0 ----------------------------------------------- IRam0_line1_Split_addr
* ... | IRam0_PMS_1 |
* ... ----------------------------------------------- IRam0_line0_Split_addr
* | IRam0_PMS_2 |
* =============================================== IRam0_DRam0_Split_addr (main I/D)
* | DRam0_PMS_1 |
* DRam0_DMA_line0_Split_addr ----------------------------------------------- ...
* | DRam0_PMS_2 | ...
* DRam0_DMA_line1_Split_addr ----------------------------------------------- IRam0_PMS_3
* | DRam0_PMS_3 | ...
* -----------------------------------------------
*
* Default settings provided by 'esp_memprot_set_prot_int' are as follows:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
* | DRam0_PMS_0 | IRam0_line1_Split_addr
* DRam0_DMA_line0_Split_addr | | =
* = =============================================== IRam0_line0_Split_addr
* DRam0_DMA_line1_Split_addr | | =
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 | IRam0_DRam0_Split_addr (main I/D)
* | IRam0_PMS_3 |
* -----------------------------------------------
*
* Once the memprot feature is locked, it can be unlocked only by digital system reset
*
* @param invoke_panic_handler register all the violation interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param split_addr specific main I/D adrees or NULL to use default ($_iram_text_end)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (members of mem_type_prot_t)
*/
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask);
/**
* @brief Returns raw contents of PMS interrupt monitor register for given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return 32-bit register value
*/
uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,40 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp32c3/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,42 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read a sequence of DPORT registers to the buffer.
*
* @param[out] buff_out Contains the read data.
* @param[in] address Initial address for reading registers.
* @param[in] num_words The number of words.
*/
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,76 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Acquire lock for HMAC cryptography peripheral
*
* Internally also locks the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_acquire(void);
/**
* @brief Release lock for HMAC cryptography peripheral
*
* Internally also releases the SHA peripheral, as the HMAC depends on the SHA peripheral
*/
void esp_crypto_hmac_lock_release(void);
/**
* @brief Acquire lock for DS cryptography peripheral
*
* Internally also locks the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_acquire(void);
/**
* @brief Release lock for DS cryptography peripheral
*
* Internally also releases the HMAC (which locks SHA), AES and MPI peripheral, as the DS depends on these peripherals
*/
void esp_crypto_ds_lock_release(void);
/**
* @brief Acquire lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_acquire(void);
/**
* @brief Release lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_release(void);
/**
* @brief Acquire lock for the mpi cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* @brief Release lock for the mpi/rsa cryptography peripheral.
*
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,218 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include "esp_hmac.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP32H2_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
HMAC peripheral problem */
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
result is invalid */
#define ESP32H2_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
is produced anyway and can be read*/
#define ESP_DS_IV_BIT_LEN 128
#define ESP_DS_IV_LEN (ESP_DS_IV_BIT_LEN / 8)
#define ESP_DS_SIGNATURE_MAX_BIT_LEN 3072
#define ESP_DS_SIGNATURE_MD_BIT_LEN 256
#define ESP_DS_SIGNATURE_M_PRIME_BIT_LEN 32
#define ESP_DS_SIGNATURE_L_BIT_LEN 32
#define ESP_DS_SIGNATURE_PADDING_BIT_LEN 64
/* Length of parameter 'C' stored in flash, in bytes
- Operands Y, M and r_bar; each 3072 bits
- Operand MD (message digest); 256 bits
- Operands M' and L; each 32 bits
- Operand beta (padding value; 64 bits
*/
#define ESP_DS_C_LEN (((ESP_DS_SIGNATURE_MAX_BIT_LEN * 3 \
+ ESP_DS_SIGNATURE_MD_BIT_LEN \
+ ESP_DS_SIGNATURE_M_PRIME_BIT_LEN \
+ ESP_DS_SIGNATURE_L_BIT_LEN \
+ ESP_DS_SIGNATURE_PADDING_BIT_LEN) / 8))
typedef struct esp_ds_context esp_ds_context_t;
typedef enum {
ESP_DS_RSA_1024 = (1024 / 32) - 1,
ESP_DS_RSA_2048 = (2048 / 32) - 1,
ESP_DS_RSA_3072 = (3072 / 32) - 1
} esp_digital_signature_length_t;
/**
* Encrypted private key data. Recommended to store in flash in this format.
*
* @note This struct has to match to one from the ROM code! This documentation is mostly taken from there.
*/
typedef struct esp_digital_signature_data {
/**
* RSA LENGTH register parameters
* (number of words in RSA key & operands, minus one).
*
* Max value 127 (for RSA 3072).
*
* This value must match the length field encrypted and stored in 'c',
* or invalid results will be returned. (The DS peripheral will
* always use the value in 'c', not this value, so an attacker can't
* alter the DS peripheral results this way, it will just truncate or
* extend the message and the resulting signature in software.)
*
* @note In IDF, the enum type length is the same as of type unsigned, so they can be used interchangably.
* See the ROM code for the original declaration of struct \c ets_ds_data_t.
*/
esp_digital_signature_length_t rsa_length;
/**
* IV value used to encrypt 'c'
*/
uint32_t iv[ESP_DS_IV_BIT_LEN / 32];
/**
* Encrypted Digital Signature parameters. Result of AES-CBC encryption
* of plaintext values. Includes an encrypted message digest.
*/
uint8_t c[ESP_DS_C_LEN];
} esp_ds_data_t;
/**
* Plaintext parameters used by Digital Signature.
*
* This is only used for encrypting the RSA parameters by calling esp_ds_encrypt_params().
* Afterwards, the result can be stored in flash or in other persistent memory.
* The encryption is a prerequisite step before any signature operation can be done.
*/
typedef struct {
uint32_t Y[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA exponent
uint32_t M[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA modulus
uint32_t Rb[ESP_DS_SIGNATURE_MAX_BIT_LEN / 32]; //!< RSA r inverse operand
uint32_t M_prime; //!< RSA M prime operand
uint32_t length; //!< RSA length in words (32 bit)
} esp_ds_p_data_t;
/**
* @brief Sign the message with a hardware key from specific key slot.
*
* This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them
* in parallel.
* It blocks until the signing is finished and then returns the signature.
*
* @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
*
* @return
* - ESP_OK if successful, the signature was written to the parameter \c signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches.
*/
esp_err_t esp_ds_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
void *signature);
/**
* @brief Start the signing process.
*
* This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
* process.
*
* @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call
* \c esp_ds_finish_sign() in a timely manner.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param esp_ds_ctx the context object which is needed for finishing the signing process later
*
* @return
* - ESP_OK if successful, the ds operation was started now and has to be finished with \c esp_ds_finish_sign()
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
*/
esp_err_t esp_ds_start_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
esp_ds_context_t **esp_ds_ctx);
/**
* Return true if the DS peripheral is busy, otherwise false.
*
* @note Only valid if \c esp_ds_start_sign() was called before.
*/
bool esp_ds_is_busy(void);
/**
* @brief Finish the signing process.
*
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
* @param esp_ds_ctx the context object retreived by \c esp_ds_start_sign()
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* This means that the encrypted RSA key parameters are invalid, indicating that they may have been tampered
* with or indicating a flash error, etc.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches (see TRM for more details).
*/
esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
/**
* @brief Encrypt the private key parameters.
*
* The encryption is a prerequisite step before any signature operation can be done.
* It is not strictly necessary to use this encryption function, the encryption could also happen on an external
* device.
*
* @param data Output buffer to store encrypted data, suitable for later use generating signatures.
* The allocated memory must be in internal memory and word aligned since it's filled by DMA. Both is asserted
* at run time.
* @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time.
* @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
* is done and 'data' is stored.
* @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
* corresponding HMAC key will be stored to efuse and then permanently erased.
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
*/
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,67 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_HMAC_H_
#define _ESP_HMAC_H_
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
HMAC_KEY_MAX
} hmac_key_id_t;
/**
* @brief
* Calculate the HMAC of a given message.
*
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
* SHA256 is used for the calculation (fixed on ESP32S2).
*
* @note Uses the HMAC peripheral in "upstream" mode.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
* @param message the message for which to calculate the HMAC
* @param message_len message length
* return ESP_ERR_INVALID_STATE if unsuccessful
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be 32 bytes long
*
* @return
* * ESP_OK, if the calculation was successful,
* * ESP_FAIL, if the hmac calculation failed
*/
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac);
#ifdef __cplusplus
}
#endif
#endif // _ESP_HMAC_H_

View File

@ -0,0 +1,456 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
/* INTERNAL API
* generic interface to PMS memory protection features
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef IRAM_SRAM_START
#define IRAM_SRAM_START 0x4037C000
#endif
#ifndef DRAM_SRAM_START
#define DRAM_SRAM_START 0x3FC7C000
#endif
#ifndef MAP_DRAM_TO_IRAM
#define MAP_DRAM_TO_IRAM(addr) (addr - DRAM_SRAM_START + IRAM_SRAM_START)
#endif
#ifndef MAP_IRAM_TO_DRAM
#define MAP_IRAM_TO_DRAM(addr) (addr - IRAM_SRAM_START + DRAM_SRAM_START)
#endif
typedef enum {
MEMPROT_NONE = 0x00000000,
MEMPROT_IRAM0_SRAM = 0x00000001,
MEMPROT_DRAM0_SRAM = 0x00000002,
MEMPROT_ALL = 0xFFFFFFFF
} mem_type_prot_t;
typedef enum {
MEMPROT_SPLITLINE_NONE = 0,
MEMPROT_IRAM0_DRAM0_SPLITLINE,
MEMPROT_IRAM0_LINE_0_SPLITLINE,
MEMPROT_IRAM0_LINE_1_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_0_SPLITLINE,
MEMPROT_DRAM0_DMA_LINE_1_SPLITLINE
} split_line_t;
typedef enum {
MEMPROT_PMS_AREA_NONE = 0,
MEMPROT_IRAM0_PMS_AREA_0,
MEMPROT_IRAM0_PMS_AREA_1,
MEMPROT_IRAM0_PMS_AREA_2,
MEMPROT_IRAM0_PMS_AREA_3,
MEMPROT_DRAM0_PMS_AREA_0,
MEMPROT_DRAM0_PMS_AREA_1,
MEMPROT_DRAM0_PMS_AREA_2,
MEMPROT_DRAM0_PMS_AREA_3
} pms_area_t;
typedef enum
{
MEMPROT_PMS_WORLD_0 = 0,
MEMPROT_PMS_WORLD_1,
MEMPROT_PMS_WORLD_2,
MEMPROT_PMS_WORLD_INVALID = 0xFFFFFFFF
} pms_world_t;
typedef enum
{
MEMPROT_PMS_OP_READ = 0,
MEMPROT_PMS_OP_WRITE,
MEMPROT_PMS_OP_FETCH,
MEMPROT_PMS_OP_INVALID = 0xFFFFFFFF
} pms_operation_type_t;
/**
* @brief Converts Memory protection type to string
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
const char *esp_memprot_mem_type_to_str(mem_type_prot_t mem_type);
/**
* @brief Converts Split line type to string
*
* @param line_type Split line type (see split_line_t enum)
*/
const char *esp_memprot_split_line_to_str(split_line_t line_type);
/**
* @brief Converts PMS Area type to string
*
* @param area_type PMS Area type (see pms_area_t enum)
*/
const char *esp_memprot_pms_to_str(pms_area_t area_type);
/**
* @brief Returns PMS splitting address for given Split line type
*
* The value is taken from PMS configuration registers (IRam0 range)
* For details on split lines see 'esp_memprot_set_prot_int' function description
*
* @param line_type Split line type (see split_line_t enum)
*
* @return appropriate split line address
*/
uint32_t *esp_memprot_get_split_addr(split_line_t line_type);
/**
* @brief Returns default main IRAM/DRAM splitting address
*
* The address value is given by _iram_text_end global (IRam0 range)
* @return Main I/D split line (IRam0_DRam0_Split_Addr)
*/
void *esp_memprot_get_default_main_split_addr(void);
/**
* @brief Sets a lock for the main IRAM/DRAM splitting address
*
* Locks can be unlocked only by digital system reset
*/
void esp_memprot_set_split_line_lock(void);
/**
* @brief Gets a lock status for the main IRAM/DRAM splitting address
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_split_line_lock(void);
/**
* @brief Sets required split line address
*
* @param line_type Split line type (see split_line_t enum)
* @param line_addr target address from a memory range relevant to given line_type (IRAM/DRAM)
*/
void esp_memprot_set_split_line(split_line_t line_type, const void *line_addr);
/**
* @brief Sets a lock for PMS Area settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS Area settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_pms_lock(mem_type_prot_t mem_type);
/**
* @brief Sets permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
* @param x Execute permission flag
*/
void esp_memprot_iram_set_pms_area(pms_area_t area_type, bool r, bool w, bool x);
/**
* @brief Gets current permissions for given PMS Area in IRam0 memory range (MEMPROT_IRAM0_SRAM)
*
* @param area_type IRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
* @param x Execute permission flag holder
*/
void esp_memprot_iram_get_pms_area(pms_area_t area_type, bool *r, bool *w, bool *x);
/**
* @brief Sets permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag
* @param w Write permission flag
*/
void esp_memprot_dram_set_pms_area(pms_area_t area_type, bool r, bool w);
/**
* @brief Gets current permissions for given PMS Area in DRam0 memory range (MEMPROT_DRAM0_SRAM)
*
* @param area_type DRam0 PMS Area type (see pms_area_t enum)
* @param r Read permission flag holder
* @param w Write permission flag holder
*/
void esp_memprot_dram_get_pms_area(pms_area_t area_type, bool *r, bool *w);
/**
* @brief Sets a lock for PMS interrupt monitor settings of required Memory type
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Gets a lock status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_monitor_lock(mem_type_prot_t mem_type);
/**
* @brief Enable PMS violation interrupt monitoring of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
* @param enable/disable
*/
void esp_memprot_set_monitor_en(mem_type_prot_t mem_type, bool enable);
/**
* @brief Gets enable/disable status for PMS interrupt monitor settings of required Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (enabled/disabled)
*/
bool esp_memprot_get_monitor_en(mem_type_prot_t mem_type);
/**
* @brief Gets CPU ID for currently active PMS violation interrupt
*
* @return CPU ID (CPU_PRO for ESP32H2)
*/
int IRAM_ATTR esp_memprot_intr_get_cpuid(void);
/**
* @brief Clears current interrupt ON flag for given Memory type
*
* Interrupt clearing happens in two steps:
* 1. Interrupt CLR flag is set (to clear the interrupt ON status)
* 2. Interrupt CLR flag is reset (to allow further monitoring)
* This operation is non-atomic by PMS module design
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void IRAM_ATTR esp_memprot_monitor_clear_intr(mem_type_prot_t mem_type);
/**
* @brief Returns active PMS violation interrupt (if any)
*
* This function iterates through supported Memory type status registers
* and returns the first interrupt-on flag. If none is found active,
* MEMPROT_NONE is returned.
* Order of checking (in current version):
* 1. MEMPROT_IRAM0_SRAM
* 2. MEMPROT_DRAM0_SRAM
*
* @return mem_type Memory protection type related to active interrupt found (see mem_type_prot_t enum)
*/
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
/**
* @brief Checks whether any violation interrupt is active
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_locked_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_is_intr_ena_any(void);
/**
* @brief Checks whether any violation interrupt is enabled
*
* @return true/false (yes/no)
*/
bool IRAM_ATTR esp_memprot_get_violate_intr_on(mem_type_prot_t mem_type);
/**
* @brief Returns the address which caused the violation interrupt (if any)
*
* The address is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return faulting address
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_addr(mem_type_prot_t mem_type);
/**
* @brief Returns the World identifier of the code causing the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return World identifier (see pms_world_t enum)
*/
pms_world_t IRAM_ATTR esp_memprot_get_violate_world(mem_type_prot_t mem_type);
/**
* @brief Returns Read or Write operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return PMS operation type relevant to mem_type parameter (se pms_operation_type_t)
*/
pms_operation_type_t IRAM_ATTR esp_memprot_get_violate_wr(mem_type_prot_t mem_type);
/**
* @brief Returns LoadStore flag of the operation type which caused the violation interrupt (if any)
*
* The value (bit) is taken from appropriate PMS violation status register, based given Memory type
* Effective only on IRam0 access
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return true/false (LoadStore bit on/off)
*/
bool IRAM_ATTR esp_memprot_get_violate_loadstore(mem_type_prot_t mem_type);
/**
* @brief Returns byte-enables for the address which caused the violation interrupt (if any)
*
* The value is taken from appropriate PMS violation status register, based given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return byte-enables
*/
uint32_t IRAM_ATTR esp_memprot_get_violate_byte_en(mem_type_prot_t mem_type);
/**
* @brief Returns raw contents of DRam0 status register 1
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_1(void);
/**
* @brief Returns raw contents of DRam0 status register 2
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_dram_status_reg_2(void);
/**
* @brief Returns raw contents of IRam0 status register
*
* @return 32-bit register value
*/
uint32_t IRAM_ATTR esp_memprot_get_iram_status_reg(void);
/**
* @brief Register PMS violation interrupt in global interrupt matrix for given Memory type
*
* Memory protection components uses specific interrupt number, see ETS_MEMPROT_ERR_INUM
* The registration makes the panic-handler routine being called when the interrupt appears
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*/
void esp_memprot_set_intr_matrix(mem_type_prot_t mem_type);
/**
* @brief Convenient routine for setting the PMS defaults
*
* Called on application startup, depending on CONFIG_ESP_SYSTEM_MEMPROT_FEATURE Kconfig settings
* For implementation details see 'esp_memprot_set_prot_int' description
*
* @param invoke_panic_handler register all interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (see 'esp_memprot_set_prot_int')
*/
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
/**
* @brief Internal routine for setting the PMS defaults
*
* Called on application startup from within 'esp_memprot_set_prot'. Allows setting a specific splitting address
* (main I/D split line) - see the parameter 'split_addr'. If the 'split_addr' equals to NULL, default I/D split line
* is used (&_iram_text_end) and all the remaining lines share the same address.
* The function sets all the split lines and PMS areas to the same space,
* ie there is a single instruction space and single data space at the end.
* The PMS split lines and permission areas scheme described below:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* ... | IRam0_PMS_0 |
* DRam0_PMS_0 ----------------------------------------------- IRam0_line1_Split_addr
* ... | IRam0_PMS_1 |
* ... ----------------------------------------------- IRam0_line0_Split_addr
* | IRam0_PMS_2 |
* =============================================== IRam0_DRam0_Split_addr (main I/D)
* | DRam0_PMS_1 |
* DRam0_DMA_line0_Split_addr ----------------------------------------------- ...
* | DRam0_PMS_2 | ...
* DRam0_DMA_line1_Split_addr ----------------------------------------------- IRam0_PMS_3
* | DRam0_PMS_3 | ...
* -----------------------------------------------
*
* Default settings provided by 'esp_memprot_set_prot_int' are as follows:
*
* DRam0/DMA IRam0
* -----------------------------------------------
* | IRam0_PMS_0 = IRam0_PMS_1 = IRam0_PMS_2 |
* | DRam0_PMS_0 | IRam0_line1_Split_addr
* DRam0_DMA_line0_Split_addr | | =
* = =============================================== IRam0_line0_Split_addr
* DRam0_DMA_line1_Split_addr | | =
* | DRam0_PMS_1 = DRam0_PMS_2 = DRam0_PMS_3 | IRam0_DRam0_Split_addr (main I/D)
* | IRam0_PMS_3 |
* -----------------------------------------------
*
* Once the memprot feature is locked, it can be unlocked only by digital system reset
*
* @param invoke_panic_handler register all the violation interrupts for panic handling (true/false)
* @param lock_feature lock the defaults to prevent further PMS settings changes (true/false)
* @param split_addr specific main I/D adrees or NULL to use default ($_iram_text_end)
* @param mem_type_mask 32-bit field of specific PMS parts to configure (members of mem_type_prot_t)
*/
void esp_memprot_set_prot_int(bool invoke_panic_handler, bool lock_feature, void *split_addr, uint32_t *mem_type_mask);
/**
* @brief Returns raw contents of PMS interrupt monitor register for given Memory type
*
* @param mem_type Memory protection type (see mem_type_prot_t enum)
*
* @return 32-bit register value
*/
uint32_t esp_memprot_get_monitor_enable_reg(mem_type_prot_t mem_type);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,40 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp32h2/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,42 @@
// Copyright 2010-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read a sequence of DPORT registers to the buffer.
*
* @param[out] buff_out Contains the read data.
* @param[in] address Initial address for reading registers.
* @param[in] num_words The number of words.
*/
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,51 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* This API should be used by all components which use the SHA, AES, HMAC and DS crypto hardware on the ESP32S2.
* They can not be used in parallel because they use the same DMA or are calling each other.
* E.g., HMAC uses SHA or DS uses HMAC and AES. See the ESP32S2 Technical Reference Manual for more details.
*
* Other unrelated components must not use it.
*/
/**
* Acquire lock for the AES and SHA cryptography peripherals, which both use the crypto DMA.
*/
void esp_crypto_dma_lock_acquire(void);
/**
* Release lock for the AES and SHA cryptography peripherals, which both use the crypto DMA.
*/
void esp_crypto_dma_lock_release(void);
/**
* Acquire lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* Release lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,198 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include "esp_hmac.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL ESP_ERR_HW_CRYPTO_BASE + 0x1 /*!< HMAC peripheral problem */
#define ESP_ERR_HW_CRYPTO_DS_INVALID_KEY ESP_ERR_HW_CRYPTO_BASE + 0x2 /*!< given HMAC key isn't correct,
HMAC peripheral problem */
#define ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST ESP_ERR_HW_CRYPTO_BASE + 0x4 /*!< message digest check failed,
result is invalid */
#define ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING ESP_ERR_HW_CRYPTO_BASE + 0x5 /*!< padding check failed, but result
is produced anyway and can be read*/
#define ESP_DS_IV_LEN 16
/* Length of parameter 'C' stored in flash */
#define ESP_DS_C_LEN (12672 / 8)
typedef struct esp_ds_context esp_ds_context_t;
typedef enum {
ESP_DS_RSA_1024 = (1024 / 32) - 1,
ESP_DS_RSA_2048 = (2048 / 32) - 1,
ESP_DS_RSA_3072 = (3072 / 32) - 1,
ESP_DS_RSA_4096 = (4096 / 32) - 1
} esp_digital_signature_length_t;
/**
* Encrypted private key data. Recommended to store in flash in this format.
*
* @note This struct has to match to one from the ROM code! This documentation is mostly taken from there.
*/
typedef struct esp_digital_signature_data {
/**
* RSA LENGTH register parameters
* (number of words in RSA key & operands, minus one).
*
* Max value 127 (for RSA 4096).
*
* This value must match the length field encrypted and stored in 'c',
* or invalid results will be returned. (The DS peripheral will
* always use the value in 'c', not this value, so an attacker can't
* alter the DS peripheral results this way, it will just truncate or
* extend the message and the resulting signature in software.)
*
* @note In IDF, the enum type length is the same as of type unsigned, so they can be used interchangably.
* See the ROM code for the original declaration of struct \c ets_ds_data_t.
*/
esp_digital_signature_length_t rsa_length;
/**
* IV value used to encrypt 'c'
*/
uint8_t iv[ESP_DS_IV_LEN];
/**
* Encrypted Digital Signature parameters. Result of AES-CBC encryption
* of plaintext values. Includes an encrypted message digest.
*/
uint8_t c[ESP_DS_C_LEN];
} esp_ds_data_t;
/** Plaintext parameters used by Digital Signature.
*
* Not used for signing with DS peripheral, but can be encrypted
* in-device by calling esp_ds_encrypt_params()
*
* @note This documentation is mostly taken from the ROM code.
*/
typedef struct {
uint32_t Y[4096/32]; //!< RSA exponent
uint32_t M[4096/32]; //!< RSA modulus
uint32_t Rb[4096/32]; //!< RSA r inverse operand
uint32_t M_prime; //!< RSA M prime operand
esp_digital_signature_length_t length; //!< RSA length
} esp_ds_p_data_t;
/**
* Sign the message.
*
* This function is a wrapper around \c esp_ds_finish_sign() and \c esp_ds_start_sign(), so do not use them
* in parallel.
* It blocks until the signing is finished and then returns the signature.
*
* @note This function locks the HMAC, SHA, AES and RSA components during its entire execution time.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
*
* @return
* - ESP_OK if successful, the signature was written to the parameter \c signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches.
*/
esp_err_t esp_ds_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
void *signature);
/**
* Start the signing process.
*
* This function yields a context object which needs to be passed to \c esp_ds_finish_sign() to finish the signing
* process.
*
* @note This function locks the HMAC, SHA, AES and RSA components, so the user has to ensure to call
* \c esp_ds_finish_sign() in a timely manner.
*
* @param message the message to be signed; its length is determined by data->rsa_length
* @param data the encrypted signing key data (AES encrypted RSA key + IV)
* @param key_id the HMAC key ID determining the HMAC key of the HMAC which will be used to decrypt the
* signing key data
* @param esp_ds_ctx the context object which is needed for finishing the signing process later
*
* @return
* - ESP_OK if successful, the ds operation was started now and has to be finished with \c esp_ds_finish_sign()
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or data->rsa_length is too long or 0
* - ESP_ERR_HW_CRYPTO_DS_HMAC_FAIL if there was an HMAC failure during retrieval of the decryption key
* - ESP_ERR_NO_MEM if there hasn't been enough memory to allocate the context object
* - ESP_ERR_HW_CRYPTO_DS_INVALID_KEY if there's a problem with passing the HMAC key to the DS component
*/
esp_err_t esp_ds_start_sign(const void *message,
const esp_ds_data_t *data,
hmac_key_id_t key_id,
esp_ds_context_t **esp_ds_ctx);
/**
* Return true if the DS peripheral is busy, otherwise false.
*
* @note Only valid if \c esp_ds_start_sign() was called before.
*/
bool esp_ds_is_busy(void);
/**
* Finish the signing process.
*
* @param signature the destination of the signature, should be (data->rsa_length + 1)*4 bytes long
* @param esp_ds_ctx the context object retreived by \c esp_ds_start_sign()
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL
* - ESP_ERR_HW_CRYPTO_DS_INVALID_DIGEST if the message digest didn't match; the signature is invalid.
* - ESP_ERR_HW_CRYPTO_DS_INVALID_PADDING if the message padding is incorrect, the signature can be read though
* since the message digest matches.
*/
esp_err_t esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx);
/**
* Encrypt the private key parameters.
*
* @param data Output buffer to store encrypted data, suitable for later use generating signatures.
* The allocated memory must be in internal memory and word aligned since it's filled by DMA. Both is asserted
* at run time.
* @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time.
* @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process
* is done and 'data' is stored.
* @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the
* corresponding HMAC key will be stored to efuse and then permanently erased.
*
* @return
* - ESP_OK if successful, the ds operation has been finished and the result is written to signature.
* - ESP_ERR_INVALID_ARG if one of the parameters is NULL or p_data->rsa_length is too long
*/
esp_err_t esp_ds_encrypt_params(esp_ds_data_t *data,
const void *iv,
const esp_ds_p_data_t *p_data,
const void *key);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,99 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_HMAC_H_
#define _ESP_HMAC_H_
#include "esp_err.h"
#include "stdbool.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The possible efuse keys for the HMAC peripheral
*/
typedef enum {
HMAC_KEY0 = 0,
HMAC_KEY1,
HMAC_KEY2,
HMAC_KEY3,
HMAC_KEY4,
HMAC_KEY5,
HMAC_KEY_MAX
} hmac_key_id_t;
/**
* @brief
* Calculate the HMAC of a given message.
*
* Calculate the HMAC \c hmac of a given message \c message with length \c message_len.
* SHA256 is used for the calculation (fixed on ESP32S2).
*
* @note Uses the HMAC peripheral in "upstream" mode.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calcuation.
* The corresponding purpose field of the key block in the efuse must be set to the HMAC upstream purpose value.
* @param message the message for which to calculate the HMAC
* @param message_len message length
* return ESP_ERR_INVALID_STATE if unsuccessful
* @param [out] hmac the hmac result; the buffer behind the provided pointer must be 32 bytes long
*
* @return
* * ESP_OK, if the calculation was successful,
* * ESP_FAIL, if the hmac calculation failed
*/
esp_err_t esp_hmac_calculate(hmac_key_id_t key_id,
const void *message,
size_t message_len,
uint8_t *hmac);
/**
* @brief
* Use HMAC peripheral in Downstream mode to re-enable the JTAG, if it is not permanently disable by HW.
* In downstream mode HMAC calculations perfomred by peripheral used internally and not provided back to user.
*
* @param key_id Determines which of the 6 key blocks in the efuses should be used for the HMAC calculation.
* The corresponding purpose field of the key block in the efuse must be set to HMAC downstream purpose.
*
* @param token Pre calculated HMAC value of the 32-byte 0x00 using SHA-256 and the known private HMAC key. The key is already
* programmed to a eFuse key block. The key block number is provided as the first parameter to this function.
*
* @return
* * ESP_OK, if the calculation was successful,
* if the calculated HMAC value matches with provided token,
* JTAG will be re-enable otherwise JTAG will remain disabled.
* Return value does not indicate the JTAG status.
* * ESP_FAIL, if the hmac calculation failed or JTAG is permanently disabled by EFUSE_HARD_DIS_JTAG eFuse parameter.
* * ESP_ERR_INVALID_ARG, invalid input arguments
*/
esp_err_t esp_hmac_jtag_enable(hmac_key_id_t key_id,
const uint8_t *token);
/**
* @brief
* Disable the JTAG which might be enable using the HMAC downstream mode. This function just clear the result generated by
* JTAG key by calling esp_hmac_jtag_enable() API.
*
* @return
* * ESP_OK return ESP_OK after writing the HMAC_SET_INVALIDATE_JTAG_REG with value 1.
*/
esp_err_t esp_hmac_jtag_disable(void);
#ifdef __cplusplus
}
#endif
#endif // _ESP_HMAC_H_

View File

@ -0,0 +1,518 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
/* INTERNAL API
* generic interface to MMU memory protection features
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
//convenient constants for better code readabilty
#define RD_ENA true
#define RD_DIS false
#define WR_ENA true
#define WR_DIS false
#define EX_ENA true
#define EX_DIS false
#define RD_LOW_ENA true
#define RD_LOW_DIS false
#define WR_LOW_ENA true
#define WR_LOW_DIS false
#define EX_LOW_ENA true
#define EX_LOW_DIS false
#define RD_HIGH_ENA true
#define RD_HIGH_DIS false
#define WR_HIGH_ENA true
#define WR_HIGH_DIS false
#define EX_HIGH_ENA true
#define EX_HIGH_DIS false
#define PANIC_HNDL_ON true
#define PANIC_HNDL_OFF false
#define MEMPROT_LOCK true
#define MEMPROT_UNLOCK false
#define DEF_SPLIT_LINE NULL
//memory range types
typedef enum {
MEMPROT_NONE = 0x00000000,
MEMPROT_IRAM0_SRAM = 0x00000001, //0x40020000-0x4006FFFF, RWX
MEMPROT_DRAM0_SRAM = 0x00000002, //0x3FFB0000-0x3FFFFFFF, RW
MEMPROT_IRAM0_RTCFAST = 0x00000004, //0x40070000-0x40071FFF, RWX
MEMPROT_DRAM0_RTCFAST = 0x00000008, //0x3FF9E000-0x3FF9FFFF, RW
MEMPROT_PERI1_RTCSLOW = 0x00000010, //0x3F421000-0x3F423000, RW
MEMPROT_PERI2_RTCSLOW_0 = 0x00000020, //0x50001000-0x50003000, RWX
MEMPROT_PERI2_RTCSLOW_1 = 0x00000040, //0x60002000-0x60004000, RWX
MEMPROT_ALL = 0xFFFFFFFF
} mem_type_prot_t;
/**
* @brief Returns splitting address for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Splitting address for the memory region required.
* The address is given by region-specific global symbol exported from linker script,
* it is not read out from related configuration register.
*/
uint32_t *IRAM_ATTR esp_memprot_get_split_addr(mem_type_prot_t mem_type);
/**
* @brief Initializes illegal memory access control (MMU) for required memory section.
*
* All memory access interrupts share ETS_MEMACCESS_ERR_INUM input channel, it is caller's
* responsibility to properly detect actual intr. source as well as possible prioritization in case
* of multiple source reported during one intr.handling routine run
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_intr_init(mem_type_prot_t mem_type);
/**
* @brief Enable/disable the memory protection interrupt
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param enable enable/disable
*/
void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable);
/**
* @brief Sets a request for clearing interrupt-on flag for specified memory region (register write)
*
* @note When called without actual interrupt-on flag set, subsequent occurrence of related interrupt is ignored.
* Should be used only after the real interrupt appears, typically as the last step in interrupt handler's routine.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_clear_intr(mem_type_prot_t mem_type);
/**
* @brief Detects which memory protection interrupt is active
*
* @note Check order
* MEMPROT_IRAM0_SRAM
* MEMPROT_IRAM0_RTCFAST
* MEMPROT_DRAM0_SRAM
* MEMPROT_DRAM0_RTCFAST
*
* @return Memory protection area type (see mem_type_prot_t enum)
*/
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
/**
* @brief Gets interrupt status register contents for specified memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Contents of status register
*/
uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type);
/**
* @brief Get details of given interrupt status
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param faulting_address Faulting address causing the interrupt [out]
* @param op_type Operation being processed at the faulting address [out]
* IRAM0: 0 - read, 1 - write
* DRAM0: 0 - read, 1 - write
* @param op_subtype Additional info for op_type [out]
* IRAM0: 0 - instruction segment access, 1 - data segment access
* DRAM0: 0 - non-atomic operation, 1 - atomic operation
*/
void IRAM_ATTR esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype);
/**
* @brief Gets string representation of required memory region identifier
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return mem_type as string
*/
const char *IRAM_ATTR esp_memprot_type_to_str(mem_type_prot_t mem_type);
/**
* @brief Detects whether any of the interrupt locks is active (requires digital system reset to unlock)
*
* @return true/false
*/
bool esp_memprot_is_locked_any(void);
/**
* @brief Sets lock for specified memory region.
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_set_lock(mem_type_prot_t mem_type);
/**
* @brief Gets lock status for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_lock(mem_type_prot_t mem_type);
/**
* @brief Gets permission control configuration register contents for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission control register contents
*/
uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt permission settings for unified management block
*
* Gets interrupt permission settings register contents for required memory region, returns settings for unified management blocks
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission settings register contents
*/
uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt permission settings for split management block
*
* Gets interrupt permission settings register contents for required memory region, returns settings for split management blocks
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission settings register contents
*/
uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type);
/**
* @brief Detects whether any of the memory protection interrupts is enabled
*
* @return true/false
*/
bool esp_memprot_is_intr_ena_any(void);
/**
* @brief Gets interrupt-enabled flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-enabled value
*/
uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt-active flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-active value
*/
uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt-clear request flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-clear request value
*/
uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type);
/**
* @brief Gets read permission value for specified block and memory region
*
* Returns read permission bit value for required unified-management block (0-3) in given memory region.
* Applicable to all memory types.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Read permission value for required block
*/
uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Gets write permission value for specified block and memory region
*
* Returns write permission bit value for required unified-management block (0-3) in given memory region.
* Applicable to all memory types.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Write permission value for required block
*/
uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Gets execute permission value for specified block and memory region
*
* Returns execute permission bit value for required unified-management block (0-3) in given memory region.
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Execute permission value for required block
*/
uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Sets permissions for specified block in DRAM region
*
* Sets Read and Write permission for specified unified-management block (0-3) in given memory region.
* Applicable only to DRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
* @param write_perm Write permission flag
* @param read_perm Read permission flag
*/
void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm);
/**
* @brief Sets permissions for high and low memory segment in DRAM region
*
* Sets Read and Write permission for both low and high memory segments given by splitting address.
* The splitting address must be equal to or higher then beginning of block 5
* Applicable only to DRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
/**
* @brief Sets permissions for specified block in IRAM region
*
* Sets Read, Write and Execute permission for specified unified-management block (0-3) in given memory region.
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
* @param write_perm Write permission flag
* @param exec_perm Execute permission flag
*/
void esp_memprot_set_uni_block_perm_iram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm, bool exec_perm);
/**
* @brief Sets permissions for high and low memory segment in IRAM region
*
* Sets Read, Write and Execute permission for both low and high memory segments given by splitting address.
* The splitting address must be equal to or higher then beginning of block 5
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_set_prot_iram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
/**
* @brief Activates memory protection for all supported memory region types
*
* @note The feature is disabled when JTAG interface is connected
*
* @param invoke_panic_handler map mem.prot interrupt to ETS_MEMACCESS_ERR_INUM and thus invokes panic handler when fired ('true' not suitable for testing)
* @param lock_feature sets LOCK bit, see esp_memprot_set_lock() ('true' not suitable for testing)
* @param mem_type_mask holds a set of required memory protection types (bitmask built of mem_type_prot_t). NULL means default (MEMPROT_ALL in this version)
*/
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
/**
* @brief Get permission settings bits for IRAM0 split mgmt. Only IRAM0 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_perm_split_bits_iram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Get permission settings bits for DRAM0 split mgmt. Only DRAM0 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
/**
* @brief Sets permissions for high and low memory segment in PERIBUS1 region
*
* Sets Read and Write permission for both low and high memory segments given by splitting address.
* Applicable only to PERIBUS1 memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
/**
* @brief Get permission settings bits for PERIBUS1 split mgmt. Only PERIBUS1 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
/**
* @brief Get permission settings bits for PERIBUS2 split mgmt. Only PERIBUS2 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_perm_split_bits_peri2(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Sets permissions for high and low memory segment in PERIBUS2 region
*
* Sets Read Write permission for both low and high memory segments given by splitting address.
* Applicable only to PERIBUS2 memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
/**
* @brief Get permissions for specified memory type. Irrelevant bits are ignored
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Get Read permission settings for low and high regions of given memory type
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Read permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr);
/**
* @brief Get Write permission settings for low and high regions of given memory type
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Write permission flag
* @param hr High segment Write permission flag
*/
void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw);
/**
* @brief Get Execute permission settings for low and high regions of given memory type
* Applicable only to IBUS-compatible memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Exec permission flag
* @param hr High segment Exec permission flag
*/
void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx);
/**
* @brief Returns the lowest address in required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type);
/**
* @brief Returns the highest address in required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type);
/**
* @brief Sets READ permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Read permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr);
/**
* @brief Sets WRITE permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Write permission flag
* @param hr High segment Write permission flag
*/
void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw);
/**
* @brief Sets EXECUTE permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Exec permission flag
* @param hr High segment Exec permission flag
*/
void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,39 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp32s2/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,146 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 __ESP_SPIRAM_H
#define __ESP_SPIRAM_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
*
* @return ESP_OK on success
*/
esp_err_t esp_spiram_init(void);
/**
* @brief Configure Cache/MMU for access to external SPI RAM.
*
* Normally this function is called from cpu_start, if CONFIG_SPIRAM_BOOT_INIT
* option is enabled. Applications which need to enable SPI RAM at run time
* can disable CONFIG_SPIRAM_BOOT_INIT, and call this function later.
*
* @attention this function must be called with flash cache disabled.
*/
void esp_spiram_init_cache(void);
/**
* @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
* (in case of a dual-core system) the app CPU is online. This test overwrites the
* memory with crap, so do not call after e.g. the heap allocator has stored important
* stuff in SPI RAM.
*
* @return true on success, false on failed memory test
*/
bool esp_spiram_test(void);
/**
* @brief Add the initialized SPI RAM to the heap allocator.
*/
esp_err_t esp_spiram_add_to_heapalloc(void);
/**
* @brief Get the size of the attached SPI RAM chip selected in menuconfig
*
* @return Size in bytes, or 0 if no external RAM chip support compiled in.
*/
size_t esp_spiram_get_size(void);
/**
* @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
* cache is disabled, because disabling cache on the ESP32 discards the data in the SPI
* RAM cache.
*
* This is meant for use from within the SPI flash code.
*/
void esp_spiram_writeback_cache(void);
/**
* @brief Reserve a pool of internal memory for specific DMA/internal allocations
*
* @param size Size of reserved pool in bytes
*
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM when no memory available for pool
*/
esp_err_t esp_spiram_reserve_dma_pool(size_t size);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start, _instruction_reserved_end;
/**
* @brief Get the start page number of the instruction in SPI flash
*
* @return start page number
*/
uint32_t instruction_flash_start_page_get(void);
/**
* @brief Get the end page number of the instruction in SPI flash
*
* @return end page number
*/
uint32_t instruction_flash_end_page_get(void);
/**
* @brief Get the offset of instruction from SPI flash to SPI RAM
*
* @return instruction offset
*/
int instruction_flash2spiram_offset(void);
#endif
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start, _rodata_reserved_end;
/**
* @brief Get the start page number of the rodata in SPI flash
*
* @return start page number
*/
uint32_t rodata_flash_start_page_get(void);
/**
* @brief Get the end page number of the rodata in SPI flash
*
* @return end page number
*/
uint32_t rodata_flash_end_page_get(void);
/**
* @brief Get the offset number of rodata from SPI flash to SPI RAM
*
* @return rodata offset
*/
int rodata_flash2spiram_offset(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,42 @@
// Copyright 2010-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 _ESP_DPORT_ACCESS_H_
#define _ESP_DPORT_ACCESS_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Read a sequence of DPORT registers to the buffer.
*
* @param[out] buff_out Contains the read data.
* @param[in] address Initial address for reading registers.
* @param[in] num_words The number of words.
*/
void esp_dport_access_read_buffer(uint32_t *buff_out, uint32_t address, uint32_t num_words);
#define DPORT_STALL_OTHER_CPU_START()
#define DPORT_STALL_OTHER_CPU_END()
#define DPORT_INTERRUPT_DISABLE()
#define DPORT_INTERRUPT_RESTORE()
#ifdef __cplusplus
}
#endif
#endif /* _ESP_DPORT_ACCESS_H_ */

View File

@ -0,0 +1,53 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* This API should be used by all components which use the SHA, AES, HMAC and DS crypto hardware on the ESP32S3.
* Not all of them can be used in parallel because they use the same underlying module.
* E.g., HMAC uses SHA or DS uses HMAC and AES. See the ESP32S3 Technical Reference Manual for more details.
*
* Other unrelated components must not use it.
*/
/**
* @brief Acquire lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_acquire(void);
/**
* @brief Release lock for the SHA and AES cryptography peripheral.
*
*/
void esp_crypto_sha_aes_lock_release(void);
/**
* Acquire lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_acquire(void);
/**
* Release lock for the MPI/RSA cryptography peripheral
*/
void esp_crypto_mpi_lock_release(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,492 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
/* INTERNAL API
* generic interface to MMU memory protection features
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
MEMPROT_NONE = 0x00000000,
MEMPROT_IRAM0_SRAM = 0x00000001,
MEMPROT_DRAM0_SRAM = 0x00000002,
MEMPROT_IRAM0_RTCFAST = 0x00000004,
MEMPROT_DRAM0_RTCFAST = 0x00000008,
MEMPROT_PERI1_RTCSLOW = 0x00000010,
MEMPROT_PERI2_RTCSLOW_0 = 0x00000020,
MEMPROT_PERI2_RTCSLOW_1 = 0x00000040,
MEMPROT_ALL = 0xFFFFFFFF
} mem_type_prot_t;
/**
* @brief Returns splitting address for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Splitting address for the memory region required.
* The address is given by region-specific global symbol exported from linker script,
* it is not read out from related configuration register.
*/
uint32_t *IRAM_ATTR esp_memprot_get_split_addr(mem_type_prot_t mem_type);
/**
* @brief Initializes illegal memory access control (MMU) for required memory section.
*
* All memory access interrupts share ETS_MEMACCESS_ERR_INUM input channel, it is caller's
* responsibility to properly detect actual intr. source as well as possible prioritization in case
* of multiple source reported during one intr.handling routine run
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_intr_init(mem_type_prot_t mem_type);
/**
* @brief Enable/disable the memory protection interrupt
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param enable enable/disable
*/
void esp_memprot_intr_ena(mem_type_prot_t mem_type, bool enable);
/**
* @brief Sets a request for clearing interrupt-on flag for specified memory region (register write)
*
* @note When called without actual interrupt-on flag set, subsequent occurrence of related interrupt is ignored.
* Should be used only after the real interrupt appears, typically as the last step in interrupt handler's routine.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_clear_intr(mem_type_prot_t mem_type);
/**
* @brief Detects which memory protection interrupt is active
*
* @note Check order
* MEMPROT_IRAM0_SRAM
* MEMPROT_IRAM0_RTCFAST
* MEMPROT_DRAM0_SRAM
* MEMPROT_DRAM0_RTCFAST
*
* @return Memory protection area type (see mem_type_prot_t enum)
*/
mem_type_prot_t IRAM_ATTR esp_memprot_get_active_intr_memtype(void);
/**
* @brief Gets interrupt status register contents for specified memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Contents of status register
*/
uint32_t esp_memprot_get_fault_reg(mem_type_prot_t mem_type);
/**
* @brief Get details of given interrupt status
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param faulting_address Faulting address causing the interrupt [out]
* @param op_type Operation being processed at the faulting address [out]
* IRAM0: 0 - read, 1 - write
* DRAM0: 0 - read, 1 - write
* @param op_subtype Additional info for op_type [out]
* IRAM0: 0 - instruction segment access, 1 - data segment access
* DRAM0: 0 - non-atomic operation, 1 - atomic operation
*/
void IRAM_ATTR esp_memprot_get_fault_status(mem_type_prot_t mem_type, uint32_t **faulting_address, uint32_t *op_type, uint32_t *op_subtype);
/**
* @brief Gets string representation of required memory region identifier
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return mem_type as string
*/
const char *IRAM_ATTR esp_memprot_type_to_str(mem_type_prot_t mem_type);
/**
* @brief Detects whether any of the interrupt locks is active (requires digital system reset to unlock)
*
* @return true/false
*/
bool esp_memprot_is_locked_any(void);
/**
* @brief Sets lock for specified memory region.
*
* Locks can be unlocked only by digital system reset
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
void esp_memprot_set_lock(mem_type_prot_t mem_type);
/**
* @brief Gets lock status for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return true/false (locked/unlocked)
*/
bool esp_memprot_get_lock(mem_type_prot_t mem_type);
/**
* @brief Gets permission control configuration register contents for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission control register contents
*/
uint32_t esp_memprot_get_conf_reg(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt permission settings for unified management block
*
* Gets interrupt permission settings register contents for required memory region, returns settings for unified management blocks
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission settings register contents
*/
uint32_t esp_memprot_get_perm_uni_reg(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt permission settings for split management block
*
* Gets interrupt permission settings register contents for required memory region, returns settings for split management blocks
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Permission settings register contents
*/
uint32_t esp_memprot_get_perm_split_reg(mem_type_prot_t mem_type);
/**
* @brief Detects whether any of the memory protection interrupts is enabled
*
* @return true/false
*/
bool esp_memprot_is_intr_ena_any(void);
/**
* @brief Gets interrupt-enabled flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-enabled value
*/
uint32_t esp_memprot_get_intr_ena_bit(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt-active flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-active value
*/
uint32_t esp_memprot_get_intr_on_bit(mem_type_prot_t mem_type);
/**
* @brief Gets interrupt-clear request flag for given memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*
* @return Interrupt-clear request value
*/
uint32_t esp_memprot_get_intr_clr_bit(mem_type_prot_t mem_type);
/**
* @brief Gets read permission value for specified block and memory region
*
* Returns read permission bit value for required unified-management block (0-3) in given memory region.
* Applicable to all memory types.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Read permission value for required block
*/
uint32_t esp_memprot_get_uni_block_read_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Gets write permission value for specified block and memory region
*
* Returns write permission bit value for required unified-management block (0-3) in given memory region.
* Applicable to all memory types.
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Write permission value for required block
*/
uint32_t esp_memprot_get_uni_block_write_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Gets execute permission value for specified block and memory region
*
* Returns execute permission bit value for required unified-management block (0-3) in given memory region.
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
*
* @return Execute permission value for required block
*/
uint32_t esp_memprot_get_uni_block_exec_bit(mem_type_prot_t mem_type, uint32_t block);
/**
* @brief Sets permissions for specified block in DRAM region
*
* Sets Read and Write permission for specified unified-management block (0-3) in given memory region.
* Applicable only to DRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
* @param write_perm Write permission flag
* @param read_perm Read permission flag
*/
void esp_memprot_set_uni_block_perm_dram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm);
/**
* @brief Sets permissions for high and low memory segment in DRAM region
*
* Sets Read and Write permission for both low and high memory segments given by splitting address.
* The splitting address must be equal to or higher then beginning of block 5
* Applicable only to DRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_prot_dram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
/**
* @brief Sets permissions for specified block in IRAM region
*
* Sets Read, Write and Execute permission for specified unified-management block (0-3) in given memory region.
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param block Memory block identifier (0-3)
* @param write_perm Write permission flag
* @param exec_perm Execute permission flag
*/
void esp_memprot_set_uni_block_perm_iram(mem_type_prot_t mem_type, uint32_t block, bool write_perm, bool read_perm, bool exec_perm);
/**
* @brief Sets permissions for high and low memory segment in IRAM region
*
* Sets Read, Write and Execute permission for both low and high memory segments given by splitting address.
* The splitting address must be equal to or higher then beginning of block 5
* Applicable only to IRAM memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_set_prot_iram(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
/**
* @brief Activates memory protection for all supported memory region types
*
* @note The feature is disabled when JTAG interface is connected
*
* @param invoke_panic_handler map mem.prot interrupt to ETS_MEMACCESS_ERR_INUM and thus invokes panic handler when fired ('true' not suitable for testing)
* @param lock_feature sets LOCK bit, see esp_memprot_set_lock() ('true' not suitable for testing)
* @param mem_type_mask holds a set of required memory protection types (bitmask built of mem_type_prot_t). NULL means default (MEMPROT_ALL in this version)
*/
void esp_memprot_set_prot(bool invoke_panic_handler, bool lock_feature, uint32_t *mem_type_mask);
/**
* @brief Get permission settings bits for IRAM0 split mgmt. Only IRAM0 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_perm_split_bits_iram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Get permission settings bits for DRAM0 split mgmt. Only DRAM0 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_split_bits_dram(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
/**
* @brief Sets permissions for high and low memory segment in PERIBUS1 region
*
* Sets Read and Write permission for both low and high memory segments given by splitting address.
* Applicable only to PERIBUS1 memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_prot_peri1(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool hw, bool hr);
/**
* @brief Get permission settings bits for PERIBUS1 split mgmt. Only PERIBUS1 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_split_bits_peri1(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *hw, bool *hr);
/**
* @brief Get permission settings bits for PERIBUS2 split mgmt. Only PERIBUS2 memory types allowed
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_perm_split_bits_peri2(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Sets permissions for high and low memory segment in PERIBUS2 region
*
* Sets Read Write permission for both low and high memory segments given by splitting address.
* Applicable only to PERIBUS2 memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param split_addr Address to split the memory region to lower and higher segment
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_set_prot_peri2(mem_type_prot_t mem_type, uint32_t *split_addr, bool lw, bool lr, bool lx, bool hw, bool hr, bool hx);
/**
* @brief Get permissions for specified memory type. Irrelevant bits are ignored
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lw Low segment Write permission flag
* @param lr Low segment Read permission flag
* @param lx Low segment Execute permission flag
* @param hw High segment Write permission flag
* @param hr High segment Read permission flag
* @param hx High segment Execute permission flag
*/
void esp_memprot_get_permissions(mem_type_prot_t mem_type, bool *lw, bool *lr, bool *lx, bool *hw, bool *hr, bool *hx);
/**
* @brief Get Read permission settings for low and high regions of given memory type
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Read permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_get_perm_read(mem_type_prot_t mem_type, bool *lr, bool *hr);
/**
* @brief Get Write permission settings for low and high regions of given memory type
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Write permission flag
* @param hr High segment Write permission flag
*/
void esp_memprot_get_perm_write(mem_type_prot_t mem_type, bool *lw, bool *hw);
/**
* @brief Get Execute permission settings for low and high regions of given memory type
* Applicable only to IBUS-compatible memory types
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Exec permission flag
* @param hr High segment Exec permission flag
*/
void esp_memprot_get_perm_exec(mem_type_prot_t mem_type, bool *lx, bool *hx);
/**
* @brief Returns the lowest address in required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
uint32_t esp_memprot_get_low_limit(mem_type_prot_t mem_type);
/**
* @brief Returns the highest address in required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
*/
uint32_t esp_memprot_get_high_limit(mem_type_prot_t mem_type);
/**
* @brief Sets READ permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Read permission flag
* @param hr High segment Read permission flag
*/
void esp_memprot_set_read_perm(mem_type_prot_t mem_type, bool lr, bool hr);
/**
* @brief Sets WRITE permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Write permission flag
* @param hr High segment Write permission flag
*/
void esp_memprot_set_write_perm(mem_type_prot_t mem_type, bool lw, bool hw);
/**
* @brief Sets EXECUTE permission bit for required memory region
*
* @param mem_type Memory protection area type (see mem_type_prot_t enum)
* @param lr Low segment Exec permission flag
* @param hr High segment Exec permission flag
*/
void esp_memprot_set_exec_perm(mem_type_prot_t mem_type, bool lx, bool hx);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,39 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file esp32s2/rtc.h
*
* This file contains declarations of rtc related functions.
*/
/**
* @brief Get current value of RTC counter in microseconds
*
* Note: this function may take up to 1 RTC_SLOW_CLK cycle to execute
*
* @return current value of RTC counter in microseconds
*/
uint64_t esp_rtc_get_time_us(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,146 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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 __ESP_SPIRAM_H
#define __ESP_SPIRAM_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize spiram interface/hardware. Normally called from cpu_start.c.
*
* @return ESP_OK on success
*/
esp_err_t esp_spiram_init(void);
/**
* @brief Configure Cache/MMU for access to external SPI RAM.
*
* Normally this function is called from cpu_start, if CONFIG_SPIRAM_BOOT_INIT
* option is enabled. Applications which need to enable SPI RAM at run time
* can disable CONFIG_SPIRAM_BOOT_INIT, and call this function later.
*
* @attention this function must be called with flash cache disabled.
*/
void esp_spiram_init_cache(void);
/**
* @brief Memory test for SPI RAM. Should be called after SPI RAM is initialized and
* (in case of a dual-core system) the app CPU is online. This test overwrites the
* memory with crap, so do not call after e.g. the heap allocator has stored important
* stuff in SPI RAM.
*
* @return true on success, false on failed memory test
*/
bool esp_spiram_test(void);
/**
* @brief Add the initialized SPI RAM to the heap allocator.
*/
esp_err_t esp_spiram_add_to_heapalloc(void);
/**
* @brief Get the size of the attached SPI RAM chip selected in menuconfig
*
* @return Size in bytes, or 0 if no external RAM chip support compiled in.
*/
size_t esp_spiram_get_size(void);
/**
* @brief Force a writeback of the data in the SPI RAM cache. This is to be called whenever
* cache is disabled, because disabling cache on the ESP32 discards the data in the SPI
* RAM cache.
*
* This is meant for use from within the SPI flash code.
*/
void esp_spiram_writeback_cache(void);
/**
* @brief Reserve a pool of internal memory for specific DMA/internal allocations
*
* @param size Size of reserved pool in bytes
*
* @return
* - ESP_OK on success
* - ESP_ERR_NO_MEM when no memory available for pool
*/
esp_err_t esp_spiram_reserve_dma_pool(size_t size);
#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS
extern int _instruction_reserved_start, _instruction_reserved_end;
/**
* @brief Get the start page number of the instruction in SPI flash
*
* @return start page number
*/
uint32_t instruction_flash_start_page_get(void);
/**
* @brief Get the end page number of the instruction in SPI flash
*
* @return end page number
*/
uint32_t instruction_flash_end_page_get(void);
/**
* @brief Get the offset of instruction from SPI flash to SPI RAM
*
* @return instruction offset
*/
int instruction_flash2spiram_offset(void);
#endif
#if CONFIG_SPIRAM_RODATA
extern int _rodata_reserved_start, _rodata_reserved_end;
/**
* @brief Get the start page number of the rodata in SPI flash
*
* @return start page number
*/
uint32_t rodata_flash_start_page_get(void);
/**
* @brief Get the end page number of the rodata in SPI flash
*
* @return end page number
*/
uint32_t rodata_flash_end_page_get(void);
/**
* @brief Get the offset number of rodata from SPI flash to SPI RAM
*
* @return rodata offset
*/
int rodata_flash2spiram_offset(void);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,2 @@
#warning esp_himem.h has been replaced by esp32/himem.h, please include esp32/himem.h instead
#include "esp32/himem.h"

View File

@ -0,0 +1,2 @@
#warning esp_spiram.h has been replaced by esp32/spiram.h, please include esp32/spiram.h instead
#include "esp32/spiram.h"

View File

@ -18,7 +18,6 @@
#include "sdkconfig.h"
#include "soc/cpu.h"
#include "hal/cpu_hal.h"
#include "soc/soc_memory_layout.h"
#include "soc/compare_set.h"
#if __XTENSA__