flash_ops_esp32s2.c
1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <string.h> 16 #include <sys/param.h> 17 18 #include "esp_spi_flash.h" 19 #include "soc/system_reg.h" 20 #include "soc/soc_memory_layout.h" 21 #include "esp32s2/rom/spi_flash.h" 22 #include "esp32s2/rom/cache.h" 23 #include "bootloader_flash.h" 24 #include "hal/spi_flash_hal.h" 25 #include "esp_flash.h" 26 #include "esp_log.h" 27 28 static const char *TAG = "spiflash_s2"; 29 30 #define SPICACHE SPIMEM0 31 #define SPIFLASH SPIMEM1 32 33 esp_rom_spiflash_result_t IRAM_ATTR spi_flash_write_encrypted_chip(size_t dest_addr, const void *src, size_t size) 34 { 35 const spi_flash_guard_funcs_t *ops = spi_flash_guard_get(); 36 esp_rom_spiflash_result_t rc; 37 38 assert((dest_addr % 16) == 0); 39 assert((size % 16) == 0); 40 41 if (!esp_ptr_internal(src)) { 42 uint8_t block[128]; // Need to buffer in RAM as we write 43 while (size > 0) { 44 size_t next_block = MIN(size, sizeof(block)); 45 memcpy(block, src, next_block); 46 47 esp_rom_spiflash_result_t r = spi_flash_write_encrypted_chip(dest_addr, block, next_block); 48 if (r != ESP_ROM_SPIFLASH_RESULT_OK) { 49 return r; 50 } 51 52 size -= next_block; 53 dest_addr += next_block; 54 src = ((uint8_t *)src) + next_block; 55 } 56 bzero(block, sizeof(block)); 57 58 return ESP_ROM_SPIFLASH_RESULT_OK; 59 } 60 else { // Already in internal memory 61 ESP_LOGV(TAG, "calling SPI_Encrypt_Write addr 0x%x src %p size 0x%x", dest_addr, src, size); 62 63 #ifndef CONFIG_SPI_FLASH_USE_LEGACY_IMPL 64 /* The ROM function SPI_Encrypt_Write assumes ADDR_BITLEN is already set but new 65 implementation doesn't automatically set this to a usable value */ 66 SPIFLASH.user1.usr_addr_bitlen = 23; 67 #endif 68 69 if (ops && ops->start) { 70 ops->start(); 71 } 72 rc = SPI_Encrypt_Write(dest_addr, src, size); 73 if (ops && ops->end) { 74 ops->end(); 75 } 76 return rc; 77 } 78 } 79 80 esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) 81 { 82 return bootloader_flash_wrap_set(mode); 83 } 84 85 esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) 86 { 87 switch(wrap_size) { 88 case 8: 89 return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B); 90 case 16: 91 return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B); 92 case 32: 93 return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B); 94 case 64: 95 return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B); 96 default: 97 return ESP_FAIL; 98 } 99 } 100 101 void spi_flash_disable_wrap(void) 102 { 103 bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); 104 } 105 106 bool spi_flash_support_wrap_size(uint32_t wrap_size) 107 { 108 if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)){ 109 return ESP_FAIL; 110 } 111 switch(wrap_size) { 112 case 0: 113 case 8: 114 case 16: 115 case 32: 116 case 64: 117 return true; 118 default: 119 return false; 120 } 121 }