diff --git a/contrib/loaders/flash/esp32/stub_flasher.c b/contrib/loaders/flash/esp32/stub_flasher.c index cf3873c89..83493df7e 100644 --- a/contrib/loaders/flash/esp32/stub_flasher.c +++ b/contrib/loaders/flash/esp32/stub_flasher.c @@ -623,11 +623,6 @@ static int stub_flash_get_map(uint32_t maps_addr) return ESP32_STUB_ERR_OK; } -static inline uint8_t stub_get_insn_size(uint8_t *insn) -{ - return insn[0] & 0x8 ? 2 : 3; -} - /** * Possible BP layouts in flash: * 1) addr is aligned to 4 bytes (in 1 sector) @@ -649,7 +644,7 @@ static uint8_t stub_flash_set_bp(uint32_t bp_flash_addr, uint32_t insn_buf_addr, return 0; } memcpy((void *)insn_buf_addr, &insn_sect[(bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)) & ~0x3UL], ESP32_STUB_BP_INSN_BUF_SIZE); - uint8_t insn_sz = stub_get_insn_size(&insn_sect[bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)]); + uint8_t insn_sz = xtensa_get_insn_size(&insn_sect[bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)]); STUB_LOGI("Read insn [%02x %02x %02x] %d bytes @ 0x%x\n", insn_sect[(bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)) + 0], insn_sect[(bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)) + 1], insn_sect[(bp_flash_addr & (ESP32_FLASH_SECTOR_SIZE-1)) + 2], insn_sz, bp_flash_addr); @@ -691,7 +686,7 @@ static int stub_flash_clear_bp(uint32_t bp_flash_addr, uint32_t insn_buf_addr, u STUB_LOGE("Failed to read insn sector (%d)!\n", rc); return ESP32_STUB_ERR_FAIL; } - uint8_t insn_sz = stub_get_insn_size(&insn[bp_flash_addr & 0x3UL]); + uint8_t insn_sz = xtensa_get_insn_size(&insn[bp_flash_addr & 0x3UL]); // this will erase full sector or two if (stub_flash_erase(bp_flash_addr, insn_sz) != ESP32_STUB_ERR_OK) { STUB_LOGE("Failed to erase insn sector!\n"); @@ -722,6 +717,7 @@ static int stub_flash_clear_bp(uint32_t bp_flash_addr, uint32_t insn_buf_addr, u return ESP32_STUB_ERR_OK; } + static int stub_flash_handler(int cmd, va_list ap) { int ret = ESP32_STUB_ERR_OK; @@ -734,7 +730,7 @@ static int stub_flash_handler(int cmd, va_list ap) uint32_t arg4 = va_arg(ap, uint32_t); // down buf size bool other_cache_enab = stub_spi_flash_cache_enabled(other_core_id); - STUB_LOGD("flash a %x, s %d\n", arg1, arg2); + STUB_LOGD("%s a %x, s %d\n", __func__, arg1, arg2); ets_efuse_read_op(); uint32_t spiconfig = ets_efuse_get_spiconfig(); @@ -894,13 +890,13 @@ int stub_main(int cmd, ...) ret = stub_flash_handler(cmd, ap); } else switch (cmd) { #if STUB_DEBUG - case ESP32_STUB_CMD_TEST: - STUB_LOGD("TEST %d\n", cmd); - break; - case ESP32_STUB_CMD_FLASH_TEST: + case ESP32_STUB_CMD_TEST: + STUB_LOGD("TEST %d\n", cmd); + break; + case ESP32_STUB_CMD_FLASH_TEST: #endif - default: - ret = ESP32_STUB_ERR_NOT_SUPPORTED; + default: + ret = ESP32_STUB_ERR_NOT_SUPPORTED; } va_end(ap); diff --git a/contrib/loaders/flash/esp32/stub_flasher.h b/contrib/loaders/flash/esp32/stub_flasher.h index 4cc8df795..8d1ad46f4 100644 --- a/contrib/loaders/flash/esp32/stub_flasher.h +++ b/contrib/loaders/flash/esp32/stub_flasher.h @@ -25,17 +25,17 @@ #define ESP32_STUB_ERR_FAIL (-1) #define ESP32_STUB_ERR_NOT_SUPPORTED (-2) -#define ESP32_STUB_CMD_TEST 0 -#define ESP32_STUB_CMD_FLASH_READ 1 -#define ESP32_STUB_CMD_FLASH_WRITE 2 -#define ESP32_STUB_CMD_FLASH_ERASE 3 -#define ESP32_STUB_CMD_FLASH_ERASE_CHECK 4 -#define ESP32_STUB_CMD_FLASH_SIZE 5 -#define ESP32_STUB_CMD_FLASH_MAP_GET 6 -#define ESP32_STUB_CMD_FLASH_BP_SET 7 -#define ESP32_STUB_CMD_FLASH_BP_CLEAR 8 +#define ESP32_STUB_CMD_FLASH_READ 0 +#define ESP32_STUB_CMD_FLASH_WRITE 1 +#define ESP32_STUB_CMD_FLASH_ERASE 2 +#define ESP32_STUB_CMD_FLASH_ERASE_CHECK 3 +#define ESP32_STUB_CMD_FLASH_SIZE 4 +#define ESP32_STUB_CMD_FLASH_MAP_GET 5 +#define ESP32_STUB_CMD_FLASH_BP_SET 6 +#define ESP32_STUB_CMD_FLASH_BP_CLEAR 7 #define ESP32_STUB_CMD_FLASH_MAX_ID ESP32_STUB_CMD_FLASH_BP_CLEAR #define ESP32_STUB_CMD_FLASH_TEST (ESP32_STUB_CMD_FLASH_MAX_ID+1) +#define ESP32_STUB_CMD_TEST 8 #define ESP32_STUB_PARTITION_TABLE_MAX_ENTRIES 10 #define ESP32_STUB_FLASH_MAPPINGS_MAX_NUM 2 // IROM, DROM @@ -55,4 +55,9 @@ struct esp32_flash_mapping { struct esp32_flash_region_mapping maps[ESP32_STUB_FLASH_MAPPINGS_MAX_NUM]; }; -#endif //ESP32_FLASHER_STUB_H \ No newline at end of file +static inline uint8_t xtensa_get_insn_size(uint8_t *insn) +{ + return insn[0] & 0x8 ? 2 : 3; +} + +#endif //ESP32_FLASHER_STUB_H diff --git a/contrib/loaders/flash/esp32/stub_flasher_code.inc b/contrib/loaders/flash/esp32/stub_flasher_code.inc index 5e1f3788b..bb7cc4994 100644 --- a/contrib/loaders/flash/esp32/stub_flasher_code.inc +++ b/contrib/loaders/flash/esp32/stub_flasher_code.inc @@ -38,36 +38,36 @@ 0x9a, 0xff, 0x2a, 0x64, 0x78, 0x15, 0x67, 0xb7, 0x03, 0x0c, 0x12, 0x1d, 0xf0, 0x78, 0x45, 0x70, 0x52, 0xe2, 0x50, 0x57, 0xc0, 0x57, 0xb4, 0x08, 0xcd, 0x04, 0xbd, 0x03, 0xad, 0x02, 0x06, 0x10, 0x00, 0x50, 0xc5, 0x20, - 0x30, 0xb3, 0x20, 0x20, 0xa2, 0x20, 0xe5, 0x0c, 0x01, 0x56, 0x8a, 0xfd, + 0x30, 0xb3, 0x20, 0x20, 0xa2, 0x20, 0xa5, 0x0c, 0x01, 0x56, 0x8a, 0xfd, 0x50, 0x84, 0xc0, 0x70, 0x88, 0xc2, 0x6d, 0x0a, 0x06, 0x06, 0x00, 0x00, - 0x70, 0xc7, 0x20, 0x30, 0xbb, 0xa0, 0x82, 0x61, 0x00, 0x25, 0x0b, 0x01, + 0x70, 0xc7, 0x20, 0x30, 0xbb, 0xa0, 0x82, 0x61, 0x00, 0xe5, 0x0a, 0x01, 0x88, 0x01, 0x56, 0xba, 0xfb, 0x1b, 0x66, 0x7a, 0x55, 0x60, 0x60, 0x74, 0x50, 0xb2, 0x41, 0x2a, 0xa5, 0x87, 0x36, 0xdf, 0x50, 0xc4, 0xc0, 0x30, - 0xbb, 0xa0, 0x65, 0x09, 0x01, 0x0c, 0x13, 0x0c, 0x02, 0xa0, 0x23, 0x93, + 0xbb, 0xa0, 0x25, 0x09, 0x01, 0x0c, 0x13, 0x0c, 0x02, 0xa0, 0x23, 0x93, 0x1d, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x04, 0x20, 0xf4, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x36, 0x41, 0x00, 0x31, 0x71, 0xff, 0x41, 0xcf, 0xff, 0xc0, 0x20, 0x00, 0x58, 0x03, 0x40, 0x45, 0x10, 0xc0, 0x20, 0x00, 0x49, 0x03, 0x31, 0xcc, 0xff, 0x41, 0xcc, 0xff, 0xc0, 0x20, 0x00, 0x58, 0x03, 0x40, 0x55, 0x10, 0x41, 0xcb, 0xff, 0x40, 0x45, 0x20, 0x51, 0x70, 0xff, 0xc0, 0x20, 0x00, 0x49, 0x03, 0x48, 0x15, 0x38, 0x35, 0x30, 0x44, - 0xc2, 0x47, 0x32, 0x04, 0x0c, 0x14, 0x86, 0x0e, 0x00, 0xe5, 0xff, 0x00, + 0xc2, 0x47, 0x32, 0x04, 0x0c, 0x14, 0x86, 0x0e, 0x00, 0xa5, 0xff, 0x00, 0x4d, 0x0a, 0x56, 0x2a, 0xff, 0x38, 0x35, 0x30, 0x32, 0x82, 0x30, 0x20, - 0xb4, 0x56, 0x72, 0xfe, 0xa5, 0xfb, 0x00, 0x21, 0xe7, 0xff, 0x81, 0x62, + 0xb4, 0x56, 0x72, 0xfe, 0x65, 0xfb, 0x00, 0x21, 0xe7, 0xff, 0x81, 0x62, 0xff, 0x20, 0x33, 0x10, 0x21, 0xe6, 0xff, 0xc0, 0x20, 0x00, 0x39, 0x02, 0x21, 0xe5, 0xff, 0xc0, 0x20, 0x00, 0x29, 0x08, 0xc0, 0x20, 0x00, 0x22, - 0x28, 0x00, 0x56, 0x62, 0xff, 0x65, 0xf9, 0x00, 0x40, 0x24, 0x20, 0x90, + 0x28, 0x00, 0x56, 0x62, 0xff, 0x25, 0xf9, 0x00, 0x40, 0x24, 0x20, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x20, 0xf4, 0x3f, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb0, 0x21, 0x06, 0x40, - 0x36, 0x61, 0x00, 0x65, 0xf7, 0x00, 0x25, 0xf7, 0x00, 0xb2, 0xa0, 0x35, + 0x36, 0x61, 0x00, 0x25, 0xf7, 0x00, 0xe5, 0xf6, 0x00, 0xb2, 0xa0, 0x35, 0xad, 0x01, 0x81, 0xfb, 0xff, 0xe0, 0x08, 0x00, 0x28, 0x01, 0x80, 0x32, 0x11, 0x0c, 0x12, 0x56, 0x7a, 0x05, 0x22, 0xa2, 0x00, 0x20, 0x23, 0x10, - 0x29, 0x01, 0x25, 0xf5, 0x00, 0x21, 0x48, 0xff, 0x31, 0xf0, 0xff, 0xc0, + 0x29, 0x01, 0xe5, 0xf4, 0x00, 0x21, 0x48, 0xff, 0x31, 0xf0, 0xff, 0xc0, 0x20, 0x00, 0x39, 0x02, 0xc0, 0x20, 0x00, 0x32, 0x22, 0x00, 0x56, 0x63, - 0xff, 0xa5, 0xf3, 0x00, 0x81, 0xec, 0xff, 0x31, 0xec, 0xff, 0xc0, 0x20, + 0xff, 0x65, 0xf3, 0x00, 0x81, 0xec, 0xff, 0x31, 0xec, 0xff, 0xc0, 0x20, 0x00, 0x42, 0x28, 0x00, 0x30, 0x34, 0x20, 0xc0, 0x20, 0x00, 0x39, 0x08, - 0x48, 0x01, 0x25, 0xf2, 0x00, 0x31, 0x3b, 0xff, 0xc0, 0x20, 0x00, 0x49, + 0x48, 0x01, 0xe5, 0xf1, 0x00, 0x31, 0x3b, 0xff, 0xc0, 0x20, 0x00, 0x49, 0x03, 0x31, 0xe5, 0xff, 0xc0, 0x20, 0x00, 0x39, 0x02, 0xc0, 0x20, 0x00, - 0x38, 0x02, 0x56, 0x73, 0xff, 0x65, 0xf0, 0x00, 0x2d, 0x03, 0x1d, 0xf0, + 0x38, 0x02, 0x56, 0x73, 0xff, 0x25, 0xf0, 0x00, 0x2d, 0x03, 0x1d, 0xf0, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf8, 0x20, 0xf4, 0x3f, 0xf8, 0x30, 0xf4, 0x3f, 0xff, 0x9f, 0x6f, 0xfe, 0x08, 0x30, 0xf4, 0x3f, 0x1c, 0x30, 0xf4, 0x3f, 0xff, 0xff, 0xff, 0xf7, 0x90, 0xe2, 0xfa, 0x3f, @@ -108,18 +108,18 @@ 0x08, 0x21, 0x1e, 0xff, 0x91, 0x1f, 0xff, 0xc0, 0x20, 0x00, 0xa8, 0x02, 0x90, 0xaa, 0x10, 0x91, 0x1d, 0xff, 0x90, 0x9a, 0x20, 0xc0, 0x20, 0x00, 0x99, 0x02, 0x98, 0x17, 0x22, 0x27, 0x02, 0x20, 0x99, 0xc2, 0x97, 0xb5, - 0x5a, 0xe5, 0xd4, 0x00, 0x56, 0x4a, 0x05, 0x28, 0x27, 0x65, 0xd1, 0x00, + 0x5a, 0xa5, 0xd4, 0x00, 0x56, 0x4a, 0x05, 0x28, 0x27, 0x25, 0xd1, 0x00, 0x20, 0x25, 0x82, 0x51, 0x3d, 0xff, 0x81, 0x3d, 0xff, 0x50, 0x22, 0x10, 0xc0, 0x20, 0x00, 0x29, 0x08, 0x21, 0xb5, 0xfe, 0x81, 0x8e, 0xff, 0xc0, 0x20, 0x00, 0x89, 0x02, 0xc0, 0x20, 0x00, 0x82, 0x22, 0x00, 0x56, 0x68, - 0xff, 0xe5, 0xce, 0x00, 0x40, 0x66, 0x80, 0x40, 0x33, 0xc0, 0x37, 0xb4, + 0xff, 0xa5, 0xce, 0x00, 0x40, 0x66, 0x80, 0x40, 0x33, 0xc0, 0x37, 0xb4, 0x02, 0xc6, 0xe0, 0xff, 0x30, 0x46, 0x80, 0x86, 0x02, 0x00, 0x00, 0x00, 0x65, 0xcc, 0xff, 0x56, 0xda, 0x00, 0x32, 0xc3, 0xff, 0x30, 0xa4, 0xc0, 0xe6, 0x13, 0xf0, 0x22, 0xa0, 0x00, 0x1d, 0xf0, 0x7c, 0xf2, 0x1d, 0xf0, 0x00, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xaa, 0x50, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xbf, 0xff, 0xff, 0x32, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xff, 0xff, 0x3f, 0x00, 0x36, 0x21, 0x03, 0x65, 0xa8, 0xff, 0xa0, 0x5a, - 0x20, 0xa1, 0xf6, 0xff, 0xc2, 0xa1, 0x40, 0x10, 0xb1, 0x20, 0xa5, 0xe3, + 0x20, 0xa1, 0xf6, 0xff, 0xc2, 0xa1, 0x40, 0x10, 0xb1, 0x20, 0x65, 0xe3, 0x00, 0x56, 0xca, 0x0e, 0x4d, 0x01, 0x3d, 0x0a, 0x62, 0x14, 0x00, 0x81, 0xf2, 0xff, 0x87, 0x96, 0x1e, 0xb0, 0x33, 0x11, 0x3a, 0x31, 0x22, 0x03, 0x02, 0x42, 0xa0, 0xff, 0x47, 0x12, 0x02, 0x86, 0x33, 0x00, 0x32, 0x03, @@ -127,11 +127,11 @@ 0x81, 0xea, 0xff, 0x87, 0x16, 0x02, 0xc6, 0x2d, 0x00, 0xa8, 0x14, 0xa7, 0xb5, 0x02, 0xc6, 0x2b, 0x00, 0x68, 0x24, 0x6a, 0x6a, 0x67, 0xb5, 0x02, 0x46, 0x29, 0x00, 0x62, 0x04, 0x02, 0x56, 0x16, 0x09, 0xb2, 0xa1, 0x40, - 0x1c, 0x8c, 0x10, 0xbb, 0x80, 0xe5, 0xdd, 0x00, 0x56, 0x1a, 0x09, 0x92, + 0x1c, 0x8c, 0x10, 0xbb, 0x80, 0xa5, 0xdd, 0x00, 0x56, 0x1a, 0x09, 0x92, 0xd1, 0x01, 0x72, 0x09, 0x40, 0x62, 0xa0, 0xe9, 0x67, 0x97, 0x77, 0x88, 0x14, 0x7d, 0x0a, 0x82, 0xc8, 0x18, 0x6d, 0x0a, 0xd2, 0xa1, 0x58, 0x86, 0x16, 0x00, 0xda, 0xb1, 0xad, 0x08, 0x0c, 0x8c, 0x82, 0x61, 0x58, 0x92, - 0x61, 0x59, 0xd2, 0x61, 0x5a, 0xe5, 0xda, 0x00, 0x82, 0x21, 0x58, 0x92, + 0x61, 0x59, 0xd2, 0x61, 0x5a, 0xa5, 0xda, 0x00, 0x82, 0x21, 0x58, 0x92, 0x21, 0x59, 0xd2, 0x21, 0x5a, 0x56, 0x8a, 0x05, 0xb2, 0x29, 0x16, 0xa1, 0xd0, 0xff, 0xc1, 0xd0, 0xff, 0xaa, 0xab, 0xa7, 0xbc, 0x0b, 0xa1, 0xcf, 0xff, 0xc1, 0xcf, 0xff, 0xa0, 0xab, 0x80, 0xa7, 0x3c, 0x19, 0xa8, 0x02, @@ -143,7 +143,7 @@ 0xff, 0x7c, 0xf2, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x04, 0x2a, 0x54, 0x40, 0x62, 0x11, 0x3a, 0x22, 0x06, 0x13, 0x00, 0x0c, 0x13, 0x32, 0x45, 0x00, 0x72, 0xa0, 0xff, 0x32, 0xd6, 0x10, 0x06, 0x0e, 0x00, 0x00, - 0xc2, 0xa2, 0x00, 0x10, 0xb1, 0x20, 0x60, 0xa6, 0x20, 0xa5, 0xd1, 0x00, + 0xc2, 0xa2, 0x00, 0x10, 0xb1, 0x20, 0x60, 0xa6, 0x20, 0x65, 0xd1, 0x00, 0x56, 0x8a, 0x03, 0x82, 0xa2, 0x00, 0x76, 0x88, 0x11, 0xaa, 0x91, 0x92, 0x09, 0x00, 0x77, 0x19, 0x07, 0x0c, 0x08, 0x82, 0x45, 0x00, 0x46, 0x00, 0x00, 0x1b, 0xaa, 0x82, 0x05, 0x00, 0x62, 0xd6, 0x02, 0xcc, 0x78, 0x1b, @@ -157,7 +157,7 @@ 0x1b, 0x00, 0x8a, 0x83, 0xa2, 0x48, 0x00, 0x8d, 0x02, 0x22, 0xc8, 0x01, 0x97, 0x92, 0xf2, 0x22, 0xa0, 0x00, 0xc0, 0x20, 0x00, 0x22, 0x63, 0x06, 0xc0, 0x20, 0x00, 0x29, 0x53, 0xc0, 0x20, 0x00, 0x29, 0x73, 0x29, 0x43, - 0xc0, 0x20, 0x00, 0x29, 0x83, 0xad, 0x03, 0x25, 0xf9, 0x00, 0x7c, 0xf2, + 0xc0, 0x20, 0x00, 0x29, 0x83, 0xad, 0x03, 0xe5, 0xf8, 0x00, 0x7c, 0xf2, 0x56, 0xca, 0x07, 0x21, 0xe6, 0xff, 0x81, 0xe7, 0xff, 0xc0, 0x20, 0x00, 0xa9, 0xa3, 0x29, 0xc3, 0x21, 0xe4, 0xff, 0x89, 0xe3, 0xc0, 0x20, 0x00, 0xa9, 0xb3, 0x81, 0xe3, 0xff, 0x22, 0x53, 0x1a, 0x22, 0x53, 0x1e, 0xc0, @@ -176,318 +176,317 @@ 0xfe, 0x3f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x86, 0x00, 0x40, 0x58, 0x86, 0x00, 0x40, 0x6c, 0x2a, 0x06, 0x40, 0x38, 0x32, 0x06, 0x40, 0x50, 0xc0, 0x00, 0x40, 0x14, 0x9a, 0x00, 0x40, - 0x36, 0x21, 0x01, 0x39, 0xd1, 0x49, 0xe1, 0x59, 0xf1, 0x62, 0x61, 0x10, - 0x72, 0x61, 0x11, 0x31, 0xe7, 0xff, 0x41, 0xe8, 0xff, 0x0c, 0x05, 0xc6, - 0x00, 0x00, 0x59, 0x03, 0x4b, 0x33, 0x47, 0x33, 0xf8, 0x31, 0xe5, 0xff, - 0x71, 0xe7, 0xff, 0xc0, 0x20, 0x00, 0x42, 0x23, 0x12, 0x40, 0x4f, 0x05, - 0x42, 0x61, 0x18, 0x41, 0xe2, 0xff, 0xc0, 0x20, 0x00, 0x52, 0x24, 0x12, - 0xc0, 0x20, 0x00, 0x72, 0x63, 0x19, 0x50, 0x5f, 0x05, 0x52, 0x61, 0x19, - 0xc0, 0x20, 0x00, 0x62, 0x23, 0x12, 0x51, 0xdd, 0xff, 0x50, 0x66, 0x10, - 0xc0, 0x20, 0x00, 0x62, 0x63, 0x12, 0x0c, 0x06, 0xc0, 0x20, 0x00, 0x62, - 0x63, 0x19, 0xc0, 0x20, 0x00, 0x72, 0x64, 0x19, 0xc0, 0x20, 0x00, 0x72, - 0x24, 0x12, 0x7c, 0xe3, 0x50, 0x57, 0x10, 0xc0, 0x20, 0x00, 0x52, 0x64, - 0x12, 0xc0, 0x20, 0x00, 0x62, 0x64, 0x19, 0x42, 0xc1, 0x30, 0x49, 0x41, - 0x42, 0xc1, 0x70, 0x49, 0x31, 0x0c, 0x44, 0x49, 0x51, 0x0c, 0x84, 0x27, - 0xa4, 0x02, 0x86, 0x01, 0x01, 0x30, 0xeb, 0x03, 0x30, 0x3d, 0x04, 0x32, - 0x61, 0x14, 0x42, 0x21, 0x14, 0x0c, 0x13, 0x82, 0x21, 0x10, 0x40, 0x63, - 0x83, 0x32, 0x21, 0x14, 0x62, 0x61, 0x16, 0x82, 0x61, 0x17, 0x48, 0xd1, - 0x68, 0xe1, 0x58, 0xf1, 0x8c, 0x53, 0x31, 0xec, 0xfd, 0xc6, 0x00, 0x00, - 0x00, 0x31, 0xec, 0xfd, 0xc0, 0x20, 0x00, 0x38, 0x03, 0x30, 0x33, 0x04, - 0x32, 0x61, 0x15, 0x81, 0xc6, 0xff, 0xe0, 0x08, 0x00, 0x81, 0xc5, 0xff, - 0xe0, 0x08, 0x00, 0x31, 0xbb, 0xff, 0x7d, 0x0a, 0xc0, 0x20, 0x00, 0x98, - 0x03, 0xcc, 0xba, 0x1c, 0xc3, 0x30, 0x39, 0x10, 0x32, 0xc3, 0xf8, 0x0c, - 0x19, 0x30, 0x79, 0x83, 0x82, 0x21, 0x15, 0x8c, 0xa8, 0xa2, 0x21, 0x16, + 0x36, 0x21, 0x01, 0x39, 0xd1, 0x49, 0xe1, 0x62, 0x61, 0x10, 0x6d, 0x02, + 0x59, 0xf1, 0x72, 0x61, 0x11, 0x21, 0xe6, 0xff, 0x31, 0xe8, 0xff, 0x0c, + 0x04, 0xc6, 0x00, 0x00, 0x49, 0x02, 0x4b, 0x22, 0x37, 0x32, 0xf8, 0x21, + 0xe5, 0xff, 0x71, 0xe6, 0xff, 0xc0, 0x20, 0x00, 0x32, 0x22, 0x12, 0x30, + 0x3f, 0x05, 0x32, 0x61, 0x18, 0x31, 0xe1, 0xff, 0xc0, 0x20, 0x00, 0x42, + 0x23, 0x12, 0xc0, 0x20, 0x00, 0x72, 0x62, 0x19, 0x40, 0x4f, 0x05, 0x42, + 0x61, 0x19, 0xc0, 0x20, 0x00, 0x52, 0x22, 0x12, 0x41, 0xdd, 0xff, 0x40, + 0x55, 0x10, 0xc0, 0x20, 0x00, 0x52, 0x62, 0x12, 0x0c, 0x05, 0xc0, 0x20, + 0x00, 0x52, 0x62, 0x19, 0xc0, 0x20, 0x00, 0x72, 0x63, 0x19, 0xc0, 0x20, + 0x00, 0x72, 0x23, 0x12, 0x7c, 0xe2, 0x40, 0x47, 0x10, 0xc0, 0x20, 0x00, + 0x42, 0x63, 0x12, 0xc0, 0x20, 0x00, 0x52, 0x63, 0x19, 0x32, 0xc1, 0x30, + 0x39, 0x41, 0x32, 0xc1, 0x70, 0x39, 0x31, 0x0c, 0x43, 0x39, 0x51, 0xa6, + 0x86, 0x02, 0x86, 0x01, 0x01, 0x20, 0xeb, 0x03, 0x20, 0x2d, 0x04, 0x22, + 0x61, 0x14, 0x32, 0x21, 0x14, 0x0c, 0x12, 0x82, 0x21, 0x10, 0x30, 0x52, + 0x83, 0x22, 0x21, 0x14, 0x52, 0x61, 0x16, 0x82, 0x61, 0x17, 0x38, 0xd1, + 0x58, 0xe1, 0x48, 0xf1, 0x8c, 0x52, 0x21, 0xec, 0xfd, 0xc6, 0x00, 0x00, + 0x00, 0x21, 0xec, 0xfd, 0xc0, 0x20, 0x00, 0x28, 0x02, 0x20, 0x23, 0x04, + 0x22, 0x61, 0x15, 0x81, 0xc6, 0xff, 0xe0, 0x08, 0x00, 0x81, 0xc5, 0xff, + 0xe0, 0x08, 0x00, 0x21, 0xbb, 0xff, 0x7d, 0x0a, 0xc0, 0x20, 0x00, 0x98, + 0x02, 0xcc, 0xba, 0x1c, 0xc2, 0x20, 0x29, 0x10, 0x22, 0xc2, 0xf8, 0x0c, + 0x19, 0x20, 0x79, 0x83, 0x82, 0x21, 0x15, 0x8c, 0xa8, 0xa2, 0x21, 0x16, 0xb2, 0xc1, 0x1c, 0x10, 0x11, 0x20, 0xa5, 0x7c, 0xff, 0xa2, 0x21, 0x14, 0xb2, 0xc1, 0x18, 0x25, 0x7c, 0xff, 0xb2, 0xa0, 0x00, 0x70, 0xa7, 0x20, - 0x81, 0xb7, 0xff, 0xe0, 0x08, 0x00, 0xa5, 0x6b, 0xff, 0x31, 0xad, 0xff, + 0x81, 0xb7, 0xff, 0xe0, 0x08, 0x00, 0xa5, 0x6b, 0xff, 0x21, 0xad, 0xff, 0xa0, 0xba, 0x20, 0xf1, 0x04, 0xff, 0xd1, 0xa9, 0xff, 0xc1, 0xa9, 0xff, - 0xa8, 0x03, 0xe2, 0xa1, 0x00, 0x81, 0xb0, 0xff, 0xe0, 0x08, 0x00, 0x25, - 0x94, 0xff, 0x8c, 0x2a, 0x86, 0x84, 0x00, 0x00, 0x0b, 0x22, 0x7c, 0xe3, - 0xb6, 0x82, 0x02, 0x06, 0xcf, 0x00, 0x31, 0xa3, 0xff, 0x30, 0x22, 0xa0, - 0x28, 0x02, 0xa0, 0x02, 0x00, 0x00, 0x25, 0xd9, 0xff, 0x3d, 0x0a, 0x2d, - 0x0a, 0x16, 0x3a, 0x08, 0xc6, 0xc8, 0x00, 0x00, 0x81, 0x9e, 0xff, 0x20, - 0x56, 0xc0, 0x80, 0x75, 0x63, 0x70, 0x90, 0x14, 0x16, 0x89, 0x00, 0x92, - 0xaf, 0xfc, 0x90, 0x77, 0x10, 0x16, 0x07, 0x07, 0x81, 0x9f, 0xff, 0xe0, - 0x08, 0x00, 0x81, 0x9d, 0xff, 0xe0, 0x08, 0x00, 0xa2, 0x61, 0x00, 0x7c, - 0xf5, 0xbd, 0x01, 0xad, 0x07, 0x59, 0x11, 0x25, 0x68, 0x00, 0x16, 0x8a, - 0x1b, 0xa2, 0x61, 0x1b, 0x81, 0x97, 0xff, 0xe0, 0x08, 0x00, 0x81, 0x95, - 0xff, 0xe0, 0x08, 0x00, 0x82, 0x21, 0x1b, 0xcd, 0x07, 0xbd, 0x08, 0x4a, - 0xa2, 0x65, 0x9e, 0x00, 0xa2, 0x61, 0x1a, 0x81, 0x90, 0xff, 0xe0, 0x08, - 0x00, 0xb2, 0x21, 0x1a, 0x82, 0x21, 0x1b, 0x8c, 0xbb, 0xad, 0x08, 0xa5, - 0x97, 0x00, 0x3d, 0x05, 0xc6, 0xad, 0x00, 0x00, 0x00, 0x00, 0x80, 0xa8, - 0x20, 0x70, 0x22, 0x80, 0x65, 0x96, 0x00, 0x56, 0x3a, 0x17, 0x25, 0x94, - 0x00, 0x56, 0xda, 0x16, 0x67, 0xb2, 0x02, 0x46, 0xde, 0xff, 0x46, 0xa6, - 0x00, 0xb6, 0x45, 0x02, 0x86, 0x57, 0x00, 0xc2, 0xa0, 0x04, 0xb2, 0xc1, - 0x20, 0x40, 0xa2, 0x80, 0xa5, 0x99, 0x00, 0x56, 0xfa, 0x14, 0x81, 0x7d, - 0xff, 0xe0, 0x08, 0x00, 0xa2, 0x61, 0x00, 0x7c, 0xf2, 0xbd, 0x01, 0xad, - 0x05, 0x29, 0x11, 0x25, 0x60, 0x00, 0x2d, 0x0a, 0x16, 0x6a, 0x13, 0xcd, - 0x05, 0xb2, 0xc1, 0x20, 0xe5, 0xc5, 0x00, 0xad, 0x02, 0xa5, 0x91, 0x00, - 0x56, 0x6a, 0x12, 0x65, 0x8f, 0x00, 0x16, 0x5a, 0x25, 0x46, 0x47, 0x00, - 0x00, 0x00, 0xbd, 0x06, 0xad, 0x04, 0x25, 0x8f, 0xff, 0x46, 0x54, 0x00, - 0x00, 0x00, 0x00, 0xcd, 0x05, 0xbd, 0x06, 0xad, 0x04, 0xe5, 0xc0, 0xff, - 0x86, 0x50, 0x00, 0xa5, 0xc9, 0xff, 0xa0, 0x3a, 0x20, 0x56, 0xea, 0x22, - 0x21, 0x1a, 0xff, 0xa0, 0x7a, 0x20, 0x52, 0x62, 0x04, 0x52, 0x21, 0x17, - 0xc0, 0x20, 0x00, 0x59, 0x62, 0xc0, 0x20, 0x00, 0x59, 0x52, 0xc0, 0x20, - 0x00, 0xa9, 0x72, 0xc0, 0x20, 0x00, 0xa9, 0x82, 0x5d, 0x0a, 0x86, 0x36, - 0x00, 0x50, 0x86, 0xc0, 0x70, 0x88, 0xc0, 0x89, 0x91, 0x81, 0x5c, 0xff, - 0xe0, 0x08, 0x00, 0x81, 0x5b, 0xff, 0xe0, 0x08, 0x00, 0xa9, 0x01, 0x7c, - 0xf8, 0xbd, 0x01, 0xa2, 0xc1, 0x24, 0x89, 0x11, 0x65, 0x68, 0x00, 0x2d, - 0x0a, 0x16, 0xda, 0x0a, 0x81, 0x55, 0xff, 0xe0, 0x08, 0x00, 0x9d, 0x02, - 0xbc, 0x97, 0x0c, 0x4d, 0x70, 0x9d, 0xc0, 0x82, 0xc1, 0x20, 0xcd, 0x09, - 0x20, 0xb2, 0x20, 0x70, 0xa8, 0x80, 0x92, 0x61, 0x1b, 0xd2, 0x61, 0x1a, - 0xa5, 0xbb, 0x00, 0xd2, 0x21, 0x1a, 0xb2, 0xc1, 0x20, 0xcd, 0x0d, 0x4a, - 0xa5, 0x25, 0x66, 0xff, 0x92, 0x21, 0x1b, 0x8c, 0x1a, 0x46, 0x17, 0x00, - 0xa8, 0x91, 0x9a, 0x92, 0xa2, 0xca, 0xfc, 0x7a, 0x7a, 0x79, 0x91, 0x4b, - 0x55, 0xb2, 0x21, 0x09, 0x72, 0xa0, 0x00, 0xb0, 0xa0, 0x14, 0x77, 0x1a, - 0x1a, 0xa0, 0x70, 0x74, 0xa2, 0xaf, 0xfc, 0xa0, 0xbb, 0x10, 0xb9, 0x91, - 0xcd, 0x07, 0xba, 0xb9, 0xa2, 0xc1, 0x20, 0x92, 0x61, 0x1b, 0x65, 0xb7, - 0x00, 0x92, 0x21, 0x1b, 0xa2, 0x21, 0x09, 0x16, 0x3a, 0x03, 0x92, 0x61, - 0x1b, 0x81, 0x37, 0xff, 0xe0, 0x08, 0x00, 0x92, 0x21, 0x1b, 0xc8, 0x91, - 0xbd, 0x09, 0x4a, 0xa5, 0xa5, 0x60, 0xff, 0xa2, 0x61, 0x1b, 0x81, 0x32, - 0xff, 0xe0, 0x08, 0x00, 0x92, 0x21, 0x1b, 0x16, 0x99, 0x00, 0x20, 0xa2, - 0x20, 0x25, 0x82, 0x00, 0x86, 0x03, 0x00, 0x00, 0x92, 0x21, 0x09, 0x90, - 0x55, 0x80, 0x20, 0xa2, 0x20, 0x25, 0x81, 0x00, 0x8c, 0x4a, 0x7c, 0xf3, - 0xc6, 0x4b, 0x00, 0x00, 0x67, 0xb5, 0x02, 0x86, 0xc7, 0xff, 0x7c, 0xf2, - 0xcc, 0xf7, 0x46, 0x48, 0x00, 0x62, 0xc1, 0x20, 0x1b, 0x37, 0x70, 0x76, - 0x80, 0x22, 0x47, 0x00, 0x30, 0x70, 0x74, 0x70, 0x30, 0x14, 0x56, 0xb3, - 0xfe, 0x0c, 0x4c, 0xb2, 0xc1, 0x20, 0x40, 0xa5, 0x80, 0x25, 0x5b, 0xff, - 0x0c, 0x12, 0xa0, 0x32, 0x93, 0x30, 0x30, 0x60, 0xc6, 0x3d, 0x00, 0x65, - 0x44, 0xff, 0x3d, 0x0a, 0xc6, 0x3b, 0x00, 0x00, 0xad, 0x04, 0x25, 0x9b, - 0xff, 0x46, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x71, 0xd3, 0xfd, 0xc1, 0x0e, - 0xff, 0x70, 0x74, 0x10, 0x50, 0xb5, 0x20, 0x70, 0xa7, 0x20, 0x65, 0x7e, - 0x00, 0x16, 0x4a, 0x00, 0x0c, 0x03, 0x46, 0x32, 0x00, 0xb1, 0x09, 0xff, - 0x60, 0xa6, 0x20, 0xb0, 0xb4, 0x10, 0x40, 0x60, 0xb4, 0xb0, 0xb5, 0x80, - 0x0c, 0x8c, 0x60, 0x65, 0x80, 0xe5, 0xaa, 0x00, 0x32, 0x06, 0x00, 0x0c, - 0x32, 0x30, 0x83, 0x04, 0x0c, 0x23, 0x80, 0x32, 0x83, 0xbd, 0x03, 0xad, - 0x04, 0x65, 0x74, 0xff, 0x56, 0xca, 0xfc, 0x81, 0xf1, 0xfe, 0x22, 0xc3, - 0xfe, 0x91, 0xb5, 0xfe, 0x4d, 0x02, 0x2d, 0x08, 0x40, 0x29, 0x93, 0x20, - 0x48, 0x74, 0x22, 0x46, 0x00, 0x42, 0x46, 0x01, 0x66, 0x33, 0x05, 0x20, - 0x20, 0x75, 0x22, 0x46, 0x02, 0xc1, 0xf4, 0xfe, 0xbd, 0x05, 0x70, 0xa7, - 0x20, 0xe5, 0x51, 0xff, 0x56, 0xca, 0xf9, 0x86, 0x16, 0x00, 0x21, 0xb4, - 0xfd, 0xc1, 0xef, 0xfe, 0x20, 0x24, 0x10, 0x50, 0xb5, 0x20, 0x20, 0xa2, - 0x20, 0xa5, 0x76, 0x00, 0x56, 0xea, 0xf1, 0x40, 0x30, 0x14, 0x3a, 0x66, - 0x32, 0x06, 0x00, 0x0c, 0x28, 0x30, 0x73, 0x04, 0x0c, 0x33, 0x70, 0x38, - 0x93, 0xbd, 0x03, 0xad, 0x04, 0x25, 0x6e, 0xff, 0x56, 0x2a, 0xf0, 0x72, - 0x06, 0x00, 0x40, 0x40, 0xb4, 0x4a, 0x45, 0x72, 0x44, 0x00, 0x72, 0x06, - 0x01, 0x72, 0x44, 0x01, 0x66, 0x33, 0x05, 0x32, 0x06, 0x02, 0x32, 0x44, - 0x02, 0xc1, 0xdd, 0xfe, 0x50, 0xb5, 0x20, 0xad, 0x02, 0x25, 0x4c, 0xff, - 0x3d, 0x0a, 0x56, 0x8a, 0xed, 0x81, 0xe0, 0xfe, 0xe0, 0x08, 0x00, 0x0c, + 0xa8, 0x02, 0xe2, 0xa1, 0x00, 0x81, 0xb0, 0xff, 0xe0, 0x08, 0x00, 0x25, + 0x94, 0xff, 0x8c, 0x2a, 0x86, 0x83, 0x00, 0x00, 0x7c, 0xe2, 0xb6, 0x86, + 0x02, 0x86, 0xcf, 0x00, 0x21, 0xa4, 0xff, 0x20, 0x66, 0xa0, 0x28, 0x06, + 0xa0, 0x02, 0x00, 0x65, 0xd9, 0xff, 0x2d, 0x0a, 0x4d, 0x0a, 0x16, 0x2a, + 0x08, 0x86, 0xc9, 0x00, 0x81, 0x9f, 0xff, 0x40, 0x65, 0xc0, 0x80, 0x76, + 0x63, 0x70, 0x90, 0x14, 0x16, 0x89, 0x00, 0x92, 0xaf, 0xfc, 0x90, 0x77, + 0x10, 0x16, 0x07, 0x07, 0x81, 0xa0, 0xff, 0xe0, 0x08, 0x00, 0x81, 0x9e, + 0xff, 0xe0, 0x08, 0x00, 0xa2, 0x61, 0x00, 0x7c, 0xf6, 0xbd, 0x01, 0xad, + 0x07, 0x69, 0x11, 0x25, 0x68, 0x00, 0x16, 0x8a, 0x1b, 0xa2, 0x61, 0x1b, + 0x81, 0x98, 0xff, 0xe0, 0x08, 0x00, 0x81, 0x96, 0xff, 0xe0, 0x08, 0x00, + 0x82, 0x21, 0x1b, 0xcd, 0x07, 0xbd, 0x08, 0x3a, 0xa4, 0x65, 0x9e, 0x00, + 0xa2, 0x61, 0x1a, 0x81, 0x91, 0xff, 0xe0, 0x08, 0x00, 0xb2, 0x21, 0x1a, + 0x82, 0x21, 0x1b, 0x8c, 0xbb, 0xad, 0x08, 0xa5, 0x97, 0x00, 0x2d, 0x06, + 0xc6, 0xae, 0x00, 0x00, 0x00, 0x00, 0x80, 0xa8, 0x20, 0x70, 0x44, 0x80, + 0x65, 0x96, 0x00, 0x56, 0x3a, 0x17, 0x25, 0x94, 0x00, 0x56, 0xda, 0x16, + 0x57, 0xb4, 0x02, 0x46, 0xde, 0xff, 0x46, 0xa7, 0x00, 0xb6, 0x46, 0x02, + 0x86, 0x57, 0x00, 0xc2, 0xa0, 0x04, 0xb2, 0xc1, 0x20, 0x30, 0xa4, 0x80, + 0xa5, 0x99, 0x00, 0x56, 0xfa, 0x14, 0x81, 0x7e, 0xff, 0xe0, 0x08, 0x00, + 0xa2, 0x61, 0x00, 0x7c, 0xf3, 0xbd, 0x01, 0xad, 0x06, 0x39, 0x11, 0x25, + 0x60, 0x00, 0x3d, 0x0a, 0x16, 0x6a, 0x13, 0xcd, 0x06, 0xb2, 0xc1, 0x20, + 0xe5, 0xc5, 0x00, 0xad, 0x03, 0xa5, 0x91, 0x00, 0x56, 0x6a, 0x12, 0x65, + 0x8f, 0x00, 0x16, 0x9a, 0x25, 0x46, 0x47, 0x00, 0x00, 0x00, 0xbd, 0x05, + 0xad, 0x03, 0x65, 0x8f, 0xff, 0x06, 0x55, 0x00, 0x00, 0x00, 0x00, 0xcd, + 0x04, 0xbd, 0x05, 0xad, 0x03, 0x25, 0xc1, 0xff, 0x46, 0x51, 0x00, 0xe5, + 0xc9, 0xff, 0xa0, 0x2a, 0x20, 0x56, 0x2a, 0x23, 0x61, 0x1b, 0xff, 0xa0, + 0x7a, 0x20, 0x42, 0x66, 0x04, 0x42, 0x21, 0x17, 0xc0, 0x20, 0x00, 0x49, + 0x66, 0xc0, 0x20, 0x00, 0x49, 0x56, 0xc0, 0x20, 0x00, 0xa9, 0x76, 0xc0, + 0x20, 0x00, 0xa9, 0x86, 0x4d, 0x0a, 0x86, 0x36, 0x00, 0x40, 0x85, 0xc0, + 0x70, 0x88, 0xc0, 0x89, 0x91, 0x81, 0x5d, 0xff, 0xe0, 0x08, 0x00, 0x81, + 0x5c, 0xff, 0xe0, 0x08, 0x00, 0xa9, 0x01, 0x7c, 0xf6, 0xbd, 0x01, 0xa2, + 0xc1, 0x24, 0x69, 0x11, 0x65, 0x68, 0x00, 0x6d, 0x0a, 0x16, 0xda, 0x0a, + 0x81, 0x56, 0xff, 0xe0, 0x08, 0x00, 0x9d, 0x06, 0xbc, 0x97, 0x0c, 0x4d, + 0x70, 0x9d, 0xc0, 0x82, 0xc1, 0x20, 0xcd, 0x09, 0x60, 0xb6, 0x20, 0x70, + 0xa8, 0x80, 0x92, 0x61, 0x1b, 0xd2, 0x61, 0x1a, 0xa5, 0xbb, 0x00, 0xd2, + 0x21, 0x1a, 0xb2, 0xc1, 0x20, 0xcd, 0x0d, 0x3a, 0xa4, 0x65, 0x66, 0xff, + 0x92, 0x21, 0x1b, 0x8c, 0x1a, 0x46, 0x17, 0x00, 0xa8, 0x91, 0x9a, 0x96, + 0xa2, 0xca, 0xfc, 0x7a, 0x7a, 0x79, 0x91, 0x4b, 0x44, 0xb2, 0x21, 0x09, + 0x72, 0xa0, 0x00, 0xb0, 0xa0, 0x14, 0x77, 0x1a, 0x1a, 0xa0, 0x70, 0x74, + 0xa2, 0xaf, 0xfc, 0xa0, 0xbb, 0x10, 0xb9, 0x91, 0xcd, 0x07, 0xba, 0xb9, + 0xa2, 0xc1, 0x20, 0x92, 0x61, 0x1b, 0x65, 0xb7, 0x00, 0x92, 0x21, 0x1b, + 0xa2, 0x21, 0x09, 0x16, 0x3a, 0x03, 0x92, 0x61, 0x1b, 0x81, 0x38, 0xff, + 0xe0, 0x08, 0x00, 0x92, 0x21, 0x1b, 0xc8, 0x91, 0xbd, 0x09, 0x3a, 0xa4, + 0xe5, 0x60, 0xff, 0xa2, 0x61, 0x1b, 0x81, 0x33, 0xff, 0xe0, 0x08, 0x00, + 0x92, 0x21, 0x1b, 0x16, 0x99, 0x00, 0x60, 0xa6, 0x20, 0x25, 0x82, 0x00, + 0x86, 0x03, 0x00, 0x00, 0x92, 0x21, 0x09, 0x90, 0x44, 0x80, 0x60, 0xa6, + 0x20, 0x25, 0x81, 0x00, 0x8c, 0x4a, 0x7c, 0xf2, 0xc6, 0x4c, 0x00, 0x00, + 0x57, 0xb4, 0x02, 0x86, 0xc7, 0xff, 0x16, 0x97, 0x12, 0x7c, 0xf2, 0x86, + 0x03, 0x00, 0x00, 0x00, 0x62, 0xc1, 0x20, 0x1b, 0x57, 0x7a, 0x76, 0x22, + 0x47, 0x00, 0x50, 0x70, 0x74, 0x70, 0x50, 0x14, 0x56, 0xc5, 0xfe, 0x0c, + 0x4c, 0xb2, 0xc1, 0x20, 0x3a, 0xa4, 0x22, 0xa0, 0x01, 0x25, 0x5b, 0xff, + 0xa0, 0x52, 0x93, 0x50, 0x20, 0x60, 0x46, 0x3e, 0x00, 0x00, 0x65, 0x44, + 0xff, 0x2d, 0x0a, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xad, 0x03, 0x25, + 0x9b, 0xff, 0xc6, 0xfb, 0xff, 0x61, 0xd3, 0xfd, 0xc1, 0x0f, 0xff, 0x60, + 0x63, 0x10, 0x40, 0xb4, 0x20, 0x60, 0xa6, 0x20, 0x25, 0x7e, 0x00, 0x16, + 0x6a, 0x00, 0x0c, 0x02, 0xc6, 0x32, 0x00, 0x00, 0x00, 0xb1, 0x09, 0xff, + 0x30, 0x70, 0xb4, 0xb0, 0xb3, 0x10, 0xb0, 0xb4, 0x80, 0x50, 0xa5, 0x20, + 0x0c, 0x8c, 0x70, 0x74, 0x80, 0xa5, 0xaa, 0x00, 0x22, 0x07, 0x00, 0x0c, + 0x2a, 0x20, 0x53, 0x04, 0x0c, 0x32, 0x50, 0x2a, 0x93, 0xbd, 0x02, 0xad, + 0x03, 0x65, 0x74, 0xff, 0x56, 0xaa, 0xfc, 0x81, 0xf1, 0xfe, 0x32, 0xc2, + 0xfe, 0x91, 0xb5, 0xfe, 0x5d, 0x03, 0x3d, 0x08, 0x50, 0x39, 0x93, 0x30, + 0x58, 0x74, 0x32, 0x47, 0x00, 0x52, 0x47, 0x01, 0x66, 0x32, 0x05, 0x30, + 0x30, 0x75, 0x32, 0x47, 0x02, 0xc1, 0xf4, 0xfe, 0xbd, 0x04, 0x60, 0xa6, + 0x20, 0xe5, 0x51, 0xff, 0x56, 0xaa, 0xf9, 0x86, 0x16, 0x00, 0x21, 0xb4, + 0xfd, 0xc1, 0xef, 0xfe, 0x20, 0x23, 0x10, 0x40, 0xb4, 0x20, 0x20, 0xa2, + 0x20, 0x65, 0x76, 0x00, 0x56, 0xaa, 0xf1, 0x30, 0x60, 0x14, 0x6a, 0x55, + 0x62, 0x05, 0x00, 0x0c, 0x28, 0x60, 0x73, 0x04, 0x0c, 0x36, 0x70, 0x68, + 0x93, 0xbd, 0x06, 0xad, 0x03, 0x25, 0x6e, 0xff, 0x56, 0xea, 0xef, 0x72, + 0x05, 0x00, 0x30, 0x30, 0xb4, 0x3a, 0x34, 0x72, 0x43, 0x00, 0x72, 0x05, + 0x01, 0x72, 0x43, 0x01, 0x66, 0x36, 0x05, 0x52, 0x05, 0x02, 0x52, 0x43, + 0x02, 0xc1, 0xdd, 0xfe, 0x20, 0xa2, 0x20, 0xbd, 0x04, 0x25, 0x4c, 0xff, + 0x2d, 0x0a, 0x56, 0x4a, 0xed, 0x81, 0xe0, 0xfe, 0xe0, 0x08, 0x00, 0x0c, 0x1a, 0x81, 0xde, 0xfe, 0xe0, 0x08, 0x00, 0xb8, 0x61, 0xa2, 0x21, 0x14, 0xe5, 0x3e, 0xff, 0x82, 0x21, 0x15, 0x8c, 0x68, 0xb8, 0x71, 0xa2, 0x21, - 0x16, 0x25, 0x3e, 0xff, 0x71, 0xc9, 0xfe, 0x21, 0xc6, 0xfe, 0x42, 0x21, - 0x18, 0xc0, 0x20, 0x00, 0x72, 0x62, 0x19, 0x10, 0x54, 0x01, 0xc0, 0x20, - 0x00, 0x42, 0x22, 0x12, 0x21, 0xc4, 0xfe, 0x0c, 0x06, 0x20, 0x44, 0x10, + 0x16, 0x25, 0x3e, 0xff, 0x71, 0xc9, 0xfe, 0x31, 0xc6, 0xfe, 0x42, 0x21, + 0x18, 0xc0, 0x20, 0x00, 0x72, 0x63, 0x19, 0x10, 0x54, 0x01, 0xc0, 0x20, + 0x00, 0x42, 0x23, 0x12, 0x31, 0xc4, 0xfe, 0x0c, 0x06, 0x30, 0x44, 0x10, 0x50, 0x44, 0x20, 0x51, 0xbe, 0xfe, 0xc0, 0x20, 0x00, 0x42, 0x65, 0x12, 0xc0, 0x20, 0x00, 0x62, 0x65, 0x19, 0x51, 0xbb, 0xfe, 0x82, 0x21, 0x19, 0xc0, 0x20, 0x00, 0x72, 0x65, 0x19, 0xc0, 0x20, 0x00, 0x72, 0x25, 0x12, - 0x10, 0x48, 0x01, 0x20, 0x27, 0x10, 0x40, 0x22, 0x20, 0xc0, 0x20, 0x00, - 0x22, 0x65, 0x12, 0xc0, 0x20, 0x00, 0x62, 0x65, 0x19, 0x2d, 0x03, 0x1d, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x4e, 0x0e, 0x36, 0x41, 0x00, 0x21, - 0xfe, 0xff, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x08, 0x36, 0x61, 0x00, 0x0c, - 0x18, 0x89, 0x01, 0x81, 0x7f, 0xfd, 0x82, 0x08, 0x01, 0x56, 0x18, 0x04, - 0xa1, 0xa9, 0xfc, 0xb1, 0xa9, 0xfc, 0xc1, 0xf9, 0xff, 0xd1, 0xa9, 0xfc, - 0x06, 0x08, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x82, 0x6a, 0x00, 0xc0, 0x20, - 0x00, 0xc2, 0x6b, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x0b, 0x56, 0x79, 0xff, - 0xc0, 0x20, 0x00, 0x98, 0x0a, 0xe8, 0x5d, 0x90, 0x9e, 0x10, 0x99, 0x01, - 0x98, 0x01, 0x07, 0xe9, 0xda, 0x86, 0x03, 0x00, 0x0c, 0x5b, 0xad, 0x01, - 0x81, 0x47, 0xfd, 0xe0, 0x08, 0x00, 0x88, 0x01, 0x07, 0xe8, 0xf0, 0x88, - 0x01, 0x89, 0x02, 0x0c, 0x02, 0x1d, 0xf0, 0x00, 0x83, 0xde, 0x1b, 0x43, - 0x36, 0x41, 0x00, 0xe5, 0xf8, 0xff, 0x82, 0x22, 0x01, 0xa0, 0x3a, 0x20, - 0x26, 0x08, 0x3c, 0x81, 0x9e, 0xfe, 0xe0, 0x08, 0x00, 0xb2, 0x22, 0x00, - 0x81, 0xf9, 0xff, 0x30, 0xcf, 0x31, 0xb7, 0x3a, 0x0b, 0x80, 0x93, 0xb2, - 0xb0, 0xaa, 0xc0, 0x90, 0x92, 0x31, 0x06, 0x03, 0x00, 0x7c, 0xf9, 0x80, - 0x83, 0xb2, 0xb0, 0xb9, 0x30, 0xaa, 0xab, 0x80, 0x92, 0x31, 0xc0, 0x89, - 0xc0, 0x80, 0x8a, 0xc2, 0x89, 0x22, 0x88, 0x22, 0x38, 0x12, 0x22, 0xa1, - 0x07, 0x37, 0xb8, 0x01, 0x0c, 0x02, 0x1d, 0xf0, 0x14, 0x10, 0x09, 0x40, - 0x36, 0x61, 0x00, 0x71, 0x3e, 0xfe, 0xc6, 0x01, 0x00, 0xad, 0x02, 0x25, - 0xfa, 0xff, 0x56, 0xca, 0x1e, 0xc0, 0x20, 0x00, 0x58, 0x97, 0x0c, 0x14, - 0x50, 0x50, 0x04, 0x40, 0x45, 0x30, 0x61, 0x40, 0xfe, 0x31, 0xf6, 0xff, - 0x30, 0x76, 0x40, 0x91, 0x3d, 0xfe, 0x90, 0x69, 0x40, 0x81, 0x4d, 0xfd, - 0x3d, 0x07, 0x80, 0x89, 0x10, 0x9c, 0x88, 0x90, 0x60, 0xe4, 0xa2, 0xa1, - 0x01, 0x56, 0xf6, 0x1a, 0xc0, 0x20, 0x00, 0x68, 0x97, 0x90, 0xbf, 0x64, - 0x60, 0x60, 0x64, 0x67, 0x1b, 0x02, 0x86, 0x67, 0x00, 0x8b, 0xa4, 0x30, - 0xaa, 0xa0, 0x0c, 0x06, 0xc0, 0x20, 0x00, 0x69, 0x2a, 0xc0, 0x20, 0x00, - 0xa8, 0x97, 0x0c, 0x2b, 0x1b, 0xaa, 0xc0, 0x20, 0x00, 0xa9, 0x97, 0x0c, - 0x1a, 0x50, 0xab, 0x93, 0xb1, 0x29, 0xfe, 0xc0, 0x20, 0x00, 0xa9, 0x0b, - 0x67, 0xf9, 0x02, 0xc6, 0x52, 0x00, 0x4b, 0x44, 0x30, 0x44, 0xb0, 0x98, - 0x44, 0xd2, 0x19, 0x00, 0x67, 0x9d, 0x02, 0xc6, 0x4e, 0x00, 0xed, 0x06, - 0xc0, 0x20, 0x00, 0x48, 0x73, 0xc0, 0x20, 0x00, 0xa8, 0x83, 0x47, 0x3a, - 0x22, 0xc0, 0x20, 0x00, 0x48, 0x53, 0xc0, 0x20, 0x00, 0xa8, 0x83, 0xa0, - 0x44, 0xc0, 0xcc, 0x64, 0x0c, 0x04, 0x42, 0x59, 0x00, 0x46, 0x45, 0x00, - 0xc0, 0x20, 0x00, 0xa8, 0x73, 0xdc, 0x7a, 0x0b, 0x44, 0x06, 0x04, 0x00, - 0xc0, 0x20, 0x00, 0x48, 0x73, 0xc0, 0x20, 0x00, 0xa2, 0x23, 0x08, 0x42, - 0xc4, 0xff, 0xa0, 0x44, 0xc0, 0x16, 0x74, 0xfd, 0x60, 0xad, 0xc0, 0xc0, - 0x20, 0x00, 0xb8, 0x83, 0x40, 0x4a, 0x63, 0xc0, 0x20, 0x00, 0xc8, 0x73, - 0xa8, 0x43, 0xc0, 0x20, 0x00, 0xf8, 0x83, 0xba, 0xba, 0xc7, 0xbf, 0x02, - 0x06, 0x21, 0x00, 0xc0, 0x20, 0x00, 0xc8, 0x83, 0xc0, 0x20, 0x00, 0xf8, - 0x53, 0x4a, 0xcc, 0xf7, 0xbc, 0x02, 0x86, 0x21, 0x00, 0xc0, 0x20, 0x00, - 0xc8, 0x73, 0x16, 0xec, 0x08, 0xc0, 0x20, 0x00, 0xc8, 0x83, 0xc0, 0x20, - 0x00, 0xf8, 0x53, 0x4a, 0xcc, 0xf7, 0x9c, 0x07, 0xc0, 0x20, 0x00, 0xe9, - 0x83, 0xc6, 0x1c, 0x00, 0xc0, 0x20, 0x00, 0xb8, 0x73, 0x0b, 0xbb, 0x47, - 0x3b, 0x6d, 0xc0, 0x20, 0x00, 0xb8, 0x83, 0xc0, 0x20, 0x00, 0xb9, 0x63, - 0xc0, 0x20, 0x00, 0xe9, 0x83, 0xc0, 0x20, 0x00, 0xc8, 0x73, 0xc0, 0x20, - 0x00, 0xb8, 0x63, 0xb7, 0x9c, 0x1d, 0xc0, 0x20, 0x00, 0xe9, 0x73, 0xc0, - 0x20, 0x00, 0xc8, 0x63, 0xc0, 0x20, 0x00, 0xb8, 0x53, 0xb7, 0xbc, 0x0b, - 0xc0, 0x20, 0x00, 0xb2, 0x23, 0x05, 0xc0, 0x20, 0x00, 0xb2, 0x63, 0x06, - 0xc0, 0x20, 0x00, 0xb8, 0x83, 0x4a, 0xbb, 0xc0, 0x20, 0x00, 0xb9, 0x83, - 0x86, 0x08, 0x00, 0x00, 0xc0, 0x20, 0x00, 0xa8, 0x73, 0xc0, 0x20, 0x00, - 0xc2, 0x23, 0x08, 0xa2, 0xca, 0xff, 0xc0, 0xaa, 0xc0, 0x47, 0x3a, 0x0f, - 0xc0, 0x20, 0x00, 0xa8, 0x83, 0x4a, 0xaa, 0xc0, 0x20, 0x00, 0xa9, 0x83, - 0xad, 0x0b, 0xcc, 0x2a, 0x06, 0xff, 0xff, 0x00, 0xb2, 0xc6, 0x02, 0xb0, - 0xb9, 0x80, 0x40, 0xc4, 0x20, 0x89, 0x01, 0x99, 0x11, 0xd9, 0x21, 0xe9, - 0x31, 0xa5, 0x70, 0x00, 0xd8, 0x21, 0x4a, 0x66, 0x88, 0x01, 0x98, 0x11, - 0xe8, 0x31, 0xd7, 0xb6, 0x02, 0xc6, 0xb2, 0xff, 0x06, 0xb9, 0xff, 0x00, - 0x00, 0x00, 0x8b, 0x55, 0xc0, 0x20, 0x00, 0x48, 0x97, 0x30, 0x35, 0xa0, - 0xc0, 0x20, 0x00, 0x38, 0x23, 0x40, 0x40, 0x64, 0x10, 0x44, 0x11, 0x30, - 0x30, 0xe4, 0x30, 0x34, 0x20, 0x80, 0x83, 0x20, 0x31, 0xcd, 0xfd, 0x80, - 0x73, 0x40, 0x0c, 0x0a, 0x41, 0xcc, 0xfd, 0x0c, 0x03, 0x30, 0x74, 0x40, - 0x37, 0x1a, 0x02, 0x86, 0x82, 0xff, 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x00, - 0x36, 0x41, 0x00, 0x91, 0xbd, 0xfd, 0xc0, 0x20, 0x00, 0x88, 0x99, 0x4d, - 0x09, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x90, 0x88, 0xa0, 0xc0, 0x20, 0x00, - 0x88, 0x28, 0x27, 0xb8, 0x0b, 0x0c, 0x02, 0x1d, 0xf0, 0x00, 0xad, 0x03, - 0x65, 0xdd, 0xff, 0xdc, 0x9a, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x80, 0x80, - 0x04, 0x8b, 0x88, 0x40, 0x88, 0xa0, 0xc0, 0x20, 0x00, 0x28, 0x28, 0x56, - 0x32, 0xfe, 0xc6, 0xf6, 0xff, 0x00, 0x00, 0x00, 0x2d, 0x0a, 0x1d, 0xf0, - 0xfc, 0x3f, 0x00, 0x00, 0x36, 0x41, 0x00, 0x30, 0xa3, 0x20, 0x31, 0xfd, - 0xff, 0x27, 0xb3, 0x03, 0x0c, 0x02, 0x1d, 0xf0, 0x41, 0xa7, 0xfd, 0xc0, + 0x10, 0x48, 0x01, 0x30, 0x37, 0x10, 0x40, 0x33, 0x20, 0xc0, 0x20, 0x00, + 0x32, 0x65, 0x12, 0xc0, 0x20, 0x00, 0x62, 0x65, 0x19, 0x1d, 0xf0, 0x00, + 0x00, 0x1c, 0x4e, 0x0e, 0x36, 0x41, 0x00, 0x21, 0xfe, 0xff, 0x1d, 0xf0, + 0x00, 0x00, 0x00, 0x08, 0x36, 0x61, 0x00, 0x0c, 0x18, 0x89, 0x01, 0x81, + 0x80, 0xfd, 0x82, 0x08, 0x01, 0x56, 0x18, 0x04, 0xa1, 0xaa, 0xfc, 0xb1, + 0xaa, 0xfc, 0xc1, 0xf9, 0xff, 0xd1, 0xaa, 0xfc, 0x06, 0x08, 0x00, 0x00, + 0xc0, 0x20, 0x00, 0x82, 0x6a, 0x00, 0xc0, 0x20, 0x00, 0xc2, 0x6b, 0x00, + 0xc0, 0x20, 0x00, 0x98, 0x0b, 0x56, 0x79, 0xff, 0xc0, 0x20, 0x00, 0x98, + 0x0a, 0xe8, 0x5d, 0x90, 0x9e, 0x10, 0x99, 0x01, 0x98, 0x01, 0x07, 0xe9, + 0xda, 0x86, 0x03, 0x00, 0x0c, 0x5b, 0xad, 0x01, 0x81, 0x48, 0xfd, 0xe0, + 0x08, 0x00, 0x88, 0x01, 0x07, 0xe8, 0xf0, 0x88, 0x01, 0x89, 0x02, 0x0c, + 0x02, 0x1d, 0xf0, 0x00, 0x83, 0xde, 0x1b, 0x43, 0x36, 0x41, 0x00, 0xe5, + 0xf8, 0xff, 0x82, 0x22, 0x01, 0xa0, 0x3a, 0x20, 0x26, 0x08, 0x3c, 0x81, + 0x9f, 0xfe, 0xe0, 0x08, 0x00, 0xb2, 0x22, 0x00, 0x81, 0xf9, 0xff, 0x30, + 0xcf, 0x31, 0xb7, 0x3a, 0x0b, 0x80, 0x93, 0xb2, 0xb0, 0xaa, 0xc0, 0x90, + 0x92, 0x31, 0x06, 0x03, 0x00, 0x7c, 0xf9, 0x80, 0x83, 0xb2, 0xb0, 0xb9, + 0x30, 0xaa, 0xab, 0x80, 0x92, 0x31, 0xc0, 0x89, 0xc0, 0x80, 0x8a, 0xc2, + 0x89, 0x22, 0x88, 0x22, 0x38, 0x12, 0x22, 0xa1, 0x07, 0x37, 0xb8, 0x01, + 0x0c, 0x02, 0x1d, 0xf0, 0x10, 0x10, 0x09, 0x40, 0x36, 0x61, 0x00, 0x71, + 0x3f, 0xfe, 0xc6, 0x01, 0x00, 0xad, 0x02, 0x25, 0xfa, 0xff, 0x56, 0xca, + 0x1e, 0xc0, 0x20, 0x00, 0x58, 0x97, 0x0c, 0x14, 0x50, 0x50, 0x04, 0x40, + 0x45, 0x30, 0x61, 0x41, 0xfe, 0x31, 0xf6, 0xff, 0x30, 0x76, 0x40, 0x91, + 0x3e, 0xfe, 0x90, 0x69, 0x40, 0x81, 0x4e, 0xfd, 0x3d, 0x07, 0x80, 0x89, + 0x10, 0x9c, 0x88, 0x90, 0x60, 0xe4, 0xa2, 0xa1, 0x01, 0x56, 0xf6, 0x1a, + 0xc0, 0x20, 0x00, 0x68, 0x97, 0x90, 0xbf, 0x64, 0x60, 0x60, 0x64, 0x67, + 0x1b, 0x02, 0x86, 0x67, 0x00, 0x8b, 0xa4, 0x30, 0xaa, 0xa0, 0x0c, 0x06, + 0xc0, 0x20, 0x00, 0x69, 0x2a, 0xc0, 0x20, 0x00, 0xa8, 0x97, 0x0c, 0x2b, + 0x1b, 0xaa, 0xc0, 0x20, 0x00, 0xa9, 0x97, 0x0c, 0x1a, 0x50, 0xab, 0x93, + 0xb1, 0x2a, 0xfe, 0xc0, 0x20, 0x00, 0xa9, 0x0b, 0x67, 0xf9, 0x02, 0xc6, + 0x52, 0x00, 0x4b, 0x44, 0x30, 0x44, 0xb0, 0x98, 0x44, 0xd2, 0x19, 0x00, + 0x67, 0x9d, 0x02, 0xc6, 0x4e, 0x00, 0xed, 0x06, 0xc0, 0x20, 0x00, 0x48, + 0x73, 0xc0, 0x20, 0x00, 0xa8, 0x83, 0x47, 0x3a, 0x22, 0xc0, 0x20, 0x00, + 0x48, 0x53, 0xc0, 0x20, 0x00, 0xa8, 0x83, 0xa0, 0x44, 0xc0, 0xcc, 0x64, + 0x0c, 0x04, 0x42, 0x59, 0x00, 0x46, 0x45, 0x00, 0xc0, 0x20, 0x00, 0xa8, + 0x73, 0xdc, 0x7a, 0x0b, 0x44, 0x06, 0x04, 0x00, 0xc0, 0x20, 0x00, 0x48, + 0x73, 0xc0, 0x20, 0x00, 0xa2, 0x23, 0x08, 0x42, 0xc4, 0xff, 0xa0, 0x44, + 0xc0, 0x16, 0x74, 0xfd, 0x60, 0xad, 0xc0, 0xc0, 0x20, 0x00, 0xb8, 0x83, + 0x40, 0x4a, 0x63, 0xc0, 0x20, 0x00, 0xc8, 0x73, 0xa8, 0x43, 0xc0, 0x20, + 0x00, 0xf8, 0x83, 0xba, 0xba, 0xc7, 0xbf, 0x02, 0x06, 0x21, 0x00, 0xc0, + 0x20, 0x00, 0xc8, 0x83, 0xc0, 0x20, 0x00, 0xf8, 0x53, 0x4a, 0xcc, 0xf7, + 0xbc, 0x02, 0x86, 0x21, 0x00, 0xc0, 0x20, 0x00, 0xc8, 0x73, 0x16, 0xec, + 0x08, 0xc0, 0x20, 0x00, 0xc8, 0x83, 0xc0, 0x20, 0x00, 0xf8, 0x53, 0x4a, + 0xcc, 0xf7, 0x9c, 0x07, 0xc0, 0x20, 0x00, 0xe9, 0x83, 0xc6, 0x1c, 0x00, + 0xc0, 0x20, 0x00, 0xb8, 0x73, 0x0b, 0xbb, 0x47, 0x3b, 0x6d, 0xc0, 0x20, + 0x00, 0xb8, 0x83, 0xc0, 0x20, 0x00, 0xb9, 0x63, 0xc0, 0x20, 0x00, 0xe9, + 0x83, 0xc0, 0x20, 0x00, 0xc8, 0x73, 0xc0, 0x20, 0x00, 0xb8, 0x63, 0xb7, + 0x9c, 0x1d, 0xc0, 0x20, 0x00, 0xe9, 0x73, 0xc0, 0x20, 0x00, 0xc8, 0x63, + 0xc0, 0x20, 0x00, 0xb8, 0x53, 0xb7, 0xbc, 0x0b, 0xc0, 0x20, 0x00, 0xb2, + 0x23, 0x05, 0xc0, 0x20, 0x00, 0xb2, 0x63, 0x06, 0xc0, 0x20, 0x00, 0xb8, + 0x83, 0x4a, 0xbb, 0xc0, 0x20, 0x00, 0xb9, 0x83, 0x86, 0x08, 0x00, 0x00, + 0xc0, 0x20, 0x00, 0xa8, 0x73, 0xc0, 0x20, 0x00, 0xc2, 0x23, 0x08, 0xa2, + 0xca, 0xff, 0xc0, 0xaa, 0xc0, 0x47, 0x3a, 0x0f, 0xc0, 0x20, 0x00, 0xa8, + 0x83, 0x4a, 0xaa, 0xc0, 0x20, 0x00, 0xa9, 0x83, 0xad, 0x0b, 0xcc, 0x2a, + 0x06, 0xff, 0xff, 0x00, 0xb2, 0xc6, 0x02, 0xb0, 0xb9, 0x80, 0x40, 0xc4, + 0x20, 0x89, 0x01, 0x99, 0x11, 0xd9, 0x21, 0xe9, 0x31, 0xa5, 0x70, 0x00, + 0xd8, 0x21, 0x4a, 0x66, 0x88, 0x01, 0x98, 0x11, 0xe8, 0x31, 0xd7, 0xb6, + 0x02, 0xc6, 0xb2, 0xff, 0x06, 0xb9, 0xff, 0x00, 0x00, 0x00, 0x8b, 0x55, + 0xc0, 0x20, 0x00, 0x48, 0x97, 0x30, 0x35, 0xa0, 0xc0, 0x20, 0x00, 0x38, + 0x23, 0x40, 0x40, 0x64, 0x10, 0x44, 0x11, 0x30, 0x30, 0xe4, 0x30, 0x34, + 0x20, 0x80, 0x83, 0x20, 0x31, 0xce, 0xfd, 0x80, 0x73, 0x40, 0x0c, 0x0a, + 0x41, 0xcd, 0xfd, 0x0c, 0x03, 0x30, 0x74, 0x40, 0x37, 0x1a, 0x02, 0x86, + 0x82, 0xff, 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x41, 0x00, 0x91, + 0xbe, 0xfd, 0xc0, 0x20, 0x00, 0x88, 0x99, 0x4d, 0x09, 0x80, 0x80, 0x04, + 0x8b, 0x88, 0x90, 0x88, 0xa0, 0xc0, 0x20, 0x00, 0x88, 0x28, 0x27, 0xb8, + 0x0b, 0x0c, 0x02, 0x1d, 0xf0, 0x00, 0xad, 0x03, 0x65, 0xdd, 0xff, 0xdc, + 0x9a, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x40, + 0x88, 0xa0, 0xc0, 0x20, 0x00, 0x28, 0x28, 0x56, 0x32, 0xfe, 0xc6, 0xf6, + 0xff, 0x00, 0x00, 0x00, 0x2d, 0x0a, 0x1d, 0xf0, 0xfc, 0x3f, 0x00, 0x00, + 0x36, 0x41, 0x00, 0x30, 0xa3, 0x20, 0x31, 0xfd, 0xff, 0x27, 0xb3, 0x03, + 0x0c, 0x02, 0x1d, 0xf0, 0x41, 0xa8, 0xfd, 0xc0, 0x20, 0x00, 0x88, 0x94, + 0x80, 0x80, 0x04, 0x8b, 0x88, 0x40, 0x88, 0xa0, 0xc0, 0x20, 0x00, 0x98, + 0x28, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x4b, 0x99, 0x80, 0x80, 0x04, 0x4b, + 0x88, 0x40, 0x88, 0xb0, 0x32, 0x18, 0x0a, 0x2a, 0x99, 0x97, 0xb3, 0x77, + 0x4b, 0x92, 0x90, 0x30, 0xf4, 0xe5, 0xd6, 0xff, 0x56, 0x4a, 0xfc, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x40, 0x88, 0xa0, - 0xc0, 0x20, 0x00, 0x98, 0x28, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x4b, 0x99, - 0x80, 0x80, 0x04, 0x4b, 0x88, 0x40, 0x88, 0xb0, 0x32, 0x18, 0x0a, 0x2a, - 0x99, 0x97, 0xb3, 0x77, 0x4b, 0x92, 0x90, 0x30, 0xf4, 0xe5, 0xd6, 0xff, - 0x56, 0x4a, 0xfc, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x80, 0x80, 0x04, 0x8b, - 0x88, 0x40, 0x88, 0xa0, 0xc0, 0x20, 0x00, 0x98, 0x28, 0xc0, 0x20, 0x00, - 0x88, 0x94, 0x9a, 0x93, 0x80, 0x80, 0x04, 0x4b, 0x88, 0x40, 0x88, 0xb0, - 0x32, 0x18, 0x0a, 0x97, 0x33, 0x9d, 0xc0, 0x20, 0x00, 0x98, 0x94, 0xc0, - 0x20, 0x00, 0x88, 0x94, 0x90, 0x90, 0x04, 0x80, 0x80, 0x04, 0x8b, 0x88, - 0x4b, 0x99, 0x40, 0x88, 0xa0, 0x40, 0x99, 0xb0, 0xc0, 0x20, 0x00, 0x38, - 0x28, 0x88, 0x49, 0x3a, 0x88, 0x16, 0x78, 0xf7, 0xc0, 0x20, 0x00, 0x98, - 0x94, 0x90, 0x90, 0x04, 0x8b, 0x99, 0x40, 0x49, 0xa0, 0xc0, 0x20, 0x00, - 0x98, 0x24, 0x4b, 0x99, 0x2a, 0x99, 0xc0, 0x20, 0x00, 0x99, 0x24, 0x86, - 0x10, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x94, 0xc0, 0x20, 0x00, - 0x88, 0x94, 0x90, 0x90, 0x04, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x4b, 0x99, - 0x40, 0x88, 0xa0, 0x40, 0x99, 0xb0, 0xc0, 0x20, 0x00, 0x38, 0x28, 0x88, - 0x49, 0xc0, 0x20, 0x00, 0x98, 0x94, 0x3a, 0x88, 0x90, 0x90, 0x04, 0x8b, - 0x99, 0x40, 0x49, 0xa0, 0xc0, 0x20, 0x00, 0x98, 0x24, 0x4b, 0x99, 0x2a, - 0x99, 0xc0, 0x20, 0x00, 0x99, 0x24, 0x16, 0x68, 0xf1, 0x40, 0xeb, 0x03, - 0x40, 0x4d, 0x04, 0x10, 0x44, 0x11, 0x20, 0x24, 0x20, 0x22, 0x58, 0x00, - 0x0c, 0x02, 0x22, 0x58, 0x01, 0x4b, 0x28, 0x1d, 0xf0, 0x00, 0x00, 0x00, - 0x36, 0x41, 0x00, 0x51, 0x66, 0xfd, 0xc0, 0x20, 0x00, 0x48, 0x75, 0xc0, - 0x20, 0x00, 0x88, 0x85, 0x9d, 0x05, 0x47, 0x38, 0x07, 0xc0, 0x20, 0x00, - 0x48, 0x85, 0x06, 0x01, 0x00, 0xc0, 0x20, 0x00, 0x48, 0x65, 0xc0, 0x20, - 0x00, 0x88, 0x75, 0x80, 0x44, 0xc0, 0x16, 0x24, 0x08, 0x88, 0x02, 0x80, - 0x84, 0x63, 0x89, 0x02, 0xc0, 0x20, 0x00, 0x28, 0x79, 0x48, 0x49, 0x2a, - 0x44, 0xc0, 0x20, 0x00, 0x28, 0x79, 0xc0, 0x20, 0x00, 0x38, 0x89, 0x27, - 0x33, 0x11, 0xc0, 0x20, 0x00, 0x28, 0x79, 0xc0, 0x20, 0x00, 0x38, 0x89, - 0x2a, 0x28, 0x27, 0x33, 0x52, 0xc6, 0x0f, 0x00, 0xc0, 0x20, 0x00, 0x28, - 0x79, 0xc0, 0x20, 0x00, 0x38, 0x69, 0x2a, 0x28, 0x27, 0x33, 0x40, 0xc0, - 0x20, 0x00, 0x28, 0x79, 0xc0, 0x20, 0x00, 0x38, 0x69, 0x2a, 0x28, 0x37, - 0x92, 0x21, 0xc0, 0x20, 0x00, 0x38, 0x69, 0xc0, 0x20, 0x00, 0x28, 0x59, - 0x27, 0xb3, 0x09, 0xc0, 0x20, 0x00, 0x28, 0x59, 0xc0, 0x20, 0x00, 0x29, - 0x69, 0x0c, 0x02, 0xc0, 0x20, 0x00, 0x29, 0x79, 0x06, 0x03, 0x00, 0x00, - 0xc0, 0x20, 0x00, 0x28, 0x79, 0x2a, 0x88, 0xc0, 0x20, 0x00, 0x89, 0x79, - 0x2d, 0x04, 0xdc, 0xb4, 0x06, 0xff, 0xff, 0x00, 0x81, 0x43, 0xfd, 0x80, - 0x68, 0x40, 0xad, 0x03, 0x67, 0x78, 0x05, 0x65, 0xbe, 0xff, 0x06, 0xd1, - 0xff, 0xa5, 0xb8, 0xff, 0x16, 0xea, 0xf3, 0x2d, 0x04, 0x1d, 0xf0, 0x00, - 0x36, 0x61, 0x00, 0x81, 0x41, 0xfc, 0xc0, 0x20, 0x00, 0x22, 0x28, 0x00, - 0x20, 0x20, 0x24, 0x56, 0x32, 0xff, 0x81, 0x3e, 0xfc, 0xc0, 0x20, 0x00, - 0x22, 0x28, 0x00, 0x20, 0x20, 0x24, 0x56, 0x32, 0xff, 0x10, 0xa1, 0x20, - 0x65, 0xaf, 0xff, 0x82, 0xa0, 0x01, 0xa0, 0x28, 0x93, 0x1d, 0xf0, 0x00, - 0x36, 0x61, 0x00, 0x22, 0xa0, 0x00, 0x22, 0x61, 0x00, 0x65, 0xfc, 0xff, - 0x81, 0x66, 0xfb, 0x21, 0x0d, 0xfc, 0xc0, 0x20, 0x00, 0x22, 0x68, 0x00, - 0xc0, 0x20, 0x00, 0x28, 0x08, 0x56, 0x72, 0xff, 0x0c, 0x22, 0x46, 0x01, - 0x00, 0x10, 0xa1, 0x20, 0x25, 0xac, 0xff, 0x82, 0x21, 0x00, 0x87, 0x02, - 0xf3, 0x22, 0xa0, 0x00, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x36, 0x41, 0x00, 0x40, 0x50, 0x14, 0x8c, 0x35, 0x0c, 0x12, 0x1d, 0xf0, - 0x00, 0x51, 0x58, 0xfb, 0x82, 0x25, 0x04, 0x80, 0x52, 0xe2, 0x40, 0x55, - 0x80, 0x57, 0x38, 0xeb, 0x65, 0xf7, 0xff, 0x52, 0xa0, 0x1f, 0x86, 0x24, - 0x00, 0xe5, 0xf9, 0xff, 0x56, 0xca, 0xfd, 0x81, 0xd3, 0xfb, 0xa1, 0xd3, - 0xfb, 0x80, 0x82, 0x10, 0x47, 0xa5, 0x2c, 0x91, 0x20, 0xfc, 0x90, 0x88, - 0x20, 0x91, 0x48, 0xfb, 0xc0, 0x20, 0x00, 0x89, 0x0a, 0xad, 0x03, 0x0c, - 0x88, 0x76, 0x88, 0x0a, 0xb8, 0x0a, 0x4b, 0xaa, 0xc0, 0x20, 0x00, 0xb9, - 0x09, 0x4b, 0x99, 0x32, 0xc3, 0x20, 0x42, 0xc4, 0xe0, 0x22, 0xc2, 0x20, - 0x86, 0x0f, 0x00, 0x00, 0x80, 0x94, 0x01, 0x90, 0x88, 0x20, 0xc0, 0x20, - 0x00, 0x89, 0x0a, 0x40, 0xa0, 0x14, 0x40, 0x42, 0x21, 0x1b, 0x84, 0x80, - 0x90, 0x74, 0x40, 0x40, 0x74, 0x8d, 0x09, 0x9d, 0x04, 0xa0, 0x98, 0x93, - 0x81, 0x37, 0xfb, 0x4d, 0x03, 0x40, 0x88, 0xc0, 0x30, 0x39, 0xa0, 0x86, - 0x02, 0x00, 0xa8, 0x04, 0x4a, 0x98, 0xc0, 0x20, 0x00, 0xa9, 0x09, 0x4b, - 0x44, 0x47, 0x93, 0xf1, 0x0c, 0x04, 0x81, 0x31, 0xfb, 0x91, 0xd5, 0xff, - 0xc0, 0x20, 0x00, 0x99, 0x08, 0xc0, 0x20, 0x00, 0x98, 0x08, 0x56, 0x79, - 0xff, 0xe5, 0xed, 0xff, 0xa6, 0x14, 0x02, 0x86, 0xd9, 0xff, 0x0c, 0x02, - 0x1d, 0xf0, 0x00, 0x00, 0x36, 0x61, 0x00, 0x81, 0x35, 0xfd, 0xe0, 0x08, - 0x00, 0x81, 0x33, 0xfd, 0xe0, 0x08, 0x00, 0xa9, 0x01, 0x7c, 0xf8, 0xbd, - 0x01, 0x0c, 0x0a, 0x89, 0x11, 0xe5, 0xc8, 0xff, 0x2d, 0x0a, 0x1d, 0xf0, - 0x36, 0x61, 0x00, 0x81, 0x2d, 0xfd, 0xe0, 0x08, 0x00, 0xa2, 0x61, 0x00, - 0x82, 0xaf, 0xff, 0x10, 0xb1, 0x20, 0xad, 0x02, 0x89, 0x11, 0x65, 0x34, - 0x00, 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x61, 0x00, 0x81, - 0x25, 0xfd, 0xe0, 0x08, 0x00, 0xbd, 0x01, 0xad, 0x02, 0xe5, 0x33, 0x00, - 0x2d, 0x0a, 0x1d, 0xf0, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x70, - 0x00, 0x00, 0x00, 0x7c, 0xeb, 0x00, 0x00, 0x70, 0xbb, 0x00, 0x00, 0x70, - 0x6b, 0x00, 0x00, 0x70, 0x3b, 0x00, 0x00, 0x70, 0x0b, 0x00, 0x00, 0x70, - 0x03, 0x00, 0x00, 0x70, 0x36, 0x41, 0x00, 0x51, 0xb3, 0xfb, 0x91, 0xf5, - 0xff, 0xc0, 0x20, 0x00, 0x88, 0x05, 0x61, 0xd9, 0xfb, 0x90, 0xa8, 0x10, - 0x51, 0xff, 0xfa, 0x71, 0xd8, 0xfb, 0x97, 0x9a, 0x56, 0xc0, 0x20, 0x00, - 0x88, 0x05, 0x60, 0x68, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0xc0, 0x20, - 0x00, 0x88, 0x05, 0x61, 0xec, 0xff, 0x60, 0x68, 0x20, 0x81, 0x56, 0xfb, - 0xc0, 0x20, 0x00, 0x69, 0x05, 0xc0, 0x20, 0x00, 0x68, 0x08, 0x51, 0x54, - 0xfb, 0x50, 0x66, 0x10, 0x51, 0xe7, 0xff, 0x50, 0x56, 0x20, 0xc0, 0x20, - 0x00, 0x59, 0x08, 0x72, 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x08, 0x62, - 0xaf, 0x00, 0x3b, 0x77, 0x60, 0x55, 0x10, 0x70, 0x70, 0x74, 0x50, 0x57, - 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0x61, 0xde, 0xff, 0x06, 0x68, 0x00, - 0xd7, 0xe8, 0x02, 0x86, 0x45, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x05, 0x60, - 0x69, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0xc0, 0x20, 0x00, 0x98, 0x05, - 0x61, 0xbe, 0xfb, 0x60, 0x69, 0x20, 0xc0, 0x20, 0x00, 0x69, 0x05, 0x77, - 0xf8, 0x02, 0x86, 0x24, 0x00, 0x82, 0x07, 0x01, 0x61, 0x3c, 0xfb, 0xec, - 0xa8, 0xc0, 0x20, 0x00, 0x88, 0x05, 0x71, 0x38, 0xfb, 0x70, 0x78, 0x10, - 0xc0, 0x20, 0x00, 0x79, 0x05, 0xc0, 0x20, 0x00, 0x78, 0x06, 0x51, 0x36, - 0xfb, 0x50, 0x77, 0x10, 0x51, 0xc9, 0xff, 0x50, 0x57, 0x20, 0xc0, 0x20, - 0x00, 0x59, 0x06, 0x61, 0xc8, 0xff, 0xc6, 0x50, 0x00, 0xc0, 0x20, 0x00, - 0x98, 0x05, 0x81, 0xa9, 0xfb, 0x80, 0x89, 0x20, 0xc0, 0x20, 0x00, 0x89, - 0x05, 0xc0, 0x20, 0x00, 0x88, 0x06, 0x51, 0x2b, 0xfb, 0x50, 0x88, 0x10, - 0x51, 0xbe, 0xff, 0x50, 0x58, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x06, 0x82, - 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x06, 0x72, 0xaf, 0x00, 0x0b, 0x88, - 0x70, 0x55, 0x10, 0x80, 0x80, 0x74, 0x50, 0x58, 0x20, 0x71, 0xc1, 0xfa, - 0xc0, 0x20, 0x00, 0x59, 0x06, 0xc0, 0x20, 0x00, 0x68, 0x07, 0x51, 0x9c, - 0xfb, 0x50, 0x66, 0x10, 0x52, 0xa0, 0xbb, 0x50, 0x56, 0x20, 0xc0, 0x20, - 0x00, 0x59, 0x07, 0x86, 0x3b, 0x00, 0x00, 0x00, 0x51, 0xb9, 0xfa, 0x61, - 0xaf, 0xff, 0x47, 0xf8, 0x08, 0x61, 0xae, 0xff, 0xe7, 0xe8, 0x02, 0x61, - 0xae, 0xff, 0xc0, 0x20, 0x00, 0x69, 0x05, 0x61, 0xb2, 0xfa, 0x51, 0x8c, - 0xfb, 0xc0, 0x20, 0x00, 0x88, 0x06, 0x50, 0x58, 0x20, 0x81, 0x0e, 0xfb, - 0xc0, 0x20, 0x00, 0x59, 0x06, 0xc0, 0x20, 0x00, 0x68, 0x08, 0x51, 0x0c, - 0xfb, 0x50, 0x66, 0x10, 0x51, 0x0c, 0xfb, 0x50, 0x56, 0x20, 0xc0, 0x20, - 0x00, 0x59, 0x08, 0x72, 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x08, 0x7b, + 0xc0, 0x20, 0x00, 0x98, 0x28, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x9a, 0x93, + 0x80, 0x80, 0x04, 0x4b, 0x88, 0x40, 0x88, 0xb0, 0x32, 0x18, 0x0a, 0x97, + 0x33, 0x9d, 0xc0, 0x20, 0x00, 0x98, 0x94, 0xc0, 0x20, 0x00, 0x88, 0x94, + 0x90, 0x90, 0x04, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x4b, 0x99, 0x40, 0x88, + 0xa0, 0x40, 0x99, 0xb0, 0xc0, 0x20, 0x00, 0x38, 0x28, 0x88, 0x49, 0x3a, + 0x88, 0x16, 0x78, 0xf7, 0xc0, 0x20, 0x00, 0x98, 0x94, 0x90, 0x90, 0x04, + 0x8b, 0x99, 0x40, 0x49, 0xa0, 0xc0, 0x20, 0x00, 0x98, 0x24, 0x4b, 0x99, + 0x2a, 0x99, 0xc0, 0x20, 0x00, 0x99, 0x24, 0x86, 0x10, 0x00, 0x00, 0x00, + 0xc0, 0x20, 0x00, 0x98, 0x94, 0xc0, 0x20, 0x00, 0x88, 0x94, 0x90, 0x90, + 0x04, 0x80, 0x80, 0x04, 0x8b, 0x88, 0x4b, 0x99, 0x40, 0x88, 0xa0, 0x40, + 0x99, 0xb0, 0xc0, 0x20, 0x00, 0x38, 0x28, 0x88, 0x49, 0xc0, 0x20, 0x00, + 0x98, 0x94, 0x3a, 0x88, 0x90, 0x90, 0x04, 0x8b, 0x99, 0x40, 0x49, 0xa0, + 0xc0, 0x20, 0x00, 0x98, 0x24, 0x4b, 0x99, 0x2a, 0x99, 0xc0, 0x20, 0x00, + 0x99, 0x24, 0x16, 0x68, 0xf1, 0x40, 0xeb, 0x03, 0x40, 0x4d, 0x04, 0x10, + 0x44, 0x11, 0x20, 0x24, 0x20, 0x22, 0x58, 0x00, 0x0c, 0x02, 0x22, 0x58, + 0x01, 0x4b, 0x28, 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, 0x51, + 0x67, 0xfd, 0xc0, 0x20, 0x00, 0x48, 0x75, 0xc0, 0x20, 0x00, 0x88, 0x85, + 0x9d, 0x05, 0x47, 0x38, 0x07, 0xc0, 0x20, 0x00, 0x48, 0x85, 0x06, 0x01, + 0x00, 0xc0, 0x20, 0x00, 0x48, 0x65, 0xc0, 0x20, 0x00, 0x88, 0x75, 0x80, + 0x44, 0xc0, 0x16, 0x24, 0x08, 0x88, 0x02, 0x80, 0x84, 0x63, 0x89, 0x02, + 0xc0, 0x20, 0x00, 0x28, 0x79, 0x48, 0x49, 0x2a, 0x44, 0xc0, 0x20, 0x00, + 0x28, 0x79, 0xc0, 0x20, 0x00, 0x38, 0x89, 0x27, 0x33, 0x11, 0xc0, 0x20, + 0x00, 0x28, 0x79, 0xc0, 0x20, 0x00, 0x38, 0x89, 0x2a, 0x28, 0x27, 0x33, + 0x52, 0xc6, 0x0f, 0x00, 0xc0, 0x20, 0x00, 0x28, 0x79, 0xc0, 0x20, 0x00, + 0x38, 0x69, 0x2a, 0x28, 0x27, 0x33, 0x40, 0xc0, 0x20, 0x00, 0x28, 0x79, + 0xc0, 0x20, 0x00, 0x38, 0x69, 0x2a, 0x28, 0x37, 0x92, 0x21, 0xc0, 0x20, + 0x00, 0x38, 0x69, 0xc0, 0x20, 0x00, 0x28, 0x59, 0x27, 0xb3, 0x09, 0xc0, + 0x20, 0x00, 0x28, 0x59, 0xc0, 0x20, 0x00, 0x29, 0x69, 0x0c, 0x02, 0xc0, + 0x20, 0x00, 0x29, 0x79, 0x06, 0x03, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x28, + 0x79, 0x2a, 0x88, 0xc0, 0x20, 0x00, 0x89, 0x79, 0x2d, 0x04, 0xdc, 0xb4, + 0x06, 0xff, 0xff, 0x00, 0x81, 0x44, 0xfd, 0x80, 0x68, 0x40, 0xad, 0x03, + 0x67, 0x78, 0x05, 0x65, 0xbe, 0xff, 0x06, 0xd1, 0xff, 0xa5, 0xb8, 0xff, + 0x16, 0xea, 0xf3, 0x2d, 0x04, 0x1d, 0xf0, 0x00, 0x36, 0x61, 0x00, 0x81, + 0x42, 0xfc, 0xc0, 0x20, 0x00, 0x22, 0x28, 0x00, 0x20, 0x20, 0x24, 0x56, + 0x32, 0xff, 0x81, 0x3f, 0xfc, 0xc0, 0x20, 0x00, 0x22, 0x28, 0x00, 0x20, + 0x20, 0x24, 0x56, 0x32, 0xff, 0x10, 0xa1, 0x20, 0x65, 0xaf, 0xff, 0x82, + 0xa0, 0x01, 0xa0, 0x28, 0x93, 0x1d, 0xf0, 0x00, 0x36, 0x61, 0x00, 0x22, + 0xa0, 0x00, 0x22, 0x61, 0x00, 0x65, 0xfc, 0xff, 0x81, 0x67, 0xfb, 0x21, + 0x0e, 0xfc, 0xc0, 0x20, 0x00, 0x22, 0x68, 0x00, 0xc0, 0x20, 0x00, 0x28, + 0x08, 0x56, 0x72, 0xff, 0x0c, 0x22, 0x46, 0x01, 0x00, 0x10, 0xa1, 0x20, + 0x25, 0xac, 0xff, 0x82, 0x21, 0x00, 0x87, 0x02, 0xf3, 0x22, 0xa0, 0x00, + 0x1d, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x36, 0x41, 0x00, 0x40, + 0x50, 0x14, 0x8c, 0x35, 0x0c, 0x12, 0x1d, 0xf0, 0x00, 0x51, 0x59, 0xfb, + 0x82, 0x25, 0x04, 0x80, 0x52, 0xe2, 0x40, 0x55, 0x80, 0x57, 0x38, 0xeb, + 0x65, 0xf7, 0xff, 0x52, 0xa0, 0x1f, 0x86, 0x24, 0x00, 0xe5, 0xf9, 0xff, + 0x56, 0xca, 0xfd, 0x81, 0xd4, 0xfb, 0xa1, 0xd4, 0xfb, 0x80, 0x82, 0x10, + 0x47, 0xa5, 0x2c, 0x91, 0x21, 0xfc, 0x90, 0x88, 0x20, 0x91, 0x49, 0xfb, + 0xc0, 0x20, 0x00, 0x89, 0x0a, 0xad, 0x03, 0x0c, 0x88, 0x76, 0x88, 0x0a, + 0xb8, 0x0a, 0x4b, 0xaa, 0xc0, 0x20, 0x00, 0xb9, 0x09, 0x4b, 0x99, 0x32, + 0xc3, 0x20, 0x42, 0xc4, 0xe0, 0x22, 0xc2, 0x20, 0x86, 0x0f, 0x00, 0x00, + 0x80, 0x94, 0x01, 0x90, 0x88, 0x20, 0xc0, 0x20, 0x00, 0x89, 0x0a, 0x40, + 0xa0, 0x14, 0x40, 0x42, 0x21, 0x1b, 0x84, 0x80, 0x90, 0x74, 0x40, 0x40, + 0x74, 0x8d, 0x09, 0x9d, 0x04, 0xa0, 0x98, 0x93, 0x81, 0x38, 0xfb, 0x4d, + 0x03, 0x40, 0x88, 0xc0, 0x30, 0x39, 0xa0, 0x86, 0x02, 0x00, 0xa8, 0x04, + 0x4a, 0x98, 0xc0, 0x20, 0x00, 0xa9, 0x09, 0x4b, 0x44, 0x47, 0x93, 0xf1, + 0x0c, 0x04, 0x81, 0x32, 0xfb, 0x91, 0xd5, 0xff, 0xc0, 0x20, 0x00, 0x99, + 0x08, 0xc0, 0x20, 0x00, 0x98, 0x08, 0x56, 0x79, 0xff, 0xe5, 0xed, 0xff, + 0xa6, 0x14, 0x02, 0x86, 0xd9, 0xff, 0x0c, 0x02, 0x1d, 0xf0, 0x00, 0x00, + 0x36, 0x61, 0x00, 0x81, 0x36, 0xfd, 0xe0, 0x08, 0x00, 0x81, 0x34, 0xfd, + 0xe0, 0x08, 0x00, 0xa9, 0x01, 0x7c, 0xf8, 0xbd, 0x01, 0x0c, 0x0a, 0x89, + 0x11, 0xe5, 0xc8, 0xff, 0x2d, 0x0a, 0x1d, 0xf0, 0x36, 0x61, 0x00, 0x81, + 0x2e, 0xfd, 0xe0, 0x08, 0x00, 0xa2, 0x61, 0x00, 0x82, 0xaf, 0xff, 0x10, + 0xb1, 0x20, 0xad, 0x02, 0x89, 0x11, 0x65, 0x34, 0x00, 0x2d, 0x0a, 0x1d, + 0xf0, 0x00, 0x00, 0x00, 0x36, 0x61, 0x00, 0x81, 0x26, 0xfd, 0xe0, 0x08, + 0x00, 0xbd, 0x01, 0xad, 0x02, 0xe5, 0x33, 0x00, 0x2d, 0x0a, 0x1d, 0xf0, + 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7c, + 0xeb, 0x00, 0x00, 0x70, 0xbb, 0x00, 0x00, 0x70, 0x6b, 0x00, 0x00, 0x70, + 0x3b, 0x00, 0x00, 0x70, 0x0b, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x70, + 0x36, 0x41, 0x00, 0x51, 0xb4, 0xfb, 0x91, 0xf5, 0xff, 0xc0, 0x20, 0x00, + 0x88, 0x05, 0x61, 0xda, 0xfb, 0x90, 0xa8, 0x10, 0x51, 0x00, 0xfb, 0x71, + 0xd9, 0xfb, 0x97, 0x9a, 0x56, 0xc0, 0x20, 0x00, 0x88, 0x05, 0x60, 0x68, + 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0xc0, 0x20, 0x00, 0x88, 0x05, 0x61, + 0xec, 0xff, 0x60, 0x68, 0x20, 0x81, 0x57, 0xfb, 0xc0, 0x20, 0x00, 0x69, + 0x05, 0xc0, 0x20, 0x00, 0x68, 0x08, 0x51, 0x55, 0xfb, 0x50, 0x66, 0x10, + 0x51, 0xe7, 0xff, 0x50, 0x56, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0x72, + 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x08, 0x62, 0xaf, 0x00, 0x3b, 0x77, + 0x60, 0x55, 0x10, 0x70, 0x70, 0x74, 0x50, 0x57, 0x20, 0xc0, 0x20, 0x00, + 0x59, 0x08, 0x61, 0xde, 0xff, 0x06, 0x68, 0x00, 0xd7, 0xe8, 0x02, 0x86, + 0x45, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x05, 0x60, 0x69, 0x10, 0xc0, 0x20, + 0x00, 0x69, 0x05, 0xc0, 0x20, 0x00, 0x98, 0x05, 0x61, 0xbf, 0xfb, 0x60, + 0x69, 0x20, 0xc0, 0x20, 0x00, 0x69, 0x05, 0x77, 0xf8, 0x02, 0x86, 0x24, + 0x00, 0x82, 0x07, 0x01, 0x61, 0x3d, 0xfb, 0xec, 0xa8, 0xc0, 0x20, 0x00, + 0x88, 0x05, 0x71, 0x39, 0xfb, 0x70, 0x78, 0x10, 0xc0, 0x20, 0x00, 0x79, + 0x05, 0xc0, 0x20, 0x00, 0x78, 0x06, 0x51, 0x37, 0xfb, 0x50, 0x77, 0x10, + 0x51, 0xc9, 0xff, 0x50, 0x57, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x06, 0x61, + 0xc8, 0xff, 0xc6, 0x50, 0x00, 0xc0, 0x20, 0x00, 0x98, 0x05, 0x81, 0xaa, + 0xfb, 0x80, 0x89, 0x20, 0xc0, 0x20, 0x00, 0x89, 0x05, 0xc0, 0x20, 0x00, + 0x88, 0x06, 0x51, 0x2c, 0xfb, 0x50, 0x88, 0x10, 0x51, 0xbe, 0xff, 0x50, + 0x58, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x06, 0x82, 0x07, 0x01, 0xc0, 0x20, + 0x00, 0x58, 0x06, 0x72, 0xaf, 0x00, 0x0b, 0x88, 0x70, 0x55, 0x10, 0x80, + 0x80, 0x74, 0x50, 0x58, 0x20, 0x71, 0xc2, 0xfa, 0xc0, 0x20, 0x00, 0x59, + 0x06, 0xc0, 0x20, 0x00, 0x68, 0x07, 0x51, 0x9d, 0xfb, 0x50, 0x66, 0x10, + 0x52, 0xa0, 0xbb, 0x50, 0x56, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x07, 0x86, + 0x3b, 0x00, 0x00, 0x00, 0x51, 0xba, 0xfa, 0x61, 0xaf, 0xff, 0x47, 0xf8, + 0x08, 0x61, 0xae, 0xff, 0xe7, 0xe8, 0x02, 0x61, 0xae, 0xff, 0xc0, 0x20, + 0x00, 0x69, 0x05, 0x61, 0xb3, 0xfa, 0x51, 0x8d, 0xfb, 0xc0, 0x20, 0x00, + 0x88, 0x06, 0x50, 0x58, 0x20, 0x81, 0x0f, 0xfb, 0xc0, 0x20, 0x00, 0x59, + 0x06, 0xc0, 0x20, 0x00, 0x68, 0x08, 0x51, 0x0d, 0xfb, 0x50, 0x66, 0x10, + 0x51, 0x0d, 0xfb, 0x50, 0x56, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0x72, + 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x08, 0x7b, 0x77, 0x62, 0xaf, 0x00, + 0x70, 0x70, 0x74, 0x60, 0x55, 0x10, 0x50, 0x57, 0x20, 0xc0, 0x20, 0x00, + 0x59, 0x08, 0xc6, 0x22, 0x00, 0xc0, 0x20, 0x00, 0x88, 0x05, 0x60, 0x68, + 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0x62, 0x07, 0x01, 0xdc, 0x36, 0xc0, + 0x20, 0x00, 0x78, 0x05, 0x61, 0xfa, 0xfa, 0x60, 0x67, 0x10, 0xc0, 0x20, + 0x00, 0x69, 0x05, 0xc6, 0x0b, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x88, + 0x05, 0x61, 0x70, 0xfb, 0x60, 0x68, 0x20, 0xc0, 0x20, 0x00, 0x69, 0x05, + 0x81, 0xf3, 0xfa, 0x72, 0x07, 0x01, 0xc0, 0x20, 0x00, 0x58, 0x08, 0x0b, 0x77, 0x62, 0xaf, 0x00, 0x70, 0x70, 0x74, 0x60, 0x55, 0x10, 0x50, 0x57, - 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0xc6, 0x22, 0x00, 0xc0, 0x20, 0x00, - 0x88, 0x05, 0x60, 0x68, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0x62, 0x07, - 0x01, 0xdc, 0x36, 0xc0, 0x20, 0x00, 0x78, 0x05, 0x61, 0xf9, 0xfa, 0x60, - 0x67, 0x10, 0xc0, 0x20, 0x00, 0x69, 0x05, 0xc6, 0x0b, 0x00, 0x00, 0x00, - 0xc0, 0x20, 0x00, 0x88, 0x05, 0x61, 0x6f, 0xfb, 0x60, 0x68, 0x20, 0xc0, - 0x20, 0x00, 0x69, 0x05, 0x81, 0xf2, 0xfa, 0x72, 0x07, 0x01, 0xc0, 0x20, - 0x00, 0x58, 0x08, 0x0b, 0x77, 0x62, 0xaf, 0x00, 0x70, 0x70, 0x74, 0x60, - 0x55, 0x10, 0x50, 0x57, 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0x61, 0x8a, - 0xfa, 0x51, 0x66, 0xfb, 0xc0, 0x20, 0x00, 0x78, 0x06, 0x50, 0x57, 0x20, - 0x71, 0xe7, 0xfa, 0xc0, 0x20, 0x00, 0x59, 0x06, 0xc0, 0x20, 0x00, 0x68, - 0x07, 0x51, 0xe4, 0xfa, 0x50, 0x66, 0x10, 0x51, 0xe4, 0xfa, 0x50, 0x56, - 0x20, 0x61, 0x7b, 0xff, 0xc0, 0x20, 0x00, 0x59, 0x07, 0x51, 0x7f, 0xfa, - 0xc0, 0x20, 0x00, 0x69, 0x05, 0x61, 0x85, 0xfa, 0x2a, 0x54, 0x78, 0x16, - 0x62, 0xa0, 0x01, 0x57, 0xb7, 0x02, 0xc6, 0x2c, 0x00, 0xa5, 0xc2, 0xff, - 0x81, 0x7f, 0xfa, 0xe1, 0x7f, 0xfa, 0x3c, 0xf5, 0xc1, 0x02, 0xfb, 0xd2, - 0xa1, 0xff, 0xfd, 0x08, 0x6d, 0x0e, 0xc6, 0x24, 0x00, 0x80, 0x72, 0x11, - 0x47, 0xa5, 0x3c, 0x91, 0x73, 0xfa, 0xc0, 0x20, 0x00, 0xd9, 0x09, 0xc0, - 0x20, 0x00, 0x79, 0x0c, 0xc0, 0x20, 0x00, 0x69, 0x0f, 0xc0, 0x20, 0x00, - 0x78, 0x0f, 0x56, 0x77, 0xff, 0xa1, 0x6f, 0xfa, 0xbd, 0x03, 0x92, 0xa0, - 0x10, 0x76, 0x89, 0x0a, 0xc0, 0x20, 0x00, 0x78, 0x0a, 0x4b, 0xaa, 0x79, - 0x0b, 0x4b, 0xbb, 0x32, 0xc3, 0x40, 0x42, 0xc4, 0xc0, 0x22, 0xc2, 0x40, - 0x46, 0x14, 0x00, 0x00, 0x21, 0x64, 0xfa, 0xc0, 0x20, 0x00, 0x79, 0x0c, - 0xc0, 0x20, 0x00, 0xd2, 0x62, 0x00, 0xc0, 0x20, 0x00, 0xe2, 0x68, 0x00, - 0xc0, 0x20, 0x00, 0x28, 0x08, 0x56, 0x72, 0xff, 0x40, 0x60, 0x14, 0x40, - 0x42, 0x21, 0x1b, 0x24, 0x20, 0x50, 0x74, 0x40, 0x40, 0x74, 0x2d, 0x05, - 0x5d, 0x04, 0x41, 0x5b, 0xfa, 0x60, 0x52, 0x93, 0x2d, 0x03, 0x20, 0x44, - 0xc0, 0x30, 0x35, 0xa0, 0xc6, 0x02, 0x00, 0x00, 0x2a, 0x54, 0xc0, 0x20, - 0x00, 0x58, 0x05, 0x59, 0x02, 0x4b, 0x22, 0x27, 0x93, 0xf1, 0x46, 0x01, - 0x00, 0xa6, 0x14, 0x02, 0x46, 0xd9, 0xff, 0x0c, 0x06, 0x2d, 0x06, 0x1d, - 0xf0, 0x00, 0x00, 0x00, 0x36, 0x41, 0x00, 0x8d, 0x02, 0x4a, 0x42, 0xc6, - 0x02, 0x00, 0x00, 0x00, 0x92, 0x03, 0x00, 0x1b, 0x33, 0x92, 0x48, 0x00, - 0x1b, 0x88, 0x47, 0x98, 0xf2, 0x1d, 0xf0, 0x00, 0x36, 0x41, 0x00, 0x22, - 0xc2, 0xfc, 0x82, 0x12, 0x00, 0x82, 0x52, 0x01, 0x0c, 0x02, 0x1d, 0xf0, - 0x36, 0x41, 0x00, 0x0c, 0x02, 0x1d, 0xf0, 0x00, 0x36, 0x41, 0x00, 0x0c, - 0x02, 0x1d, 0xf0 + 0x20, 0xc0, 0x20, 0x00, 0x59, 0x08, 0x61, 0x8b, 0xfa, 0x51, 0x67, 0xfb, + 0xc0, 0x20, 0x00, 0x78, 0x06, 0x50, 0x57, 0x20, 0x71, 0xe8, 0xfa, 0xc0, + 0x20, 0x00, 0x59, 0x06, 0xc0, 0x20, 0x00, 0x68, 0x07, 0x51, 0xe5, 0xfa, + 0x50, 0x66, 0x10, 0x51, 0xe5, 0xfa, 0x50, 0x56, 0x20, 0x61, 0x7b, 0xff, + 0xc0, 0x20, 0x00, 0x59, 0x07, 0x51, 0x80, 0xfa, 0xc0, 0x20, 0x00, 0x69, + 0x05, 0x61, 0x86, 0xfa, 0x2a, 0x54, 0x78, 0x16, 0x62, 0xa0, 0x01, 0x57, + 0xb7, 0x02, 0xc6, 0x2c, 0x00, 0xa5, 0xc2, 0xff, 0x81, 0x80, 0xfa, 0xe1, + 0x80, 0xfa, 0x3c, 0xf5, 0xc1, 0x03, 0xfb, 0xd2, 0xa1, 0xff, 0xfd, 0x08, + 0x6d, 0x0e, 0xc6, 0x24, 0x00, 0x80, 0x72, 0x11, 0x47, 0xa5, 0x3c, 0x91, + 0x74, 0xfa, 0xc0, 0x20, 0x00, 0xd9, 0x09, 0xc0, 0x20, 0x00, 0x79, 0x0c, + 0xc0, 0x20, 0x00, 0x69, 0x0f, 0xc0, 0x20, 0x00, 0x78, 0x0f, 0x56, 0x77, + 0xff, 0xa1, 0x70, 0xfa, 0xbd, 0x03, 0x92, 0xa0, 0x10, 0x76, 0x89, 0x0a, + 0xc0, 0x20, 0x00, 0x78, 0x0a, 0x4b, 0xaa, 0x79, 0x0b, 0x4b, 0xbb, 0x32, + 0xc3, 0x40, 0x42, 0xc4, 0xc0, 0x22, 0xc2, 0x40, 0x46, 0x14, 0x00, 0x00, + 0x21, 0x65, 0xfa, 0xc0, 0x20, 0x00, 0x79, 0x0c, 0xc0, 0x20, 0x00, 0xd2, + 0x62, 0x00, 0xc0, 0x20, 0x00, 0xe2, 0x68, 0x00, 0xc0, 0x20, 0x00, 0x28, + 0x08, 0x56, 0x72, 0xff, 0x40, 0x60, 0x14, 0x40, 0x42, 0x21, 0x1b, 0x24, + 0x20, 0x50, 0x74, 0x40, 0x40, 0x74, 0x2d, 0x05, 0x5d, 0x04, 0x41, 0x5c, + 0xfa, 0x60, 0x52, 0x93, 0x2d, 0x03, 0x20, 0x44, 0xc0, 0x30, 0x35, 0xa0, + 0xc6, 0x02, 0x00, 0x00, 0x2a, 0x54, 0xc0, 0x20, 0x00, 0x58, 0x05, 0x59, + 0x02, 0x4b, 0x22, 0x27, 0x93, 0xf1, 0x46, 0x01, 0x00, 0xa6, 0x14, 0x02, + 0x46, 0xd9, 0xff, 0x0c, 0x06, 0x2d, 0x06, 0x1d, 0xf0, 0x00, 0x00, 0x00, + 0x36, 0x41, 0x00, 0x8d, 0x02, 0x4a, 0x42, 0xc6, 0x02, 0x00, 0x00, 0x00, + 0x92, 0x03, 0x00, 0x1b, 0x33, 0x92, 0x48, 0x00, 0x1b, 0x88, 0x47, 0x98, + 0xf2, 0x1d, 0xf0, 0x00, 0x36, 0x41, 0x00, 0x22, 0xc2, 0xfc, 0x82, 0x12, + 0x00, 0x82, 0x52, 0x01, 0x0c, 0x02, 0x1d, 0xf0, 0x36, 0x41, 0x00, 0x0c, + 0x02, 0x1d, 0xf0, 0x00, 0x36, 0x41, 0x00, 0x0c, 0x02, 0x1d, 0xf0 diff --git a/contrib/loaders/flash/esp32/stub_flasher_data.inc b/contrib/loaders/flash/esp32/stub_flasher_data.inc index 46e5fe755..2bbec0379 100644 --- a/contrib/loaders/flash/esp32/stub_flasher_data.inc +++ b/contrib/loaders/flash/esp32/stub_flasher_data.inc @@ -1,5 +1,5 @@ - 0xae, 0x09, 0x09, 0x40, 0xa7, 0x0a, 0x09, 0x40, 0x8e, 0x0a, 0x09, 0x40, - 0x9b, 0x0a, 0x09, 0x40, 0xe7, 0x0b, 0x09, 0x40, 0xf0, 0x0b, 0x09, 0x40, - 0xfb, 0x0b, 0x09, 0x40, 0x76, 0x0c, 0x09, 0x40, 0x00, 0x00, 0x04, 0x00, + 0xab, 0x09, 0x09, 0x40, 0xa3, 0x0a, 0x09, 0x40, 0x8a, 0x0a, 0x09, 0x40, + 0x97, 0x0a, 0x09, 0x40, 0xe6, 0x0b, 0x09, 0x40, 0xf1, 0x0b, 0x09, 0x40, + 0xf9, 0x0b, 0x09, 0x40, 0x76, 0x0c, 0x09, 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/src/flash/nor/esp32.c b/src/flash/nor/esp32.c index cacc265b6..c92dfffbd 100644 --- a/src/flash/nor/esp32.c +++ b/src/flash/nor/esp32.c @@ -76,7 +76,7 @@ #include #include #include "time_support.h" -#include +#include "contrib/loaders/flash/esp32/stub_flasher.h" #include "contrib/loaders/flash/esp32/stub_flasher_image.h" #include "target/esp32.h" @@ -796,7 +796,7 @@ struct esp32_flash_sw_breakpoint * esp32_add_flash_breakpoint(struct target *tar LOG_ERROR("Failed to alloc memory for sw breakpoint data!"); return NULL; } - sw_bp->oocd_bp = breakpoint; + sw_bp->data.oocd_bp = breakpoint; sw_bp->bank = bank; init_mem_param(&mp, 2/*2nd usr arg*/, 3/*size in bytes*/, PARAM_IN); diff --git a/src/target/esp108_common.c b/src/target/esp108_common.c index 9f030ef59..cd983e042 100755 --- a/src/target/esp108_common.c +++ b/src/target/esp108_common.c @@ -253,19 +253,6 @@ int xtensa_examine(struct target *target) return ERROR_OK; } -uint32_t xtensa_read_reg_direct(struct target *target, uint8_t reg) -{ - uint32_t result = 0xdeadface; - uint8_t dsr[4]; - - esp108_queue_nexus_reg_read(target, reg, dsr); - esp108_queue_tdi_idle(target); - int res = jtag_execute_queue(); - if (res != ERROR_OK) return result; - result = intfromchars(dsr); - return result; -} - int read_reg_direct(struct target *target, uint8_t addr) { uint8_t dsr[4]; @@ -275,7 +262,6 @@ int read_reg_direct(struct target *target, uint8_t addr) return intfromchars(dsr); } - int xtensa_write_uint32(struct target *target, uint32_t addr, uint32_t val) { @@ -407,7 +393,7 @@ int xtensa_wait_algorithm_generic(struct target *target, for (int i = 0; i < num_mem_params; i++) { LOG_DEBUG("Check mem param @ 0x%x", mem_params[i].address); if (mem_params[i].direction != PARAM_OUT) { - LOG_USER("Read mem param @ 0x%x", mem_params[i].address); + LOG_DEBUG("Read mem param @ 0x%x", mem_params[i].address); retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value); @@ -435,8 +421,6 @@ int xtensa_wait_algorithm_generic(struct target *target, for (int i = core_cache->num_regs - 1; i >= 0; i--) { uint32_t regvalue; regvalue = esp108_reg_get(&core_cache->reg_list[i]); - // LOG_DEBUG("check register %s with value 0x%x -> 0x%8.8" PRIx32, - // core_cache->reg_list[i].name, regvalue, algorithm_info->context[i]); if (i == XT_REG_IDX_DEBUGCAUSE) { //FIXME: restoring DEBUGCAUSE causes exception when executing corresponding instruction in DIR LOG_DEBUG("Skip restoring register %s: 0x%x -> 0x%8.8" PRIx32, diff --git a/src/target/esp32.c b/src/target/esp32.c index 01995cc1f..1acd8abcb 100755 --- a/src/target/esp32.c +++ b/src/target/esp32.c @@ -547,7 +547,6 @@ static int xtensa_resume_cpu(struct target *target, xtensa_step(target, current, address, handle_breakpoints); } } - //Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an //exception; we need to clear that and return to the breakpoints gdb has set on resume. bpena = 0; @@ -939,7 +938,7 @@ static int esp32_handle_target_event(struct target *target, enum target_event ev int ret = esp32_remove_flash_breakpoint(target, flash_bp); if (ret != ERROR_OK) { LOG_ERROR("%s: Failed to remove SW flash BP @ 0x%x (%d)!", - target->cmd_name, flash_bp->oocd_bp->address, ret); + target->cmd_name, flash_bp->data.oocd_bp->address, ret); return ret; } } @@ -958,7 +957,50 @@ static int esp32_handle_target_event(struct target *target, enum target_event ev default: break; } + return ERROR_OK; +} + +static struct esp32_sw_breakpoint * esp32_add_sw_breakpoint(struct target *target, struct breakpoint *breakpoint) +{ + union { + uint32_t d32; + uint8_t d8[4]; + } break_insn; + + int ret = target_read_buffer(target, breakpoint->address, 3, break_insn.d8); + if (ret != ERROR_OK) { + LOG_ERROR("%s: Faied to read insn (%d)!", target->cmd_name, ret); + return NULL; + } + struct esp32_sw_breakpoint *sw_bp = malloc(sizeof(struct esp32_flash_sw_breakpoint)); + if (sw_bp == NULL) { + LOG_ERROR("Failed to alloc memory for sw breakpoint data!"); + return NULL; + } + sw_bp->insn_sz = xtensa_get_insn_size(break_insn.d8); + memcpy(sw_bp->insn, break_insn.d8, sw_bp->insn_sz); + sw_bp->oocd_bp = breakpoint; + + break_insn.d32 = sw_bp->insn_sz == 2 ? XT_INS_BREAKN(0) : XT_INS_BREAK(0, 0); + + ret = target_write_buffer(target, breakpoint->address, sw_bp->insn_sz, break_insn.d8); + if (ret != ERROR_OK) { + LOG_ERROR("%s: Faied to read insn (%d)!", target->cmd_name, ret); + free(sw_bp); + return NULL; + } + + return sw_bp; +} +static int esp32_remove_sw_breakpoint(struct target *target, struct esp32_sw_breakpoint *breakpoint) +{ + int ret = target_write_buffer(target, breakpoint->oocd_bp->address, breakpoint->insn_sz, breakpoint->insn); + if (ret != ERROR_OK) { + LOG_ERROR("%s: Faied to read insn (%d)!", target->cmd_name, ret); + return ret; + } + free(breakpoint); return ERROR_OK; } @@ -968,7 +1010,21 @@ static int xtensa_add_breakpoint(struct target *target, struct breakpoint *break size_t slot; if (breakpoint->type == BKPT_SOFT) { - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + for(slot = 0; slot < ESP32_SW_BREAKPOINTS_MAX_NUM; slot++) { + if (esp32->sw_brps[slot] == NULL || esp32->sw_brps[slot]->oocd_bp == breakpoint) break; + } + if (slot == ESP32_SW_BREAKPOINTS_MAX_NUM) + { + LOG_WARNING("%s: max SW slot reached, slot=%i", __func__, (unsigned int)slot); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + esp32->sw_brps[slot] = esp32_add_sw_breakpoint(target, breakpoint); + if (esp32->sw_brps[slot] == NULL) { + LOG_ERROR("%s: Faied to add SW BP!", target->cmd_name); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + LOG_DEBUG("%s: placed SW breakpoint %d at 0x%X", target->cmd_name, (int)slot, breakpoint->address); + return ERROR_OK; } for(slot = 0; slot < esp32->num_brps; slot++) { @@ -978,11 +1034,11 @@ static int xtensa_add_breakpoint(struct target *target, struct breakpoint *break { LOG_WARNING("%s: max HW slot reached, slot=%i", __func__, (unsigned int)slot); for(slot = 0; slot < ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM; slot++) { - if (esp32->flash_sw_brps[slot] == NULL || esp32->flash_sw_brps[slot]->oocd_bp == breakpoint) break; + if (esp32->flash_sw_brps[slot] == NULL || esp32->flash_sw_brps[slot]->data.oocd_bp == breakpoint) break; } if (slot == ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM) { - LOG_WARNING("%s: max SW slot reached, slot=%i", __func__, (unsigned int)slot); + LOG_WARNING("%s: max SW flash slot reached, slot=%i", __func__, (unsigned int)slot); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } esp32->flash_sw_brps[slot] = esp32_add_flash_breakpoint(target, breakpoint); @@ -1007,7 +1063,23 @@ static int xtensa_remove_breakpoint(struct target *target, struct breakpoint *br LOG_DEBUG("%s: %p", __func__, breakpoint); if (breakpoint->type == BKPT_SOFT) { - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + for(slot = 0; slot < ESP32_SW_BREAKPOINTS_MAX_NUM; slot++) { + if(esp32->sw_brps[slot] != NULL && esp32->sw_brps[slot]->oocd_bp == breakpoint) + break; + } + if (slot == ESP32_SW_BREAKPOINTS_MAX_NUM) + { + LOG_WARNING("%s: max SW slot reached, slot=%i", __func__, (unsigned int)slot); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + int ret = esp32_remove_sw_breakpoint(target, esp32->sw_brps[slot]); + if (ret != ERROR_OK) { + LOG_ERROR("%s: Failed to remove SW BP (%d)!", target->cmd_name, ret); + return ret; + } + esp32->sw_brps[slot] = NULL; + LOG_DEBUG("%s: cleared SW breakpoint %d at 0x%X", target->cmd_name, (int)slot, breakpoint->address); + return ERROR_OK; } for(slot = 0; slot < esp32->num_brps; slot++) { @@ -1017,7 +1089,7 @@ static int xtensa_remove_breakpoint(struct target *target, struct breakpoint *br if (slot==esp32->num_brps) { LOG_DEBUG("%s: HW BP not found!", target->cmd_name); for(slot = 0; slot < ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM; slot++) { - if(esp32->flash_sw_brps[slot] != NULL && esp32->flash_sw_brps[slot]->oocd_bp == breakpoint) + if(esp32->flash_sw_brps[slot] != NULL && esp32->flash_sw_brps[slot]->data.oocd_bp == breakpoint) break; } if (slot == ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM) { @@ -1352,7 +1424,8 @@ static int xtensa_target_create(struct target *target, Jim_Interp *interp) esp32->hw_brps = calloc(XT_NUM_BREAKPOINTS, sizeof(struct breakpoint *)); esp32->num_wps = XT_NUM_WATCHPOINTS; esp32->hw_wps = calloc(XT_NUM_WATCHPOINTS, sizeof(struct watchpoint *)); - esp32->flash_sw_brps = calloc(ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM, sizeof(struct esp32_flash_sw_breakpoint *)); + esp32->flash_sw_brps = calloc(ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM, sizeof(struct esp32_flash_sw_breakpoint *)); + esp32->sw_brps = calloc(ESP32_SW_BREAKPOINTS_MAX_NUM, sizeof(struct esp32_sw_breakpoint *)); //Create the register cache cache->name = "Xtensa registers"; @@ -1470,7 +1543,7 @@ static size_t esp32_read_cores_num(struct target *target) LOG_DEBUG("Read APP CPU ctrl reg 0x%x", appcpu_ctrl); if (appcpu_ctrl & ESP32_DPORT_APPCPU_CLKGATE_EN) { cores_num++; - LOG_INFO("APP CPU enabled"); + LOG_DEBUG("APP CPU enabled"); } LOG_DEBUG("Detected %u cores", (uint32_t)cores_num); return cores_num; @@ -1549,21 +1622,22 @@ static int xtensa_poll(struct target *target) struct reg *cpu_reg_list = esp32->core_caches[i]->reg_list; // volatile int temp_cause = xtensa_read_reg_direct(esp32->esp32_targets[i], XT_REG_IDX_DEBUGCAUSE); int cause = esp108_reg_get(&cpu_reg_list[XT_REG_IDX_DEBUGCAUSE]); + int exc_cause = esp108_reg_get(&cpu_reg_list[XT_REG_IDX_EXCCAUSE]); volatile unsigned int dsr_core = xtensa_read_dsr(esp32->esp32_targets[i]); if ((dsr_core&OCDDSR_DEBUGPENDBREAK) != 0) { if (esp32->active_cpu != i) { - LOG_INFO("active_cpu: %u, changed to %u, reson = 0x%08x", (uint32_t)esp32->active_cpu, (uint32_t)i, dsr_core); + LOG_INFO("active_cpu: %u, changed to %u, reason = 0x%08x", (uint32_t)esp32->active_cpu, (uint32_t)i, dsr_core); } esp32->active_cpu = i; } int dcrset = read_reg_direct(esp32->esp32_targets[i], NARADR_DCRSET); - LOG_DEBUG("%s: Halt reason =0x%08X, dsr=0x%08x, dcrset=0x%08x", - esp32->esp32_targets[i]->cmd_name, cause, dsr_core, dcrset); + LOG_DEBUG("%s: Halt reason=0x%08X, exc_cause=%d, dsr=0x%08x, dcrset=0x%08x", + esp32->esp32_targets[i]->cmd_name, cause, exc_cause, dsr_core, dcrset); if (cause&DEBUGCAUSE_IC) { target->debug_reason = DBG_REASON_SINGLESTEP; diff --git a/src/target/esp32.h b/src/target/esp32.h index 62fd7d876..f059a8e54 100755 --- a/src/target/esp32.h +++ b/src/target/esp32.h @@ -42,6 +42,7 @@ enum esp32_isrmasking_mode { #define ESP32_DBG_STUBS_STACK_MIN_SIZE 2048 #define ESP32_FLASH_SW_BREAKPOINTS_MAX_NUM 32 +#define ESP32_SW_BREAKPOINTS_MAX_NUM 32 /** * Debug stubs table entries IDs @@ -89,29 +90,33 @@ struct esp32_dbg_stubs { struct esp32_dbg_stubs_desc desc; }; -struct esp32_flash_sw_breakpoint { - struct flash_bank *bank; +struct esp32_sw_breakpoint { struct breakpoint *oocd_bp; - // insns with surrounding bytes - uint8_t insn[3]; // 0|-|-|-|x|4|x|x|-|-|8 + // insn + uint8_t insn[3]; // insn size uint8_t insn_sz; // 2 or 3 bytes }; +struct esp32_flash_sw_breakpoint { + struct flash_bank *bank; + struct esp32_sw_breakpoint data; +}; + struct esp32_common { // Common fields definition for all esp108 targets ESP108_COMMON_FIELDS; - struct target* esp32_targets[ESP32_CPU_COUNT]; - size_t active_cpu; - struct reg_cache * core_caches[ESP32_CPU_COUNT]; - int64_t current_threadid; - enum esp32_isrmasking_mode isrmasking_mode; - size_t cores_num; - //TODO: move to esp108 common part - struct esp32_dbg_stubs dbg_stubs; - struct esp32_flash_sw_breakpoint **flash_sw_brps; + struct target* esp32_targets[ESP32_CPU_COUNT]; + size_t active_cpu; + struct reg_cache * core_caches[ESP32_CPU_COUNT]; + int64_t current_threadid; + enum esp32_isrmasking_mode isrmasking_mode; + size_t cores_num; + struct esp32_sw_breakpoint ** sw_brps; + struct esp32_flash_sw_breakpoint ** flash_sw_brps; + struct esp32_dbg_stubs dbg_stubs; }; struct esp32_flash_sw_breakpoint * esp32_add_flash_breakpoint(struct target *target, struct breakpoint *breakpoint); diff --git a/testing/esp/debug_backend.py b/testing/esp/debug_backend.py index fdc483ca2..a053d2dc0 100644 --- a/testing/esp/debug_backend.py +++ b/testing/esp/debug_backend.py @@ -374,6 +374,15 @@ def data_eval_expr(self, expr): raise DebuggerError('Failed to eval expression!') return res_body['value'] + def get_reg(self, nm): + sval = self.data_eval_expr('$%s' % nm) + # for PC we get something like '0x400e0db8 ' + # TODO: use regexp to extract value + fn_start = sval.find(' <') + if fn_start != -1: + sval = sval[:fn_start] + return int(sval, 0) + def get_variables_at_frame(self, thread_num=None, frame_num = 0): # -stack-list-variables [ --no-frame-filters ] [ --skip-unavailable ] print-values if thread_num: diff --git a/testing/esp/debug_backend_tests.py b/testing/esp/debug_backend_tests.py index d04f4b943..856a0a3a5 100644 --- a/testing/esp/debug_backend_tests.py +++ b/testing/esp/debug_backend_tests.py @@ -122,7 +122,13 @@ def run(self, result, debug=False): get_logger().debug('Load %s for %d tests', app_cfg_id, self._groupped_suites[app_cfg_id][1].countTestCases()) # load only if app bins are configured (used) for these tests if self.load_app_bins and self._groupped_suites[app_cfg_id][0]: - self._load_app(self._groupped_suites[app_cfg_id][0]) + try: + self._load_app(self._groupped_suites[app_cfg_id][0]) + except: + get_logger().critical('Failed to load %s!', app_cfg_id) + for test in self._groupped_suites[app_cfg_id][1]: + result.addSkip(test, 'test app load failure') + continue dbg.get_gdb().exec_file_set(self._groupped_suites[app_cfg_id][0].build_app_elf_path()) self._groupped_suites[app_cfg_id][1]._run_tests(result, debug) return result @@ -193,7 +199,7 @@ def stop_exec(self): state,_ = self.gdb.get_target_state() if state != dbg.Gdb.TARGET_STATE_STOPPED: self.gdb.exec_interrupt() - rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 10) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_SIGINT) def resume_exec(self, loc=None): @@ -262,6 +268,20 @@ def setUp(self): self.assertEqual(frame['func'], 'app_main') self.gdb.delete_bp(bp) # ready to select and start test (should be done in test method) + self.bpns = [] + self.wps = {} + + def tearDown(self): + for bpn in self.bpns: + self.gdb.delete_bp(bpn) + for _,wpn in self.wps.items(): + self.gdb.delete_bp(wpn) + + def add_bp(self, loc, ignore_count=0, cond=''): + self.bpns.append(self.gdb.add_bp(loc, ignore_count=ignore_count, cond=cond)) + + def add_wp(self, exp, tp='w'): + self.wps[exp] = self.gdb.add_wp(exp, tp=tp) def select_sub_test(self, sub_test_num): """ Selects sub test in app running on target @@ -291,6 +311,7 @@ def __init__(self, methodName='runTest'): self.test_app_cfg.bin_dir = os.path.join('output', 'default') self.test_app_cfg.build_dir = os.path.join('builds', 'default') + class DebuggerGenericTestAppTestsSingle(DebuggerGenericTestAppTests): """ Base class to run tests which use generic test app in single core mode """ 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 afe858914..38bef4a25 100644 --- 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 @@ -10,6 +10,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" +#include "driver/timer.h" #include "sdkconfig.h" /* Can run 'make menuconfig' to choose the GPIO to blink, @@ -21,6 +22,10 @@ #include "esp_log.h" const static char *TAG = "ut_app"; +#define TEST_BREAK_LOC(_nm_) \ + volatile static const int _nm_ ## _break_ln = __LINE__; \ + s_tmp_ln = _nm_ ## _break_ln; + // used to prevent linker from optimizing out the variables holding BP line numbers volatile static int s_tmp_ln = 0; // test app algorithm selector @@ -30,12 +35,94 @@ volatile static int s_count1 = 0; volatile static int s_count2 = 100; volatile static int s_count3 = 200; -#define TEST_BREAK_LOC(_nm_) \ - volatile static const int _nm_ ## _break_ln = __LINE__; \ - s_tmp_ln = _nm_ ## _break_ln; +extern void gcov_task(void *pvParameter); + +struct blink_task_arg { + int tim_grp; + int tim_id; + uint32_t tim_period; +}; -void blink_task(void *pvParameter) +static void test_timer_init(int timer_group, int timer_idx, uint32_t period) { + timer_config_t config; + uint64_t alarm_val = (period * (TIMER_BASE_CLK / 1000000UL)) / 2; + + config.alarm_en = 1; + config.auto_reload = 1; + config.counter_dir = TIMER_COUNT_UP; + config.divider = 2; //Range is 2 to 65536 + config.intr_type = TIMER_INTR_LEVEL; + config.counter_en = TIMER_PAUSE; + /*Configure timer*/ + timer_init(timer_group, timer_idx, &config); + /*Stop timer counter*/ + timer_pause(timer_group, timer_idx); + /*Load counter value */ + timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); + /*Set alarm value*/ + timer_set_alarm_value(timer_group, timer_idx, alarm_val); + /*Enable timer interrupt*/ + timer_enable_intr(timer_group, timer_idx); +} + +static void test_timer_isr_func(void) +{ + s_tmp_ln++; +} + +static void IRAM_ATTR test_timer_isr_ram_func(void) +{ + s_tmp_ln++; +} + +static void test_timer_isr(void *arg) +{ + struct blink_task_arg *tim_arg = (struct blink_task_arg *)arg; + + test_timer_isr_func(); + test_timer_isr_ram_func(); + + if (tim_arg->tim_grp == 0) { + if (tim_arg->tim_id == 0) { + TIMERG0.int_clr_timers.t0 = 1; + TIMERG0.hw_timer[0].update = 1; + TIMERG0.hw_timer[0].config.alarm_en = 1; + } else { + TIMERG0.int_clr_timers.t1 = 1; + TIMERG0.hw_timer[1].update = 1; + TIMERG0.hw_timer[1].config.alarm_en = 1; + } + } else if (tim_arg->tim_grp == 1) { + if (tim_arg->tim_id == 0) { + TIMERG1.int_clr_timers.t0 = 1; + TIMERG1.hw_timer[0].update = 1; + TIMERG1.hw_timer[0].config.alarm_en = 1; + } else { + TIMERG1.int_clr_timers.t1 = 1; + TIMERG1.hw_timer[1].update = 1; + TIMERG1.hw_timer[1].config.alarm_en = 1; + } + } +} + +static void blink_task(void *pvParameter) +{ + struct blink_task_arg *arg = (struct blink_task_arg *)pvParameter; + + if (arg) { + test_timer_init(arg->tim_grp, arg->tim_id, arg->tim_period); + int res = timer_isr_register(arg->tim_grp, arg->tim_id, test_timer_isr, arg, 0, NULL); + if (res != ESP_OK) { + ESP_LOGE(TAG, "Failed to register timer ISR (%d)!", res); + return; + } + res = timer_start(arg->tim_grp, arg->tim_id); + if (res != ESP_OK) { + ESP_LOGE(TAG, "Failed to start timer (%d)!", res); + return; + } + } /* Configure the IOMUX register for pad BLINK_GPIO (some pads are muxed to GPIO on reset already, but some default to other functions and need to be switched to GPIO. Consult the @@ -82,7 +169,7 @@ void window_exception_test(void* arg) printf("sum=%d\n",sum); } -void scratch_reg_using_task(void *pvParameter) +static void scratch_reg_using_task(void *pvParameter) { int val = 100; while(1) { @@ -98,16 +185,58 @@ void scratch_reg_using_task(void *pvParameter) } } -/* Add new */ +static void IRAM_ATTR dummy_iram_func(void) +{ + __asm__ volatile ( + ".global _step_over_bp_break5\n" \ + ".type _step_over_bp_break5,@function\n" \ + "_step_over_bp_break5:\n" \ + " movi a3,30\n" \ + " nop\n" \ + ".global _step_over_bp_break6\n" \ + ".type _step_over_bp_break6,@function\n" \ + "_step_over_bp_break6:\n" \ + " mov a4,a3\n" \ + :::"a3", "a4"); +} -extern void gcov_task(void *pvParameter); +static void step_over_bp_task(void *pvParameter) +{ + while(1) { + __asm__ volatile ( + ".global _step_over_bp_break1\n" \ + ".type _step_over_bp_break1,@function\n" \ + "_step_over_bp_break1:\n" \ + " movi a3,20\n" \ + " nop\n" \ + ".global _step_over_bp_break2\n" \ + ".type _step_over_bp_break2,@function\n" \ + "_step_over_bp_break2:\n" \ + " mov a4,a3\n" \ + ".global _step_over_bp_break3\n" \ + ".type _step_over_bp_break3,@function\n" \ + "_step_over_bp_break3:\n" \ + " movi a4,10\n" \ + " nop\n" \ + ".global _step_over_bp_break4\n" \ + ".type _step_over_bp_break4,@function\n" \ + "_step_over_bp_break4:\n" \ + " mov a5,a4\n" \ + :::"a3","a4","a5"); + dummy_iram_func(); + } +} + +/* Add new */ void app_main() { + static struct blink_task_arg task_arg = { .tim_grp = TIMER_GROUP_1, .tim_id = TIMER_0, .tim_period = 500000UL}; + ESP_LOGI(TAG, "Run test %d\n", s_run_test); switch(s_run_test){ case 100: - xTaskCreate(&blink_task, "blink_task", 2048, NULL, 5, NULL); + xTaskCreate(&blink_task, "blink_task", 2048, &task_arg, 5, NULL); break; case 101: xTaskCreatePinnedToCore(&blink_task, "blink_task0", 2048, NULL, 5, NULL, 0); @@ -120,6 +249,9 @@ void app_main() xTaskCreatePinnedToCore(&scratch_reg_using_task, "sreg_task", 2048, NULL, 5, NULL, 1); #endif break; + case 103: + xTaskCreate(&step_over_bp_task, "step_over_bp_task", 2048, NULL, 5, NULL); + break; case 200: xTaskCreate(&window_exception_test, "win_exc_task", 8192, NULL, 5, NULL); break; diff --git a/testing/esp/test_bp.py b/testing/esp/test_bp.py index 10ae1a366..0298a8fc9 100644 --- a/testing/esp/test_bp.py +++ b/testing/esp/test_bp.py @@ -14,10 +14,56 @@ def get_logger(): # TESTS IMPLEMENTATION # ######################################################################## -class BreakpointTestsImpl: +class PoiTestsImpl: + """ Break/Watchpoint test cases common functions + """ + + + def run_to_bp_and_check_basic(self, exp_rsn, func_name): + self.resume_exec() + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.assertEqual(rsn, exp_rsn) + cur_frame = self.gdb.get_current_frame() + self.assertEqual(cur_frame['func'], func_name) + frames = self.gdb.get_backtrace() + self.assertTrue(len(frames) > 0) + self.assertEqual(frames[0]['func'], cur_frame['func']) + self.assertEqual(frames[0]['line'], cur_frame['line']) + return frames + + def run_to_bp_and_check(self, exp_rsn, func_name, lineno_var_prefs): + frames = self.run_to_bp_and_check_basic(exp_rsn, func_name) + outmost_frame = len(frames) - 1 + # Sometimes GDB does not provide full backtrace. so check this + # we can only check line numbers in 'blink_task', + # because its code is under control of test framework + if outmost_frame == 0 and func_name != 'blink_task': + return + # outermost frame should be in 'blink_task' function + self.assertEqual(frames[outmost_frame]['func'], 'blink_task') + self.gdb.select_frame(outmost_frame) + # read line number from variable and compare with what GDB provides + if len(lineno_var_prefs) == 1: + line_num = self.gdb.data_eval_expr('%s_break_ln' % lineno_var_prefs[0]) + self.assertEqual(frames[outmost_frame]['line'], line_num) + else: + # for tests which set multiple BPs/WPs and expect hits on both cores + # it is hard to predict the order of hits, + # so just check that debugger has stopped on one of the locations + line_nums = [] + for p in lineno_var_prefs: + line_nums.append(self.gdb.data_eval_expr('%s_break_ln' % p)) + self.assertTrue(frames[outmost_frame]['line'] in line_nums) + + +class BreakpointTestsImpl(PoiTestsImpl): """ Breakpoints test cases which are common for dual and single core modes """ + def setUp(self): + # 2 HW breaks + 1 flash SW break + RAM SW break + self.bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] + def test_multi_reset_break(self): """ This test checks that breakpoint works just after the reset: @@ -30,43 +76,22 @@ def test_multi_reset_break(self): for i in range(3): self.gdb.target_reset() rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) - bp = self.gdb.add_bp('app_main') + self.add_bp('app_main') self.resume_exec() rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.gdb.delete_bp(self.bpns.pop()) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_BP) - self.gdb.delete_bp(bp) - - def run_to_bp_and_check(self, exp_rsn, func_name, lineno_var_prefs): - self.resume_exec() - rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) - self.assertEqual(rsn, exp_rsn) cur_frame = self.gdb.get_current_frame() - self.assertEqual(cur_frame['func'], func_name) - frames = self.gdb.get_backtrace() - self.assertTrue(len(frames) > 0) - self.assertEqual(frames[0]['func'], cur_frame['func']) - self.assertEqual(frames[0]['line'], cur_frame['line']) - outmost_frame = len(frames) - 1 - # Sometimes GDB does not provide full backtrace. so check this - # we can only check line numbers in 'blink_task', - # because its code is under control of test framework - if outmost_frame == 0 and func_name != 'blink_task': - return - # outermost frame should be in 'blink_task' function - self.assertEqual(frames[outmost_frame]['func'], 'blink_task') - self.gdb.select_frame(outmost_frame) - # read line number from variable and compare with what GDB provides - if len(lineno_var_prefs) == 1: - line_num = self.gdb.data_eval_expr('%s_break_ln' % lineno_var_prefs[0]) - self.assertEqual(frames[outmost_frame]['line'], line_num) - else: - # for tests which set multiple BPs/WPs and expect hits on both cores - # it is hard to predict the order of hits, - # so just check that debugger has stopped on one of the location - line_nums = [] - for p in lineno_var_prefs: - line_nums.append(self.gdb.data_eval_expr('%s_break_ln' % p)) - self.assertTrue(frames[outmost_frame]['line'] in line_nums) + self.assertEqual(cur_frame['func'], 'app_main') + + def readd_bps(self): + # remove all BPs except the first one + for i in range(1, len(self.bpns)): + self.gdb.delete_bp(self.bpns[i]) + self.bpns = self.bpns[:1] + # add removed BPs back + for i in range(1, len(self.bps)): + self.add_bp(self.bps[i]) def test_bp_add_remove_run(self): """ @@ -78,37 +103,21 @@ def test_bp_add_remove_run(self): 5) Check backtrace at the stop point. 6) Removes several breakpoints and adds them again. 7) Repeat steps 3-5 several times. - 8) Finally delete all breakpoints, resume execution and ensure that target is running. """ self.select_sub_test(100) - # 2 HW breaks + 1 flash SW break + RAM SW break - bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] - bpns = [] - for f in bps: - bpns.append(self.gdb.add_bp(f)) - def readd_bps(bps_nums, bps_names): - # remove all BPs except the first one - for i in range(1, len(bps_nums)): - self.gdb.delete_bp(bps_nums[i]) - bps_nums = bps_nums[:1] - # add removed BPs back - for i in range(1, len(bps_names)): - bps_nums.append(self.gdb.add_bp(bps_names[i])) - return bps_nums - bpns = readd_bps(bpns, bps) + for f in self.bps: + self.add_bp(f) + self.readd_bps() # break at gpio_set_direction self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'gpio_set_direction', ['gpio_set_direction']) - bpns = readd_bps(bpns, bps) + self.readd_bps() for i in range(2): # break at gpio_set_level self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'gpio_set_level', ['gpio_set_level%d' % (i % 2)]) - bpns = readd_bps(bpns, bps) + self.readd_bps() # break at vTaskDelay self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'vTaskDelay', ['vTaskDelay%d' % (i % 2)]) - bpns = readd_bps(bpns, bps) - for bpn in bpns: - self.gdb.delete_bp(bpn) - self.resume_exec() + self.readd_bps() def test_bp_ignore_count(self): """ @@ -120,17 +129,13 @@ def test_bp_ignore_count(self): 5) Check that conditioned breakpoint stopped the target only when its 'ignore count' is exceeded. 6) Check backtrace at the stop point. 7) Repeat steps 3-6 several times. - 8) Finally delete all breakpoints, resume execution and ensure that target is running. """ self.select_sub_test(100) - # 2 HW breaks + 1 flash SW break + RAM SW break - bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] - bpns = [] - for f in bps: + for f in self.bps: if f == 'vTaskDelay': - bpns.append(self.gdb.add_bp(f, ignore_count=2)) + self.add_bp(f, ignore_count=2) else: - bpns.append(self.gdb.add_bp(f)) + self.add_bp(f) # break at gpio_set_direction self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'gpio_set_direction', ['gpio_set_direction']) for i in range(3): @@ -139,9 +144,6 @@ def test_bp_ignore_count(self): if i > 1: # break at vTaskDelay self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'vTaskDelay', ['vTaskDelay%d' % (i % 2)]) - for bpn in bpns: - self.gdb.delete_bp(bpn) - self.resume_exec() def test_bp_cond_expr(self): """ @@ -153,17 +155,13 @@ def test_bp_cond_expr(self): 5) Check that conditioned breakpoint stopped the target only when its 'conditional expression' is true. 6) Check backtrace at the stop point. 7) Repeat steps 3-6 several times. - 8) Finally delete all breakpoints, resume execution and ensure that target is running. """ self.select_sub_test(100) - # 2 HW breaks + 1 flash SW break + RAM SW break - bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] - bpns = [] - for f in bps: + for f in self.bps: if f == 'vTaskDelay': - bpns.append(self.gdb.add_bp(f, cond='s_count1 == 1')) + self.add_bp(f, cond='s_count1 == 1') else: - bpns.append(self.gdb.add_bp(f)) + self.add_bp(f) # break at gpio_set_direction self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'gpio_set_direction', ['gpio_set_direction']) for i in range(6): @@ -173,9 +171,6 @@ def test_bp_cond_expr(self): if i == 2 or i == 3: # break at vTaskDelay self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_BP, 'vTaskDelay', ['vTaskDelay%d' % (i % 2)]) - for bpn in bpns: - self.gdb.delete_bp(bpn) - self.resume_exec() def test_bp_and_reconnect(self): """ @@ -189,30 +184,46 @@ def test_bp_and_reconnect(self): 6) Disconnect GDB from OOCD. 7) Connect GDB to OOCD. 8) Repeat steps 3-7 several times. - 9) Finally delete all breakpoints, resume execution and ensure that target is running. """ self.select_sub_test(100) - # self.gdb.monitor_run('esp32 setcores 1') - # 2 HW breaks + 1 flash SW break + RAM SW break - bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] - bpns = [] - for f in bps: - bpns.append(self.gdb.add_bp(f)) - for i in range(10): + for f in self.bps: + self.add_bp(f) + for i in range(5): self.resume_exec() rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_BP) cur_frame = self.gdb.get_current_frame() - self.assertTrue(cur_frame['func'] in bps) + self.assertTrue(cur_frame['func'] in self.bps) frames = self.gdb.get_backtrace() self.assertTrue(len(frames) > 0) self.assertEqual(frames[0]['func'], cur_frame['func']) self.assertEqual(frames[0]['line'], cur_frame['line']) self.gdb.disconnect() self.gdb.connect() - for bpn in bpns: - self.gdb.delete_bp(bpn) - self.resume_exec() + + def test_bp_in_isr(self): + """ + This test checks that the first several breakpoint's hits can be ignored: + 1) Select appropriate sub-test number on target. + 2) Set several breakpoints in ISR code to cover all types of them (HW, SW). + 3) Resume target and wait for brekpoints to hit. + 4) Check that target has stopped in the right place. + 5) Repeat steps 3-4 several times. + """ + # 2 HW breaks + 1 flash SW break + RAM SW break + self.bps = ['app_main', 'test_timer_isr', 'test_timer_isr_func', 'test_timer_isr_ram_func'] + self.select_sub_test(100) + for f in self.bps: + self.add_bp(f) + for i in range(3): + self.run_to_bp_and_check_basic(dbg.Gdb.TARGET_STOP_REASON_BP, 'test_timer_isr') + self.run_to_bp_and_check_basic(dbg.Gdb.TARGET_STOP_REASON_BP, 'test_timer_isr_func') + self.run_to_bp_and_check_basic(dbg.Gdb.TARGET_STOP_REASON_BP, 'test_timer_isr_ram_func') + + +class WatchpointTestsImpl(PoiTestsImpl): + """ Watchpoints test cases which are common for dual and single core modes + """ def test_wp_simple(self): """ @@ -224,19 +235,18 @@ def test_wp_simple(self): 5) Check backtrace at the stop point. 6) Check that watched expression has correct value. 7) Repeat steps 3-6 several times. - 8) Finally delete the watchpoint, resume execution and ensure that target is running. """ self.select_sub_test(100) - wps = {'s_count1': None} - for e in wps: - wps[e] = self.gdb.add_wp(e, 'rw') + self.wps = {'s_count1': None} + for e in self.wps: + self.add_wp(e, 'rw') cnt = 0 for i in range(3): # 'count' read self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_SIGTRAP, 'blink_task', ['s_count10']) var_val = int(self.gdb.data_eval_expr('s_count1')) self.assertEqual(var_val, cnt) - # 'count' write + # 'count' read self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_SIGTRAP, 'blink_task', ['s_count11']) var_val = int(self.gdb.data_eval_expr('s_count1')) self.assertEqual(var_val, cnt) @@ -245,9 +255,6 @@ def test_wp_simple(self): var_val = int(self.gdb.data_eval_expr('s_count1')) self.assertEqual(var_val, cnt) cnt += 1 - for _,wp in wps.items(): - self.gdb.delete_bp(wp) - self.resume_exec() def test_wp_and_reconnect(self): """ @@ -261,15 +268,14 @@ def test_wp_and_reconnect(self): 6) Disconnect GDB from OOCD. 7) Connect GDB to OOCD. 8) Repeat steps 3-7 several times. - 9) Finally delete all watchpoints, resume execution and ensure that target is running. """ self.select_sub_test(100) - wps = {'s_count1': None, 's_count2': None} + self.wps = {'s_count1': None, 's_count2': None} cnt = 0 cnt2 = 100 - for e in wps: - wps[e] = self.gdb.add_wp(e, 'w') - for i in range(10): + for e in self.wps: + self.add_wp(e, 'w') + for i in range(5): if (i % 2) == 0: self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_SIGTRAP, 'blink_task', ['s_count11']) var_val = int(self.gdb.data_eval_expr('s_count1')) @@ -282,9 +288,6 @@ def test_wp_and_reconnect(self): cnt2 -= 1 self.gdb.disconnect() self.gdb.connect() - for _,wp in wps.items(): - self.gdb.delete_bp(wp) - self.resume_exec() ######################################################################## @@ -295,6 +298,10 @@ class DebuggerBreakpointTestsDual(DebuggerGenericTestAppTestsDual, BreakpointTes """ Test cases for breakpoints in dual core mode """ + def setUp(self): + DebuggerGenericTestAppTestsDual.setUp(self) + BreakpointTestsImpl.setUp(self) + def test_2cores_concurrently_hit_bps(self): """ This test checks that 2 cores can concurrently hit the same set of breakpoints. @@ -304,27 +311,40 @@ def test_2cores_concurrently_hit_bps(self): 4) Check that target has stopped in the right place. 5) Check backtrace at the stop point. 6) Repeat steps 3-5 several times. - 7) Finally delete all the breakpoints, resume execution and ensure that target is running. + 7) Check that all set breakpoints hit one time at least. """ + hit_cnt = [0] * len(self.bps) self.select_sub_test(101) - # 2 HW breaks + 1 flash SW break + RAM SW break - bps = ['app_main', 'gpio_set_direction', 'gpio_set_level', 'vTaskDelay'] - bpns = [] - for f in bps: - bpns.append(self.gdb.add_bp(f)) - for i in range(10): + for f in self.bps: + self.add_bp(f) + for i in range(30): self.resume_exec() - rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 10) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_BP) cur_frame = self.gdb.get_current_frame() - self.assertTrue(cur_frame['func'] in bps) + self.assertTrue(cur_frame['func'] in self.bps) + f_idx = self.bps.index(cur_frame['func']) + hit_cnt[f_idx] += 1 frames = self.gdb.get_backtrace() self.assertTrue(len(frames) > 0) self.assertEqual(frames[0]['func'], cur_frame['func']) self.assertEqual(frames[0]['line'], cur_frame['line']) - for bpn in bpns: - self.gdb.delete_bp(bpn) - self.resume_exec() + for cnt in hit_cnt[1:]: + self.assertTrue(cnt > 0) + + +class DebuggerBreakpointTestsSingle(DebuggerGenericTestAppTestsSingle, BreakpointTestsImpl): + """ Test cases for breakpoints in single core mode + """ + + def setUp(self): + DebuggerGenericTestAppTestsSingle.setUp(self) + BreakpointTestsImpl.setUp(self) + + +class DebuggerWatchpointTestsDual(DebuggerGenericTestAppTestsDual, WatchpointTestsImpl): + """ Test cases for watchpoints in dual core mode + """ def test_2cores_concurrently_hit_wps(self): """ @@ -335,22 +355,18 @@ def test_2cores_concurrently_hit_wps(self): 4) Check that target has stopped in the right place. 5) Check backtrace at the stop point. 6) Repeat steps 3-5 several times. - 7) Finally delete all the watchpoints, resume execution and ensure that target is running. """ self.select_sub_test(101) - wps = {'s_count1': None, 's_count2': None} + self.wps = {'s_count1': None, 's_count2': None} cnt = 0 cnt2 = 100 - for e in wps: - wps[e] = self.gdb.add_wp(e, 'w') + for e in self.wps: + self.add_wp(e, 'w') for i in range(10): self.run_to_bp_and_check(dbg.Gdb.TARGET_STOP_REASON_SIGTRAP, 'blink_task', ['s_count11', 's_count2']) - for _,wp in wps.items(): - self.gdb.delete_bp(wp) - self.resume_exec() -class DebuggerBreakpointTestsSingle(DebuggerGenericTestAppTestsSingle, BreakpointTestsImpl): - """ Test cases for breakpoints in single core mode +class DebuggerWatchpointTestsSingle(DebuggerGenericTestAppTestsSingle, WatchpointTestsImpl): + """ Test cases for watchpoints in single core mode """ - pass \ No newline at end of file + pass diff --git a/testing/esp/test_step.py b/testing/esp/test_step.py index 6ac8aef2f..1b26a8aae 100644 --- a/testing/esp/test_step.py +++ b/testing/esp/test_step.py @@ -14,21 +14,91 @@ def get_logger(): # TESTS IMPLEMENTATION # ######################################################################## -class DebuggerStepTestsImpl: +class StepTestsImpl: """ Stepping test cases generic for dual and single core modes """ - @unittest.skip('not implemented') - def test_step(self): - pass + def do_step_over_bp_check(self, funcs): + self.resume_exec() + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_BP) + cur_frame = self.gdb.get_current_frame() + self.assertEqual(cur_frame['func'], funcs[0]) + old_pc = self.gdb.get_reg('pc') + self.gdb.exec_next_insn() # step over movi + self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_RUNNING, 5) + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_STEPPED) + new_pc = self.gdb.get_reg('pc') + self.assertTrue(((new_pc - old_pc) == 2) or ((new_pc - old_pc) == 3)) + old_pc = new_pc + self.gdb.exec_next_insn() # step over nop + self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_RUNNING, 5) + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_BP) + cur_frame = self.gdb.get_current_frame() + self.assertEqual(cur_frame['func'], funcs[1]) + new_pc = self.gdb.get_reg('pc') + self.assertTrue(((new_pc - old_pc) == 2) or ((new_pc - old_pc) == 3)) - @unittest.skip('not implemented') - def test_step_over_breakpoint(self): - pass + def test_step_over_bp(self): + """ + This test checks that debugger can step over breakpoint. + 1) Select appropriate sub-test number on target. + 2) Set several breakpoints to cover all types of them (HW, SW). Two BPs of every type. + 3) Resume target and wait for the first breakpoint to hit. + 4) Check that target has stopped in the right place. + 5) Performs step from stop point (to the second breakpoint of that type). + 6) Check that PC changed correctly. + 7) Repeat steps 3-6 several times for every type of breakpoints. + """ + bps = ['_step_over_bp_break1', '_step_over_bp_break2', # HW BPs + '_step_over_bp_break3', '_step_over_bp_break4', # SW flash BPs + '_step_over_bp_break5', '_step_over_bp_break6'] # SW RAM BPs + for f in bps: + self.add_bp(f) + self.select_sub_test(103) + for i in range(2): + # step from and over HW BPs + self.do_step_over_bp_check(['step_over_bp_task', '_step_over_bp_break2']) + # step from and over SW flash BPs + self.do_step_over_bp_check(['_step_over_bp_break3', '_step_over_bp_break4']) + # step from and over SW RAM BPs + self.do_step_over_bp_check(['dummy_iram_func', '_step_over_bp_break6']) + + def do_step_over_wp_check(self, func): + self.resume_exec() + rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) + self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_SIGTRAP) + cur_frame = self.gdb.get_current_frame() + self.assertEqual(cur_frame['func'], func) + old_pc = self.gdb.get_reg('pc') + self.gdb.exec_next_insn() + new_pc = self.gdb.get_reg('pc') + self.assertTrue(((new_pc - old_pc) == 2) or ((new_pc - old_pc) == 3)) - @unittest.skip('not implemented') - def test_step_after_active_thread_swicth(self): - pass + def test_step_over_wp(self): + """ + This test checks that debugger can step over triggered watchpoint. + 1) Select appropriate sub-test number on target. + 2) Set access watchpoint. + 3) Resume target and wait for watchpoint to hit. + 4) Check that target has stopped in the right place. + 5) Performs step from stop point. + 6) Check that PC changed correctly. + 7) Repeat steps 3-6 several times. + """ + self.wps = {'s_count1': None} + for e in self.wps: + self.add_wp(e, 'rw') + self.select_sub_test(100) + for i in range(2): + # 'count' read + self.do_step_over_wp_check('blink_task') + # 'count' read + self.do_step_over_wp_check('blink_task') + # 'count' write + self.do_step_over_wp_check('blink_task') def test_step_window_exception(self): # start the test, stopping at the window_exception_test function @@ -72,7 +142,7 @@ def test_step_over_insn_using_scratch_reg(self): """ self.select_sub_test(102) val = 100 - bp = self.gdb.add_bp('_scratch_reg_using_task_break') + self.add_bp('_scratch_reg_using_task_break') for i in range(5): self.resume_exec() rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) @@ -83,30 +153,27 @@ def test_step_over_insn_using_scratch_reg(self): self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_RUNNING, 5) rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_STEPPED) - reg_val = int(self.gdb.data_eval_expr('$a3')) + reg_val = self.gdb.get_reg('a3') self.assertEqual(reg_val, val) self.gdb.exec_next_insn() self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_RUNNING, 5) rsn = self.gdb.wait_target_state(dbg.Gdb.TARGET_STATE_STOPPED, 5) self.assertEqual(rsn, dbg.Gdb.TARGET_STOP_REASON_STEPPED) - reg_val = int(self.gdb.data_eval_expr('$a4')) + reg_val = self.gdb.get_reg('a4') self.assertEqual(reg_val, val) val += 1 - self.gdb.delete_bp(bp) - self.resume_exec() ######################################################################## # TESTS DEFINITION WITH SPECIAL TESTS # ######################################################################## -class DebuggerStepTestsDual(DebuggerGenericTestAppTestsDual, DebuggerStepTestsImpl): +class DebuggerStepTestsDual(DebuggerGenericTestAppTestsDual, StepTestsImpl): """ Test cases for dual core mode """ pass - -class DebuggerStepTestsSingle(DebuggerGenericTestAppTestsSingle, DebuggerStepTestsImpl): +class DebuggerStepTestsSingle(DebuggerGenericTestAppTestsSingle, StepTestsImpl): """ Test cases for single core mode """ pass