1# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 2# Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3# 4# SPDX-License-Identifier: GPL-2.0-or-later 5 6import struct 7import time 8from typing import Dict, Optional 9 10from ..loader import ESPLoader 11from ..util import FatalError, NotSupportedError 12 13 14class ESP32ROM(ESPLoader): 15 """Access class for ESP32 ROM bootloader""" 16 17 CHIP_NAME = "ESP32" 18 IMAGE_CHIP_ID = 0 19 IS_STUB = False 20 21 CHIP_DETECT_MAGIC_VALUE = [0x00F01D83] 22 23 IROM_MAP_START = 0x400D0000 24 IROM_MAP_END = 0x40400000 25 26 DROM_MAP_START = 0x3F400000 27 DROM_MAP_END = 0x3F800000 28 29 # ESP32 uses a 4 byte status reply 30 STATUS_BYTES_LENGTH = 4 31 32 SPI_REG_BASE = 0x3FF42000 33 SPI_USR_OFFS = 0x1C 34 SPI_USR1_OFFS = 0x20 35 SPI_USR2_OFFS = 0x24 36 SPI_MOSI_DLEN_OFFS = 0x28 37 SPI_MISO_DLEN_OFFS = 0x2C 38 EFUSE_RD_REG_BASE = 0x3FF5A000 39 40 EFUSE_BLK0_RDATA3_REG_OFFS = EFUSE_RD_REG_BASE + 0x00C 41 EFUSE_BLK0_RDATA5_REG_OFFS = EFUSE_RD_REG_BASE + 0x014 42 43 EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = EFUSE_RD_REG_BASE + 0x18 44 EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 7 # EFUSE_RD_DISABLE_DL_ENCRYPT 45 46 EFUSE_SPI_BOOT_CRYPT_CNT_REG = EFUSE_RD_REG_BASE # EFUSE_BLK0_WDATA0_REG 47 EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7F << 20 # EFUSE_FLASH_CRYPT_CNT 48 49 EFUSE_RD_ABS_DONE_REG = EFUSE_RD_REG_BASE + 0x018 50 EFUSE_RD_ABS_DONE_0_MASK = 1 << 4 51 EFUSE_RD_ABS_DONE_1_MASK = 1 << 5 52 53 EFUSE_VDD_SPI_REG = EFUSE_RD_REG_BASE + 0x10 54 VDD_SPI_XPD = 1 << 14 # XPD_SDIO_REG 55 VDD_SPI_TIEH = 1 << 15 # XPD_SDIO_TIEH 56 VDD_SPI_FORCE = 1 << 16 # XPD_SDIO_FORCE 57 58 DR_REG_SYSCON_BASE = 0x3FF66000 59 APB_CTL_DATE_ADDR = DR_REG_SYSCON_BASE + 0x7C 60 APB_CTL_DATE_V = 0x1 61 APB_CTL_DATE_S = 31 62 63 SPI_W0_OFFS = 0x80 64 65 UART_CLKDIV_REG = 0x3FF40014 66 67 XTAL_CLK_DIVIDER = 1 68 69 RTCCALICFG1 = 0x3FF5F06C 70 TIMERS_RTC_CALI_VALUE = 0x01FFFFFF 71 TIMERS_RTC_CALI_VALUE_S = 7 72 73 GPIO_STRAP_REG = 0x3FF44038 74 GPIO_STRAP_VDDSPI_MASK = 1 << 5 # GPIO_STRAP_VDDSDIO 75 76 RTC_CNTL_SDIO_CONF_REG = 0x3FF48074 77 RTC_CNTL_XPD_SDIO_REG = 1 << 31 78 RTC_CNTL_DREFH_SDIO_M = 3 << 29 79 RTC_CNTL_DREFM_SDIO_M = 3 << 27 80 RTC_CNTL_DREFL_SDIO_M = 3 << 25 81 RTC_CNTL_SDIO_FORCE = 1 << 22 82 RTC_CNTL_SDIO_PD_EN = 1 << 21 83 84 FLASH_SIZES = { 85 "1MB": 0x00, 86 "2MB": 0x10, 87 "4MB": 0x20, 88 "8MB": 0x30, 89 "16MB": 0x40, 90 "32MB": 0x50, 91 "64MB": 0x60, 92 "128MB": 0x70, 93 } 94 95 FLASH_FREQUENCY = { 96 "80m": 0xF, 97 "40m": 0x0, 98 "26m": 0x1, 99 "20m": 0x2, 100 } 101 102 BOOTLOADER_FLASH_OFFSET = 0x1000 103 104 OVERRIDE_VDDSDIO_CHOICES = ["1.8V", "1.9V", "OFF"] 105 106 MEMORY_MAP = [ 107 [0x00000000, 0x00010000, "PADDING"], 108 [0x3F400000, 0x3F800000, "DROM"], 109 [0x3F800000, 0x3FC00000, "EXTRAM_DATA"], 110 [0x3FF80000, 0x3FF82000, "RTC_DRAM"], 111 [0x3FF90000, 0x40000000, "BYTE_ACCESSIBLE"], 112 [0x3FFAE000, 0x40000000, "DRAM"], 113 [0x3FFE0000, 0x3FFFFFFC, "DIRAM_DRAM"], 114 [0x40000000, 0x40070000, "IROM"], 115 [0x40070000, 0x40078000, "CACHE_PRO"], 116 [0x40078000, 0x40080000, "CACHE_APP"], 117 [0x40080000, 0x400A0000, "IRAM"], 118 [0x400A0000, 0x400BFFFC, "DIRAM_IRAM"], 119 [0x400C0000, 0x400C2000, "RTC_IRAM"], 120 [0x400D0000, 0x40400000, "IROM"], 121 [0x50000000, 0x50002000, "RTC_DATA"], 122 ] 123 124 FLASH_ENCRYPTED_WRITE_ALIGN = 32 125 126 UF2_FAMILY_ID = 0x1C5F21B0 127 128 KEY_PURPOSES: Dict[int, str] = {} 129 130 """ Try to read the BLOCK1 (encryption key) and check if it is valid """ 131 132 def is_flash_encryption_key_valid(self): 133 """Bit 0 of efuse_rd_disable[3:0] is mapped to BLOCK1 134 this bit is at position 16 in EFUSE_BLK0_RDATA0_REG""" 135 word0 = self.read_efuse(0) 136 rd_disable = (word0 >> 16) & 0x1 137 138 # reading of BLOCK1 is NOT ALLOWED so we assume valid key is programmed 139 if rd_disable: 140 return True 141 else: 142 # reading of BLOCK1 is ALLOWED so we will read and verify for non-zero. 143 # When ESP32 has not generated AES/encryption key in BLOCK1, 144 # the contents will be readable and 0. 145 # If the flash encryption is enabled it is expected to have a valid 146 # non-zero key. We break out on first occurrence of non-zero value 147 key_word = [0] * 7 148 for i in range(len(key_word)): 149 key_word[i] = self.read_efuse(14 + i) 150 # key is non-zero so break & return 151 if key_word[i] != 0: 152 return True 153 return False 154 155 def get_flash_crypt_config(self): 156 """For flash encryption related commands we need to make sure 157 user has programmed all the relevant efuse correctly so before 158 writing encrypted write_flash_encrypt esptool will verify the values 159 of flash_crypt_config to be non zero if they are not read 160 protected. If the values are zero a warning will be printed 161 162 bit 3 in efuse_rd_disable[3:0] is mapped to flash_crypt_config 163 this bit is at position 19 in EFUSE_BLK0_RDATA0_REG""" 164 word0 = self.read_efuse(0) 165 rd_disable = (word0 >> 19) & 0x1 166 167 if rd_disable == 0: 168 """we can read the flash_crypt_config efuse value 169 so go & read it (EFUSE_BLK0_RDATA5_REG[31:28])""" 170 word5 = self.read_efuse(5) 171 word5 = (word5 >> 28) & 0xF 172 return word5 173 else: 174 # if read of the efuse is disabled we assume it is set correctly 175 return 0xF 176 177 def get_encrypted_download_disabled(self): 178 return ( 179 self.read_reg(self.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG) 180 & self.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT 181 ) 182 183 def get_flash_encryption_enabled(self): 184 flash_crypt_cnt = ( 185 self.read_reg(self.EFUSE_SPI_BOOT_CRYPT_CNT_REG) 186 & self.EFUSE_SPI_BOOT_CRYPT_CNT_MASK 187 ) 188 # Flash encryption enabled when odd number of bits are set 189 return bin(flash_crypt_cnt).count("1") & 1 != 0 190 191 def get_secure_boot_enabled(self): 192 efuses = self.read_reg(self.EFUSE_RD_ABS_DONE_REG) 193 rev = self.get_chip_revision() 194 return efuses & self.EFUSE_RD_ABS_DONE_0_MASK or ( 195 rev >= 300 and efuses & self.EFUSE_RD_ABS_DONE_1_MASK 196 ) 197 198 def get_pkg_version(self): 199 word3 = self.read_efuse(3) 200 pkg_version = (word3 >> 9) & 0x07 201 pkg_version += ((word3 >> 2) & 0x1) << 3 202 return pkg_version 203 204 def get_chip_revision(self): 205 return self.get_major_chip_version() * 100 + self.get_minor_chip_version() 206 207 def get_minor_chip_version(self): 208 return (self.read_efuse(5) >> 24) & 0x3 209 210 def get_major_chip_version(self): 211 rev_bit0 = (self.read_efuse(3) >> 15) & 0x1 212 rev_bit1 = (self.read_efuse(5) >> 20) & 0x1 213 apb_ctl_date = self.read_reg(self.APB_CTL_DATE_ADDR) 214 rev_bit2 = (apb_ctl_date >> self.APB_CTL_DATE_S) & self.APB_CTL_DATE_V 215 combine_value = (rev_bit2 << 2) | (rev_bit1 << 1) | rev_bit0 216 217 revision = { 218 0: 0, 219 1: 1, 220 3: 2, 221 7: 3, 222 }.get(combine_value, 0) 223 return revision 224 225 def get_chip_description(self): 226 pkg_version = self.get_pkg_version() 227 major_rev = self.get_major_chip_version() 228 minor_rev = self.get_minor_chip_version() 229 rev3 = major_rev == 3 230 sc = self.read_efuse(3) & (1 << 0) # single core, CHIP_VER DIS_APP_CPU 231 232 chip_name = { 233 0: "ESP32-S0WDQ6" if sc else "ESP32-D0WDQ6-V3" if rev3 else "ESP32-D0WDQ6", 234 1: "ESP32-S0WD" if sc else "ESP32-D0WD-V3" if rev3 else "ESP32-D0WD", 235 2: "ESP32-D2WD", 236 4: "ESP32-U4WDH", 237 5: "ESP32-PICO-V3" if rev3 else "ESP32-PICO-D4", 238 6: "ESP32-PICO-V3-02", 239 7: "ESP32-D0WDR2-V3", 240 }.get(pkg_version, "unknown ESP32") 241 242 return f"{chip_name} (revision v{major_rev}.{minor_rev})" 243 244 def get_chip_features(self): 245 features = ["WiFi"] 246 word3 = self.read_efuse(3) 247 248 # names of variables in this section are lowercase 249 # versions of EFUSE names as documented in TRM and 250 # ESP-IDF efuse_reg.h 251 252 chip_ver_dis_bt = word3 & (1 << 1) 253 if chip_ver_dis_bt == 0: 254 features += ["BT"] 255 256 chip_ver_dis_app_cpu = word3 & (1 << 0) 257 if chip_ver_dis_app_cpu: 258 features += ["Single Core"] 259 else: 260 features += ["Dual Core"] 261 262 chip_cpu_freq_rated = word3 & (1 << 13) 263 if chip_cpu_freq_rated: 264 chip_cpu_freq_low = word3 & (1 << 12) 265 if chip_cpu_freq_low: 266 features += ["160MHz"] 267 else: 268 features += ["240MHz"] 269 270 pkg_version = self.get_pkg_version() 271 if pkg_version in [2, 4, 5, 6]: 272 features += ["Embedded Flash"] 273 274 if pkg_version == 6: 275 features += ["Embedded PSRAM"] 276 277 word4 = self.read_efuse(4) 278 adc_vref = (word4 >> 8) & 0x1F 279 if adc_vref: 280 features += ["VRef calibration in efuse"] 281 282 blk3_part_res = word3 >> 14 & 0x1 283 if blk3_part_res: 284 features += ["BLK3 partially reserved"] 285 286 word6 = self.read_efuse(6) 287 coding_scheme = word6 & 0x3 288 features += [ 289 "Coding Scheme %s" 290 % { 291 0: "None", 292 1: "3/4", 293 2: "Repeat (UNSUPPORTED)", 294 3: "None (may contain encoding data)", 295 }[coding_scheme] 296 ] 297 298 return features 299 300 def get_chip_spi_pads(self): 301 """Read chip spi pad config 302 return: clk, q, d, hd, cd 303 """ 304 efuse_blk0_rdata5 = self.read_reg(self.EFUSE_BLK0_RDATA5_REG_OFFS) 305 spi_pad_clk = efuse_blk0_rdata5 & 0x1F 306 spi_pad_q = (efuse_blk0_rdata5 >> 5) & 0x1F 307 spi_pad_d = (efuse_blk0_rdata5 >> 10) & 0x1F 308 spi_pad_cs = (efuse_blk0_rdata5 >> 15) & 0x1F 309 310 efuse_blk0_rdata3_reg = self.read_reg(self.EFUSE_BLK0_RDATA3_REG_OFFS) 311 spi_pad_hd = (efuse_blk0_rdata3_reg >> 4) & 0x1F 312 return spi_pad_clk, spi_pad_q, spi_pad_d, spi_pad_hd, spi_pad_cs 313 314 def read_efuse(self, n): 315 """Read the nth word of the ESP3x EFUSE region.""" 316 return self.read_reg(self.EFUSE_RD_REG_BASE + (4 * n)) 317 318 def chip_id(self): 319 raise NotSupportedError(self, "Function chip_id") 320 321 def read_mac(self, mac_type="BASE_MAC"): 322 """Read MAC from EFUSE region""" 323 if mac_type != "BASE_MAC": 324 return None 325 words = [self.read_efuse(2), self.read_efuse(1)] 326 bitstring = struct.pack(">II", *words) 327 bitstring = bitstring[2:8] # trim the 2 byte CRC 328 return tuple(bitstring) 329 330 def get_erase_size(self, offset, size): 331 return size 332 333 def _get_efuse_flash_voltage(self) -> Optional[str]: 334 efuse = self.read_reg(self.EFUSE_VDD_SPI_REG) 335 # check efuse setting 336 if efuse & (self.VDD_SPI_FORCE | self.VDD_SPI_XPD | self.VDD_SPI_TIEH): 337 return "3.3V" 338 elif efuse & (self.VDD_SPI_FORCE | self.VDD_SPI_XPD): 339 return "1.8V" 340 elif efuse & self.VDD_SPI_FORCE: 341 return "OFF" 342 return None 343 344 def _get_rtc_cntl_flash_voltage(self) -> Optional[str]: 345 reg = self.read_reg(self.RTC_CNTL_SDIO_CONF_REG) 346 # check if override is set in RTC_CNTL_SDIO_CONF_REG 347 if reg & self.RTC_CNTL_SDIO_FORCE: 348 if reg & self.RTC_CNTL_DREFH_SDIO_M: 349 return "1.9V" 350 elif reg & self.RTC_CNTL_XPD_SDIO_REG: 351 return "1.8V" 352 else: 353 return "OFF" 354 return None 355 356 def get_flash_voltage(self): 357 """Get flash voltage setting and print it to the console.""" 358 voltage = self._get_rtc_cntl_flash_voltage() 359 source = "RTC_CNTL" 360 if not voltage: 361 voltage = self._get_efuse_flash_voltage() 362 source = "eFuse" 363 if not voltage: 364 strap_reg = self.read_reg(self.GPIO_STRAP_REG) 365 strap_reg &= self.GPIO_STRAP_VDDSPI_MASK 366 voltage = "1.8V" if strap_reg else "3.3V" 367 source = "a strapping pin" 368 print(f"Flash voltage set by {source} to {voltage}") 369 370 def override_vddsdio(self, new_voltage): 371 new_voltage = new_voltage.upper() 372 if new_voltage not in self.OVERRIDE_VDDSDIO_CHOICES: 373 raise FatalError( 374 f"The only accepted VDDSDIO overrides are {', '.join(self.OVERRIDE_VDDSDIO_CHOICES)}" 375 ) 376 # RTC_CNTL_SDIO_TIEH is not used here, setting TIEH=1 would set 3.3V output, 377 # not safe for esptool.py to do 378 379 reg_val = self.RTC_CNTL_SDIO_FORCE # override efuse setting 380 reg_val |= self.RTC_CNTL_SDIO_PD_EN 381 if new_voltage != "OFF": 382 reg_val |= self.RTC_CNTL_XPD_SDIO_REG # enable internal LDO 383 if new_voltage == "1.9V": 384 reg_val |= ( 385 self.RTC_CNTL_DREFH_SDIO_M 386 | self.RTC_CNTL_DREFM_SDIO_M 387 | self.RTC_CNTL_DREFL_SDIO_M 388 ) # boost voltage 389 self.write_reg(self.RTC_CNTL_SDIO_CONF_REG, reg_val) 390 print("VDDSDIO regulator set to %s" % new_voltage) 391 392 def read_flash_slow(self, offset, length, progress_fn): 393 BLOCK_LEN = 64 # ROM read limit per command (this limit is why it's so slow) 394 395 data = b"" 396 while len(data) < length: 397 block_len = min(BLOCK_LEN, length - len(data)) 398 try: 399 r = self.check_command( 400 "read flash block", 401 self.ESP_READ_FLASH_SLOW, 402 struct.pack("<II", offset + len(data), block_len), 403 ) 404 except FatalError: 405 print( 406 "Hint: Consider specifying flash size using '--flash_size' argument" 407 ) 408 raise 409 if len(r) < block_len: 410 raise FatalError( 411 "Expected %d byte block, got %d bytes. Serial errors?" 412 % (block_len, len(r)) 413 ) 414 # command always returns 64 byte buffer, 415 # regardless of how many bytes were actually read from flash 416 data += r[:block_len] 417 if progress_fn and (len(data) % 1024 == 0 or len(data) == length): 418 progress_fn(len(data), length) 419 return data 420 421 def get_rom_cal_crystal_freq(self): 422 """ 423 Get the crystal frequency calculated by the ROM 424 """ 425 # - Simulate the calculation in the ROM to get the XTAL frequency 426 # calculated by the ROM 427 428 cali_val = ( 429 self.read_reg(self.RTCCALICFG1) >> self.TIMERS_RTC_CALI_VALUE_S 430 ) & self.TIMERS_RTC_CALI_VALUE 431 clk_8M_freq = self.read_efuse(4) & (0xFF) # EFUSE_RD_CK8M_FREQ 432 rom_calculated_freq = cali_val * 15625 * clk_8M_freq / 40 433 return rom_calculated_freq 434 435 def change_baud(self, baud): 436 assert self.CHIP_NAME == "ESP32", "This workaround should only apply to ESP32" 437 # It's a workaround to avoid esp32 CK_8M frequency drift. 438 rom_calculated_freq = self.get_rom_cal_crystal_freq() 439 valid_freq = 40000000 if rom_calculated_freq > 33000000 else 26000000 440 false_rom_baud = int(baud * rom_calculated_freq // valid_freq) 441 442 print(f"Changing baud rate to {baud}") 443 self.command(self.ESP_CHANGE_BAUDRATE, struct.pack("<II", false_rom_baud, 0)) 444 print("Changed.") 445 self._set_port_baudrate(baud) 446 time.sleep(0.05) # get rid of garbage sent during baud rate change 447 self.flush_input() 448 449 def check_spi_connection(self, spi_connection): 450 # Pins 30, 31 do not exist 451 if not set(spi_connection).issubset(set(range(0, 30)) | set((32, 33))): 452 raise FatalError("SPI Pin numbers must be in the range 0-29, 32, or 33.") 453 454 455class ESP32StubLoader(ESP32ROM): 456 """Access class for ESP32 stub loader, runs on top of ROM.""" 457 458 FLASH_WRITE_SIZE = 0x4000 # matches MAX_WRITE_BLOCK in stub_loader.c 459 STATUS_BYTES_LENGTH = 2 # same as ESP8266, different to ESP32 ROM 460 IS_STUB = True 461 462 def __init__(self, rom_loader): 463 self.secure_download_mode = rom_loader.secure_download_mode 464 self._port = rom_loader._port 465 self._trace_enabled = rom_loader._trace_enabled 466 self.cache = rom_loader.cache 467 self.flush_input() # resets _slip_reader 468 469 def change_baud(self, baud): 470 ESPLoader.change_baud(self, baud) 471 472 473ESP32ROM.STUB_CLASS = ESP32StubLoader 474