diff --git a/contrib/loaders/flash/esp/esp32/stub_flasher_chip.c b/contrib/loaders/flash/esp/esp32/stub_flasher_chip.c index 16a6ec3e15..4fafb6d076 100644 --- a/contrib/loaders/flash/esp/esp32/stub_flasher_chip.c +++ b/contrib/loaders/flash/esp/esp32/stub_flasher_chip.c @@ -178,16 +178,6 @@ static bool esp32_flash_cache_enabled(uint32_t cpuid) return result; } -static inline uint32_t stub_get_coreid() -{ - int id; - __asm__ volatile ( - "rsr.prid %0\n" - " extui %0,%0,13,1" - : "=r" (id)); - return id; -} - static uint32_t esp32_flash_exec_usr_cmd(uint32_t cmd) { uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG; diff --git a/contrib/loaders/flash/esp/esp32s3/Makefile b/contrib/loaders/flash/esp/esp32s3/Makefile new file mode 100644 index 0000000000..93e5bcc56b --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/Makefile @@ -0,0 +1,59 @@ +# Makefile to compile the flasher stub program +# +# Note that YOU DO NOT NEED TO COMPILE THIS IN ORDER TO JUST USE + +# See the comments in the top of the Makefile for parameters that +# you probably want to override. +# +# Copyright (c) 2021 Espressif Systems +# All rights reserved +# +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +# Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Prefix for ESP32-S3 cross compilers (can include a directory path) +CROSS ?= xtensa-esp32s3-elf- + +# Path to the esp-idf root dir +IDF_PATH ?= ../.. + +STUB_CHIP_PATH := $(shell pwd) +STUB_COMMON_PATH := $(STUB_CHIP_PATH)/.. +STUB_CHIP_ARCH_PATH := $(STUB_COMMON_PATH)/xtensa +STUB_OBJ_DEPS := sdkconfig.h +STUB_LD_SCRIPT := stub.ld +STUB_CHIP := ESP32S3 + +SRCS := $(IDF_PATH)/components/app_trace/port/xtensa/port.c \ + $(IDF_PATH)/components/xtensa/eri.c \ + $(IDF_PATH)/components/esp_hw_support/port/esp32s3/rtc_clk.c \ + $(IDF_PATH)/components/esp_hw_support/port/esp32s3/rtc_clk_init.c \ + $(IDF_PATH)/components/esp_hw_support/port/esp32s3/rtc_time.c + +CFLAGS := -mlongcalls -mtext-section-literals + +INCLUDES := -I$(IDF_PATH)/components/esp32s3/include -I$(IDF_PATH)/components/soc/esp32s3/include \ + -I$(IDF_PATH)/components/esp_rom/include/esp32s3 -I$(IDF_PATH)/components/xtensa/esp32s3/include \ + -I$(IDF_PATH)/components/hal/esp32s3/include \ + -I$(IDF_PATH)/components/esp_hw_support/port/esp32s3/private_include \ + -I$(IDF_PATH)/components/esp_hw_support/port/esp32s3 \ + -I$(IDF_PATH)/components/xtensa/include \ + -I$(IDF_PATH)/components/freertos/include \ + -I$(IDF_PATH)/components/freertos/port/xtensa/include + +DEFINES := + +LDFLAGS := -L$(IDF_PATH)/components/esp32s3/ld -T$(IDF_PATH)/components/esp_rom/esp32s3/ld/esp32s3.rom.ld \ + -T$(IDF_PATH)/components/esp_rom/esp32s3/ld/esp32s3.rom.api.ld + +include ../stub_common.mk diff --git a/contrib/loaders/flash/esp/esp32s3/sdkconfig.h b/contrib/loaders/flash/esp/esp32s3/sdkconfig.h new file mode 100644 index 0000000000..d6658b82f1 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/sdkconfig.h @@ -0,0 +1,33 @@ +#ifndef _STUB_SDKCONFIG_H_ +#define _STUB_SDKCONFIG_H_ + +#define CONFIG_IDF_TARGET_ARCH_XTENSA 1 +#define CONFIG_IDF_TARGET_ESP32S3 1 +#define CONFIG_FREERTOS_UNICORE 0 +/* Use ROM flash driver patch + * #define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 + * Disable application module multi-threading lock */ +#define CONFIG_APPTRACE_LOCK_ENABLE 0 +/* Enable apptarce module for flash data transfers */ +#define CONFIG_APPTRACE_DEST_JTAG 1 +#define CONFIG_APPTRACE_MEMBUFS_APPTRACE_PROTO_ENABLE 1 +#define CONFIG_APPTRACE_ENABLE 1 +#define CONFIG_APPTRACE_BUF_SIZE 0 +#define CONFIG_APPTRACE_PENDING_DATA_SIZE_MAX 0 +/* Debug UART number */ +#define CONFIG_CONSOLE_UART_NUM 0 +/* Debug UART baudrate */ +#define CONFIG_CONSOLE_UART_BAUDRATE 115200 +/* alloc apptrace data buffers on stack */ +#define CONFIG_STUB_STACK_DATA_POOL_SIZE (2*CONFIG_APPTRACE_BUF_SIZE) + +/* needed due to apptrace sources usage */ +#define CONFIG_LOG_MAXIMUM_LEVEL 0 +/* needed due to various checks in IDF headers */ +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 +/* TODO: use current clk, get it from PLL settings */ +#define CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ 160 +/* Unused by stub, just for compilation of IDF */ +#define CONFIG_PARTITION_TABLE_OFFSET 0x8000 + +#endif /*_STUB_SDKCONFIG_H_ */ diff --git a/contrib/loaders/flash/esp/esp32s3/stub.ld b/contrib/loaders/flash/esp/esp32s3/stub.ld new file mode 100644 index 0000000000..cb266f6969 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub.ld @@ -0,0 +1,29 @@ +/*************************************************************************** + * LD script for ESP32-S3 flasher stub * + * Copyright (C) 2021 Espressif Systems Ltd. * + * Author: Alexey Gerenkov * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ + +MEMORY { + /* place stub at the beginning of the OpenOCD working area, + remaining space will be used for other chunks */ + iram : org = 0x403B0000, len = 0x4000 + dram : org = 0x3FCE0000, len = 0xC000 +} + +INCLUDE stub_common.ld diff --git a/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.c b/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.c new file mode 100644 index 0000000000..2def82c45f --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.c @@ -0,0 +1,513 @@ +/*************************************************************************** + * ESP32-S3 specific flasher stub functions * + * Copyright (C) 2021 Espressif Systems Ltd. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ +#include +#include "sdkconfig.h" +#include "soc/rtc.h" +#include "soc/efuse_periph.h" +#include "soc/spi_mem_reg.h" +#include "soc/extmem_reg.h" +#include "soc/system_reg.h" +#include "soc/gpio_reg.h" +#include "soc/mmu.h" +#include "xtensa/hal.h" +#include "esp_spi_flash.h" +#include "rtc_clk_common.h" +#include "stub_rom_chip.h" +#include "stub_flasher_int.h" +#include "stub_flasher_chip.h" + +#define EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT (1 << 4) + +/* Cache MMU related definitions */ +#define STUB_CACHE_BUS_PRO EXTMEM_DCACHE_SHUT_CORE0_BUS +#define STUB_CACHE_BUS_APP EXTMEM_DCACHE_SHUT_CORE1_BUS +#define STUB_MMU_DROM_VADDR SOC_MMU_VADDR0_START_ADDR +#define STUB_MMU_DROM_PAGES_START SOC_MMU_DROM0_PAGES_START +#define STUB_MMU_DROM_PAGES_END SOC_MMU_DROM0_PAGES_END +#define STUB_MMU_TABLE SOC_MMU_DPORT_PRO_FLASH_MMU_TABLE /* 0x600c5000 */ +#define STUB_MMU_INVALID_ENTRY_VAL SOC_MMU_INVALID_ENTRY_VAL /* 0x100 */ + +/* SPI Flash map request data */ +struct spiflash_map_req { + /* Request mapping SPI Flash base address */ + uint32_t src_addr; + /* Request mapping SPI Flash size */ + uint32_t size; + /* Mapped memory pointer */ + void *ptr; + /* Mapped started MMU page index */ + uint32_t start_page; + /* Mapped MMU page count */ + uint32_t page_cnt; +}; + +uint32_t g_stub_cpu_freq_hz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ * MHZ; + +extern bool ets_efuse_flash_octal_mode(void); + +void vPortEnterCritical(void *mux) +{ +} + +void vPortExitCritical(void *mux) +{ +} + +#if STUB_LOG_LOCAL_LEVEL > STUB_LOG_INFO +void stub_print_cache_mmu_registers(void) +{ + uint32_t icache_ctrl1_reg = REG_READ(EXTMEM_DCACHE_CTRL1_REG); + + STUB_LOGD("dcache_ctrl1_reg: 0x%x\n", + icache_ctrl1_reg); +} +#endif + +uint32_t stub_flash_get_id(void) +{ + uint32_t ret; + + STUB_LOGD("flash %x, cs %x, bs %x, ss %x, ps %x, sm %x\n", + rom_spiflash_legacy_data->chip.device_id, + rom_spiflash_legacy_data->chip.chip_size, + rom_spiflash_legacy_data->chip.block_size, + rom_spiflash_legacy_data->chip.sector_size, + rom_spiflash_legacy_data->chip.page_size, + rom_spiflash_legacy_data->chip.status_mask); + + if (rom_spiflash_legacy_data->dummy_len_plus[1] == 0) + REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + else { + REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY); + REG_WRITE( + PERIPHS_SPI_FLASH_USRREG1, + (rom_spiflash_legacy_data->dummy_len_plus[1] - + 1) << SPI_MEM_USR_DUMMY_CYCLELEN_S); + + } + WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0, 0);/* clear register */ + WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDID); + while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0) ; + ret = READ_PERI_REG(PERIPHS_SPI_FLASH_C0) & 0xffffff; + STUB_LOGD("Flash ID read %x\n", ret); + return ret >> 16; +} + +void stub_flash_cache_flush(void) +{ + /* we do not know breakpoint program address here, so invalidate the + * whole ICache */ + Cache_Invalidate_ICache_All(); +} + +static void stub_cache_init(uint32_t cpuid) +{ + STUB_LOGD("stub_cache_init\n"); + /* init cache mmu, set cache mode, invalidate cache tags, enable cache*/ + REG_SET_BIT(SYSTEM_CACHE_CONTROL_REG, SYSTEM_DCACHE_CLK_ON); + REG_SET_BIT(SYSTEM_CACHE_CONTROL_REG, SYSTEM_DCACHE_RESET); + REG_CLR_BIT(SYSTEM_CACHE_CONTROL_REG, SYSTEM_DCACHE_RESET); + /* init cache owner bit */ + Cache_Owner_Init(); + /* clear mmu entry */ + Cache_MMU_Init(); + /* config cache mode */ + Cache_Set_Default_Mode(); + Cache_Enable_DCache(0); + if (cpuid == 0) + REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, STUB_CACHE_BUS_PRO); + else + REG_CLR_BIT(EXTMEM_DCACHE_CTRL1_REG, STUB_CACHE_BUS_APP); +} + +static bool stub_is_cache_enabled(uint32_t cpuid) +{ + bool is_enabled = REG_GET_BIT(EXTMEM_DCACHE_CTRL_REG, EXTMEM_DCACHE_ENABLE) != 0; + int cache_bus_disabled = REG_READ(EXTMEM_DCACHE_CTRL1_REG) & + (cpuid == 0 ? STUB_CACHE_BUS_PRO : STUB_CACHE_BUS_APP); + return is_enabled && !cache_bus_disabled; +} + +void stub_flash_state_prepare(struct stub_flash_state *state) +{ + uint32_t core_id = stub_get_coreid(); + uint32_t spiconfig = ets_efuse_get_spiconfig(); + + state->cache_enabled = stub_is_cache_enabled(core_id); + if (!state->cache_enabled) { + STUB_LOGI("Cache needs to be enabled for CPU%d\n", core_id); + stub_cache_init(core_id); + } + + if (ets_efuse_flash_octal_mode()) + STUB_LOGE("Octal flah not supported yet!\n"); + + esp_rom_spiflash_attach(spiconfig, 0); +} + +void stub_flash_state_restore(struct stub_flash_state *state) +{ + /* we do not disable or store the cache settings. So, nothing to restore*/ +} + +#define RTC_PLL_FREQ_320M 320 +#define RTC_PLL_FREQ_480M 480 + +rtc_xtal_freq_t stub_rtc_clk_xtal_freq_get(void) +{ + uint32_t xtal_freq_reg = READ_PERI_REG(RTC_XTAL_FREQ_REG); + if (!clk_val_is_valid(xtal_freq_reg)) + return RTC_XTAL_FREQ_40M; + return reg_val_to_clk_val(xtal_freq_reg); +} + +/* Obviously we can call rtc_clk_cpu_freq_get_config() from esp-idf +But this call may cause undesired locks due to ets_printf or abort +*/ +int stub_rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config) +{ + rtc_cpu_freq_src_t source; + uint32_t source_freq_mhz; + uint32_t div; + uint32_t freq_mhz; + uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); + switch (soc_clk_sel) { + case DPORT_SOC_CLK_SEL_XTAL: { + source = RTC_CPU_FREQ_SRC_XTAL; + div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT) + 1; + source_freq_mhz = (uint32_t) stub_rtc_clk_xtal_freq_get(); + freq_mhz = source_freq_mhz / div; + } + break; + case DPORT_SOC_CLK_SEL_PLL: { + source = RTC_CPU_FREQ_SRC_PLL; + uint32_t cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, + SYSTEM_CPUPERIOD_SEL); + uint32_t pllfreq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, + SYSTEM_PLL_FREQ_SEL); + source_freq_mhz = (pllfreq_sel) ? RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M; + if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80) { + div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4; + freq_mhz = 80; + } else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160) { + div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2; + div = 3; + freq_mhz = 160; + } else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_240) { + div = 2; + freq_mhz = 240; + } else { + /* unsupported frequency configuration */ + return -1; + } + break; + } + case DPORT_SOC_CLK_SEL_8M: + source = RTC_CPU_FREQ_SRC_8M; + source_freq_mhz = 8; + div = 1; + freq_mhz = source_freq_mhz; + break; + default: + /* unsupported frequency configuration */ + return -2; + } + *out_config = (rtc_cpu_freq_config_t) { + .source = source, + .source_freq_mhz = source_freq_mhz, + .div = div, + .freq_mhz = freq_mhz + }; + return 0; +} + +/* this function has almost the same implementation for ESP32 and ESP32-S2 + * TODO: move to common file */ +int stub_cpu_clock_configure(int cpu_freq_mhz) +{ + rtc_cpu_freq_config_t old_config; + int ret = stub_rtc_clk_cpu_freq_get_config(&old_config); + if (ret < 0) { + /* this return value will avoid undesired restore requests for unsupported frequency + *configuration */ + old_config.freq_mhz = 0; + } + +#if STUB_LOG_LOCAL_LEVEL > STUB_LOG_NONE + uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); +#endif + + /* set to maximum possible value */ + if (cpu_freq_mhz == -1) + cpu_freq_mhz = CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ; + + /* Set CPU to configured value. Keep other clocks unmodified. */ + if (cpu_freq_mhz > 0) { + rtc_clk_config_t clk_cfg = RTC_CLK_CONFIG_DEFAULT(); + /* ESP32-S2 doesn't have XTAL_FREQ choice, always 40MHz. + So using default value is fine */ + clk_cfg.cpu_freq_mhz = cpu_freq_mhz; + clk_cfg.slow_freq = rtc_clk_slow_freq_get(); + clk_cfg.fast_freq = rtc_clk_fast_freq_get(); + rtc_clk_init(clk_cfg); + + g_stub_cpu_freq_hz = cpu_freq_mhz * MHZ; + } + + return old_config.freq_mhz; +} + +#if STUB_LOG_LOCAL_LEVEL > STUB_LOG_NONE +void stub_uart_console_configure() +{ + extern bool g_uart_print; + /* set the default parameter to UART module, but don't enable RX interrupt */ + uartAttach(NULL); + /* first enable uart0 as printf channel */ + uint32_t clock = ets_get_apb_freq(); + ets_update_cpu_frequency(clock/1000000); + + Uart_Init(ets_efuse_get_uart_print_channel(), UART_CLK_FREQ_ROM); + /* install to print later + * Non-Flash Boot can print + * Flash Boot can print when RTC_CNTL_STORE4_REG bit0 is 0 (can be 1 after deep sleep, software reset) and printf boot. + * print boot determined by GPIO and efuse, see ets_is_print_boot + */ + g_uart_print = true; + ets_install_uart_printf(); +} +#endif + +uint32_t stub_esp_clk_cpu_freq(void) +{ + return g_stub_cpu_freq_hz; +} + +esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len) +{ + int32_t total_sector_num; + int32_t head_sector_num; + uint32_t sector_no; + uint32_t sector_num_per_block; + + /* set read mode to Fastmode ,not QDIO mode for erase + * + * TODO: this is probably a bug as it doesn't re-enable QIO mode, not serious as this + * function is not used in IDF. + * esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE); */ + + /* check if area is oversize of flash */ + if ((start_addr + area_len) > rom_spiflash_legacy_data->chip.chip_size) + return ESP_ROM_SPIFLASH_RESULT_ERR; + + /* start_addr is aligned as sector boundary */ + if (0 != (start_addr % rom_spiflash_legacy_data->chip.sector_size)) + return ESP_ROM_SPIFLASH_RESULT_ERR; + + /* Unlock flash to enable erase */ + if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_unlock(/*&rom_spiflash_legacy_data->chip*/)) + return ESP_ROM_SPIFLASH_RESULT_ERR; + + sector_no = start_addr / rom_spiflash_legacy_data->chip.sector_size; + sector_num_per_block = rom_spiflash_legacy_data->chip.block_size / + rom_spiflash_legacy_data->chip.sector_size; + total_sector_num = + (0 == + (area_len % + rom_spiflash_legacy_data->chip.sector_size)) ? area_len / + rom_spiflash_legacy_data->chip.sector_size : + 1 + (area_len / rom_spiflash_legacy_data->chip.sector_size); + + /* check if erase area reach over block boundary */ + head_sector_num = sector_num_per_block - (sector_no % sector_num_per_block); + + head_sector_num = + (head_sector_num >= total_sector_num) ? total_sector_num : head_sector_num; + + /* JJJ, BUG of 6.0 erase + * middle part of area is aligned by blocks */ + total_sector_num -= head_sector_num; + + /* head part of area is erased */ + while (0 != head_sector_num) { + if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) + return ESP_ROM_SPIFLASH_RESULT_ERR; + sector_no++; + head_sector_num--; + } + while (total_sector_num > sector_num_per_block) { + if (ESP_ROM_SPIFLASH_RESULT_OK != + esp_rom_spiflash_erase_block(sector_no / sector_num_per_block)) + return ESP_ROM_SPIFLASH_RESULT_ERR; + sector_no += sector_num_per_block; + total_sector_num -= sector_num_per_block; + } + + /* tail part of area burn */ + while (0 < total_sector_num) { + if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) + return ESP_ROM_SPIFLASH_RESULT_ERR; + sector_no++; + total_sector_num--; + } + + return ESP_ROM_SPIFLASH_RESULT_OK; +} + +static inline bool esp_flash_encryption_enabled(void) +{ + uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, + EFUSE_SPI_BOOT_CRYPT_CNT); + + /* __builtin_parity is in flash, so we calculate parity inline */ + bool enabled = false; + while (flash_crypt_cnt) { + if (flash_crypt_cnt & 1) + enabled = !enabled; + flash_crypt_cnt >>= 1; + } + return enabled; +} + +esp_flash_enc_mode_t stub_get_flash_encryption_mode(void) +{ + static esp_flash_enc_mode_t s_mode = ESP_FLASH_ENC_MODE_DEVELOPMENT; + static bool s_first = true; + + if (s_first) { + if (esp_flash_encryption_enabled()) { + /* Check if SPI_BOOT_CRYPT_CNT is write protected */ + bool flash_crypt_cnt_wr_dis = REG_READ(EFUSE_RD_WR_DIS_REG) & + EFUSE_WR_DIS_SPI_BOOT_CRYPT_CNT; + if (!flash_crypt_cnt_wr_dis) { + uint8_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA1_REG, + EFUSE_SPI_BOOT_CRYPT_CNT); + /* Check if SPI_BOOT_CRYPT_CNT set for permanent encryption */ + if (flash_crypt_cnt == EFUSE_SPI_BOOT_CRYPT_CNT_V) + flash_crypt_cnt_wr_dis = true; + } + + if (flash_crypt_cnt_wr_dis) { + uint8_t dis_dl_enc = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA0_REG, + EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); + uint8_t dis_dl_icache = REG_GET_FIELD(EFUSE_RD_REPEAT_DATA0_REG, + EFUSE_DIS_DOWNLOAD_ICACHE); + if (dis_dl_enc && dis_dl_icache) + s_mode = ESP_FLASH_ENC_MODE_RELEASE; + } + + } else + s_mode = ESP_FLASH_ENC_MODE_DISABLED; + + s_first = false; + } + + STUB_LOGD("flash_encryption_mode: %d\n", s_mode); + + return s_mode; +} + +static int stub_flash_mmap(struct spiflash_map_req *req) +{ + uint32_t map_src = req->src_addr & (~(SPI_FLASH_MMU_PAGE_SIZE - 1)); + uint32_t map_size = req->size + (req->src_addr - map_src); + uint32_t flash_page = map_src / SPI_FLASH_MMU_PAGE_SIZE; + uint32_t page_cnt = (map_size + SPI_FLASH_MMU_PAGE_SIZE - 1) / SPI_FLASH_MMU_PAGE_SIZE; + int start_page, ret = ESP_ROM_SPIFLASH_RESULT_ERR; + uint32_t icache_state, dcache_state; + + icache_state = Cache_Suspend_ICache(); + dcache_state = Cache_Suspend_DCache(); + + for (start_page = STUB_MMU_DROM_PAGES_START; start_page < STUB_MMU_DROM_PAGES_END; + ++start_page) { + if (STUB_MMU_TABLE[start_page] == STUB_MMU_INVALID_ENTRY_VAL) + break; + } + + if (start_page == STUB_MMU_DROM_PAGES_END) { + STUB_LOGW("Failed to find free MMU page! Use the first one.\n"); + start_page = STUB_MMU_DROM_PAGES_START; + } + + if (start_page + page_cnt < STUB_MMU_DROM_PAGES_END) { + for (int i = 0; i < page_cnt; i++) + STUB_MMU_TABLE[start_page + i] = SOC_MMU_PAGE_IN_FLASH( + flash_page + i); + + req->start_page = start_page; + req->page_cnt = page_cnt; + req->ptr = (void *)(STUB_MMU_DROM_VADDR + + (start_page - STUB_MMU_DROM_PAGES_START) * SPI_FLASH_MMU_PAGE_SIZE + + (req->src_addr - map_src)); + Cache_Invalidate_Addr((uint32_t)(STUB_MMU_DROM_VADDR + + (start_page - STUB_MMU_DROM_PAGES_START) * SPI_FLASH_MMU_PAGE_SIZE), + page_cnt * SPI_FLASH_MMU_PAGE_SIZE); + ret = ESP_ROM_SPIFLASH_RESULT_OK; + } + + STUB_LOGD( + "start_page: %d map_src: %x map_size: %x page_cnt: %d flash_page: %d map_ptr: %x\n", + start_page, + map_src, + map_size, + page_cnt, + flash_page, + req->ptr); + + Cache_Resume_DCache(dcache_state); + Cache_Resume_ICache(icache_state); + + return ret; +} + +static void stub_flash_ummap(const struct spiflash_map_req *req) +{ + uint32_t icache_state, dcache_state; + + icache_state = Cache_Suspend_ICache(); + dcache_state = Cache_Suspend_DCache(); + + for (int i = req->start_page; i < req->start_page + req->page_cnt; ++i) + STUB_MMU_TABLE[i] = STUB_MMU_INVALID_ENTRY_VAL; + + Cache_Resume_DCache(dcache_state); + Cache_Resume_ICache(icache_state); +} + + +int stub_flash_read_buff(uint32_t addr, void *buffer, uint32_t size) +{ + struct spiflash_map_req req = { + .src_addr = addr, + .size = size, + }; + + int ret = stub_flash_mmap(&req); + + if (ret) + return ret; + + memcpy(buffer, req.ptr, size); + + stub_flash_ummap(&req); + + return ESP_ROM_SPIFLASH_RESULT_OK; +} diff --git a/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.h b/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.h new file mode 100644 index 0000000000..e64b55194d --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * ESP32-S3 flasher stub definitions * + * Copyright (C) 2021 Espressif Systems Ltd. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ +#ifndef ESP32S3_FLASHER_STUB_H +#define ESP32S3_FLASHER_STUB_H + +#include "sdkconfig.h" + +#define STUB_FLASH_SECTOR_SIZE 4096 +/* Flash geometry constants */ +#define STUB_FLASH_BLOCK_SIZE 65536 +#define STUB_FLASH_PAGE_SIZE 256 +#define STUB_FLASH_STATUS_MASK 0xFFFF + +struct stub_flash_state { + uint32_t cache_flags[2]; + bool cache_enabled; +}; +void stub_flash_state_prepare(struct stub_flash_state *state); +void stub_flash_state_restore(struct stub_flash_state *state); + +uint32_t stub_esp_clk_cpu_freq(void); + +#include "stub_xtensa_chips.h" + +#endif /*ESP32S3_FLASHER_STUB_H */ diff --git a/contrib/loaders/flash/esp/esp32s3/stub_flasher_code.inc b/contrib/loaders/flash/esp/esp32s3/stub_flasher_code.inc new file mode 100644 index 0000000000..69848bfd74 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_flasher_code.inc @@ -0,0 +1,768 @@ + 0x88, 0x02, 0xce, 0x3f, 0x70, 0x02, 0xce, 0x3f, 0x36, 0x41, 0x00, 0x81, + 0xfd, 0xff, 0xbd, 0x02, 0x82, 0x08, 0x00, 0xcd, 0x03, 0x8c, 0xf8, 0x91, + 0xfb, 0xff, 0x88, 0x29, 0x8c, 0x88, 0x88, 0x58, 0x8c, 0x48, 0xa2, 0x29, + 0x03, 0xe0, 0x08, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0xe4, 0xff, 0xce, 0x3f, + 0x18, 0x20, 0x00, 0x60, 0xff, 0xff, 0xff, 0xdf, 0x00, 0x00, 0x00, 0x20, + 0x1c, 0x20, 0x00, 0x60, 0x58, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x10, 0x36, 0x41, 0x00, 0x21, 0xf7, 0xff, 0x81, 0xf7, + 0xff, 0xa8, 0x02, 0xc0, 0x20, 0x00, 0x98, 0x08, 0x22, 0x0a, 0x19, 0xcc, + 0xd2, 0x21, 0xf4, 0xff, 0x20, 0x99, 0x10, 0xc0, 0x20, 0x00, 0x99, 0x08, + 0x06, 0x06, 0x00, 0x00, 0x21, 0xf2, 0xff, 0x20, 0x99, 0x20, 0xc0, 0x20, + 0x00, 0x99, 0x08, 0x82, 0x0a, 0x19, 0x21, 0xef, 0xff, 0x0b, 0x88, 0xc0, + 0x20, 0x00, 0x89, 0x02, 0x81, 0xee, 0xff, 0x0c, 0x02, 0xc0, 0x20, 0x00, + 0x29, 0x08, 0x91, 0xec, 0xff, 0x21, 0xec, 0xff, 0xc0, 0x20, 0x00, 0x29, + 0x09, 0xc0, 0x20, 0x00, 0x28, 0x09, 0x56, 0x72, 0xff, 0xc0, 0x20, 0x00, + 0x28, 0x08, 0x20, 0x20, 0x75, 0x1d, 0xf0, 0x00, 0x1c, 0x00, 0x10, 0x00, + 0x36, 0x41, 0x00, 0x21, 0xfe, 0xff, 0x20, 0x62, 0x40, 0x20, 0x26, 0x05, + 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, + 0x00, 0x10, 0x01, 0x00, 0x18, 0x10, 0x0c, 0x60, 0x36, 0x41, 0x00, 0x2c, + 0x09, 0x81, 0xfa, 0xff, 0xcc, 0x42, 0x91, 0xfa, 0xff, 0x81, 0xfa, 0xff, + 0x90, 0x88, 0x20, 0x91, 0xfa, 0xff, 0x0c, 0x02, 0xc0, 0x20, 0x00, 0x89, + 0x09, 0x1d, 0xf0, 0x00, 0x14, 0x00, 0x10, 0x00, 0x36, 0x41, 0x00, 0x0c, + 0x08, 0x91, 0xfd, 0xff, 0x80, 0x79, 0x40, 0x1d, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x36, 0x41, 0x00, 0x91, + 0xe7, 0xff, 0x80, 0x69, 0x40, 0xa1, 0xfb, 0xff, 0x10, 0x22, 0x11, 0xa0, + 0x22, 0x10, 0x30, 0x30, 0xe4, 0x30, 0x22, 0x20, 0x31, 0xf9, 0xff, 0x30, + 0x88, 0x10, 0x80, 0x22, 0x20, 0x20, 0x79, 0x40, 0x25, 0xfc, 0xff, 0x0c, + 0x02, 0x1d, 0xf0, 0x00, 0x03, 0x01, 0x3b, 0x40, 0x36, 0x41, 0x00, 0x81, + 0xfe, 0xff, 0x91, 0xeb, 0xff, 0x80, 0x79, 0x40, 0x81, 0xd9, 0xff, 0x80, + 0x68, 0x40, 0x92, 0xa0, 0x00, 0x77, 0x78, 0x14, 0x80, 0xaf, 0x64, 0x80, + 0x80, 0xe4, 0x97, 0x98, 0x05, 0x20, 0x80, 0x64, 0xa7, 0x18, 0x05, 0x25, + 0xf9, 0xff, 0x92, 0xa1, 0x01, 0x90, 0x29, 0x20, 0x90, 0x00, 0x00, 0x00, + 0x36, 0x41, 0x00, 0x80, 0xeb, 0x03, 0x80, 0x8d, 0x04, 0x92, 0x02, 0x00, + 0x0c, 0x02, 0x87, 0x59, 0x08, 0x21, 0xca, 0xff, 0x20, 0x62, 0x40, 0x20, + 0x27, 0x05, 0x1d, 0xf0, 0x00, 0x00, 0xcd, 0x3f, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x40, 0xcd, 0x3f, 0x20, 0x50, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, + 0x36, 0x41, 0x00, 0x8d, 0x02, 0x90, 0xeb, 0x03, 0x90, 0x9d, 0x04, 0x56, + 0x19, 0x04, 0xc0, 0x20, 0x00, 0x99, 0xb2, 0xc0, 0x20, 0x00, 0x99, 0xa2, + 0xc0, 0x20, 0x00, 0x99, 0xc2, 0xc0, 0x20, 0x00, 0x99, 0xd2, 0x99, 0x92, + 0x21, 0xf2, 0xff, 0xa1, 0xf3, 0xff, 0x29, 0x58, 0x21, 0xf1, 0xff, 0xc0, + 0x20, 0x00, 0x99, 0x38, 0x29, 0x68, 0xa9, 0x78, 0x29, 0x88, 0xc0, 0x20, + 0x00, 0x99, 0x48, 0x21, 0xbb, 0xff, 0xa1, 0xed, 0xff, 0xc0, 0x20, 0x00, + 0x99, 0x28, 0xc0, 0x20, 0x00, 0xa2, 0x62, 0x00, 0x21, 0xeb, 0xff, 0x0c, + 0x2a, 0xa0, 0x72, 0x40, 0xa2, 0xa0, 0x80, 0xa0, 0x72, 0x40, 0x0c, 0x02, + 0xa1, 0xab, 0xff, 0x20, 0x7a, 0x40, 0xa1, 0xba, 0xff, 0x20, 0x7a, 0x40, + 0x0c, 0x1a, 0x00, 0x19, 0x40, 0x00, 0x9a, 0xa1, 0xa2, 0x08, 0x00, 0xa0, + 0x99, 0x20, 0x92, 0x48, 0x00, 0x1d, 0xf0, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x50, 0x0c, 0x60, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x18, 0x00, 0x40, + 0xb4, 0x18, 0x00, 0x40, 0x5c, 0x19, 0x00, 0x40, 0x68, 0x19, 0x00, 0x40, + 0xb0, 0x16, 0x00, 0x40, 0xc0, 0x18, 0x00, 0x40, 0xa8, 0x18, 0x00, 0x40, + 0x36, 0x81, 0x00, 0x39, 0x31, 0x31, 0xf4, 0xff, 0x81, 0xf7, 0xff, 0xe0, + 0x08, 0x00, 0x30, 0x34, 0x80, 0x20, 0x50, 0xf4, 0xa9, 0x11, 0x81, 0xf4, + 0xff, 0xe0, 0x08, 0x00, 0x50, 0x73, 0x80, 0xa2, 0x61, 0x02, 0x81, 0xf2, + 0xff, 0xe0, 0x08, 0x00, 0x70, 0x30, 0xf5, 0xa0, 0x62, 0x41, 0x46, 0x05, + 0x00, 0x81, 0xea, 0xff, 0xe0, 0x96, 0x11, 0x8a, 0x99, 0xc0, 0x20, 0x00, + 0xa8, 0x09, 0x91, 0xc2, 0xff, 0x97, 0x1a, 0x0e, 0x62, 0xc6, 0x01, 0x81, + 0xea, 0xff, 0xe0, 0x08, 0x00, 0xa0, 0xa2, 0x41, 0xa7, 0x36, 0xdd, 0x81, + 0xe7, 0xff, 0xe0, 0x08, 0x00, 0xa0, 0xa2, 0x41, 0x67, 0x9a, 0x08, 0x81, + 0xe3, 0xff, 0xe0, 0x08, 0x00, 0xa0, 0x62, 0x41, 0x6a, 0x93, 0x99, 0x41, + 0x69, 0x01, 0x81, 0xe0, 0xff, 0xe0, 0x08, 0x00, 0x98, 0x41, 0xa0, 0xa2, + 0x41, 0xa7, 0xb9, 0x70, 0xa1, 0xd8, 0xff, 0xe0, 0x96, 0x11, 0xaa, 0x99, + 0x20, 0x20, 0xf5, 0x0c, 0x0a, 0xc6, 0x02, 0x00, 0x00, 0x2a, 0xba, 0xc0, + 0x20, 0x00, 0xb9, 0x09, 0x1b, 0xaa, 0x4b, 0x99, 0x37, 0x9a, 0xf1, 0x81, + 0xd4, 0xff, 0xe0, 0x08, 0x00, 0xa9, 0x41, 0x81, 0xd2, 0xff, 0xe0, 0x08, + 0x00, 0x98, 0x41, 0x22, 0xd6, 0x3c, 0x90, 0x82, 0x41, 0x2a, 0x88, 0xa0, + 0xa2, 0x41, 0xa0, 0x88, 0xc0, 0x00, 0x88, 0x11, 0x5a, 0x58, 0x81, 0xcb, + 0xff, 0xe0, 0x08, 0x00, 0xa9, 0x41, 0x81, 0xc9, 0xff, 0xe0, 0x08, 0x00, + 0x88, 0x41, 0xb1, 0xc4, 0xff, 0x80, 0x82, 0x41, 0x2a, 0x88, 0xa0, 0xa2, + 0x41, 0xa0, 0xa8, 0xc0, 0xb0, 0xb7, 0x10, 0x00, 0xaa, 0x11, 0x81, 0xc4, + 0xff, 0xe0, 0x08, 0x00, 0x0c, 0x02, 0xc6, 0x01, 0x00, 0x0c, 0x03, 0x39, + 0x01, 0x5d, 0x03, 0x0c, 0x12, 0xa8, 0x21, 0x81, 0xc0, 0xff, 0xe0, 0x08, + 0x00, 0xa8, 0x11, 0x81, 0xbf, 0xff, 0xe0, 0x08, 0x00, 0x56, 0x12, 0x04, + 0xa8, 0x31, 0xcd, 0x04, 0xbd, 0x05, 0x65, 0xcc, 0x01, 0x81, 0xb4, 0xff, + 0xe0, 0x08, 0x00, 0xa0, 0x5a, 0x20, 0x81, 0xb3, 0xff, 0xe0, 0x08, 0x00, + 0x48, 0x01, 0x71, 0xae, 0xff, 0x4a, 0x33, 0x81, 0x88, 0xff, 0xc6, 0x02, + 0x00, 0xe0, 0x64, 0x11, 0x7a, 0x66, 0xc0, 0x20, 0x00, 0x89, 0x06, 0x1b, + 0x44, 0x37, 0x34, 0xf0, 0x81, 0xaf, 0xff, 0xe0, 0x08, 0x00, 0xad, 0x05, + 0x81, 0xae, 0xff, 0xe0, 0x08, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0xbe, + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xff, 0xff, 0x00, + 0x36, 0x81, 0x00, 0x1c, 0x8c, 0xbd, 0x01, 0xad, 0x02, 0xa5, 0xe9, 0xff, + 0x5d, 0x0a, 0x56, 0xea, 0x06, 0x62, 0x01, 0x00, 0x42, 0xa0, 0xe9, 0x47, + 0x96, 0x65, 0x22, 0xc2, 0x18, 0x6d, 0x0a, 0x4d, 0x0a, 0xc6, 0x13, 0x00, + 0xc2, 0xa0, 0x08, 0xb2, 0xc1, 0x18, 0x20, 0xa2, 0x20, 0x65, 0xe7, 0xff, + 0x16, 0x2a, 0x00, 0x46, 0x12, 0x00, 0x98, 0x61, 0x81, 0xee, 0xff, 0xa1, + 0xee, 0xff, 0x80, 0x89, 0x80, 0x87, 0xba, 0x0b, 0x81, 0xed, 0xff, 0xa1, + 0xed, 0xff, 0x80, 0x89, 0x80, 0x87, 0x3a, 0x1b, 0xf6, 0x24, 0x26, 0xf0, + 0x84, 0x11, 0x4a, 0x88, 0xe0, 0x88, 0x11, 0x8a, 0x83, 0x99, 0x28, 0x98, + 0x71, 0x8b, 0xa2, 0x1b, 0x44, 0xa9, 0x18, 0x99, 0x38, 0x40, 0x40, 0xf4, + 0x88, 0x71, 0x1b, 0x66, 0x8b, 0x88, 0x8a, 0x22, 0x82, 0x01, 0x01, 0x87, + 0x26, 0xa9, 0x49, 0x03, 0x86, 0x00, 0x00, 0x00, 0x7c, 0xf5, 0x2d, 0x05, + 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x04, 0x1b, 0x62, 0x2a, 0x54, 0x40, + 0x66, 0x11, 0x3a, 0x22, 0xc6, 0x11, 0x00, 0x00, 0x0c, 0x13, 0x32, 0x45, + 0x00, 0x72, 0xd6, 0xf0, 0x32, 0xa0, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, + 0xc2, 0xa2, 0x00, 0x10, 0xb1, 0x20, 0x70, 0xa7, 0x20, 0x25, 0xdf, 0xff, + 0x56, 0x2a, 0x03, 0x82, 0xa2, 0x00, 0x76, 0x88, 0x11, 0xaa, 0x91, 0x92, + 0x09, 0x00, 0x37, 0x19, 0x07, 0x0c, 0x03, 0x32, 0x45, 0x00, 0x06, 0x03, + 0x00, 0x1b, 0xaa, 0x82, 0x05, 0x00, 0x72, 0xd7, 0x02, 0x8c, 0x18, 0x67, + 0x97, 0xcd, 0x1b, 0x55, 0x62, 0xd6, 0x10, 0x40, 0x75, 0xc0, 0x27, 0x37, + 0xb2, 0x0c, 0x02, 0x46, 0x00, 0x00, 0x7c, 0xf2, 0x1d, 0xf0, 0x00, 0x00, + 0xc0, 0x80, 0x00, 0x60, 0x78, 0x00, 0xce, 0x3f, 0x80, 0x00, 0xce, 0x3f, + 0xd0, 0x05, 0x00, 0x40, 0x36, 0x41, 0x00, 0x21, 0xfb, 0xff, 0xc0, 0x20, + 0x00, 0xc8, 0x02, 0xc0, 0x20, 0xf4, 0xc0, 0x80, 0xf5, 0x87, 0x92, 0x07, + 0x82, 0xcc, 0xff, 0x7c, 0xd9, 0x87, 0xb9, 0x0d, 0xb1, 0xf6, 0xff, 0xa1, + 0xf6, 0xff, 0x2c, 0x82, 0x81, 0xf6, 0xff, 0xe0, 0x08, 0x00, 0x1d, 0xf0, + 0x00, 0x80, 0x00, 0x00, 0xb3, 0x81, 0x00, 0x00, 0xf0, 0x49, 0x02, 0x00, + 0x74, 0x80, 0x00, 0x60, 0x68, 0xf0, 0x01, 0x60, 0xff, 0x9f, 0xff, 0xff, + 0x80, 0xf0, 0x01, 0x60, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 0x80, 0x84, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x01, 0x60, 0x00, 0x06, 0x00, 0x40, + 0x36, 0x41, 0x00, 0x41, 0xf0, 0xff, 0xc0, 0x20, 0x00, 0x38, 0x04, 0x30, + 0x3e, 0x15, 0x66, 0x13, 0x07, 0xa5, 0xf7, 0xff, 0x0c, 0x22, 0x86, 0x07, + 0x00, 0x25, 0xf7, 0xff, 0x0c, 0x12, 0x26, 0x23, 0x16, 0xc0, 0x20, 0x00, + 0x38, 0x04, 0x0c, 0x22, 0x30, 0x3e, 0x15, 0x26, 0x13, 0x09, 0x32, 0xc3, + 0xfe, 0x0c, 0x14, 0x0c, 0x02, 0x30, 0x24, 0x83, 0x41, 0xe3, 0xff, 0xc0, + 0x20, 0x00, 0x38, 0x04, 0x30, 0x38, 0x41, 0x66, 0x22, 0x16, 0x07, 0xe3, + 0x13, 0xc0, 0x20, 0x00, 0x88, 0x04, 0x92, 0xa1, 0x00, 0x90, 0x88, 0x20, + 0xc0, 0x20, 0x00, 0x89, 0x04, 0xc6, 0x05, 0x00, 0x00, 0x66, 0x12, 0x13, + 0x81, 0xd9, 0xff, 0x92, 0xa2, 0x00, 0xc0, 0x20, 0x00, 0x48, 0x08, 0x90, + 0x44, 0x20, 0xc0, 0x20, 0x00, 0x42, 0x68, 0x00, 0x81, 0xd5, 0xff, 0x91, + 0xd5, 0xff, 0xc0, 0x20, 0x00, 0x48, 0x08, 0x90, 0x44, 0x10, 0x30, 0x92, + 0x11, 0x90, 0x44, 0x20, 0xc0, 0x20, 0x00, 0x49, 0x08, 0x41, 0xd0, 0xff, + 0xc0, 0x20, 0x00, 0x48, 0x04, 0x07, 0xe4, 0x13, 0xc0, 0x20, 0x00, 0x42, + 0x28, 0x00, 0xc7, 0x64, 0x0a, 0x41, 0xc5, 0xff, 0xc0, 0x20, 0x00, 0x98, + 0x08, 0x47, 0x09, 0xf7, 0xc0, 0x20, 0x00, 0x48, 0x08, 0x91, 0xc8, 0xff, + 0x90, 0x44, 0x10, 0xc0, 0x20, 0x00, 0x49, 0x08, 0xc0, 0x20, 0x00, 0x48, + 0x08, 0x91, 0xc5, 0xff, 0x90, 0x44, 0x10, 0x91, 0xc5, 0xff, 0x90, 0x44, + 0x20, 0xc0, 0x20, 0x00, 0x49, 0x08, 0x41, 0xbf, 0xff, 0xc0, 0x20, 0x00, + 0x88, 0x04, 0x80, 0x80, 0x64, 0x66, 0x22, 0x10, 0x91, 0xc0, 0xff, 0xc1, + 0xb5, 0xff, 0x90, 0x88, 0x20, 0xc0, 0x20, 0x00, 0x89, 0x04, 0x86, 0x08, + 0x00, 0x66, 0x12, 0x10, 0x91, 0xbb, 0xff, 0xc1, 0xb1, 0xff, 0x90, 0x88, + 0x20, 0xc0, 0x20, 0x00, 0x89, 0x04, 0x86, 0x03, 0x00, 0x91, 0xb7, 0xff, + 0xc1, 0xae, 0xff, 0x90, 0x88, 0x20, 0xc0, 0x20, 0x00, 0x82, 0x64, 0x00, + 0x41, 0xad, 0xff, 0x91, 0xb4, 0xff, 0xc0, 0x20, 0x00, 0x82, 0x24, 0x00, + 0xa1, 0xb4, 0xff, 0x90, 0x88, 0x10, 0xc0, 0x20, 0x00, 0x82, 0x64, 0x00, + 0x91, 0xb0, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x04, 0xb1, 0xb0, 0xff, 0x90, + 0x88, 0x20, 0xc0, 0x20, 0x00, 0x89, 0x04, 0x0c, 0x0d, 0xe5, 0xb2, 0x01, + 0x81, 0xae, 0xff, 0xe0, 0x08, 0x00, 0xb1, 0x9b, 0xff, 0x91, 0xa0, 0xff, + 0xad, 0x04, 0xc0, 0x20, 0x00, 0x88, 0x0a, 0xb7, 0x08, 0x0a, 0x81, 0xa7, + 0xff, 0xc0, 0x20, 0x00, 0x88, 0x08, 0xc6, 0x01, 0x00, 0xc0, 0x20, 0x00, + 0x88, 0x09, 0x07, 0x68, 0xe4, 0xc0, 0x20, 0x00, 0x88, 0x04, 0x91, 0x9d, + 0xff, 0x80, 0x33, 0x11, 0x90, 0x88, 0x10, 0xc0, 0x20, 0x00, 0x89, 0x04, + 0x41, 0x91, 0xff, 0x92, 0xa1, 0x00, 0xc0, 0x20, 0x00, 0x88, 0x04, 0x90, + 0x33, 0x10, 0x92, 0xae, 0xff, 0x90, 0x88, 0x10, 0x80, 0x33, 0x20, 0xc0, + 0x20, 0x00, 0x39, 0x04, 0x66, 0x12, 0x10, 0xc0, 0x20, 0x00, 0x28, 0x04, + 0x32, 0xad, 0xff, 0x30, 0x22, 0x10, 0xc0, 0x20, 0x00, 0x22, 0x64, 0x00, + 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x0c, 0x60, + 0x10, 0x00, 0x0c, 0x60, 0x2c, 0x01, 0xce, 0x3f, 0xff, 0x00, 0xfc, 0xff, + 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x84, 0x80, 0x00, 0x60, + 0xff, 0x3f, 0xc0, 0xff, 0x00, 0xc0, 0x3f, 0x00, 0xff, 0xff, 0x01, 0xfe, + 0x00, 0x00, 0xc8, 0x00, 0x78, 0x80, 0x00, 0x60, 0xff, 0xff, 0xbf, 0xff, + 0xff, 0xff, 0x7f, 0x80, 0x00, 0x00, 0x40, 0x00, 0xff, 0x8f, 0xff, 0xff, + 0x44, 0xe0, 0x00, 0x60, 0x00, 0xff, 0x03, 0x00, 0xff, 0xbf, 0xfd, 0xff, + 0x28, 0x00, 0x28, 0x00, 0xb2, 0x00, 0xce, 0x3f, 0xdf, 0x00, 0xce, 0x3f, + 0xec, 0x00, 0xce, 0x3f, 0xff, 0xf3, 0xff, 0xff, 0x00, 0x80, 0x00, 0x60, + 0x40, 0xe0, 0x00, 0x60, 0x11, 0x01, 0xce, 0x3f, 0xff, 0xff, 0x1f, 0xe0, + 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, + 0xc0, 0x84, 0x00, 0x60, 0xc4, 0x84, 0x00, 0x60, 0x60, 0x80, 0x00, 0x60, + 0xff, 0xff, 0xf1, 0xff, 0x00, 0x00, 0x06, 0x00, 0xff, 0x1f, 0xff, 0xff, + 0x00, 0x60, 0x00, 0x00, 0xff, 0xe3, 0xff, 0xff, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x1c, 0x80, 0x00, 0x60, 0x3f, 0xc0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xfb, + 0x74, 0x00, 0xce, 0x3f, 0x40, 0x42, 0x0f, 0x00, 0x9c, 0x06, 0x00, 0x40, + 0x6c, 0x5d, 0x00, 0x40, 0x60, 0x5d, 0x00, 0x40, 0x36, 0xc1, 0x00, 0x41, + 0xcc, 0xff, 0xc0, 0x20, 0x00, 0x38, 0x04, 0x30, 0x3a, 0x14, 0x26, 0x13, + 0x3f, 0x8c, 0xf3, 0x32, 0xc3, 0xfe, 0x0c, 0x85, 0x0c, 0x04, 0x30, 0x45, + 0x83, 0x3d, 0x04, 0x46, 0x15, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x38, + 0x04, 0x41, 0x33, 0xff, 0x30, 0x30, 0x94, 0xc0, 0x20, 0x00, 0x48, 0x04, + 0x1b, 0x33, 0x40, 0x50, 0xf4, 0x40, 0x60, 0xf5, 0x67, 0x95, 0x09, 0x0b, + 0x44, 0x7c, 0xd6, 0x47, 0x36, 0x02, 0x46, 0x00, 0x00, 0x2c, 0x85, 0x30, + 0x35, 0xc2, 0x86, 0x09, 0x00, 0x31, 0xb9, 0xff, 0xc0, 0x20, 0x00, 0x48, + 0x03, 0xc0, 0x20, 0x00, 0x38, 0x03, 0x40, 0x40, 0x14, 0x5c, 0x03, 0x16, + 0x14, 0x01, 0x32, 0xa0, 0xa0, 0x26, 0x14, 0x0b, 0x42, 0xc4, 0xfe, 0x52, + 0xa0, 0x00, 0x32, 0xa0, 0xf0, 0x40, 0x35, 0x93, 0x26, 0x02, 0x05, 0xe6, + 0x12, 0x05, 0x46, 0x89, 0x01, 0x22, 0xa0, 0xa0, 0x51, 0xae, 0xff, 0x0c, + 0x0a, 0x78, 0x15, 0x48, 0x05, 0x20, 0x50, 0x94, 0x50, 0x60, 0xf4, 0x69, + 0x41, 0x61, 0x2a, 0xff, 0x49, 0x21, 0xc0, 0x20, 0x00, 0x88, 0x06, 0x79, + 0x31, 0x80, 0x9e, 0x15, 0x89, 0xb1, 0xc0, 0x20, 0x00, 0x88, 0x06, 0x99, + 0x61, 0x99, 0x51, 0x80, 0x9d, 0x05, 0x99, 0x71, 0x98, 0x41, 0x89, 0xa1, + 0x80, 0x89, 0x11, 0x91, 0xa1, 0xff, 0x79, 0x11, 0x90, 0x44, 0x10, 0x98, + 0x71, 0x80, 0x44, 0x20, 0xe0, 0x89, 0x01, 0x91, 0x9e, 0xff, 0x71, 0x9f, + 0xff, 0x90, 0x44, 0x10, 0x98, 0x61, 0x80, 0x44, 0x20, 0xd0, 0x89, 0x01, + 0x91, 0x9b, 0xff, 0x90, 0x44, 0x10, 0x80, 0x44, 0x20, 0x49, 0x21, 0x49, + 0x01, 0x40, 0x85, 0x75, 0x40, 0x4d, 0x25, 0x89, 0x91, 0x49, 0x81, 0x81, + 0x97, 0xff, 0xc0, 0x20, 0x00, 0x48, 0x07, 0x80, 0x44, 0x10, 0x81, 0x95, + 0xff, 0x80, 0x44, 0x20, 0xc0, 0x20, 0x00, 0x49, 0x07, 0xc0, 0x20, 0x00, + 0x48, 0x06, 0x71, 0x92, 0xff, 0x70, 0x44, 0x10, 0x71, 0x92, 0xff, 0x81, + 0x93, 0xff, 0x70, 0x44, 0x20, 0xc0, 0x20, 0x00, 0x49, 0x06, 0x41, 0x8f, + 0xff, 0x98, 0x91, 0xc0, 0x20, 0x00, 0x78, 0x04, 0x80, 0x77, 0x10, 0xc0, + 0x20, 0x00, 0x79, 0x04, 0xc0, 0x20, 0x00, 0x78, 0x04, 0x81, 0x8b, 0xff, + 0x80, 0x77, 0x10, 0x90, 0x89, 0x01, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, + 0x79, 0x04, 0xc0, 0x20, 0x00, 0x78, 0x04, 0x81, 0x87, 0xff, 0x80, 0x77, + 0x20, 0xc0, 0x20, 0x00, 0x79, 0x04, 0xc0, 0x20, 0x00, 0x48, 0x06, 0x7c, + 0x77, 0x70, 0x44, 0x10, 0xc0, 0x20, 0x00, 0x49, 0x06, 0xc0, 0x20, 0x00, + 0x48, 0x06, 0x88, 0x81, 0x71, 0x80, 0xff, 0x70, 0x44, 0x10, 0x40, 0x78, + 0x11, 0x70, 0x44, 0x20, 0xc0, 0x20, 0x00, 0x49, 0x06, 0xc0, 0x20, 0x00, + 0x78, 0x06, 0x0c, 0x84, 0x40, 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, 0x06, + 0x61, 0x79, 0xff, 0x81, 0x79, 0xff, 0xc0, 0x20, 0x00, 0x78, 0x06, 0x80, + 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, 0x06, 0xc0, 0x20, 0x00, 0x78, 0x06, + 0x81, 0x75, 0xff, 0x80, 0x77, 0x10, 0xc0, 0x20, 0x00, 0x79, 0x06, 0x81, + 0x90, 0xff, 0xe0, 0x08, 0x00, 0x61, 0xcf, 0xfe, 0x71, 0x71, 0xff, 0xc0, + 0x20, 0x00, 0x79, 0x06, 0x71, 0x5c, 0xff, 0xc0, 0x20, 0x00, 0x68, 0x07, + 0x60, 0x6a, 0x14, 0x26, 0x16, 0x19, 0x8c, 0x36, 0x06, 0x0d, 0x00, 0x00, + 0x00, 0xc0, 0x20, 0x00, 0x48, 0x07, 0xa5, 0xb2, 0xff, 0x40, 0x40, 0x94, + 0x1b, 0x44, 0x40, 0x4a, 0xc2, 0x86, 0x0b, 0x00, 0x41, 0x53, 0xff, 0xc0, + 0x20, 0x00, 0x62, 0x24, 0x00, 0xc0, 0x20, 0x00, 0x42, 0x24, 0x00, 0x60, + 0x60, 0x14, 0x42, 0xa0, 0x50, 0x9c, 0x66, 0x42, 0xa0, 0xa0, 0x26, 0x16, + 0x11, 0x42, 0xa0, 0xf0, 0x26, 0x26, 0x0b, 0xb1, 0xbb, 0xfe, 0xa1, 0x5c, + 0xff, 0x81, 0xbb, 0xfe, 0xe0, 0x08, 0x00, 0xe5, 0xae, 0xff, 0x8d, 0x0a, + 0x57, 0x3a, 0x12, 0x50, 0x7a, 0xc2, 0x70, 0x61, 0x41, 0xaa, 0x66, 0x70, + 0x66, 0xc2, 0x0c, 0x0e, 0x67, 0x15, 0x25, 0xc6, 0x0c, 0x00, 0x5c, 0x06, + 0x67, 0x15, 0x10, 0x62, 0xa0, 0xa0, 0x67, 0x15, 0x10, 0x62, 0xa0, 0xf0, + 0x0c, 0x27, 0x67, 0x15, 0x0a, 0x46, 0x07, 0x00, 0x0c, 0x67, 0x86, 0x00, + 0x00, 0x00, 0x0c, 0x37, 0x0c, 0x1e, 0x82, 0xa1, 0xe0, 0x61, 0x36, 0xff, + 0xc0, 0x20, 0x00, 0x68, 0x06, 0x60, 0x6a, 0x14, 0x56, 0xce, 0x07, 0xc6, + 0x03, 0x00, 0xb1, 0x47, 0xff, 0xa1, 0x47, 0xff, 0x81, 0xa5, 0xfe, 0xe0, + 0x08, 0x00, 0x06, 0xff, 0xff, 0x00, 0x1c, 0x2f, 0xa6, 0x35, 0x01, 0x1c, + 0x7f, 0xa2, 0xa0, 0x6d, 0xd2, 0xa0, 0x04, 0xc2, 0xa0, 0x06, 0xb2, 0xa0, + 0x01, 0x81, 0x5a, 0xff, 0xe0, 0x08, 0x00, 0xa5, 0xae, 0xff, 0x51, 0x27, + 0xff, 0xa2, 0xac, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x05, 0x0b, 0x77, 0xa0, + 0x99, 0x10, 0xc0, 0x20, 0x00, 0x99, 0x05, 0xc0, 0x20, 0x00, 0x88, 0x05, + 0x70, 0x70, 0x94, 0xa0, 0x88, 0x10, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, + 0x79, 0x05, 0xc0, 0x20, 0x00, 0x78, 0x05, 0x81, 0x33, 0xff, 0x80, 0x77, + 0x10, 0xc0, 0x20, 0x00, 0x79, 0x05, 0x26, 0x16, 0x02, 0xc6, 0x7a, 0x00, + 0x61, 0x30, 0xff, 0x72, 0xa5, 0x40, 0xc0, 0x20, 0x00, 0x58, 0x06, 0x46, + 0x75, 0x00, 0x00, 0x00, 0x66, 0x16, 0x02, 0xc6, 0x55, 0x00, 0x71, 0x2a, + 0xff, 0x92, 0xaa, 0xbf, 0xc0, 0x20, 0x00, 0x62, 0x27, 0x00, 0x90, 0x66, + 0x10, 0xc0, 0x20, 0x00, 0x62, 0x67, 0x00, 0x82, 0x61, 0x0e, 0x65, 0xa0, + 0xff, 0x71, 0x24, 0xff, 0x7c, 0xbb, 0xc0, 0x20, 0x00, 0x68, 0x07, 0x88, + 0xe1, 0xb0, 0x66, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x07, 0xc0, 0x20, 0x00, + 0x98, 0x07, 0x0c, 0x86, 0x60, 0x99, 0x20, 0xc0, 0x20, 0x00, 0x99, 0x07, + 0x92, 0xa1, 0xe0, 0x71, 0x03, 0xff, 0x97, 0x98, 0x46, 0xc0, 0x20, 0x00, + 0x88, 0x07, 0x0c, 0x4c, 0xc0, 0x88, 0x20, 0x0c, 0x09, 0xc0, 0x20, 0x00, + 0x89, 0x07, 0xa2, 0xca, 0xe0, 0x0c, 0x37, 0x8d, 0x09, 0xa0, 0x87, 0x93, + 0x89, 0xc1, 0x0c, 0x1b, 0x1c, 0xa8, 0xa0, 0x86, 0x93, 0x0c, 0x5d, 0xed, + 0x0c, 0x6d, 0x0b, 0xa0, 0xed, 0x93, 0xa0, 0x69, 0x93, 0xd2, 0xa0, 0x6b, + 0xa2, 0xa0, 0x66, 0xe9, 0xe1, 0x89, 0xd1, 0x81, 0x24, 0xff, 0xe0, 0x08, + 0x00, 0x7d, 0x06, 0xe8, 0xe1, 0xc6, 0x0c, 0x00, 0xc0, 0x20, 0x00, 0x68, + 0x07, 0xa2, 0xca, 0xe0, 0xb0, 0x66, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x07, + 0x0c, 0x4c, 0x0c, 0x66, 0xa0, 0x6c, 0x93, 0x0c, 0x1b, 0x69, 0xd1, 0x0c, + 0x07, 0x6d, 0x0b, 0xa0, 0x67, 0x93, 0xd2, 0xa0, 0x69, 0xa2, 0xa0, 0x66, + 0x81, 0x17, 0xff, 0xe0, 0x08, 0x00, 0x0c, 0x39, 0x99, 0xc1, 0x0c, 0x5e, + 0xc0, 0xde, 0x11, 0x60, 0xdd, 0x20, 0x0c, 0x2c, 0x0c, 0x1b, 0xa2, 0xa0, + 0x66, 0x81, 0x10, 0xff, 0xe0, 0x08, 0x00, 0xd8, 0xd1, 0x0c, 0x3c, 0x0c, + 0x1b, 0xa2, 0xa0, 0x66, 0x81, 0x0d, 0xff, 0xe0, 0x08, 0x00, 0xfd, 0x07, + 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x5c, 0x0c, 0x1b, 0xa2, 0xa0, 0x66, 0x81, + 0x07, 0xff, 0xe0, 0x08, 0x00, 0xfd, 0x07, 0x0c, 0x4e, 0x0c, 0x6d, 0x0c, + 0x5c, 0x0c, 0x1b, 0xa2, 0xa0, 0x66, 0x81, 0x02, 0xff, 0xe0, 0x08, 0x00, + 0x68, 0xc1, 0xd2, 0xa0, 0x60, 0xd0, 0xd6, 0x20, 0x0c, 0x6c, 0x0c, 0x1b, + 0xa2, 0xa0, 0x66, 0x81, 0xfe, 0xfe, 0xe0, 0x08, 0x00, 0x0c, 0x1d, 0xbd, + 0x0d, 0x0c, 0x2f, 0x0c, 0x0e, 0x0c, 0x9c, 0xa2, 0xa0, 0x66, 0x81, 0xf8, + 0xfe, 0xe0, 0x08, 0x00, 0x0c, 0x2f, 0x0c, 0x4e, 0x0c, 0x5d, 0x0c, 0x6c, + 0x0c, 0x1b, 0xa2, 0xa0, 0x66, 0x81, 0xf3, 0xfe, 0xe0, 0x08, 0x00, 0x0c, + 0x1f, 0x0c, 0x6e, 0x0c, 0x7d, 0xcd, 0x0e, 0xbd, 0x0f, 0xa2, 0xa0, 0x66, + 0x81, 0xef, 0xfe, 0xe0, 0x08, 0x00, 0x5c, 0x07, 0x0c, 0x06, 0x1c, 0x7f, + 0x77, 0x15, 0x22, 0x72, 0xa0, 0xa0, 0x0c, 0x16, 0x77, 0x15, 0x1a, 0x72, + 0xa0, 0xf0, 0x0c, 0x26, 0x1c, 0xef, 0x77, 0x15, 0x10, 0xb1, 0x27, 0xfe, + 0xa1, 0xcf, 0xfe, 0x62, 0xa0, 0x00, 0x81, 0x27, 0xfe, 0xe0, 0x08, 0x00, + 0x1c, 0x7f, 0x0c, 0x0e, 0x0c, 0x4d, 0x0c, 0x6c, 0x0c, 0x1b, 0xa2, 0xa0, + 0x6d, 0x81, 0xdf, 0xfe, 0xe0, 0x08, 0x00, 0xe5, 0x8f, 0xff, 0x71, 0xad, + 0xfe, 0x7c, 0xc8, 0xc0, 0x20, 0x00, 0x58, 0x07, 0x80, 0x55, 0x10, 0x60, + 0x55, 0x20, 0x61, 0xa8, 0xfe, 0xc0, 0x20, 0x00, 0x59, 0x07, 0xc0, 0x20, + 0x00, 0x58, 0x06, 0x72, 0xac, 0x00, 0x70, 0x55, 0x10, 0xc0, 0x20, 0x00, + 0x59, 0x06, 0x71, 0xb9, 0xfe, 0xc0, 0x20, 0x00, 0x58, 0x06, 0x70, 0x55, + 0x10, 0x72, 0xa4, 0x00, 0x70, 0x55, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x06, + 0xa0, 0xea, 0x03, 0x82, 0x21, 0x04, 0xcd, 0x04, 0xa0, 0xb8, 0xa2, 0xa0, + 0xa8, 0x82, 0xd2, 0xa0, 0x00, 0xa5, 0x51, 0x01, 0xa0, 0xea, 0x13, 0x61, + 0x9a, 0xfe, 0x48, 0x01, 0x98, 0x41, 0x60, 0x44, 0x10, 0x68, 0x71, 0x80, + 0x59, 0x11, 0x50, 0x44, 0x20, 0xe0, 0x56, 0x01, 0x61, 0x96, 0xfe, 0x88, + 0x61, 0x60, 0x44, 0x10, 0x61, 0x95, 0xfe, 0x50, 0x44, 0x20, 0x60, 0x44, + 0x10, 0xd0, 0x58, 0x01, 0x61, 0xa8, 0xfe, 0x50, 0x44, 0x20, 0x98, 0x91, + 0x60, 0x44, 0x10, 0x68, 0x81, 0xb0, 0x59, 0x01, 0x50, 0x44, 0x20, 0x30, + 0x56, 0x01, 0x61, 0xa3, 0xfe, 0x60, 0x44, 0x10, 0x61, 0xa3, 0xfe, 0x50, + 0x44, 0x20, 0x51, 0xa2, 0xfe, 0x49, 0x01, 0x60, 0x64, 0x10, 0x57, 0x16, + 0x02, 0x06, 0x21, 0x00, 0x71, 0xa0, 0xfe, 0x81, 0xa2, 0xfe, 0xc0, 0x20, + 0x00, 0x58, 0x07, 0x60, 0x55, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x07, 0x71, + 0x9c, 0xfe, 0xc0, 0x20, 0x00, 0x58, 0x07, 0x60, 0x55, 0x20, 0xc0, 0x20, + 0x00, 0x59, 0x07, 0x51, 0x99, 0xfe, 0xc0, 0x20, 0x00, 0x78, 0x05, 0x80, + 0x77, 0x10, 0x81, 0x98, 0xfe, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, + 0x05, 0xc0, 0x20, 0x00, 0x78, 0x05, 0x81, 0x95, 0xfe, 0x80, 0x77, 0x10, + 0x81, 0x95, 0xfe, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, 0x05, 0xc0, + 0x20, 0x00, 0x78, 0x05, 0x81, 0x92, 0xfe, 0x80, 0x77, 0x10, 0x81, 0x91, + 0xfe, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, 0x05, 0xc0, 0x20, 0x00, + 0x78, 0x05, 0x82, 0xa2, 0x00, 0x80, 0x77, 0x20, 0xc0, 0x20, 0x00, 0x79, + 0x05, 0xc0, 0x20, 0x00, 0x78, 0x05, 0x81, 0x8a, 0xfe, 0x80, 0x77, 0x20, + 0xc0, 0x20, 0x00, 0x79, 0x05, 0x27, 0x74, 0x58, 0x51, 0xe2, 0xfd, 0x72, + 0xaf, 0xbf, 0xc0, 0x20, 0x00, 0x48, 0x05, 0x81, 0x86, 0xfe, 0x70, 0x44, + 0x10, 0x71, 0x83, 0xfe, 0xc0, 0x20, 0x00, 0x49, 0x05, 0xc0, 0x20, 0x00, + 0x48, 0x07, 0x3c, 0x2a, 0x80, 0x44, 0x10, 0x82, 0xa1, 0x40, 0x80, 0x44, + 0x20, 0xc0, 0x20, 0x00, 0x49, 0x07, 0x81, 0xe4, 0xfd, 0xe0, 0x08, 0x00, + 0x41, 0xdc, 0xfd, 0x47, 0x96, 0x0e, 0xc0, 0x20, 0x00, 0x48, 0x05, 0x62, + 0xaf, 0x7f, 0x60, 0x44, 0x10, 0xc6, 0x02, 0x00, 0x00, 0xc0, 0x20, 0x00, + 0x48, 0x05, 0x62, 0xa0, 0x80, 0x60, 0x44, 0x20, 0xc0, 0x20, 0x00, 0x49, + 0x05, 0x41, 0xcb, 0xfd, 0x61, 0xa0, 0xfc, 0xc0, 0x20, 0x00, 0x58, 0x04, + 0x88, 0xa1, 0x60, 0x55, 0x10, 0x61, 0x9d, 0xfc, 0x0c, 0x3a, 0x60, 0x68, + 0x10, 0x60, 0x55, 0x20, 0xc0, 0x20, 0x00, 0x52, 0x64, 0x00, 0x81, 0xd1, + 0xfd, 0xe0, 0x08, 0x00, 0xc0, 0x20, 0x00, 0x58, 0x04, 0x61, 0x68, 0xfe, + 0x98, 0xb1, 0x60, 0x55, 0x10, 0x61, 0x67, 0xfe, 0x0c, 0x08, 0x60, 0x69, + 0x10, 0x60, 0x55, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x04, 0xc0, 0x20, 0x00, + 0x58, 0x04, 0x98, 0x51, 0x62, 0xae, 0xff, 0x60, 0x55, 0x10, 0x72, 0xa1, + 0x00, 0x0b, 0x69, 0x9d, 0x08, 0x60, 0x97, 0x83, 0x90, 0x55, 0x20, 0xc0, + 0x20, 0x00, 0x59, 0x04, 0xc0, 0x20, 0x00, 0x58, 0x04, 0x61, 0x5b, 0xfe, + 0x98, 0x51, 0x71, 0x2c, 0xfe, 0x60, 0x55, 0x10, 0x62, 0xc9, 0xfe, 0x60, + 0x78, 0x93, 0x70, 0x55, 0x20, 0xc0, 0x20, 0x00, 0x52, 0x64, 0x00, 0xa2, + 0xa1, 0x2c, 0x81, 0xb8, 0xfd, 0xe0, 0x08, 0x00, 0x41, 0x55, 0xfe, 0x40, + 0x22, 0x82, 0x41, 0x52, 0xfe, 0x29, 0x04, 0x2d, 0x03, 0x1d, 0xf0, 0x00, + 0x10, 0x00, 0xce, 0x3f, 0x34, 0x00, 0xce, 0x3f, 0x36, 0x41, 0x00, 0xb0, + 0xeb, 0x03, 0xb0, 0xbd, 0x04, 0x21, 0x69, 0xfc, 0x56, 0xab, 0x01, 0xc2, + 0xa0, 0x18, 0x20, 0xa2, 0x20, 0x65, 0x2d, 0x01, 0x31, 0xf8, 0xff, 0x0c, + 0x18, 0x39, 0x22, 0x31, 0xf7, 0xff, 0x39, 0x32, 0x31, 0x62, 0xfc, 0x82, + 0x43, 0x00, 0x0c, 0x03, 0x88, 0x02, 0xcc, 0x88, 0x1b, 0x33, 0x8b, 0x22, + 0x66, 0x33, 0xf4, 0x86, 0x03, 0x00, 0x88, 0x08, 0xa8, 0x12, 0xe0, 0x08, + 0x00, 0x16, 0xba, 0xfe, 0x7c, 0xf2, 0x06, 0x04, 0x00, 0x31, 0x84, 0xfc, + 0x20, 0x63, 0x40, 0x81, 0x9a, 0xfc, 0x80, 0x22, 0x20, 0x20, 0x73, 0x40, + 0x0c, 0x02, 0x1d, 0xf0, 0x80, 0x01, 0xce, 0x3f, 0xec, 0x1c, 0x00, 0x40, + 0x10, 0x1d, 0x00, 0x40, 0x34, 0x1d, 0x00, 0x40, 0x40, 0x1d, 0x00, 0x40, + 0xf8, 0x1c, 0x00, 0x40, 0x36, 0x41, 0x00, 0x81, 0x82, 0xfd, 0x0c, 0x07, + 0x80, 0x81, 0xc0, 0x10, 0x18, 0x00, 0x81, 0xf7, 0xff, 0xe0, 0x08, 0x00, + 0x61, 0xf5, 0xff, 0x0c, 0x2b, 0xad, 0x06, 0x81, 0xf5, 0xff, 0xe0, 0x08, + 0x00, 0x06, 0x0a, 0x00, 0x81, 0x7a, 0xfd, 0xbd, 0x01, 0x80, 0x53, 0x63, + 0xcd, 0x05, 0x20, 0xa7, 0x80, 0x25, 0x35, 0xff, 0x56, 0xfa, 0x03, 0x50, + 0xd0, 0x14, 0xcc, 0xad, 0xcd, 0x05, 0xbd, 0x01, 0xad, 0x06, 0x81, 0xec, + 0xff, 0xe0, 0x08, 0x00, 0x50, 0x33, 0xc0, 0x5a, 0x77, 0x56, 0x33, 0xfd, + 0xcc, 0xe4, 0xb2, 0xa0, 0xd8, 0xad, 0x06, 0x25, 0x04, 0x01, 0x2d, 0x04, + 0x46, 0x06, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x04, 0xad, 0x06, 0x81, 0xe4, + 0xff, 0xe0, 0x08, 0x00, 0x81, 0xe4, 0xff, 0xe0, 0x08, 0x00, 0x2d, 0x03, + 0x46, 0x00, 0x00, 0x7c, 0xf2, 0x1d, 0xf0, 0x00, 0x83, 0xde, 0x1b, 0x43, + 0xcc, 0x1b, 0x00, 0x40, 0x36, 0x41, 0x00, 0x81, 0xfe, 0xff, 0xe0, 0x08, + 0x00, 0x21, 0x0d, 0xfe, 0x81, 0xfb, 0xff, 0x28, 0x02, 0x0c, 0x03, 0x80, + 0x22, 0xa2, 0x20, 0x22, 0xd5, 0x20, 0x2a, 0xc2, 0x1d, 0xf0, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x36, 0x41, 0x00, 0xa5, 0xfd, 0xff, 0x81, 0xfd, + 0xff, 0x91, 0xfc, 0xff, 0x82, 0x62, 0x02, 0x92, 0x62, 0x03, 0x81, 0x63, + 0xfd, 0x91, 0x62, 0xfd, 0xa2, 0x62, 0x00, 0xb9, 0x12, 0x89, 0x42, 0x99, + 0x52, 0x1d, 0xf0, 0x00, 0x36, 0x81, 0x00, 0x21, 0x1a, 0xfc, 0xa2, 0xa1, + 0x03, 0x22, 0x02, 0x00, 0x9c, 0xc2, 0x21, 0x18, 0xfc, 0xa2, 0xa1, 0x06, + 0x88, 0x22, 0x9c, 0x28, 0x88, 0x48, 0x8c, 0xe8, 0xad, 0x01, 0xe5, 0xfb, + 0xff, 0x88, 0x22, 0xa8, 0x32, 0x88, 0x48, 0xbd, 0x01, 0xe0, 0x08, 0x00, + 0x2d, 0x0a, 0x1d, 0xf0, 0x36, 0x81, 0x00, 0xa2, 0xa1, 0x02, 0x16, 0xc2, + 0x02, 0x31, 0x0c, 0xfc, 0xa2, 0xa1, 0x03, 0x32, 0x03, 0x00, 0x16, 0x03, + 0x02, 0x31, 0x0a, 0xfc, 0xa2, 0xa1, 0x06, 0x82, 0x23, 0x02, 0x9c, 0x48, + 0x88, 0x28, 0x9c, 0x08, 0xad, 0x01, 0x65, 0xf8, 0xff, 0x88, 0x23, 0xa8, + 0x33, 0x88, 0x28, 0xcd, 0x01, 0xbd, 0x02, 0xe0, 0x08, 0x00, 0x2d, 0x0a, + 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x81, 0x00, 0xad, 0x02, 0xac, 0x72, 0x31, + 0xfe, 0xfb, 0x32, 0x03, 0x00, 0xad, 0x03, 0x9c, 0xd3, 0x31, 0xfc, 0xfb, + 0xa8, 0x23, 0x9c, 0x6a, 0x88, 0x1a, 0xad, 0x08, 0x9c, 0x08, 0xad, 0x01, + 0xe5, 0xf4, 0xff, 0x88, 0x23, 0xa8, 0x33, 0x88, 0x18, 0xcd, 0x01, 0xbd, + 0x02, 0xe0, 0x08, 0x00, 0x2d, 0x0a, 0x1d, 0xf0, 0x36, 0x81, 0x00, 0xa2, + 0xa1, 0x02, 0x16, 0xc2, 0x02, 0x31, 0xf0, 0xfb, 0xa2, 0xa1, 0x03, 0x32, + 0x03, 0x00, 0x16, 0x03, 0x02, 0x31, 0xee, 0xfb, 0xa2, 0xa1, 0x06, 0x82, + 0x23, 0x02, 0x9c, 0x48, 0x88, 0x68, 0x9c, 0x08, 0xad, 0x01, 0x65, 0xf1, + 0xff, 0x88, 0x23, 0xa8, 0x33, 0x88, 0x78, 0xcd, 0x01, 0xbd, 0x02, 0xe0, + 0x08, 0x00, 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x81, 0x00, 0x32, + 0x22, 0x00, 0x30, 0xa3, 0x20, 0x16, 0x83, 0x02, 0x31, 0xe1, 0xfb, 0x32, + 0x03, 0x00, 0xad, 0x03, 0x9c, 0xd3, 0x31, 0xdf, 0xfb, 0xa8, 0x23, 0x9c, + 0x6a, 0x88, 0x6a, 0xad, 0x08, 0x9c, 0x08, 0xad, 0x01, 0xa5, 0xed, 0xff, + 0x88, 0x23, 0xa8, 0x33, 0x88, 0x68, 0xcd, 0x01, 0xbd, 0x02, 0xe0, 0x08, + 0x00, 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x61, 0x00, 0x0c, + 0x16, 0x06, 0x0c, 0x00, 0x65, 0xe9, 0xff, 0x42, 0x23, 0x00, 0x72, 0x23, + 0x01, 0x40, 0x4a, 0xc0, 0x60, 0x56, 0x20, 0x47, 0x3a, 0x01, 0x0c, 0x05, + 0x70, 0xbb, 0xc0, 0x50, 0xbb, 0xc0, 0x58, 0x33, 0x49, 0x43, 0xb9, 0x53, + 0x57, 0x2b, 0x0d, 0xb7, 0x15, 0x02, 0x86, 0x6a, 0x00, 0x58, 0x23, 0x57, + 0x34, 0x02, 0x86, 0x68, 0x00, 0x58, 0x02, 0xc0, 0x20, 0x00, 0x48, 0x12, + 0x58, 0x05, 0xc0, 0x20, 0x00, 0xa8, 0x12, 0xe0, 0x05, 0x00, 0x5d, 0x0a, + 0x56, 0x2a, 0x19, 0x7c, 0xf3, 0x40, 0x33, 0x30, 0x30, 0x30, 0x04, 0xe0, + 0x63, 0x11, 0x6a, 0x62, 0xc0, 0x20, 0x00, 0xa9, 0x26, 0xc0, 0x20, 0x00, + 0x68, 0x12, 0xad, 0x03, 0x1b, 0x66, 0xc0, 0x20, 0x00, 0x69, 0x12, 0x68, + 0x02, 0x2b, 0x33, 0x68, 0x16, 0xd0, 0x33, 0x11, 0x30, 0x32, 0x80, 0xe0, + 0x06, 0x00, 0x78, 0x03, 0x38, 0x02, 0xa2, 0x23, 0x03, 0xe0, 0x0a, 0x00, + 0x16, 0x2a, 0x13, 0x82, 0x17, 0x00, 0x16, 0xc8, 0x12, 0x6d, 0x05, 0x9d, + 0x05, 0xc0, 0x20, 0x00, 0x38, 0xb2, 0xc0, 0x20, 0x00, 0xa8, 0xc2, 0x37, + 0x3a, 0x1d, 0xc0, 0x20, 0x00, 0x38, 0x92, 0xc0, 0x20, 0x00, 0xa8, 0xc2, + 0xa0, 0x33, 0xc0, 0x16, 0x63, 0x10, 0xc0, 0x20, 0x00, 0xa8, 0xb2, 0xdc, + 0x9a, 0x0b, 0x33, 0x86, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x38, + 0xb2, 0xc0, 0x20, 0x00, 0xa2, 0x22, 0x0c, 0x32, 0xc3, 0xff, 0xa0, 0x33, + 0xc0, 0x16, 0x43, 0x0e, 0x60, 0xa8, 0xc0, 0x30, 0x3a, 0x63, 0xb8, 0x82, + 0xc0, 0x20, 0x00, 0xa8, 0xc2, 0xc0, 0x20, 0x00, 0xc8, 0xb2, 0xc0, 0x20, + 0x00, 0xd8, 0xc2, 0xaa, 0xab, 0xc7, 0xbd, 0x02, 0x46, 0x21, 0x00, 0xc0, + 0x20, 0x00, 0xc8, 0xc2, 0xc0, 0x20, 0x00, 0xd8, 0x92, 0xca, 0xc3, 0xd7, + 0xbc, 0x02, 0x86, 0x21, 0x00, 0xc0, 0x20, 0x00, 0xc8, 0xb2, 0x16, 0xec, + 0x08, 0xc0, 0x20, 0x00, 0xc8, 0xc2, 0xc0, 0x20, 0x00, 0xd8, 0x92, 0xca, + 0xc3, 0xd7, 0x9c, 0x07, 0xc0, 0x20, 0x00, 0x99, 0xc2, 0x06, 0x1d, 0x00, + 0xc0, 0x20, 0x00, 0xa8, 0xb2, 0x0b, 0xaa, 0x37, 0x3a, 0x6d, 0xc0, 0x20, + 0x00, 0xa8, 0xc2, 0xc0, 0x20, 0x00, 0xa9, 0xa2, 0xc0, 0x20, 0x00, 0x99, + 0xc2, 0xc0, 0x20, 0x00, 0xc8, 0xb2, 0xc0, 0x20, 0x00, 0xa8, 0xa2, 0xa7, + 0x9c, 0x1d, 0xc0, 0x20, 0x00, 0x99, 0xb2, 0xc0, 0x20, 0x00, 0xc8, 0xa2, + 0xc0, 0x20, 0x00, 0xa8, 0x92, 0xa7, 0xbc, 0x0b, 0xc0, 0x20, 0x00, 0xa2, + 0x22, 0x09, 0xc0, 0x20, 0x00, 0xa2, 0x62, 0x0a, 0xc0, 0x20, 0x00, 0xa8, + 0xc2, 0xaa, 0xa3, 0xc0, 0x20, 0x00, 0xa9, 0xc2, 0xad, 0x0b, 0xc6, 0x07, + 0x00, 0xc0, 0x20, 0x00, 0xb8, 0xb2, 0xc0, 0x20, 0x00, 0xc2, 0x22, 0x0c, + 0x0b, 0xbb, 0xc0, 0xbb, 0xc0, 0x37, 0x3b, 0x0f, 0xc0, 0x20, 0x00, 0xb8, + 0xc2, 0xba, 0xb3, 0xc0, 0x20, 0x00, 0xb2, 0x62, 0x0c, 0x56, 0x3a, 0x00, + 0x06, 0xff, 0xff, 0x00, 0x2b, 0xb6, 0xcd, 0x03, 0xba, 0xb7, 0x89, 0x01, + 0x99, 0x11, 0xa5, 0xdc, 0x00, 0x88, 0x01, 0x3a, 0x66, 0x98, 0x11, 0x87, + 0xb6, 0x02, 0xc6, 0xb6, 0xff, 0x0c, 0x03, 0x32, 0x57, 0x00, 0x40, 0x40, + 0x04, 0xe0, 0x44, 0x11, 0x4a, 0x42, 0xc0, 0x20, 0x00, 0xa8, 0x12, 0x28, + 0x02, 0xc0, 0x20, 0x00, 0xb8, 0x24, 0x22, 0x22, 0x02, 0xe0, 0x02, 0x00, + 0x46, 0x06, 0x00, 0x00, 0x52, 0xa1, 0x07, 0x86, 0x04, 0x00, 0x48, 0x23, + 0x26, 0x04, 0x02, 0x46, 0x87, 0xff, 0x48, 0x33, 0x66, 0x04, 0x02, 0x86, + 0x91, 0xff, 0x86, 0x84, 0xff, 0x2d, 0x05, 0x1d, 0xf0, 0x00, 0x00, 0x00, + 0x36, 0x41, 0x00, 0x50, 0xeb, 0x03, 0x50, 0x5d, 0x04, 0x82, 0x02, 0x00, + 0xa2, 0xa1, 0x03, 0x57, 0x58, 0x3f, 0xc0, 0x20, 0x00, 0x88, 0x22, 0x4b, + 0x52, 0x80, 0x80, 0x04, 0xe0, 0x88, 0x11, 0x8a, 0x82, 0xc0, 0x20, 0x00, + 0x88, 0x38, 0x37, 0xb8, 0x10, 0x0c, 0x0a, 0xc6, 0x08, 0x00, 0x40, 0xb4, + 0x20, 0x50, 0xa5, 0x20, 0xe5, 0xdc, 0xff, 0x56, 0x7a, 0x01, 0xc0, 0x20, + 0x00, 0x88, 0x22, 0x80, 0x80, 0x04, 0xe0, 0x88, 0x11, 0x8a, 0x82, 0xc0, + 0x20, 0x00, 0x88, 0x38, 0x87, 0x33, 0xde, 0x86, 0xf5, 0xff, 0x2d, 0x0a, + 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x00, 0x40, 0xeb, 0x03, 0x40, 0x4d, + 0x04, 0x82, 0x02, 0x00, 0xa2, 0xa1, 0x03, 0x47, 0x58, 0x35, 0xc0, 0x20, + 0x00, 0x88, 0x22, 0x4b, 0x42, 0x80, 0x80, 0x04, 0xe0, 0x88, 0x11, 0x8a, + 0x82, 0xc0, 0x20, 0x00, 0x88, 0x38, 0x46, 0x02, 0x00, 0x00, 0xbd, 0x03, + 0xad, 0x04, 0xe5, 0xd7, 0xff, 0xdc, 0x3a, 0xc0, 0x20, 0x00, 0x88, 0x22, + 0x80, 0x80, 0x04, 0xe0, 0x88, 0x11, 0x8a, 0x82, 0xc0, 0x20, 0x00, 0xa8, + 0x38, 0x56, 0x1a, 0xfe, 0x2d, 0x0a, 0x1d, 0xf0, 0x36, 0x41, 0x00, 0x5d, + 0x02, 0x80, 0xeb, 0x03, 0x80, 0x8d, 0x04, 0x92, 0x02, 0x00, 0x0c, 0x16, + 0x4b, 0x22, 0x87, 0xd9, 0x06, 0x0c, 0x02, 0x46, 0x41, 0x00, 0x00, 0x00, + 0xc0, 0x20, 0x00, 0x88, 0xc5, 0xc0, 0x20, 0x00, 0x98, 0xd5, 0x87, 0x39, + 0x07, 0xc0, 0x20, 0x00, 0x88, 0xd5, 0x06, 0x01, 0x00, 0xc0, 0x20, 0x00, + 0x88, 0xb5, 0xc0, 0x20, 0x00, 0x98, 0xc5, 0x90, 0x88, 0xc0, 0x16, 0x38, + 0x08, 0x28, 0x03, 0x20, 0x88, 0x63, 0x89, 0x03, 0xc0, 0x20, 0x00, 0x28, + 0xc5, 0x38, 0x95, 0x2a, 0x23, 0xc0, 0x20, 0x00, 0x38, 0xc5, 0xc0, 0x20, + 0x00, 0x48, 0xd5, 0x37, 0x34, 0x11, 0xc0, 0x20, 0x00, 0x38, 0xc5, 0xc0, + 0x20, 0x00, 0x48, 0xd5, 0x3a, 0x38, 0x37, 0x34, 0x52, 0x06, 0x10, 0x00, + 0xc0, 0x20, 0x00, 0x38, 0xc5, 0xc0, 0x20, 0x00, 0x48, 0xb5, 0x3a, 0x38, + 0x37, 0x34, 0x40, 0xc0, 0x20, 0x00, 0x38, 0xc5, 0xc0, 0x20, 0x00, 0x48, + 0xb5, 0x3a, 0x38, 0x47, 0x93, 0x22, 0xc0, 0x20, 0x00, 0x48, 0xb5, 0xc0, + 0x20, 0x00, 0x38, 0xa5, 0x37, 0xb4, 0x09, 0xc0, 0x20, 0x00, 0x38, 0xa5, + 0xc0, 0x20, 0x00, 0x39, 0xb5, 0x0c, 0x03, 0xc0, 0x20, 0x00, 0x39, 0xc5, + 0x46, 0x03, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x38, 0xc5, 0x3a, 0x88, + 0xc0, 0x20, 0x00, 0x89, 0xc5, 0x56, 0xf2, 0x05, 0x06, 0xff, 0xff, 0x00, + 0x00, 0x82, 0x25, 0x01, 0xa2, 0x28, 0x03, 0xe0, 0x0a, 0x00, 0x16, 0xaa, + 0x00, 0xbd, 0x04, 0xad, 0x02, 0xa5, 0xc8, 0xff, 0x06, 0xd0, 0xff, 0x00, + 0x82, 0x24, 0x02, 0x66, 0x08, 0x08, 0x82, 0x24, 0x03, 0x66, 0x08, 0x02, + 0x06, 0xcc, 0xff, 0x65, 0xb1, 0xff, 0x82, 0x24, 0x00, 0xc8, 0x14, 0x80, + 0x8a, 0xc0, 0x9d, 0x06, 0x87, 0x3a, 0x01, 0x0c, 0x09, 0xc0, 0xbb, 0xc0, + 0x90, 0xbb, 0xc0, 0x98, 0x34, 0x89, 0x44, 0xb9, 0x54, 0x97, 0xab, 0x02, + 0x06, 0xc3, 0xff, 0xb7, 0x19, 0x02, 0xc6, 0xbf, 0xff, 0x98, 0x24, 0x97, + 0xb8, 0x02, 0x86, 0xbf, 0xff, 0x06, 0xbd, 0xff, 0x1d, 0xf0, 0x00, 0x00, + 0x36, 0x41, 0x00, 0xbd, 0x04, 0x50, 0xeb, 0x03, 0x50, 0x5d, 0x04, 0x82, + 0x02, 0x00, 0x57, 0xd8, 0x06, 0x0c, 0x02, 0x06, 0x45, 0x00, 0x00, 0x00, + 0xc0, 0x20, 0x00, 0x52, 0x22, 0x02, 0x50, 0x50, 0x04, 0x52, 0xc5, 0x02, + 0xd0, 0x55, 0x11, 0x50, 0x52, 0x80, 0x58, 0x25, 0x52, 0xc5, 0xfc, 0x37, + 0x35, 0xde, 0xc0, 0x20, 0x00, 0x58, 0x22, 0x50, 0x50, 0x04, 0xe0, 0x55, + 0x11, 0x5a, 0x52, 0xc0, 0x20, 0x00, 0x98, 0x35, 0xc0, 0x20, 0x00, 0x88, + 0x22, 0x4b, 0x53, 0x80, 0x80, 0x04, 0x2b, 0x88, 0xd0, 0x88, 0x11, 0x8a, + 0x82, 0x88, 0x28, 0x5a, 0x99, 0x97, 0xb8, 0x77, 0x4b, 0xa2, 0xe5, 0xbd, + 0xff, 0x56, 0xca, 0xfa, 0xc0, 0x20, 0x00, 0x88, 0x22, 0x50, 0x90, 0xf4, + 0x80, 0x80, 0x04, 0xe0, 0x88, 0x11, 0x8a, 0x82, 0xc0, 0x20, 0x00, 0xa8, + 0x38, 0xc0, 0x20, 0x00, 0x88, 0x22, 0xaa, 0x99, 0x80, 0x80, 0x04, 0x2b, + 0x88, 0xd0, 0x88, 0x11, 0x8a, 0x82, 0x88, 0x28, 0x97, 0x38, 0x81, 0xc0, + 0x20, 0x00, 0x98, 0x22, 0xc0, 0x20, 0x00, 0x88, 0x22, 0x90, 0x90, 0x04, + 0x80, 0x80, 0x04, 0x2b, 0x99, 0xe0, 0x88, 0x11, 0xd0, 0x99, 0x11, 0x8a, + 0x82, 0x9a, 0x92, 0xc0, 0x20, 0x00, 0x88, 0x38, 0x98, 0x19, 0x8a, 0x89, + 0x16, 0x98, 0xf5, 0xc0, 0x20, 0x00, 0x98, 0x22, 0x90, 0x90, 0x04, 0xe0, + 0x99, 0x11, 0x9a, 0x22, 0xc0, 0x20, 0x00, 0x98, 0x32, 0x5a, 0x59, 0xc0, + 0x20, 0x00, 0x59, 0x32, 0x46, 0x10, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x98, + 0x22, 0xc0, 0x20, 0x00, 0x88, 0x22, 0x90, 0x90, 0x04, 0x80, 0x80, 0x04, + 0x2b, 0x99, 0xe0, 0x88, 0x11, 0xd0, 0x99, 0x11, 0x8a, 0x82, 0x9a, 0x92, + 0xc0, 0x20, 0x00, 0x88, 0x38, 0x98, 0x19, 0x8a, 0x89, 0xc0, 0x20, 0x00, + 0x98, 0x22, 0x90, 0x90, 0x04, 0xe0, 0x99, 0x11, 0x9a, 0x22, 0xc0, 0x20, + 0x00, 0x98, 0x32, 0x5a, 0x59, 0xc0, 0x20, 0x00, 0x59, 0x32, 0x16, 0xb8, + 0xef, 0x20, 0xeb, 0x03, 0x20, 0x2d, 0x04, 0x10, 0x22, 0x11, 0x30, 0x32, + 0x20, 0x0c, 0x02, 0x22, 0x58, 0x01, 0x32, 0x58, 0x00, 0x4b, 0x28, 0x1d, + 0xf0, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, + 0x2c, 0x0a, 0x00, 0x40, 0xfc, 0x09, 0x00, 0x40, 0x08, 0x0a, 0x00, 0x40, + 0x36, 0x41, 0x00, 0x20, 0x40, 0xb4, 0x8c, 0x44, 0x41, 0xf9, 0xff, 0x40, + 0x22, 0x10, 0x30, 0x40, 0xb4, 0x16, 0xb4, 0x00, 0x41, 0xf7, 0xff, 0x40, + 0x33, 0x80, 0x41, 0xf4, 0xff, 0x40, 0x33, 0x10, 0x65, 0x97, 0xff, 0x51, + 0x95, 0xfa, 0x30, 0x42, 0x80, 0x62, 0x25, 0x00, 0x82, 0x26, 0x01, 0x47, + 0x38, 0x75, 0x48, 0x36, 0x40, 0x42, 0xe2, 0x56, 0xd4, 0x06, 0x81, 0xee, + 0xff, 0xe0, 0x08, 0x00, 0x56, 0x4a, 0x06, 0x58, 0x05, 0x68, 0x35, 0x58, + 0x25, 0x60, 0x83, 0xc2, 0x60, 0x42, 0xc2, 0x60, 0x55, 0xc2, 0x60, 0x33, + 0xe2, 0x1b, 0x28, 0x50, 0x64, 0xe2, 0x30, 0x28, 0x83, 0x60, 0x65, 0xc0, + 0x20, 0x66, 0x43, 0x4a, 0x36, 0xc6, 0x02, 0x00, 0xad, 0x04, 0x81, 0xe3, + 0xff, 0xe0, 0x08, 0x00, 0xfc, 0x4a, 0x1b, 0x44, 0x37, 0x94, 0xf0, 0x60, + 0x22, 0xc0, 0xc6, 0x03, 0x00, 0x50, 0xa3, 0xc2, 0x81, 0xdf, 0xff, 0xe0, + 0x08, 0x00, 0xdc, 0xea, 0x5a, 0x33, 0x50, 0x22, 0xc0, 0x27, 0x35, 0xec, + 0x3a, 0x32, 0x46, 0x02, 0x00, 0x81, 0xd8, 0xff, 0xe0, 0x08, 0x00, 0xcc, + 0x9a, 0x0b, 0x22, 0x20, 0xa3, 0xc0, 0xe6, 0x12, 0xef, 0x46, 0x01, 0x00, + 0x7c, 0xf2, 0x46, 0x01, 0x00, 0x00, 0xa5, 0x8e, 0xff, 0x0c, 0x02, 0x1d, + 0xf0, 0x00, 0x00, 0x00, 0x70, 0x00, 0xce, 0x3f, 0x34, 0x70, 0x00, 0x60, + 0x2c, 0x70, 0x00, 0x60, 0x30, 0x70, 0x00, 0x60, 0x6c, 0x00, 0xce, 0x3f, + 0x6c, 0x09, 0x00, 0x40, 0x14, 0x0a, 0x00, 0x40, 0x36, 0x41, 0x00, 0x25, + 0x8c, 0xff, 0xa1, 0xf7, 0xff, 0x82, 0x0a, 0x00, 0x16, 0x38, 0x06, 0x81, + 0xf6, 0xff, 0xb2, 0xa0, 0x01, 0xc0, 0x20, 0x00, 0x92, 0x28, 0x00, 0x82, + 0xa0, 0x00, 0x90, 0x92, 0x25, 0xc6, 0x02, 0x00, 0x07, 0x69, 0x05, 0xb0, + 0x88, 0x30, 0x80, 0x80, 0x74, 0x90, 0x91, 0x41, 0x56, 0x09, 0xff, 0xb1, + 0xf0, 0xff, 0xbc, 0x28, 0x81, 0xed, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x08, + 0x47, 0xe8, 0x0d, 0x81, 0xe9, 0xff, 0xc0, 0x20, 0x00, 0x88, 0x08, 0x80, + 0x82, 0x25, 0x66, 0x78, 0x1c, 0x91, 0xe7, 0xff, 0xc0, 0x20, 0x00, 0x88, + 0x09, 0xc0, 0x20, 0x00, 0x98, 0x09, 0x80, 0x84, 0xb5, 0x90, 0x9a, 0x41, + 0x90, 0x88, 0x10, 0x07, 0x68, 0x03, 0x0c, 0x28, 0x89, 0x0b, 0x0c, 0x08, + 0x82, 0x4a, 0x00, 0x81, 0xe0, 0xff, 0xcd, 0x04, 0x88, 0x08, 0xbd, 0x03, + 0x20, 0xa2, 0x20, 0x16, 0x98, 0x00, 0x81, 0xdd, 0xff, 0xe0, 0x08, 0x00, + 0x86, 0x01, 0x00, 0x00, 0x81, 0xdc, 0xff, 0xe0, 0x08, 0x00, 0x2d, 0x0a, + 0xe5, 0x82, 0xff, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x58, 0x02, 0xce, 0x3f, + 0xf8, 0xaa, 0x00, 0x00, 0xf4, 0xaa, 0x00, 0x00, 0xf0, 0xaa, 0x00, 0x00, + 0xff, 0x7f, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x10, 0xab, 0x00, 0x00, + 0x1c, 0xab, 0x00, 0x00, 0x14, 0xab, 0x00, 0x00, 0x18, 0xab, 0x00, 0x00, + 0x20, 0xab, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x30, 0xab, 0x00, 0x00, + 0x34, 0xab, 0x00, 0x00, 0x2c, 0xab, 0x00, 0x00, 0x28, 0xab, 0x00, 0x00, + 0x24, 0xab, 0x00, 0x00, 0x08, 0xab, 0x00, 0x00, 0x40, 0xab, 0x00, 0x00, + 0x28, 0x08, 0x00, 0x40, 0x36, 0x41, 0x00, 0x81, 0xfd, 0xff, 0x20, 0x52, + 0x20, 0x80, 0x81, 0xc0, 0x10, 0x18, 0x00, 0x25, 0x6d, 0xff, 0xa0, 0x2a, + 0x20, 0x56, 0x9a, 0x25, 0xb2, 0x25, 0x03, 0xa8, 0x25, 0x65, 0x87, 0xfe, + 0x31, 0xe4, 0xff, 0x48, 0x05, 0x81, 0xe7, 0xff, 0x49, 0x03, 0x48, 0x45, + 0x8a, 0x61, 0x49, 0x13, 0x48, 0x15, 0x69, 0x33, 0x49, 0x23, 0x42, 0xc1, + 0x10, 0x49, 0x43, 0x49, 0x53, 0x91, 0xe2, 0xff, 0x31, 0xdd, 0xff, 0xa1, + 0xe2, 0xff, 0x1a, 0x99, 0x3a, 0xb4, 0x1a, 0xaa, 0x29, 0x06, 0x29, 0x09, + 0xb9, 0x0a, 0x46, 0x83, 0x00, 0xe1, 0xdc, 0xff, 0x61, 0xdd, 0xff, 0x10, + 0xee, 0x80, 0xe8, 0x0e, 0x10, 0x66, 0x80, 0x68, 0x06, 0xe0, 0x33, 0xc0, + 0x32, 0x66, 0x00, 0xe5, 0x76, 0xff, 0x81, 0xd7, 0xff, 0x1a, 0x88, 0xa8, + 0x08, 0x65, 0x88, 0xff, 0x91, 0xd6, 0xff, 0x1a, 0x99, 0xa9, 0x09, 0x16, + 0x6a, 0x1d, 0x65, 0x75, 0xff, 0xb1, 0xd2, 0xff, 0x88, 0x06, 0x1a, 0xbb, + 0xe8, 0x0b, 0x61, 0xca, 0xff, 0xb1, 0xd0, 0xff, 0x91, 0xd1, 0xff, 0x1a, + 0xbb, 0x6a, 0xa4, 0x1a, 0x99, 0xe9, 0x0b, 0x0c, 0x17, 0x31, 0xc3, 0xff, + 0xa9, 0x09, 0x06, 0x59, 0x00, 0xb1, 0xcb, 0xff, 0x92, 0x23, 0x04, 0x10, + 0xbb, 0x80, 0xb8, 0x0b, 0xe1, 0xca, 0xff, 0x89, 0x0b, 0xb1, 0x29, 0xfb, + 0xea, 0xa1, 0xba, 0x99, 0xb8, 0x53, 0x61, 0xbe, 0xff, 0xb0, 0x99, 0xc0, + 0x99, 0x0a, 0x98, 0x23, 0x7d, 0x02, 0x97, 0xb8, 0x01, 0x0c, 0x27, 0x91, + 0xc3, 0xff, 0x1a, 0x99, 0x89, 0x09, 0xe5, 0x6f, 0xff, 0x6a, 0x94, 0xa1, + 0xc1, 0xff, 0x61, 0xb5, 0xff, 0x1a, 0xaa, 0x6a, 0xb4, 0x61, 0xba, 0xff, + 0xb9, 0x0a, 0x79, 0x01, 0x1a, 0x66, 0xb8, 0x06, 0x61, 0xbd, 0xff, 0xe8, + 0x53, 0xc8, 0x0a, 0xd8, 0x43, 0xa8, 0x33, 0x1a, 0x66, 0xfd, 0x09, 0x92, + 0x66, 0x00, 0x81, 0xbd, 0xff, 0xe0, 0x08, 0x00, 0x7d, 0x0a, 0xa5, 0x6c, + 0xff, 0xa1, 0xb4, 0xff, 0xe1, 0xb0, 0xff, 0x1a, 0xaa, 0xa8, 0x0a, 0x1a, + 0xee, 0x68, 0x0a, 0xa8, 0x23, 0xe8, 0x0e, 0x60, 0xaa, 0xc0, 0xa9, 0x23, + 0xb1, 0xae, 0xff, 0x6a, 0xae, 0xe1, 0xa9, 0xff, 0x1a, 0xbb, 0x1a, 0xee, + 0x88, 0x0b, 0xa9, 0x0e, 0xa1, 0xac, 0xff, 0x60, 0x88, 0xc0, 0x1a, 0xaa, + 0x98, 0x0a, 0x68, 0x53, 0x98, 0x09, 0xf8, 0x43, 0x9a, 0x96, 0x0b, 0x67, + 0x60, 0x67, 0x20, 0x99, 0x53, 0x60, 0x6f, 0x05, 0xf0, 0x99, 0xc0, 0xcc, + 0x96, 0xa2, 0xd9, 0x80, 0x0c, 0x1b, 0xa0, 0x6b, 0x83, 0x16, 0x96, 0x0a, + 0xd1, 0x93, 0xff, 0x68, 0x1d, 0x60, 0xa9, 0x63, 0x16, 0xda, 0x08, 0xb1, + 0x94, 0xff, 0xa7, 0x3b, 0x51, 0x67, 0xb9, 0x04, 0x86, 0x38, 0x00, 0x00, + 0x00, 0xe1, 0x98, 0xff, 0x61, 0xf8, 0xfa, 0x10, 0xee, 0x80, 0x82, 0x6e, + 0x00, 0xe1, 0x97, 0xff, 0xa0, 0xc6, 0xc0, 0x1a, 0xee, 0x99, 0x0e, 0xe1, + 0x96, 0xff, 0xb2, 0xa0, 0xff, 0x1a, 0xee, 0xd9, 0x0e, 0xe1, 0x94, 0xff, + 0xaa, 0xaf, 0x1a, 0xee, 0xf9, 0x0e, 0x65, 0x82, 0x00, 0xad, 0x06, 0x61, + 0x91, 0xff, 0xb1, 0x8f, 0xff, 0x1a, 0x66, 0xf8, 0x06, 0xe1, 0x8c, 0xff, + 0x61, 0x8a, 0xff, 0x1a, 0xbb, 0x1a, 0xee, 0x1a, 0x66, 0xd8, 0x0b, 0x98, + 0x0e, 0x88, 0x06, 0xe1, 0x86, 0xff, 0x61, 0x87, 0xff, 0x1a, 0xee, 0xcd, + 0x0a, 0xa8, 0x0d, 0x89, 0x0e, 0xe1, 0x85, 0xff, 0x1a, 0x66, 0x99, 0x06, + 0x1a, 0xee, 0xd9, 0x0e, 0xbd, 0x0f, 0x25, 0xd3, 0xff, 0xb1, 0x80, 0xff, + 0x61, 0x7e, 0xff, 0xe1, 0x80, 0xff, 0x1a, 0x66, 0x1a, 0xbb, 0x1a, 0xee, + 0x88, 0x06, 0x98, 0x0b, 0xd8, 0x0e, 0x56, 0x0a, 0x06, 0x68, 0x0d, 0x9a, + 0x66, 0x69, 0x0d, 0x68, 0x1d, 0x90, 0x96, 0xc0, 0x68, 0x4d, 0x99, 0x1d, + 0x69, 0x5d, 0x8c, 0xb8, 0x68, 0x13, 0x8c, 0x76, 0x70, 0x6f, 0x31, 0x70, + 0x66, 0xc0, 0x96, 0xb6, 0xe8, 0x96, 0xd7, 0x03, 0x31, 0x64, 0xff, 0x38, + 0x13, 0xcc, 0x57, 0x8c, 0x63, 0x46, 0x0c, 0x00, 0x00, 0x00, 0x16, 0xc3, + 0x02, 0x31, 0x67, 0xff, 0x10, 0x33, 0x80, 0xa2, 0x23, 0x00, 0x65, 0x68, + 0xff, 0xdc, 0x8a, 0x61, 0x6d, 0xff, 0x81, 0x61, 0xff, 0x6a, 0x31, 0x1a, + 0x88, 0x88, 0x08, 0x38, 0x03, 0x3a, 0x98, 0x81, 0x5e, 0xff, 0x1a, 0x88, + 0x99, 0x08, 0x46, 0x02, 0x00, 0x7c, 0xf2, 0xc6, 0x04, 0x00, 0x7c, 0xd2, + 0x86, 0x03, 0x00, 0x91, 0x59, 0xff, 0x38, 0x15, 0x1a, 0x99, 0x98, 0x09, + 0x37, 0xb9, 0x02, 0x86, 0x78, 0xff, 0x1d, 0xf0, 0x1c, 0x80, 0x00, 0x00, + 0x14, 0x80, 0x00, 0x00, 0x18, 0x80, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, + 0x30, 0x80, 0x00, 0x00, 0x36, 0x41, 0x00, 0x81, 0xfe, 0xff, 0x20, 0x42, + 0x20, 0x80, 0x81, 0xc0, 0x10, 0x18, 0x00, 0xa5, 0x44, 0xff, 0xa0, 0x2a, + 0x20, 0x56, 0x0a, 0x17, 0xb2, 0x24, 0x03, 0xa8, 0x24, 0xe5, 0x5e, 0xfe, + 0x71, 0x42, 0xff, 0x38, 0x04, 0x51, 0xf1, 0xff, 0x39, 0x07, 0x38, 0x44, + 0x1a, 0x55, 0x39, 0x17, 0x31, 0x43, 0xff, 0x19, 0x47, 0x1a, 0x33, 0x29, + 0x03, 0x31, 0xa7, 0xfa, 0x19, 0x57, 0x3a, 0x31, 0x39, 0x05, 0x06, 0x4d, + 0x00, 0x61, 0x3d, 0xff, 0x10, 0x66, 0x80, 0x68, 0x06, 0x60, 0x55, 0xc0, + 0x52, 0x63, 0x00, 0xe5, 0x4f, 0xff, 0xad, 0x03, 0xa5, 0x61, 0xff, 0x81, + 0xe5, 0xff, 0x1a, 0x88, 0xa9, 0x08, 0x16, 0xaa, 0x10, 0xa5, 0x4e, 0xff, + 0xa1, 0xe2, 0xff, 0x68, 0x03, 0x1a, 0xaa, 0x58, 0x0a, 0xa1, 0xe0, 0xff, + 0x1a, 0xaa, 0x59, 0x0a, 0x86, 0x2d, 0x00, 0x00, 0xa8, 0x57, 0x98, 0x47, + 0x81, 0x96, 0xfa, 0x90, 0x9a, 0xc0, 0x6a, 0xb9, 0x5d, 0x06, 0xb7, 0xb8, + 0x02, 0x90, 0x58, 0xc0, 0x81, 0xd9, 0xff, 0xcd, 0x05, 0x1a, 0x88, 0xb8, + 0x08, 0x81, 0xd7, 0xff, 0x50, 0x66, 0xc0, 0x1a, 0x88, 0x99, 0x08, 0x25, + 0x58, 0x00, 0x81, 0xd3, 0xff, 0xa1, 0xd3, 0xff, 0x1a, 0x88, 0x88, 0x08, + 0x1a, 0xaa, 0x98, 0x0a, 0x5a, 0xa8, 0x81, 0xcf, 0xff, 0x5a, 0x99, 0x1a, + 0x88, 0xa9, 0x08, 0xa8, 0x57, 0x0c, 0x1b, 0x5a, 0x5a, 0x59, 0x57, 0x58, + 0x17, 0x0c, 0x0a, 0x90, 0x55, 0xc0, 0x50, 0xab, 0x83, 0xa0, 0x50, 0x74, + 0xcc, 0x75, 0xa2, 0xd9, 0x80, 0xa0, 0x5b, 0x83, 0x16, 0x25, 0x05, 0x51, + 0x16, 0xff, 0xcd, 0x09, 0x97, 0x35, 0x20, 0x81, 0xc4, 0xff, 0x51, 0x7b, + 0xfa, 0xa8, 0x47, 0x1a, 0x88, 0x90, 0xc5, 0xc0, 0x90, 0xaa, 0x80, 0x99, + 0x08, 0xb2, 0xa0, 0xff, 0x65, 0x64, 0x00, 0xa1, 0xbe, 0xff, 0xcd, 0x05, + 0x1a, 0xaa, 0x98, 0x0a, 0x51, 0xbc, 0xff, 0xb8, 0x47, 0xa8, 0x07, 0x10, + 0x55, 0x80, 0x92, 0x65, 0x00, 0x65, 0xb7, 0xff, 0x81, 0xb8, 0xff, 0x1a, + 0x88, 0x98, 0x08, 0xdc, 0x9a, 0x58, 0x07, 0x9a, 0x55, 0x59, 0x07, 0x58, + 0x17, 0x90, 0x95, 0xc0, 0x58, 0x47, 0x99, 0x17, 0x59, 0x57, 0x8c, 0xb6, + 0x58, 0x17, 0x56, 0x25, 0xf4, 0x06, 0x01, 0x00, 0x7c, 0xf5, 0x86, 0x00, + 0x00, 0x20, 0x52, 0x20, 0x61, 0xab, 0xff, 0x10, 0x66, 0x80, 0xa2, 0x26, + 0x00, 0xa5, 0x4e, 0xff, 0xdc, 0xca, 0xdc, 0xf5, 0x81, 0xa6, 0xff, 0xa1, + 0xf9, 0xfe, 0x1a, 0x88, 0x88, 0x08, 0x1a, 0xaa, 0xa8, 0x0a, 0x58, 0x08, + 0x5a, 0x6a, 0xa1, 0xf5, 0xfe, 0x1a, 0xaa, 0x69, 0x0a, 0x46, 0x02, 0x00, + 0x7c, 0xf2, 0xc6, 0x04, 0x00, 0x7c, 0xd2, 0x86, 0x03, 0x00, 0x61, 0xf0, + 0xfe, 0x58, 0x14, 0x1a, 0x66, 0x68, 0x06, 0x57, 0xb6, 0x02, 0xc6, 0xae, + 0xff, 0x1d, 0xf0, 0x00, 0x80, 0x01, 0xce, 0x3f, 0x2d, 0xf0, 0x00, 0x00, + 0x89, 0x02, 0xce, 0x3f, 0x00, 0x40, 0x0c, 0x60, 0x04, 0x40, 0x0c, 0x60, + 0x48, 0x00, 0x0c, 0x60, 0x64, 0x01, 0xce, 0x3f, 0x34, 0x01, 0xce, 0x3f, + 0xfe, 0x3f, 0x00, 0x00, 0xaa, 0x50, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x74, 0x1f, 0x00, 0x40, 0x74, 0x19, 0x00, 0x40, 0x98, 0x19, 0x00, 0x40, + 0x50, 0x16, 0x00, 0x40, 0x90, 0x18, 0x00, 0x40, 0x04, 0x20, 0x00, 0x40, + 0xec, 0x0a, 0x00, 0x40, 0x50, 0x0a, 0x00, 0x40, 0xd4, 0x16, 0x00, 0x40, + 0x36, 0x01, 0x01, 0x39, 0xd1, 0x49, 0xe1, 0x72, 0x61, 0x11, 0x7d, 0x02, + 0x59, 0xf1, 0x62, 0x61, 0x10, 0x21, 0xe7, 0xff, 0x31, 0xe9, 0xff, 0x0c, + 0x04, 0xc6, 0x00, 0x00, 0x49, 0x02, 0x4b, 0x22, 0x37, 0x32, 0xf8, 0x22, + 0xc1, 0x30, 0x7c, 0xfa, 0xe5, 0xb9, 0xfe, 0x29, 0x91, 0x22, 0xc1, 0x60, + 0x29, 0x81, 0x0c, 0x42, 0x29, 0xa1, 0x0c, 0xb3, 0x7c, 0xe2, 0x77, 0xa3, + 0x02, 0x06, 0xd1, 0x00, 0x38, 0xd1, 0x48, 0xe1, 0x68, 0xf1, 0x20, 0xeb, + 0x03, 0x20, 0x2d, 0x04, 0x81, 0xe4, 0xff, 0xe0, 0x08, 0x00, 0x91, 0xdb, + 0xff, 0x81, 0xd9, 0xff, 0x5d, 0x0a, 0xc0, 0x20, 0x00, 0x88, 0x08, 0x0c, + 0x2b, 0xc0, 0x20, 0x00, 0xa8, 0x09, 0x0c, 0x19, 0x20, 0x9b, 0x93, 0x80, + 0x80, 0x04, 0x97, 0x8a, 0x02, 0x56, 0xe8, 0x06, 0x81, 0xd4, 0xff, 0x0c, + 0x4a, 0xc0, 0x20, 0x00, 0x98, 0x08, 0xa0, 0x99, 0x20, 0xc0, 0x20, 0x00, + 0x99, 0x08, 0xc0, 0x20, 0x00, 0x98, 0x08, 0x0c, 0x8a, 0xa0, 0x99, 0x20, + 0xc0, 0x20, 0x00, 0x99, 0x08, 0xc0, 0x20, 0x00, 0x98, 0x08, 0xa2, 0xaf, + 0xf7, 0xa0, 0x99, 0x10, 0xc0, 0x20, 0x00, 0x92, 0x68, 0x00, 0x81, 0xce, + 0xff, 0xe0, 0x08, 0x00, 0x81, 0xce, 0xff, 0xe0, 0x08, 0x00, 0x81, 0xcd, + 0xff, 0xe0, 0x08, 0x00, 0x0c, 0x0a, 0x81, 0xcc, 0xff, 0xe0, 0x08, 0x00, + 0x81, 0xc0, 0xff, 0xcc, 0xa2, 0xc0, 0x20, 0x00, 0x28, 0x08, 0x7c, 0xe9, + 0x86, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x22, 0x28, 0x00, 0x92, + 0xaf, 0xfd, 0x90, 0x22, 0x10, 0xc0, 0x20, 0x00, 0x22, 0x68, 0x00, 0x81, + 0xc3, 0xff, 0xe0, 0x08, 0x00, 0x0c, 0x0b, 0xad, 0x05, 0x81, 0xc1, 0xff, + 0xe0, 0x08, 0x00, 0x25, 0x38, 0xfe, 0xa2, 0xca, 0xee, 0xf6, 0x7a, 0x0b, + 0x21, 0xb3, 0xff, 0xe0, 0xaa, 0x11, 0xaa, 0xa2, 0xb8, 0x0a, 0xcc, 0xeb, + 0x22, 0xc7, 0xfc, 0x0c, 0x1b, 0x0c, 0x07, 0x20, 0xb7, 0x83, 0xb0, 0x20, + 0x60, 0x06, 0x9b, 0x00, 0x66, 0x47, 0x04, 0x2d, 0x0b, 0x06, 0x99, 0x00, + 0x51, 0xcd, 0xf8, 0xf1, 0x4a, 0xf9, 0x58, 0x05, 0xd1, 0xf1, 0xf8, 0xc1, + 0x9c, 0xfa, 0xa8, 0x05, 0xe2, 0xa1, 0x00, 0x81, 0xb1, 0xff, 0xe0, 0x08, + 0x00, 0x81, 0x25, 0xfe, 0xe0, 0x08, 0x00, 0x5d, 0x0a, 0x8c, 0x1a, 0xc6, + 0x50, 0x00, 0x0c, 0xb8, 0x77, 0xb8, 0x02, 0xc6, 0x89, 0x00, 0x81, 0x9f, + 0xff, 0xe0, 0x77, 0x11, 0x7a, 0x78, 0x78, 0x07, 0xa0, 0x07, 0x00, 0x25, + 0x12, 0xff, 0x2d, 0x0a, 0x56, 0x1a, 0x22, 0x86, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x81, 0x99, 0xff, 0x50, 0x74, 0xc0, 0x80, 0x67, 0x63, 0x60, 0x90, + 0x14, 0x16, 0x79, 0x00, 0x7c, 0xc9, 0x90, 0x66, 0x10, 0x16, 0xb6, 0x1f, + 0x25, 0x1f, 0xff, 0xad, 0x06, 0x25, 0x2a, 0xff, 0x7d, 0x0a, 0x16, 0xca, + 0x0f, 0x65, 0x1e, 0xff, 0x25, 0x1e, 0xff, 0xcd, 0x06, 0xbd, 0x07, 0x50, + 0xa3, 0x80, 0xa5, 0x4d, 0xfe, 0xa2, 0x61, 0x14, 0x25, 0x1d, 0xff, 0xad, + 0x07, 0x65, 0x24, 0xff, 0x82, 0x21, 0x14, 0xa0, 0xa8, 0x20, 0x56, 0x8a, + 0x0d, 0x6a, 0x55, 0xa5, 0x20, 0xff, 0x56, 0x0a, 0x0d, 0x47, 0x35, 0xac, + 0x46, 0x71, 0x00, 0x0c, 0x4c, 0xbd, 0x01, 0x50, 0xa3, 0x80, 0xe5, 0x4a, + 0xfe, 0x56, 0xda, 0x0b, 0x70, 0xa7, 0x20, 0xa5, 0x25, 0xff, 0x2d, 0x0a, + 0x16, 0x2a, 0x0b, 0xcd, 0x07, 0xbd, 0x01, 0xe5, 0x26, 0x00, 0xad, 0x02, + 0xa5, 0x20, 0xff, 0x56, 0x3a, 0x0a, 0x65, 0x1d, 0xff, 0x2d, 0x0a, 0x16, + 0x6a, 0x19, 0x06, 0x26, 0x00, 0x00, 0xbd, 0x04, 0xad, 0x03, 0x65, 0x7e, + 0xff, 0x46, 0x5c, 0x00, 0x60, 0xc6, 0x20, 0x40, 0xb4, 0x20, 0x30, 0xa3, + 0x20, 0x25, 0x65, 0xfe, 0x86, 0x58, 0x00, 0x00, 0xad, 0x03, 0x65, 0xc1, + 0xff, 0x46, 0x56, 0x00, 0xad, 0x03, 0x65, 0x98, 0xff, 0x46, 0x54, 0x00, + 0x60, 0xc6, 0x20, 0x40, 0xb4, 0x20, 0x30, 0xa3, 0x20, 0xa5, 0x0c, 0xff, + 0x86, 0x50, 0x00, 0xa5, 0x24, 0xfe, 0xa2, 0xca, 0xee, 0xf6, 0x7a, 0x08, + 0xe0, 0xaa, 0x11, 0xa0, 0x22, 0x80, 0x52, 0x22, 0x00, 0x22, 0xa0, 0x00, + 0x29, 0x04, 0x2c, 0x06, 0x21, 0xae, 0xf9, 0xbd, 0x04, 0xad, 0x03, 0x66, + 0x03, 0x2d, 0xcd, 0x06, 0xbd, 0x01, 0xad, 0x02, 0xe5, 0x41, 0xfe, 0xec, + 0xfa, 0x31, 0x5e, 0xff, 0x72, 0x11, 0x00, 0x30, 0x30, 0xf4, 0x37, 0x97, + 0x1f, 0xa8, 0x11, 0xa7, 0x35, 0x1f, 0x38, 0x21, 0x3a, 0x3a, 0x37, 0x35, + 0x18, 0x32, 0x01, 0x02, 0x22, 0xc2, 0x20, 0x56, 0x33, 0xfd, 0xbd, 0x04, + 0x25, 0x55, 0xfe, 0xc6, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xa2, 0x86, + 0x3e, 0x00, 0x7c, 0xf2, 0x46, 0x3d, 0x00, 0x81, 0x5b, 0xff, 0xe0, 0x08, + 0x00, 0x71, 0xcc, 0xfd, 0xc1, 0x50, 0xff, 0x70, 0x73, 0x10, 0x60, 0xb6, + 0x20, 0x70, 0xa7, 0x20, 0xe5, 0x3c, 0xfe, 0x16, 0x5a, 0x00, 0x0c, 0x02, + 0x46, 0x35, 0x00, 0x00, 0x30, 0x50, 0xb4, 0x5a, 0x56, 0x22, 0x05, 0x00, + 0x0c, 0x28, 0x20, 0x23, 0x04, 0x0c, 0x3b, 0x20, 0xb8, 0x93, 0x2d, 0x0b, + 0xcd, 0x0b, 0xad, 0x04, 0xbd, 0x05, 0xe5, 0x17, 0x00, 0xbd, 0x02, 0xad, + 0x03, 0xa5, 0x70, 0xff, 0x56, 0x2a, 0xfd, 0x31, 0x37, 0xff, 0x26, 0x22, + 0x02, 0x31, 0xb7, 0xf8, 0x30, 0x48, 0x74, 0x32, 0x45, 0x00, 0x42, 0x45, + 0x01, 0x66, 0x32, 0x05, 0x30, 0x30, 0x75, 0x32, 0x45, 0x02, 0xc1, 0x39, + 0xff, 0xbd, 0x06, 0xad, 0x07, 0x65, 0x7b, 0xff, 0x56, 0xaa, 0xfa, 0x86, + 0x16, 0x00, 0x81, 0x3e, 0xff, 0xe0, 0x08, 0x00, 0x71, 0xb0, 0xfd, 0xc1, + 0x33, 0xff, 0x70, 0x73, 0x10, 0xbd, 0x06, 0xad, 0x07, 0xe5, 0x35, 0xfe, + 0x56, 0xea, 0xf6, 0x52, 0x04, 0x00, 0x0c, 0x28, 0x50, 0x53, 0x04, 0x0c, + 0x32, 0x50, 0x28, 0x93, 0xbd, 0x02, 0xad, 0x03, 0xe5, 0x6a, 0xff, 0x5d, + 0x02, 0x2d, 0x0a, 0x56, 0x3a, 0xf5, 0x82, 0x04, 0x00, 0x30, 0x30, 0xb4, + 0x3a, 0x36, 0x82, 0x43, 0x00, 0x82, 0x04, 0x01, 0x82, 0x43, 0x01, 0x66, + 0x35, 0x05, 0x42, 0x04, 0x02, 0x42, 0x43, 0x02, 0xc1, 0x22, 0xff, 0xbd, + 0x06, 0xad, 0x07, 0xa5, 0x75, 0xff, 0x56, 0xca, 0xf2, 0x81, 0x27, 0xff, + 0xe0, 0x08, 0x00, 0x86, 0x07, 0x00, 0x00, 0x00, 0x00, 0xad, 0x03, 0xe5, + 0x85, 0xfe, 0x2d, 0x0a, 0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xe2, + 0x46, 0x02, 0x00, 0x00, 0xf6, 0x47, 0x02, 0x06, 0x8f, 0xff, 0x06, 0xc1, + 0xff, 0x1d, 0xf0, 0x00, 0x36, 0x41, 0x00, 0xcd, 0x03, 0x0c, 0x0b, 0xad, + 0x02, 0x65, 0x1d, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x00, 0x80, + 0xeb, 0x03, 0x80, 0x8d, 0x04, 0x22, 0x02, 0x00, 0x92, 0xa1, 0x03, 0x00, + 0x08, 0x40, 0x20, 0x20, 0xb1, 0x20, 0x20, 0x04, 0x0c, 0x08, 0x20, 0x89, + 0x83, 0x2d, 0x08, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, 0x80, + 0xeb, 0x03, 0x80, 0x8d, 0x04, 0x92, 0x02, 0x00, 0x87, 0x59, 0x18, 0xc0, + 0x20, 0x00, 0x49, 0xb2, 0xc0, 0x20, 0x00, 0x49, 0xa2, 0x0c, 0x08, 0xc0, + 0x20, 0x00, 0x89, 0xc2, 0x39, 0x92, 0xc0, 0x20, 0x00, 0x82, 0x62, 0x0d, + 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x00, 0x80, 0xeb, 0x03, 0x80, 0x8d, + 0x04, 0x92, 0x02, 0x00, 0x22, 0xa1, 0x03, 0x87, 0x59, 0x0a, 0x32, 0xc3, + 0xfc, 0x22, 0x13, 0x00, 0x22, 0x53, 0x01, 0x0c, 0x02, 0x1d, 0xf0, 0x00, + 0x00, 0x76, 0x94, 0x09, 0x62, 0x03, 0x00, 0x1b, 0x33, 0x62, 0x45, 0x00, + 0x1b, 0x55, 0x1d, 0xf0, 0xb6, 0x74, 0xed, 0x62, 0x03, 0x00, 0x1b, 0x33, + 0x42, 0xc4, 0xff, 0x62, 0x45, 0x00, 0x52, 0xc5, 0x01, 0x17, 0x65, 0x27, + 0xb6, 0x64, 0xd9, 0x62, 0x03, 0x00, 0x72, 0x03, 0x01, 0x2b, 0x33, 0x42, + 0xc4, 0xfe, 0x62, 0x45, 0x00, 0x72, 0x45, 0x01, 0x2b, 0x55, 0x86, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x21, 0x00, 0x20, 0x52, 0x20, 0x07, 0xe2, + 0xc6, 0x17, 0xe2, 0xd7, 0x40, 0x74, 0x41, 0x20, 0x83, 0x01, 0x56, 0xa8, + 0x05, 0x76, 0x97, 0x15, 0x68, 0x03, 0x78, 0x13, 0x69, 0x05, 0x68, 0x23, + 0x79, 0x15, 0x78, 0x33, 0x69, 0x25, 0x32, 0xc3, 0x10, 0x79, 0x35, 0x52, + 0xc5, 0x10, 0x37, 0x64, 0x0b, 0x68, 0x03, 0x78, 0x13, 0x8b, 0x33, 0x69, + 0x05, 0x79, 0x15, 0x8b, 0x55, 0x27, 0xe4, 0x07, 0x17, 0xe4, 0x14, 0x07, + 0xe4, 0x21, 0x1d, 0xf0, 0x68, 0x03, 0x4b, 0x33, 0x69, 0x05, 0x4b, 0x55, + 0x17, 0xe4, 0x04, 0x07, 0xe4, 0x11, 0x1d, 0xf0, 0x62, 0x13, 0x00, 0x2b, + 0x33, 0x62, 0x55, 0x00, 0x2b, 0x55, 0x07, 0xe4, 0x02, 0x1d, 0xf0, 0x00, + 0x62, 0x03, 0x00, 0x62, 0x45, 0x00, 0x1d, 0xf0, 0x16, 0xa4, 0xff, 0x00, + 0x23, 0x40, 0x80, 0xbe, 0x15, 0xb0, 0x33, 0xc0, 0x68, 0x03, 0x76, 0x97, + 0x21, 0x78, 0x13, 0x88, 0x23, 0x60, 0x67, 0x81, 0x69, 0x05, 0x98, 0x33, + 0x70, 0x78, 0x81, 0x79, 0x15, 0x68, 0x43, 0x80, 0x89, 0x81, 0x89, 0x25, + 0x32, 0xc3, 0x10, 0x90, 0x96, 0x81, 0x99, 0x35, 0x52, 0xc5, 0x10, 0x37, + 0x64, 0x15, 0x78, 0x13, 0x88, 0x23, 0x60, 0x67, 0x81, 0x69, 0x05, 0x8b, + 0x33, 0x70, 0x78, 0x81, 0x79, 0x15, 0x52, 0xc5, 0x08, 0x80, 0x68, 0x20, + 0x27, 0x64, 0x0c, 0x78, 0x13, 0x4b, 0x33, 0x60, 0x67, 0x81, 0x69, 0x05, + 0x4b, 0x55, 0x6d, 0x07, 0xba, 0x33, 0x17, 0xe4, 0x06, 0x07, 0xe4, 0x18, + 0x1d, 0xf0, 0x00, 0x00, 0x62, 0x03, 0x00, 0x72, 0x03, 0x01, 0x2b, 0x33, + 0x62, 0x45, 0x00, 0x72, 0x45, 0x01, 0x2b, 0x55, 0x07, 0xe4, 0x01, 0x1d, + 0xf0, 0x62, 0x03, 0x00, 0x62, 0x45, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x76, 0x94, 0x04, 0x32, 0x45, 0x00, 0x1b, 0x55, 0x1d, 0xf0, 0x00, + 0xb6, 0x84, 0xf1, 0x32, 0x45, 0x00, 0x1b, 0x55, 0x0b, 0x44, 0x17, 0x65, + 0x28, 0xb6, 0x84, 0xe4, 0x32, 0x55, 0x00, 0x2b, 0x55, 0x42, 0xc4, 0xfe, + 0x86, 0x06, 0x00, 0x00, 0x36, 0x21, 0x00, 0x30, 0x30, 0x74, 0x80, 0x73, + 0x11, 0x70, 0x33, 0x20, 0x00, 0x73, 0x11, 0x70, 0x33, 0x20, 0x5d, 0x02, + 0x07, 0xe2, 0xcc, 0x17, 0xe2, 0xd6, 0x40, 0x74, 0x41, 0x76, 0x97, 0x0a, + 0x39, 0x05, 0x39, 0x15, 0x39, 0x25, 0x39, 0x35, 0x52, 0xc5, 0x10, 0x37, + 0x64, 0x06, 0x39, 0x05, 0x39, 0x15, 0x52, 0xc5, 0x08, 0x27, 0x64, 0x03, + 0x39, 0x05, 0x4b, 0x55, 0x17, 0x64, 0x04, 0x32, 0x55, 0x00, 0x2b, 0x55, + 0x07, 0x64, 0x02, 0x32, 0x45, 0x00, 0x1d, 0xf0, 0x36, 0x41, 0x00, 0xdd, + 0x03, 0xad, 0x04, 0x3d, 0x05, 0xcd, 0x02, 0x9d, 0x0d, 0x56, 0x45, 0x18, + 0x47, 0x3d, 0x02, 0x86, 0x20, 0x00, 0x20, 0xf4, 0x40, 0x9c, 0xc2, 0x20, + 0x80, 0x60, 0x00, 0x08, 0x40, 0xc0, 0x80, 0x91, 0x00, 0x12, 0x40, 0x00, + 0x9d, 0xa1, 0x00, 0x12, 0x40, 0x00, 0xa4, 0xa1, 0x90, 0x98, 0x20, 0x00, + 0x12, 0x40, 0x00, 0xcc, 0xa1, 0xa0, 0x80, 0xf5, 0x80, 0xd9, 0xe2, 0xa0, + 0x40, 0xf4, 0x80, 0x99, 0xc2, 0x00, 0xdd, 0x11, 0xc0, 0xb0, 0xf5, 0x90, + 0x24, 0x82, 0xb0, 0xbd, 0x20, 0x27, 0xbb, 0x13, 0xaa, 0xbb, 0x0b, 0x59, + 0xa7, 0x3b, 0x0a, 0x27, 0xbb, 0x07, 0x92, 0xc9, 0xfe, 0xaa, 0xbb, 0x46, + 0x00, 0x00, 0x9d, 0x05, 0x20, 0xbb, 0xc0, 0x80, 0x2b, 0xe2, 0x80, 0xbb, + 0xc2, 0x00, 0x22, 0x11, 0xc0, 0xc0, 0xf4, 0xb0, 0x44, 0x82, 0xc0, 0xc2, + 0x20, 0x47, 0xbc, 0x0f, 0xca, 0xca, 0x22, 0xcb, 0xff, 0x47, 0xbc, 0x05, + 0xb2, 0xcb, 0xfe, 0xa7, 0xbc, 0x01, 0xbd, 0x02, 0x00, 0x89, 0x11, 0xb0, + 0x88, 0x20, 0x06, 0x74, 0x00, 0xcc, 0x34, 0x0c, 0x13, 0x40, 0xa3, 0xc2, + 0x50, 0xfa, 0x40, 0xa0, 0x8d, 0xc0, 0x0c, 0x13, 0x16, 0x95, 0x08, 0x2c, + 0x04, 0x50, 0x44, 0xc0, 0x00, 0x15, 0x40, 0x00, 0xaa, 0xa1, 0x00, 0x04, + 0x40, 0xd0, 0x30, 0x91, 0x00, 0x15, 0x40, 0x00, 0x8d, 0xa1, 0x00, 0x04, + 0x40, 0x20, 0x40, 0x91, 0x00, 0x15, 0x40, 0x00, 0xc2, 0xa1, 0xa0, 0x20, + 0xf5, 0x80, 0x44, 0x20, 0x20, 0xb3, 0xe2, 0xa0, 0x80, 0xf4, 0x20, 0x33, + 0xc2, 0x00, 0xbb, 0x11, 0x40, 0x90, 0xf5, 0x30, 0x58, 0x82, 0x90, 0x9b, + 0x20, 0x57, 0xb9, 0x13, 0xaa, 0x99, 0x0b, 0xb3, 0xa7, 0x39, 0x0a, 0x57, + 0xb9, 0x07, 0x32, 0xc3, 0xfe, 0xaa, 0x99, 0x46, 0x00, 0x00, 0x3d, 0x0b, + 0x50, 0x99, 0xc0, 0x20, 0xb9, 0xe2, 0x20, 0x99, 0xc2, 0x90, 0x28, 0x82, + 0x00, 0xbb, 0x11, 0x40, 0x80, 0xf4, 0x80, 0x8b, 0x20, 0x27, 0xb8, 0x13, + 0xaa, 0x88, 0x0b, 0x49, 0xa7, 0x38, 0x0a, 0x27, 0xb8, 0x07, 0x92, 0xc9, + 0xfe, 0xaa, 0x88, 0x46, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x33, 0x11, 0x20, + 0x88, 0xc0, 0x90, 0x33, 0x20, 0xa0, 0x50, 0xf5, 0x50, 0xb8, 0xe2, 0xa0, + 0x40, 0xf4, 0x50, 0x88, 0xc2, 0x00, 0xbb, 0x11, 0xc0, 0x90, 0xf5, 0x80, + 0x24, 0x82, 0x90, 0x9b, 0x20, 0x27, 0xb9, 0x13, 0xaa, 0x99, 0x0b, 0xb8, + 0xa7, 0x39, 0x0a, 0x27, 0xb9, 0x07, 0x82, 0xc8, 0xfe, 0xaa, 0x99, 0x46, + 0x00, 0x00, 0x8d, 0x0b, 0x20, 0x99, 0xc0, 0x50, 0x29, 0xe2, 0x50, 0x99, + 0xc2, 0x00, 0x22, 0x11, 0xc0, 0xc0, 0xf4, 0x90, 0x44, 0x82, 0xc0, 0xc2, + 0x20, 0x47, 0xbc, 0x0f, 0xca, 0xca, 0x22, 0xc9, 0xff, 0xa7, 0x3c, 0x05, + 0x92, 0xc9, 0xfe, 0x47, 0x3c, 0x01, 0x9d, 0x02, 0x00, 0x88, 0x11, 0x90, + 0x88, 0x20, 0x06, 0x35, 0x00, 0x0c, 0x03, 0x8d, 0x03, 0x57, 0xbd, 0x02, + 0x86, 0x32, 0x00, 0xb0, 0xf5, 0x40, 0x37, 0x9b, 0x17, 0x0c, 0x18, 0xd7, + 0x35, 0x02, 0xb0, 0x8b, 0x20, 0x0c, 0x13, 0x47, 0xb2, 0x01, 0x0c, 0x03, + 0x30, 0x88, 0x20, 0x80, 0x80, 0x74, 0x86, 0x2a, 0x00, 0x2c, 0x09, 0xb0, + 0x99, 0xc0, 0x00, 0x09, 0x40, 0x40, 0x30, 0x91, 0x00, 0x1b, 0x40, 0x00, + 0x55, 0xa1, 0x50, 0x53, 0x20, 0x00, 0x09, 0x40, 0xd0, 0x80, 0x91, 0x00, + 0x1b, 0x40, 0x00, 0x3d, 0xa1, 0x00, 0x09, 0x40, 0x20, 0x90, 0x91, 0x50, + 0xd0, 0xf5, 0x30, 0x39, 0x20, 0x50, 0xc0, 0xf4, 0xd0, 0x98, 0xe2, 0xd0, + 0x88, 0xc2, 0x00, 0x99, 0x11, 0x30, 0xe0, 0xf5, 0x80, 0xac, 0x82, 0xe0, + 0x99, 0x20, 0x00, 0x1b, 0x40, 0x00, 0x44, 0xa1, 0xa7, 0xb9, 0x14, 0x5a, + 0x99, 0x0b, 0xe8, 0xa7, 0xb9, 0x0b, 0x57, 0x39, 0x08, 0x82, 0xc8, 0xfe, + 0x5a, 0x99, 0x86, 0x00, 0x00, 0x00, 0x8d, 0x0e, 0xa0, 0xa9, 0xc0, 0xd0, + 0x9a, 0xe2, 0xd0, 0xaa, 0xc2, 0x00, 0x99, 0x11, 0x30, 0x30, 0xf4, 0xa0, + 0xcc, 0x82, 0x30, 0x39, 0x20, 0xc7, 0xb3, 0x13, 0x5a, 0x33, 0x0b, 0x9a, + 0x57, 0x33, 0x0a, 0xc7, 0xb3, 0x07, 0xa2, 0xca, 0xfe, 0x5a, 0x33, 0x46, + 0x00, 0x00, 0xad, 0x09, 0x00, 0x88, 0x11, 0xa0, 0x88, 0x20, 0x40, 0x58, + 0x82, 0x40, 0x48, 0xa2, 0xc0, 0x33, 0xc0, 0x47, 0x33, 0x0b, 0x00, 0x1b, + 0x40, 0x00, 0x22, 0xa1, 0x57, 0xb2, 0x04, 0x47, 0x93, 0x01, 0x0b, 0x88, + 0x0c, 0x03, 0x2d, 0x08, 0x1d, 0xf0 diff --git a/contrib/loaders/flash/esp/esp32s3/stub_flasher_data.inc b/contrib/loaders/flash/esp/esp32s3/stub_flasher_data.inc new file mode 100644 index 0000000000..eb8f9800a1 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_flasher_data.inc @@ -0,0 +1,32 @@ + 0x40, 0x01, 0x3b, 0x40, 0xd4, 0x00, 0x3b, 0x40, 0x10, 0x01, 0x3b, 0x40, + 0xb4, 0x00, 0x3b, 0x40, 0xa4, 0x01, 0x3b, 0x40, 0x70, 0x14, 0x3b, 0x40, + 0xc0, 0x1f, 0x3b, 0x40, 0xa8, 0x12, 0x3b, 0x40, 0x00, 0x13, 0x3b, 0x40, + 0x94, 0x1f, 0x3b, 0x40, 0x4c, 0x13, 0x3b, 0x40, 0x70, 0x1f, 0x3b, 0x40, + 0x74, 0x01, 0x3b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x68, 0x89, 0x09, + 0x72, 0x74, 0x63, 0x5f, 0x63, 0x6c, 0x6b, 0x00, 0x25, 0x73, 0x28, 0x77, + 0x61, 0x72, 0x6e, 0x29, 0x3a, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x20, 0x52, 0x54, 0x43, 0x5f, 0x58, 0x54, 0x41, 0x4c, 0x5f, 0x46, + 0x52, 0x45, 0x51, 0x5f, 0x52, 0x45, 0x47, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x20, 0x30, 0x78, 0x25, 0x30, 0x38, 0x78, 0x00, 0x25, 0x73, + 0x28, 0x65, 0x72, 0x72, 0x29, 0x3a, 0x20, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x6e, 0x63, 0x79, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x72, 0x74, 0x63, 0x5f, 0x63, + 0x6c, 0x6b, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x25, 0x73, 0x28, 0x65, + 0x72, 0x72, 0x29, 0x3a, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x20, 0x43, 0x50, 0x55, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x25, 0x73, 0x28, + 0x65, 0x72, 0x72, 0x29, 0x3a, 0x20, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x20, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x00, + 0x28, 0x50, 0x04, 0x00, 0xff, 0x64, 0x00, 0x00, 0x33, 0x1d, 0x3b, 0x40, + 0xe4, 0x1d, 0x3b, 0x40, 0xca, 0x1d, 0x3b, 0x40, 0xd4, 0x1d, 0x3b, 0x40, + 0x4e, 0x1f, 0x3b, 0x40, 0x03, 0x1e, 0x3b, 0x40, 0x67, 0x1e, 0x3b, 0x40, + 0xda, 0x1e, 0x3b, 0x40, 0x4e, 0x1f, 0x3b, 0x40, 0xec, 0x1d, 0x3b, 0x40, + 0xf4, 0x1d, 0x3b, 0x40, 0x41, 0x1f, 0x3b, 0x40, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01 diff --git a/contrib/loaders/flash/esp/esp32s3/stub_flasher_image.h b/contrib/loaders/flash/esp/esp32s3/stub_flasher_image.h new file mode 100644 index 0000000000..e1ceaa3820 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_flasher_image.h @@ -0,0 +1,7 @@ +#define ESP32S3_STUB_BSS_SIZE 0x0000109UL + +#define ESP32S3_STUB_ENTRY_ADDR 0x0403b1bd8UL + +#define ESP32S3_STUB_APPTRACE_CTRL_ADDR 0x0 +/*#define ESP32S3_STUB_BUILD_IDF_REV d0a1feb5d41 +*/ diff --git a/contrib/loaders/flash/esp/esp32s3/stub_rom_chip.h b/contrib/loaders/flash/esp/esp32s3/stub_rom_chip.h new file mode 100644 index 0000000000..6e7ae37ec0 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_rom_chip.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * ESP32-S3 specific rom header files * + * Copyright (C) 2021 Espressif Systems Ltd. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ +#ifndef ESP_STUB_ROM_H +#define ESP_STUB_ROM_H + +#include "esp32s3/rom/ets_sys.h" +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/miniz.h" +#include "esp32s3/rom/spi_flash.h" +#include "esp32s3/rom/cache.h" +#include "esp32s3/rom/efuse.h" +#include "esp32s3/rom/uart.h" +#include "esp32s3/rom/rtc.h" +#include "esp32s3/rom/sha.h" + +#endif diff --git a/contrib/loaders/flash/esp/esp32s3/stub_sha.c b/contrib/loaders/flash/esp/esp32s3/stub_sha.c new file mode 100644 index 0000000000..01a25c3234 --- /dev/null +++ b/contrib/loaders/flash/esp/esp32s3/stub_sha.c @@ -0,0 +1,44 @@ +/* Copyright 2021 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. */ + +#include +#include "stub_rom_chip.h" + +static SHA_CTX ctx; + +/* this function has the same implementation for ESP32-S2 + * TODO: move to common file */ +void stub_sha256_start(void) +{ + /* Enable SHA hardware */ + ets_sha_enable(); + ets_sha_init(&ctx, SHA2_256); +} + +void stub_sha256_data(const void *data, size_t data_len) +{ + if (data_len % 4 != 0) + return; + ets_sha_update(&ctx, data, data_len, false); +} + +void stub_sha256_finish(uint8_t *digest) +{ + if (digest == NULL) { + bzero(&ctx, sizeof(ctx)); + return; + } + ets_sha_finish(&ctx, digest); + ets_sha_disable(); +} diff --git a/contrib/loaders/flash/esp/stub_common.mk b/contrib/loaders/flash/esp/stub_common.mk index 620d712adb..a480a6dc8a 100644 --- a/contrib/loaders/flash/esp/stub_common.mk +++ b/contrib/loaders/flash/esp/stub_common.mk @@ -53,15 +53,27 @@ CFLAGS += -std=gnu99 -Wall -Werror -Os \ -nostdlib -fno-builtin -flto \ -Wl,-static -g -ffunction-sections -Wl,--gc-sections -INCLUDES += -I. -I$(STUB_COMMON_PATH) -I$(STUB_CHIP_PATH) -I$(IDF_PATH)/components/soc/include \ - -I$(IDF_PATH)/components/app_trace/include -I$(IDF_PATH)/components/driver/include \ - -I$(IDF_PATH)/components/freertos/include -I$(IDF_PATH)/components/log/include -I$(IDF_PATH)/components/heap/include \ - -I$(IDF_PATH)/components/bootloader_support/include -I$(IDF_PATH)/components/esp_rom/include \ - -I$(IDF_PATH)/components/esp_common/include -I$(IDF_PATH)/components/efuse/include \ +INCLUDES += -I. -I$(STUB_COMMON_PATH) -I$(STUB_CHIP_PATH) -I$(STUB_CHIP_ARCH_PATH) \ + -I$(IDF_PATH)/components/soc/include \ + -I$(IDF_PATH)/components/driver/include \ + -I$(IDF_PATH)/components/log/include \ + -I$(IDF_PATH)/components/heap/include \ + -I$(IDF_PATH)/components/bootloader_support/include \ + -I$(IDF_PATH)/components/efuse/include \ + -I$(IDF_PATH)/components/hal/include \ + -I$(IDF_PATH)/components/newlib/platform_include \ + -I$(IDF_PATH)/components/esp_timer/include \ + -I$(IDF_PATH)/components/esp_rom/include \ + -I$(IDF_PATH)/components/esp_common/include \ + -I$(IDF_PATH)/components/esp_system/include \ + -I$(IDF_PATH)/components/esp_system/port/public_compat \ -I$(IDF_PATH)/components/esp_hw_support/include \ - -I$(IDF_PATH)/components/hal/include -I$(IDF_PATH)/components/esp_timer/include \ - -I$(IDF_PATH)/components/esp_system/include -I$(IDF_PATH)/components/newlib/platform_include \ - -I$(IDF_PATH)/components/spi_flash/private_include -I$(IDF_PATH)/components/app_trace/private_include \ + -I$(IDF_PATH)/components/esp_hw_support/include/soc \ + -I$(IDF_PATH)/components/freertos/include/esp_additions \ + -I$(IDF_PATH)/components/spi_flash/include \ + -I$(IDF_PATH)/components/spi_flash/private_include \ + -I$(IDF_PATH)/components/app_trace/include \ + -I$(IDF_PATH)/components/app_trace/private_include \ -I$(IDF_PATH)/components/app_trace/port/include DEFINES += -Dasm=__asm__ diff --git a/contrib/loaders/flash/esp/xtensa/stub_xtensa_chips.h b/contrib/loaders/flash/esp/xtensa/stub_xtensa_chips.h index a3868a9ee2..4287d743b4 100644 --- a/contrib/loaders/flash/esp/xtensa/stub_xtensa_chips.h +++ b/contrib/loaders/flash/esp/xtensa/stub_xtensa_chips.h @@ -22,6 +22,7 @@ #include "eri.h" #include "trax.h" +#include "stub_flasher.h" #define ESP_APPTRACE_TRAX_BLOCK_SIZE (0x4000UL) #define ESP_APPTRACE_USR_DATA_LEN_MAX (ESP_APPTRACE_TRAX_BLOCK_SIZE - 2) @@ -34,7 +35,7 @@ #define CPUTICKS2US(_t_) ((_t_)/(stub_esp_clk_cpu_freq()/1000000)) -inline int stub_apptrace_hw_init(void) +inline int stub_apptrace_prepare(void) { /* imply that host is auto-connected */ uint32_t reg = eri_read(ESP_APPTRACE_TRAX_CTRL_REG); @@ -46,8 +47,8 @@ inline int stub_apptrace_hw_init(void) inline uint64_t stub_get_time(void) { - uint32_t ticks = xthal_get_ccount() - return CPUTICKS2US(ticks); + uint32_t ticks = xthal_get_ccount(); + return CPUTICKS2US(ticks); } inline int64_t esp_timer_get_time(void) @@ -65,4 +66,14 @@ static inline uint32_t stub_get_break_insn(uint8_t insn_sz) return insn_sz == 2 ? XT_INS_BREAKN : XT_INS_BREAK; } +static inline uint32_t stub_get_coreid() +{ + int id; + __asm__ volatile ( + "rsr.prid %0\n" + " extui %0,%0,13,1" + : "=r" (id)); + return id; +} + #endif /*ESP_XTENSA_CHIPS_FLASHER_STUB_H */ diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 0aa9cdc03b..5f1954f35b 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -32,6 +32,7 @@ NOR_DRIVERS = \ %D%/esp32.c \ %D%/esp32s2.c \ %D%/esp32c3.c \ + %D%/esp32s3.c \ %D%/esirisc_flash.c \ %D%/faux.c \ %D%/fespi.c \ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index dc4c849eeb..4b9a123c8b 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -43,6 +43,7 @@ extern const struct flash_driver esirisc_flash; extern const struct flash_driver esp32_flash; extern const struct flash_driver esp32s2_flash; extern const struct flash_driver esp32c3_flash; +extern const struct flash_driver esp32s3_flash; extern const struct flash_driver faux_flash; extern const struct flash_driver fm3_flash; extern const struct flash_driver fm4_flash; @@ -116,6 +117,7 @@ static const struct flash_driver * const flash_drivers[] = { &esp32_flash, &esp32s2_flash, &esp32c3_flash, + &esp32s3_flash, &faux_flash, &fm3_flash, &fm4_flash, diff --git a/src/flash/nor/esp32s3.c b/src/flash/nor/esp32s3.c new file mode 100644 index 0000000000..ac98094195 --- /dev/null +++ b/src/flash/nor/esp32s3.c @@ -0,0 +1,239 @@ +/************************************************************************** + * ESP32-S3 flash driver for OpenOCD * + * Copyright (C) 2021 Espressif Systems Ltd. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include +#include +#include +#include +#include "esp_xtensa.h" +#include "contrib/loaders/flash/esp/esp32s3/stub_flasher_image.h" + +#define ESP32_S3_FLASH_SECTOR_SIZE 4096 + +struct esp32s3_flash_bank { + struct esp_xtensa_flash_bank esp_xtensa; +}; + +static const uint8_t esp32s3_flasher_stub_code[] = { +#include "contrib/loaders/flash/esp/esp32s3/stub_flasher_code.inc" +}; +static const uint8_t esp32s3_flasher_stub_data[] = { +#include "contrib/loaders/flash/esp/esp32s3/stub_flasher_data.inc" +}; + +static const struct esp_flasher_stub_config s_stub_cfg = { + .code = esp32s3_flasher_stub_code, + .code_sz = sizeof(esp32s3_flasher_stub_code), + .data = esp32s3_flasher_stub_data, + .data_sz = sizeof(esp32s3_flasher_stub_data), + .entry_addr = ESP32S3_STUB_ENTRY_ADDR, + .bss_sz = ESP32S3_STUB_BSS_SIZE, + .first_user_reg_param = XTENSA_STUB_ARGS_FUNC_START +}; + + +static bool esp32s3_is_irom_address(target_addr_t addr) +{ + return (addr >= ESP32_S3_IROM_LOW && addr < ESP32_S3_IROM_HIGH); +} + +static bool esp32s3_is_drom_address(target_addr_t addr) +{ + return (addr >= ESP32_S3_DROM_LOW && addr < ESP32_S3_DROM_HIGH); +} + +static const struct esp_flasher_stub_config *esp32s3_get_stub(struct flash_bank *bank) +{ + return &s_stub_cfg; +} + +/* flash bank esp32s3 0 0 + If is zero flash size will be autodetected, otherwise user value will be used + */ +FLASH_BANK_COMMAND_HANDLER(esp32s3_flash_bank_command) +{ + struct esp32s3_flash_bank *esp32s3_info; + + if (CMD_ARGC < 6) + return ERROR_COMMAND_SYNTAX_ERROR; + + esp32s3_info = malloc(sizeof(struct esp32s3_flash_bank)); + if (esp32s3_info == NULL) + return ERROR_FAIL; + int ret = esp_xtensa_flash_init(&esp32s3_info->esp_xtensa, + ESP32_S3_FLASH_SECTOR_SIZE, + esp_xtensa_smp_run_func_image, + esp32s3_is_irom_address, + esp32s3_is_drom_address, + esp32s3_get_stub); + if (ret != ERROR_OK) { + free(esp32s3_info); + return ret; + } + esp32s3_info->esp_xtensa.esp.flash_min_offset = 0; + bank->driver_priv = esp32s3_info; + return ERROR_OK; +} + +static int esp32s3_get_info(struct flash_bank *bank, char *buf, int buf_size) +{ + snprintf(buf, buf_size, "ESP32-S3"); + return ERROR_OK; +} + +COMMAND_HANDLER(esp32s3_cmd_appimage_flashoff) +{ + struct target *target = get_current_target(CMD_CTX); + + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->head) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(esp_flash_cmd_appimage_flashoff_do, curr); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(esp_flash_cmd_appimage_flashoff_do, target); +} + +COMMAND_HANDLER(esp32s3_cmd_compression) +{ + struct target *target = get_current_target(CMD_CTX); + + if (target->smp) { + struct target_list *head; + struct target *curr; + foreach_smp_target(head, target->head) { + curr = head->target; + int ret = CALL_COMMAND_HANDLER(esp_flash_cmd_set_compression, curr); + if (ret != ERROR_OK) + return ret; + } + return ERROR_OK; + } + return CALL_COMMAND_HANDLER(esp_flash_cmd_set_compression, target); +} + +COMMAND_HANDLER(esp32s3_cmd_verify_bank_hash) +{ + return CALL_COMMAND_HANDLER(esp_flash_parse_cmd_verify_bank_hash, + get_current_target(CMD_CTX)); +} + +COMMAND_HANDLER(esp32s3_cmd_set_clock) +{ + return CALL_COMMAND_HANDLER(esp_flash_parse_cmd_clock_boost, + get_current_target(CMD_CTX)); +} + +const struct command_registration esp32s3_flash_command_handlers[] = { + { + .name = "appimage_offset", + .handler = esp32s3_cmd_appimage_flashoff, + .mode = COMMAND_ANY, + .help = + "Set offset of application image in flash. Use -1 to debug the first application image from partition table.", + .usage = "offset", + }, + { + .name = "compression", + .handler = esp32s3_cmd_compression, + .mode = COMMAND_ANY, + .help = + "Set compression flag", + .usage = "['on'|'off']", + }, + { + .name = "verify_bank_hash", + .handler = esp32s3_cmd_verify_bank_hash, + .mode = COMMAND_ANY, + .usage = "bank_id filename [offset]", + .help = "Perform a comparison between the file and the contents of the " + "flash bank using SHA256 hash values. Allow optional offset from beginning of the bank " + "(defaults to zero).", + }, + { + .name = "flash_stub_clock_boost", + .handler = esp32s3_cmd_set_clock, + .mode = COMMAND_ANY, + .help = + "Set cpu clock freq to the max level. Use 'off' to restore the clock speed", + .usage = "['on'|'off']", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration esp32s3_command_handlers[] = { + { + .name = "esp", + .mode = COMMAND_ANY, + .help = "ESP flash command group", + .usage = "", + .chain = esp32s3_flash_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration esp32s3_legacy_command_handlers[] = { + { + .name = "esp32s3", + .mode = COMMAND_ANY, + .help = "ESP32_S3 flash command group", + .usage = "", + .chain = esp32s3_flash_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration esp32s3_all_command_handlers[] = { + { + .usage = "", + .chain = esp32s3_command_handlers, + }, + { + .usage = "", + .chain = esp32s3_legacy_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +struct flash_driver esp32s3_flash = { + .name = "esp32s3", + .commands = esp32s3_all_command_handlers, + .flash_bank_command = esp32s3_flash_bank_command, + .erase = esp_flash_erase, + .protect = esp_flash_protect, + .write = esp_flash_write, + .read = esp_flash_read, + .probe = esp_flash_probe, + .auto_probe = esp_flash_auto_probe, + .erase_check = esp_flash_blank_check, + .protect_check = esp_flash_protect_check, + .info = esp32s3_get_info, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/src/target/esp32s3.c b/src/target/esp32s3.c index 561e48db15..6ed5d22749 100644 --- a/src/target/esp32s3.c +++ b/src/target/esp32s3.c @@ -49,7 +49,7 @@ implementation. #define ESP32_S3_RTC_DRAM_HIGH 0x60100000 #define ESP32_S3_RTC_DATA_LOW 0x50000000 #define ESP32_S3_RTC_DATA_HIGH 0x50002000 -#define ESP32_S3_EXTRAM_DATA_LOW 0x3D800000 +#define ESP32_S3_EXTRAM_DATA_LOW 0x3D000000 #define ESP32_S3_EXTRAM_DATA_HIGH 0x3E000000 #define ESP32_S3_SYS_RAM_LOW 0x60000000UL #define ESP32_S3_SYS_RAM_HIGH (ESP32_S3_SYS_RAM_LOW+0x10000000UL) diff --git a/src/target/esp32s3.h b/src/target/esp32s3.h index 4cfe87248a..e2d0a2bc49 100644 --- a/src/target/esp32s3.h +++ b/src/target/esp32s3.h @@ -23,10 +23,10 @@ #include "esp_xtensa_smp.h" -#define ESP32_S3_DROM_LOW 0x3D000000 -#define ESP32_S3_DROM_HIGH 0x3D800000 +#define ESP32_S3_DROM_LOW 0x3C000000 +#define ESP32_S3_DROM_HIGH 0x3D000000 #define ESP32_S3_IROM_LOW 0x42000000 -#define ESP32_S3_IROM_HIGH 0x43000000 +#define ESP32_S3_IROM_HIGH 0x44000000 /*Number of registers returned directly by the G command *Corresponds to the amount of regs listed in regformats/reg-xtensa.dat in the gdb source */ diff --git a/tcl/board/esp32s3-builtin.cfg b/tcl/board/esp32s3-builtin.cfg index 6f87d9b515..fbf7b875a6 100644 --- a/tcl/board/esp32s3-builtin.cfg +++ b/tcl/board/esp32s3-builtin.cfg @@ -9,3 +9,11 @@ source [find interface/esp_usb_jtag.cfg] # Source the ESP32-S3 configuration file source [find target/esp32s3.cfg] + +# Currently builtin USB-JTAG stucks during flash probing +# TODO: Remove code below when problem is above is fixed +set flash_list_size [llength [flash list]] +if { $flash_list_size != 0} { + echo "WARNING: ESP32-S3 target may experience problems when accessing flash via builtin USB-JTAG adapter!" + echo "WARNING: It is recommended to disable flash support by running OpenOCD with `-c 'set ESP_FLASH_SIZE 0'` or use external JTAG adapter." +} diff --git a/tcl/target/esp32s3.cfg b/tcl/target/esp32s3.cfg index f70b29dc66..e02e947a6b 100644 --- a/tcl/target/esp32s3.cfg +++ b/tcl/target/esp32s3.cfg @@ -1,11 +1,6 @@ # The ESP32-S3 only supports JTAG. transport select jtag -# TODO: remove this when flash support is implemented -if { ![info exists ESP_FLASH_SIZE] } { - set ESP_FLASH_SIZE "0" -} - # Source the ESP common configuration file source [find target/esp_common.cfg] @@ -48,7 +43,7 @@ if { $_RTOS == "none" } { } else { target create $_TARGETNAME_0 $_CHIPNAME -endian little -chain-position $_TARGETNAME_0 -coreid 0 -rtos $_RTOS } -configure_esp_workarea $_TARGETNAME_0 0x403C0000 0x3400 0x3FCE0000 0x10000 +configure_esp_workarea $_TARGETNAME_0 0x403B0000 0x3400 0x3FCE0000 0x10000 configure_esp_flash_bank $_TARGETNAME_0 $_CHIPNAME $_FLASH_SIZE # APP-CPU if { $_ONLYCPU != 1 } { diff --git a/testing/esp/debug_backend_tests.py b/testing/esp/debug_backend_tests.py index a18530d73c..2c906d4ea5 100644 --- a/testing/esp/debug_backend_tests.py +++ b/testing/esp/debug_backend_tests.py @@ -317,14 +317,18 @@ def _load_app(self, app_cfg): if state != dbg.TARGET_STATE_STOPPED: self.gdb.exec_interrupt() self.gdb.wait_target_state(dbg.TARGET_STATE_STOPPED, 5) - # write bootloader - self.gdb.target_program(app_cfg.build_bld_bin_path(), app_cfg.bld_off) - # write partition table - self.gdb.target_program(app_cfg.build_pt_bin_path(), app_cfg.pt_off) - # write application - # Currently we can not use GDB ELF loading facility for ESP32, so write binary image instead - # _gdb.target_download() - self.gdb.target_program(app_cfg.build_app_bin_path(), app_cfg.app_off) + if testee_info.idf_ver < IdfVersion.fromstr('4.0'): + # write bootloader + self.gdb.target_program(app_cfg.build_bld_bin_path(), app_cfg.bld_off) + # write partition table + self.gdb.target_program(app_cfg.build_pt_bin_path(), app_cfg.pt_off) + # write application + # Currently we can not use GDB ELF loading facility for ESP32, so write binary image instead + # _gdb.target_download() + self.gdb.target_program(app_cfg.build_app_bin_path(), app_cfg.app_off) + else: + # flash using 'flasher_args.json' + self.gdb.target_program_bins(app_cfg.build_bins_dir()) self.gdb.target_reset() diff --git a/testing/esp/run_tests.py b/testing/esp/run_tests.py index 8f44d86816..3f685c5fc6 100755 --- a/testing/esp/run_tests.py +++ b/testing/esp/run_tests.py @@ -29,7 +29,8 @@ os.path.join('board', 'esp32-wrover-kit-3.3v.cfg') ], 'commands' : [], - 'chip_name' : 'esp32' + 'chip_name' : 'esp32', + 'target_triple' : 'xtensa-esp32-elf' }, 'esp32-solo-devkitj' : { 'files' : [ @@ -37,7 +38,8 @@ os.path.join('target', 'esp32-solo-1.cfg') ], 'commands' : [], - 'chip_name' : 'esp32-solo' + 'chip_name' : 'esp32-solo', + 'target_triple' : 'xtensa-esp32-elf' }, 'esp32s2-devkitj' : { 'files' : [ @@ -45,28 +47,48 @@ os.path.join('target', 'esp32s2.cfg') ], 'commands' : [], - 'chip_name' : 'esp32s2' + 'chip_name' : 'esp32s2', + 'target_triple' : 'xtensa-esp32s2-elf' }, 'esp32s2-kaluga-1' : { 'files' : [ os.path.join('board', 'esp32s2-kaluga-1.cfg') ], 'commands' : [], - 'chip_name' : 'esp32s2' + 'chip_name' : 'esp32s2', + 'target_triple' : 'xtensa-esp32s2-elf' }, 'esp32c3-ftdi' : { 'files' : [ os.path.join('board', 'esp32c3-ftdi.cfg') ], 'commands' : [], - 'chip_name' : 'esp32c3' + 'chip_name' : 'esp32c3', + 'target_triple' : 'riscv32-esp-elf' }, 'esp32c3-builtin' : { 'files' : [ os.path.join('board', 'esp32c3-builtin.cfg') ], 'commands' : [], - 'chip_name' : 'esp32c3' + 'chip_name' : 'esp32c3', + 'target_triple' : 'riscv32-esp-elf' + }, + 'esp32s3-ftdi' : { + 'files' : [ + os.path.join('board', 'esp32s3-ftdi.cfg') + ], + 'commands' : [], + 'chip_name' : 'esp32s3', + 'target_triple' : 'xtensa-esp32s3-elf' + }, + 'esp32s3-builtin' : { + 'files' : [ + os.path.join('board', 'esp32s3-builtin.cfg') + ], + 'commands' : [], + 'chip_name' : 'esp32s3', + 'target_triple' : 'xtensa-esp32s3-elf' }, } @@ -114,12 +136,13 @@ def run(self): def dbg_start(toolchain, oocd, oocd_tcl, oocd_cfg_files, oocd_cfg_cmds, debug_oocd, - chip_name, log_level, log_stream, log_file, gdb_log): + chip_name, target_triple, log_level, log_stream, log_file, gdb_log): global _oocd_inst, _gdb_inst connect_tmo = 15 remote_tmo = 10 # Start OpenOCD _oocd_inst = dbg.create_oocd(chip_name=chip_name, + target_triple=target_triple, oocd_exec=oocd, oocd_scripts=oocd_tcl, oocd_cfg_files=oocd_cfg_files, @@ -137,6 +160,7 @@ def dbg_start(toolchain, oocd, oocd_tcl, oocd_cfg_files, oocd_cfg_cmds, debug_oo os.environ["ESP_XTENSA_GDB_PRIV_REGS_FIX"] = "1" # Start GDB _gdb_inst = dbg.create_gdb(chip_name=chip_name, + target_triple=target_triple, gdb_path='%sgdb' % toolchain, remote_target='127.0.0.1:%d' % dbg.Oocd.GDB_PORT, log_level=log_level, @@ -277,7 +301,8 @@ def main(): # start debugger, ideally we should run all tests w/o restarting it dbg_start(args.toolchain, args.oocd, args.oocd_tcl, board_tcl['files'], board_tcl['commands'], - args.debug_oocd, board_tcl['chip_name'], log_lev, ch, fh, args.gdb_log_file) + args.debug_oocd, board_tcl['chip_name'], board_tcl['target_triple'], + log_lev, ch, fh, args.gdb_log_file) res = None try: # run tests from the same directory this file is diff --git a/testing/esp/test_apps/gen_ut_app/main/gen_ut_app.c b/testing/esp/test_apps/gen_ut_app/main/gen_ut_app.c index a940f09665..7ae2d92b31 100755 --- a/testing/esp/test_apps/gen_ut_app/main/gen_ut_app.c +++ b/testing/esp/test_apps/gen_ut_app/main/gen_ut_app.c @@ -28,10 +28,15 @@ const static char *TAG = "ut_app"; #define TIM_UPD(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].update = 1;}while(0) #define TIM_ALARM_EN(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].config.alarm_en = 1;}while(0) #else -#define TIM_CLR(_tg_, _tn_) do{ TIMERG ## _tg_.int_clr_timers.t ## _tn_ ## _int_clr = 1;}while(0) +#define TIM_CLR(_tg_, _tn_) do{ TIMERG ## _tg_.int_clr_timers.t ## _tn_ ## _int_clr = 1;}while(0) +#if CONFIG_IDF_TARGET_ESP32S3 +#define TIM_UPD(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].update.tn_update = 1;}while(0) +#define TIM_ALARM_EN(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].config.tn_alarm_en = 1;}while(0) +#else #define TIM_UPD(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].update.tx_update = 1;}while(0) #define TIM_ALARM_EN(_tg_, _tn_) do{ TIMERG ## _tg_.hw_timer[(_tn_)].config.tx_alarm_en = 1;}while(0) #endif +#endif #define SPIRAM_TEST_ARRAY_SZ 5 diff --git a/tools/format-esp.sh b/tools/format-esp.sh index d71d8e2081..1c70169a2e 100755 --- a/tools/format-esp.sh +++ b/tools/format-esp.sh @@ -41,6 +41,7 @@ ./tools/uncrustify1.sh src/flash/nor/esp32s2.c ./tools/uncrustify1.sh src/flash/nor/esp32.c ./tools/uncrustify1.sh src/flash/nor/esp32c3.c +./tools/uncrustify1.sh src/flash/nor/esp32s3.c ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32/sdkconfig.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32/stub_flasher_chip.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32/stub_flasher_image.h @@ -56,6 +57,11 @@ ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32c3/stub_flasher_chip.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32c3/stub_flasher_image.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32c3/stub_sha.c +./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32s3/sdkconfig.h +./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.c +./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32s3/stub_flasher_chip.h +./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32s3/stub_flasher_image.h +./tools/uncrustify1.sh contrib/loaders/flash/esp/esp32s3/stub_sha.c ./tools/uncrustify1.sh contrib/loaders/flash/esp/xtensa/stub_xtensa_chips.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/stub_flasher_int.h ./tools/uncrustify1.sh contrib/loaders/flash/esp/stub_flasher.c