1 /* 2 * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include "sdkconfig.h" 10 11 #if !CONFIG_IDF_TARGET_ESP32 12 #error esp_himem is only supported on ESP32 13 #else 14 15 #include <stddef.h> 16 #include "esp_err.h" 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 //Opaque pointers as handles for ram/range data 23 typedef struct esp_himem_ramdata_t *esp_himem_handle_t; 24 typedef struct esp_himem_rangedata_t *esp_himem_rangehandle_t; 25 26 //ESP32 MMU block size 27 #define ESP_HIMEM_BLKSZ (0x8000) 28 29 #define ESP_HIMEM_MAPFLAG_RO 1 /*!< Indicates that a mapping will only be read from. Note that this is unused for now. */ 30 31 /** 32 * @brief Allocate a block in high memory 33 * 34 * @param size Size of the to-be-allocated block, in bytes. Note that this needs to be 35 * a multiple of the external RAM mmu block size (32K). 36 * @param[out] handle_out Handle to be returned 37 * @returns - ESP_OK if succesful 38 * - ESP_ERR_NO_MEM if out of memory 39 * - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K 40 */ 41 esp_err_t esp_himem_alloc(size_t size, esp_himem_handle_t *handle_out); 42 43 44 /** 45 * @brief Allocate a memory region to map blocks into 46 * 47 * This allocates a contiguous CPU memory region that can be used to map blocks 48 * of physical memory into. 49 * 50 * @param size Size of the range to be allocated. Note this needs to be a multiple of 51 * the external RAM mmu block size (32K). 52 * @param[out] handle_out Handle to be returned 53 * @returns - ESP_OK if succesful 54 * - ESP_ERR_NO_MEM if out of memory or address space 55 * - ESP_ERR_INVALID_SIZE if size is not a multiple of 32K 56 */ 57 esp_err_t esp_himem_alloc_map_range(size_t size, esp_himem_rangehandle_t *handle_out); 58 59 /** 60 * @brief Map a block of high memory into the CPUs address space 61 * 62 * This effectively makes the block available for read/write operations. 63 * 64 * @note The region to be mapped needs to have offsets and sizes that are aligned to the 65 * SPI RAM MMU block size (32K) 66 * 67 * @param handle Handle to the block of memory, as given by esp_himem_alloc 68 * @param range Range handle to map the memory in 69 * @param ram_offset Offset into the block of physical memory of the block to map 70 * @param range_offset Offset into the address range where the block will be mapped 71 * @param len Length of region to map 72 * @param flags One of ESP_HIMEM_MAPFLAG_* 73 * @param[out] out_ptr Pointer to variable to store resulting memory pointer in 74 * @returns - ESP_OK if the memory could be mapped 75 * - ESP_ERR_INVALID_ARG if offset, range or len aren't MMU-block-aligned (32K) 76 * - ESP_ERR_INVALID_SIZE if the offsets/lengths don't fit in the allocated memory or range 77 * - ESP_ERR_INVALID_STATE if a block in the selected ram offset/length is already mapped, or 78 * if a block in the selected range offset/length already has a mapping. 79 */ 80 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); 81 82 83 /** 84 * @brief Free a block of physical memory 85 * 86 * This clears out the associated handle making the memory available for re-allocation again. 87 * This will only succeed if none of the memory blocks currently have a mapping. 88 * 89 * @param handle Handle to the block of memory, as given by esp_himem_alloc 90 * @returns - ESP_OK if the memory is succesfully freed 91 * - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped 92 */ 93 esp_err_t esp_himem_free(esp_himem_handle_t handle); 94 95 96 97 /** 98 * @brief Free a mapping range 99 * 100 * This clears out the associated handle making the range available for re-allocation again. 101 * This will only succeed if none of the range blocks currently are used for a mapping. 102 * 103 * @param handle Handle to the range block, as given by esp_himem_alloc_map_range 104 * @returns - ESP_OK if the memory is succesfully freed 105 * - ESP_ERR_INVALID_ARG if the handle still is (partially) mapped to 106 */ 107 esp_err_t esp_himem_free_map_range(esp_himem_rangehandle_t handle); 108 109 110 /** 111 * @brief Unmap a region 112 * 113 * @param range Range handle 114 * @param ptr Pointer returned by esp_himem_map 115 * @param len Length of the block to be unmapped. Must be aligned to the SPI RAM MMU blocksize (32K) 116 * @returns - ESP_OK if the memory is succesfully unmapped, 117 * - ESP_ERR_INVALID_ARG if ptr or len are invalid. 118 */ 119 esp_err_t esp_himem_unmap(esp_himem_rangehandle_t range, void *ptr, size_t len); 120 121 122 /** 123 * @brief Get total amount of memory under control of himem API 124 * 125 * @returns Amount of memory, in bytes 126 */ 127 size_t esp_himem_get_phys_size(void); 128 129 /** 130 * @brief Get free amount of memory under control of himem API 131 * 132 * @returns Amount of free memory, in bytes 133 */ 134 size_t esp_himem_get_free_size(void); 135 136 137 /** 138 * @brief Get amount of SPI memory address space needed for bankswitching 139 * 140 * @note This is also weakly defined in esp32/spiram.c and returns 0 there, so 141 * if no other function in this file is used, no memory is reserved. 142 * 143 * @returns Amount of reserved area, in bytes 144 */ 145 size_t esp_himem_reserved_area_size(void); 146 147 148 #ifdef __cplusplus 149 } 150 #endif 151 152 #endif // !CONFIG_IDF_TARGET_ESP32 153