From 6a3c8ae67633a11fdd88c03095126d2a2a358e67 Mon Sep 17 00:00:00 2001 From: "Peter D. Gray" Date: Tue, 15 Apr 2025 10:06:16 -0400 Subject: [PATCH] New bootrom version releases --- stm32/COLDCARD_Q1/file_time.c | 6 +- stm32/MK4-Makefile | 4 +- stm32/Q1-Makefile | 4 +- stm32/mk4-bootloader/releases/3.2.1.txt | 4 + .../releases/3.2.1/bootloader.bin | Bin 0 -> 114688 bytes .../releases/3.2.1/bootloader.dfu | Bin 0 -> 114997 bytes .../releases/3.2.1/bootloader.lss | 34612 +++++++++++++++ stm32/q1-bootloader/releases/1.1.0.txt | 4 + .../releases/1.1.0/bootloader.bin | Bin 0 -> 114688 bytes .../releases/1.1.0/bootloader.dfu | Bin 0 -> 114997 bytes .../releases/1.1.0/bootloader.lss | 35454 ++++++++++++++++ 11 files changed, 70081 insertions(+), 7 deletions(-) create mode 100644 stm32/mk4-bootloader/releases/3.2.1.txt create mode 100644 stm32/mk4-bootloader/releases/3.2.1/bootloader.bin create mode 100644 stm32/mk4-bootloader/releases/3.2.1/bootloader.dfu create mode 100644 stm32/mk4-bootloader/releases/3.2.1/bootloader.lss create mode 100644 stm32/q1-bootloader/releases/1.1.0.txt create mode 100644 stm32/q1-bootloader/releases/1.1.0/bootloader.bin create mode 100644 stm32/q1-bootloader/releases/1.1.0/bootloader.dfu create mode 100644 stm32/q1-bootloader/releases/1.1.0/bootloader.lss diff --git a/stm32/COLDCARD_Q1/file_time.c b/stm32/COLDCARD_Q1/file_time.c index 9114d8bc..fa9c0306 100644 --- a/stm32/COLDCARD_Q1/file_time.c +++ b/stm32/COLDCARD_Q1/file_time.c @@ -2,12 +2,12 @@ // // AUTO-generated. // -// built: 2025-02-26 -// version: 1.4.0Q +// built: 2025-04-15 +// version: 1.3.2Q // #include // this overrides ports/stm32/fatfs_port.c uint32_t get_fattime(void) { - return 0x5a5a0880UL; + return 0x5a8f0860UL; } diff --git a/stm32/MK4-Makefile b/stm32/MK4-Makefile index e9ea2d56..4069613f 100644 --- a/stm32/MK4-Makefile +++ b/stm32/MK4-Makefile @@ -12,14 +12,14 @@ HW_MODEL = mk4 PARENT_MKFILE = MK4-Makefile # This is release of the bootloader that will be built into the factory.dfu -BOOTLOADER_VERSION = 3.2.0 +BOOTLOADER_VERSION = 3.2.1 BOOTLOADER_DIR = mk4-bootloader LATEST_RELEASE = $(shell ls -t1 ../releases/*-mk4-*.dfu | head -1) # Our version for this release. # - caution, the bootrom will not accept version < 3.0.0 -VERSION_STRING = 5.5.0 +VERSION_STRING = 5.4.2 # keep near top, because defined default target (all) include shared.mk diff --git a/stm32/Q1-Makefile b/stm32/Q1-Makefile index b6067ca8..f5dda365 100644 --- a/stm32/Q1-Makefile +++ b/stm32/Q1-Makefile @@ -10,13 +10,13 @@ HW_MODEL = q1 PARENT_MKFILE = Q1-Makefile # This is release of the bootloader that will be built into the factory.dfu -BOOTLOADER_VERSION = 1.0.4 +BOOTLOADER_VERSION = 1.1.0 BOOTLOADER_DIR = q1-bootloader LATEST_RELEASE = $(shell ls -t1 ../releases/*-q1-*.dfu | head -1) # Our version for this release. -VERSION_STRING = 1.4.0Q +VERSION_STRING = 1.3.2Q # Remove this closer to shipping. #$(warning "Forcing debug build") diff --git a/stm32/mk4-bootloader/releases/3.2.1.txt b/stm32/mk4-bootloader/releases/3.2.1.txt new file mode 100644 index 00000000..8f3fdd6b --- /dev/null +++ b/stm32/mk4-bootloader/releases/3.2.1.txt @@ -0,0 +1,4 @@ +0904b790af34c8acd8e3156cd5b4e818ae09e93611e90c673a7953fec67802d0 bootloader.dfu +7c7acbb849d17721f9a53b613d631f8bb8ed3b49c2bf5e1a413511c7d9105775 bootloader.bin +e71a730d2025bfcc0bf334614c60022e8df3d847c7c6a53f172aace004d69553 bootloader.lss +3.2.1 time=20250415.090935 git=master@adcf2c8e diff --git a/stm32/mk4-bootloader/releases/3.2.1/bootloader.bin b/stm32/mk4-bootloader/releases/3.2.1/bootloader.bin new file mode 100644 index 0000000000000000000000000000000000000000..964e8174bccce58583f1f51cdb4e64b4e52c013e GIT binary patch literal 114688 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 z?@!*k{L;l;`U8eQ z>$X)YWuA$TGwx8rn!Prjo22G7+Jxxxfff!-qgCKePP)OQ6LswTD67s~B2DcJTc`GD)Fonx#Lf&V5#!A5y^hu*bE0$x_o9`q zGpSD|O7F3KT$?Cri`Pl=*(`VsYP|j@o}Y*3fc-^JUeH=F|NI^ z55x@oE)&b76@6h#MqgOG|BFX^@pG?xA2LlS9#ymsuUyH_9F`yPYNYG%x|S#LH4Kt| zxgN`%hUetqYfMQK6Ir?Y!WC2Gt*=)0=wDF}Xrgt9#tuD_011!)36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg z011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!) z36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@ zkN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg t011!)36KB@kN^pg011!)36KB@kN^pg011!)36KB@kN^pg!2h$rzXA3r6|n#S literal 0 HcmV?d00001 diff --git a/stm32/mk4-bootloader/releases/3.2.1/bootloader.dfu b/stm32/mk4-bootloader/releases/3.2.1/bootloader.dfu new file mode 100644 index 0000000000000000000000000000000000000000..13784b5898e71a93c54c741cd5677940bf3d492b GIT binary patch literal 114997 zcmd?Sdw3K@)<0f-nVC)|mk9}wgg|;`0)!0UKoG)3oy>%0AV5IT7ZKNiAWjm52)d%a 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 literal 0 HcmV?d00001 diff --git a/stm32/mk4-bootloader/releases/3.2.1/bootloader.lss b/stm32/mk4-bootloader/releases/3.2.1/bootloader.lss new file mode 100644 index 00000000..a67725ce --- /dev/null +++ b/stm32/mk4-bootloader/releases/3.2.1/bootloader.lss @@ -0,0 +1,34612 @@ + +bootloader.elf: file format elf32-littlearm + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .text 0000ea48 08000000 08000000 00010000 2**8 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .relocate 00000150 2009e000 0800ea48 0002e000 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 2 .bss 000002e8 2009e150 0800eb98 0002e150 2**2 + ALLOC + 3 .stack 00000800 2009e438 0800ee80 0002e150 2**0 + ALLOC + 4 .debug_info 0002bc2d 00000000 00000000 0002e150 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 5 .debug_abbrev 00005f7a 00000000 00000000 00059d7d 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 6 .debug_loc 00014618 00000000 00000000 0005fcf7 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 7 .debug_aranges 000010c8 00000000 00000000 0007430f 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 8 .debug_ranges 00002148 00000000 00000000 000753d7 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 9 .debug_macro 00032533 00000000 00000000 0007751f 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 10 .debug_line 0001de5f 00000000 00000000 000a9a52 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 11 .debug_str 0011cbb0 00000000 00000000 000c78b1 2**0 + CONTENTS, READONLY, DEBUGGING, OCTETS + 12 .comment 00000049 00000000 00000000 001e4461 2**0 + CONTENTS, READONLY + 13 .ARM.attributes 00000032 00000000 00000000 001e44aa 2**0 + CONTENTS, READONLY + 14 .debug_frame 000036f4 00000000 00000000 001e44dc 2**2 + CONTENTS, READONLY, DEBUGGING, OCTETS + +Disassembly of section .text: + +08000000 <_sfixed>: + 8000000: 200a0000 .word 0x200a0000 + 8000004: 080000b5 .word 0x080000b5 + 8000008: 0800001d .word 0x0800001d + 800000c: 0800001f .word 0x0800001f + 8000010: 08000021 .word 0x08000021 + 8000014: 08000023 .word 0x08000023 + 8000018: 08000025 .word 0x08000025 + +0800001c : + 800001c: be01 bkpt 0x0001 + +0800001e : + 800001e: be02 bkpt 0x0002 + +08000020 : + 8000020: be03 bkpt 0x0003 + +08000022 : + 8000022: be04 bkpt 0x0004 + +08000024 : + 8000024: be05 bkpt 0x0005 + 8000026: e7fe b.n 8000026 + +08000028 : + ... + 8000040: 08000305 .word 0x08000305 + +08000044 : + 8000044: 00000200 .word 0x00000200 + ... + 8000060: 20296328 .word 0x20296328 + 8000064: 79706f43 .word 0x79706f43 + 8000068: 68676972 .word 0x68676972 + 800006c: 30322074 .word 0x30322074 + 8000070: 322d3831 .word 0x322d3831 + 8000074: 20323230 .word 0x20323230 + 8000078: 43207962 .word 0x43207962 + 800007c: 6b6e696f .word 0x6b6e696f + 8000080: 20657469 .word 0x20657469 + 8000084: 2e636e49 .word 0x2e636e49 + 8000088: 0a200a20 .word 0x0a200a20 + 800008c: 73696854 .word 0x73696854 + 8000090: 61707320 .word 0x61707320 + 8000094: 66206563 .word 0x66206563 + 8000098: 7220726f .word 0x7220726f + 800009c: 21746e65 .word 0x21746e65 + 80000a0: 73754a20 .word 0x73754a20 + 80000a4: 42312074 .word 0x42312074 + 80000a8: 792f4354 .word 0x792f4354 + 80000ac: 2e726165 .word 0x2e726165 + 80000b0: 0a200a20 .word 0x0a200a20 + +080000b4 : + 80000b4: f000 f816 bl 80000e4 + 80000b8: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 80000bc: f04f 0100 mov.w r1, #0 + 80000c0: f04f 0200 mov.w r2, #0 + 80000c4: f04f 0300 mov.w r3, #0 + 80000c8: f000 f91c bl 8000304 + 80000cc: f248 0120 movw r1, #32800 ; 0x8020 + 80000d0: ea4f 3101 mov.w r1, r1, lsl #12 + 80000d4: 6808 ldr r0, [r1, #0] + 80000d6: 4685 mov sp, r0 + 80000d8: f04f 0001 mov.w r0, #1 + 80000dc: f8d1 e004 ldr.w lr, [r1, #4] + 80000e0: 4770 bx lr + ... + +080000e4 : + void +firewall_setup(void) +{ + // This is critical: without the clock enabled to "SYSCFG" we + // can't tell the FW is enabled or not! Enabling it would also not work + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000e4: 4b1b ldr r3, [pc, #108] ; (8000154 ) +{ + 80000e6: b500 push {lr} + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000e8: 6e1a ldr r2, [r3, #96] ; 0x60 + 80000ea: f042 0201 orr.w r2, r2, #1 + 80000ee: 661a str r2, [r3, #96] ; 0x60 + 80000f0: 6e1b ldr r3, [r3, #96] ; 0x60 +{ + 80000f2: b08b sub sp, #44 ; 0x2c + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000f4: f003 0301 and.w r3, r3, #1 + 80000f8: 9300 str r3, [sp, #0] + 80000fa: 9b00 ldr r3, [sp, #0] + + if(__HAL_FIREWALL_IS_ENABLED()) { + 80000fc: 4b16 ldr r3, [pc, #88] ; (8000158 ) + 80000fe: 685b ldr r3, [r3, #4] + 8000100: 07db lsls r3, r3, #31 + 8000102: d524 bpl.n 800014e + // REMINDERS: + // - cannot debug anything in boot loader w/ firewall enabled (no readback, no bkpt) + // - when RDP=2, this protection still important or else python can read pairing secret + // - in factory mode (RDP!=2), it's nice to have this disabled so we can debug still + // - could look at RDP level here, but it would be harder to completely reset the bag number! + if(check_all_ones_raw(rom_secrets->bag_number, sizeof(rom_secrets->bag_number))) { + 8000104: 4815 ldr r0, [pc, #84] ; (800015c ) + 8000106: 2120 movs r1, #32 + 8000108: f002 faae bl 8002668 + 800010c: b9f8 cbnz r0, 800014e + // for debug builds, never enable firewall + return; +#endif + + extern int firewall_starts; // see startup.S ... aligned@256 (0x08000300) + uint32_t start = (uint32_t)&firewall_starts; + 800010e: 4b14 ldr r3, [pc, #80] ; (8000160 ) + uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE); + 8000110: 4a14 ldr r2, [pc, #80] ; (8000164 ) + // but sensitive stuff is still there (which would allow bypass) + // - so it's important to enable option bytes to set write-protect flash of entire bootloader + // - to disable debug and complete protection, must enable write-protect "level 2" (RDP=2) + // + + FIREWALL_InitTypeDef init = { + 8000112: 9302 str r3, [sp, #8] + uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE); + 8000114: 1ad3 subs r3, r2, r3 + FIREWALL_InitTypeDef init = { + 8000116: e9cd 3203 strd r3, r2, [sp, #12] + 800011a: f44f 4380 mov.w r3, #16384 ; 0x4000 + 800011e: e9cd 3005 strd r3, r0, [sp, #20] + 8000122: e9cd 0007 strd r0, r0, [sp, #28] + 8000126: 9009 str r0, [sp, #36] ; 0x24 + .VDataSegmentLength = 0, + .VolatileDataExecution = 0, + .VolatileDataShared = 0, + }; + + int rv = HAL_FIREWALL_Config((FIREWALL_InitTypeDef *)&init); + 8000128: a802 add r0, sp, #8 + 800012a: f000 f821 bl 8000170 + if(rv) { + 800012e: b110 cbz r0, 8000136 + INCONSISTENT("fw"); + 8000130: 480d ldr r0, [pc, #52] ; (8000168 ) + 8000132: f000 fc89 bl 8000a48 + } + + __HAL_FIREWALL_PREARM_DISABLE(); + 8000136: 4b0d ldr r3, [pc, #52] ; (800016c ) + 8000138: 6a1a ldr r2, [r3, #32] + 800013a: f022 0201 bic.w r2, r2, #1 + 800013e: 621a str r2, [r3, #32] + 8000140: 6a1b ldr r3, [r3, #32] + 8000142: f003 0301 and.w r3, r3, #1 + 8000146: 9301 str r3, [sp, #4] + 8000148: 9b01 ldr r3, [sp, #4] + HAL_FIREWALL_EnableFirewall(); + 800014a: f000 f88b bl 8000264 +} + 800014e: b00b add sp, #44 ; 0x2c + 8000150: f85d fb04 ldr.w pc, [sp], #4 + 8000154: 40021000 .word 0x40021000 + 8000158: 40010000 .word 0x40010000 + 800015c: 0801c050 .word 0x0801c050 + 8000160: 08000300 .word 0x08000300 + 8000164: 0801c000 .word 0x0801c000 + 8000168: 0800d700 .word 0x0800d700 + 800016c: 40011c00 .word 0x40011c00 + +08000170 : + * @param fw_init: Firewall initialization structure + * @note The API returns HAL_ERROR if the Firewall is already enabled. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init) +{ + 8000170: b573 push {r0, r1, r4, r5, r6, lr} + /* Check the Firewall initialization structure allocation */ + if(fw_init == NULL) + 8000172: b910 cbnz r0, 800017a + { + return HAL_ERROR; + 8000174: 2001 movs r0, #1 + /* Set Firewall Configuration Register VDE and VDS bits + (volatile data execution and shared configuration) */ + MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared); + + return HAL_OK; +} + 8000176: b002 add sp, #8 + 8000178: bd70 pop {r4, r5, r6, pc} + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 800017a: 4b19 ldr r3, [pc, #100] ; (80001e0 ) + 800017c: 6e1a ldr r2, [r3, #96] ; 0x60 + 800017e: f042 0280 orr.w r2, r2, #128 ; 0x80 + 8000182: 661a str r2, [r3, #96] ; 0x60 + 8000184: 6e1b ldr r3, [r3, #96] ; 0x60 + 8000186: f003 0380 and.w r3, r3, #128 ; 0x80 + 800018a: 9301 str r3, [sp, #4] + 800018c: 9b01 ldr r3, [sp, #4] + if (__HAL_FIREWALL_IS_ENABLED() != RESET) + 800018e: 4b15 ldr r3, [pc, #84] ; (80001e4 ) + 8000190: 685b ldr r3, [r3, #4] + 8000192: 07db lsls r3, r3, #31 + 8000194: d5ee bpl.n 8000174 + if (fw_init->CodeSegmentLength != 0U) + 8000196: 6841 ldr r1, [r0, #4] + if (fw_init->NonVDataSegmentLength < 0x100U) + 8000198: 68c2 ldr r2, [r0, #12] + if (fw_init->CodeSegmentLength != 0U) + 800019a: b109 cbz r1, 80001a0 + if (fw_init->NonVDataSegmentLength < 0x100U) + 800019c: 2aff cmp r2, #255 ; 0xff + 800019e: d9e9 bls.n 8000174 + WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress)); + 80001a0: 6803 ldr r3, [r0, #0] + 80001a2: 4e11 ldr r6, [pc, #68] ; (80001e8 ) + if (fw_init->VDataSegmentLength != 0U) + 80001a4: 6944 ldr r4, [r0, #20] + WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress)); + 80001a6: ea03 0506 and.w r5, r3, r6 + 80001aa: 4b10 ldr r3, [pc, #64] ; (80001ec ) + 80001ac: 601d str r5, [r3, #0] + WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength)); + 80001ae: 4d10 ldr r5, [pc, #64] ; (80001f0 ) + 80001b0: 4029 ands r1, r5 + 80001b2: 6059 str r1, [r3, #4] + WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress)); + 80001b4: 6881 ldr r1, [r0, #8] + WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength)); + 80001b6: 402a ands r2, r5 + WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress)); + 80001b8: 4031 ands r1, r6 + 80001ba: 6099 str r1, [r3, #8] + WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength)); + 80001bc: 60da str r2, [r3, #12] + WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress)); + 80001be: 6901 ldr r1, [r0, #16] + 80001c0: 4a0c ldr r2, [pc, #48] ; (80001f4 ) + 80001c2: 4011 ands r1, r2 + WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength)); + 80001c4: 4022 ands r2, r4 + WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress)); + 80001c6: 6119 str r1, [r3, #16] + WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength)); + 80001c8: 615a str r2, [r3, #20] + MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared); + 80001ca: e9d0 2006 ldrd r2, r0, [r0, #24] + 80001ce: 6a19 ldr r1, [r3, #32] + 80001d0: 4302 orrs r2, r0 + 80001d2: f021 0106 bic.w r1, r1, #6 + 80001d6: 430a orrs r2, r1 + 80001d8: 621a str r2, [r3, #32] + return HAL_OK; + 80001da: 2000 movs r0, #0 + 80001dc: e7cb b.n 8000176 + 80001de: bf00 nop + 80001e0: 40021000 .word 0x40021000 + 80001e4: 40010000 .word 0x40010000 + 80001e8: 00ffff00 .word 0x00ffff00 + 80001ec: 40011c00 .word 0x40011c00 + 80001f0: 003fff00 .word 0x003fff00 + 80001f4: 0003ffc0 .word 0x0003ffc0 + +080001f8 : +void HAL_FIREWALL_GetConfig(FIREWALL_InitTypeDef * fw_config) +{ + + /* Enable Firewall clock, in case no Firewall configuration has been carried + out up to this point */ + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 80001f8: 4b15 ldr r3, [pc, #84] ; (8000250 ) + 80001fa: 6e1a ldr r2, [r3, #96] ; 0x60 +{ + 80001fc: b573 push {r0, r1, r4, r5, r6, lr} + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 80001fe: f042 0280 orr.w r2, r2, #128 ; 0x80 + 8000202: 661a str r2, [r3, #96] ; 0x60 + 8000204: 6e1b ldr r3, [r3, #96] ; 0x60 + + /* Retrieve code segment protection setting */ + fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD); + 8000206: 4e13 ldr r6, [pc, #76] ; (8000254 ) + fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG); + 8000208: 4d13 ldr r5, [pc, #76] ; (8000258 ) + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 800020a: f003 0380 and.w r3, r3, #128 ; 0x80 + 800020e: 9301 str r3, [sp, #4] + 8000210: 9b01 ldr r3, [sp, #4] + fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD); + 8000212: 4b12 ldr r3, [pc, #72] ; (800025c ) + 8000214: 681a ldr r2, [r3, #0] + 8000216: 4032 ands r2, r6 + 8000218: 6002 str r2, [r0, #0] + fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG); + 800021a: 685c ldr r4, [r3, #4] + 800021c: 402c ands r4, r5 + 800021e: 6044 str r4, [r0, #4] + + /* Retrieve non volatile data segment protection setting */ + fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD); + 8000220: 6899 ldr r1, [r3, #8] + fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG); + + /* Retrieve volatile data segment protection setting */ + fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD); + 8000222: 4c0f ldr r4, [pc, #60] ; (8000260 ) + fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD); + 8000224: 4031 ands r1, r6 + 8000226: 6081 str r1, [r0, #8] + fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG); + 8000228: 68da ldr r2, [r3, #12] + 800022a: 402a ands r2, r5 + 800022c: 60c2 str r2, [r0, #12] + fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD); + 800022e: 6919 ldr r1, [r3, #16] + 8000230: 4021 ands r1, r4 + 8000232: 6101 str r1, [r0, #16] + fw_config->VDataSegmentLength = (READ_REG(FIREWALL->VDSL) & FW_VDSL_LENG); + 8000234: 695a ldr r2, [r3, #20] + 8000236: 4022 ands r2, r4 + 8000238: 6142 str r2, [r0, #20] + + /* Retrieve volatile data execution setting */ + fw_config->VolatileDataExecution = (READ_REG(FIREWALL->CR) & FW_CR_VDE); + 800023a: 6a1a ldr r2, [r3, #32] + 800023c: f002 0204 and.w r2, r2, #4 + 8000240: 6182 str r2, [r0, #24] + + /* Retrieve volatile data shared setting */ + fw_config->VolatileDataShared = (READ_REG(FIREWALL->CR) & FW_CR_VDS); + 8000242: 6a1b ldr r3, [r3, #32] + 8000244: f003 0302 and.w r3, r3, #2 + 8000248: 61c3 str r3, [r0, #28] + + return; +} + 800024a: b002 add sp, #8 + 800024c: bd70 pop {r4, r5, r6, pc} + 800024e: bf00 nop + 8000250: 40021000 .word 0x40021000 + 8000254: 00ffff00 .word 0x00ffff00 + 8000258: 003fff00 .word 0x003fff00 + 800025c: 40011c00 .word 0x40011c00 + 8000260: 0003ffc0 .word 0x0003ffc0 + +08000264 : + * @retval None + */ +void HAL_FIREWALL_EnableFirewall(void) +{ + /* Clears FWDIS bit of SYSCFG CFGR1 register */ + CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_FWDIS); + 8000264: 4a02 ldr r2, [pc, #8] ; (8000270 ) + 8000266: 6853 ldr r3, [r2, #4] + 8000268: f023 0301 bic.w r3, r3, #1 + 800026c: 6053 str r3, [r2, #4] + +} + 800026e: 4770 bx lr + 8000270: 40010000 .word 0x40010000 + +08000274 : + * @retval None + */ +void HAL_FIREWALL_EnablePreArmFlag(void) +{ + /* Set FPA bit */ + SET_BIT(FIREWALL->CR, FW_CR_FPA); + 8000274: 4a02 ldr r2, [pc, #8] ; (8000280 ) + 8000276: 6a13 ldr r3, [r2, #32] + 8000278: f043 0301 orr.w r3, r3, #1 + 800027c: 6213 str r3, [r2, #32] +} + 800027e: 4770 bx lr + 8000280: 40011c00 .word 0x40011c00 + +08000284 : + * @retval None + */ +void HAL_FIREWALL_DisablePreArmFlag(void) +{ + /* Clear FPA bit */ + CLEAR_BIT(FIREWALL->CR, FW_CR_FPA); + 8000284: 4a02 ldr r2, [pc, #8] ; (8000290 ) + 8000286: 6a13 ldr r3, [r2, #32] + 8000288: f023 0301 bic.w r3, r3, #1 + 800028c: 6213 str r3, [r2, #32] +} + 800028e: 4770 bx lr + 8000290: 40011c00 .word 0x40011c00 + ... + +08000300 <_firewall_start>: + 8000300: 0f193a11 .word 0x0f193a11 + +08000304 : + 8000304: f24e 0900 movw r9, #57344 ; 0xe000 + 8000308: f2c2 0909 movt r9, #8201 ; 0x2009 + 800030c: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 8000310: 44ca add sl, r9 + +08000312 : + 8000312: f849 ab04 str.w sl, [r9], #4 + 8000316: 45d1 cmp r9, sl + 8000318: d1fb bne.n 8000312 + 800031a: 46ea mov sl, sp + 800031c: 46cd mov sp, r9 + 800031e: e92d 4400 stmdb sp!, {sl, lr} + +08000322 : + 8000322: f000 f841 bl 80003a8 + 8000326: e8bd 4400 ldmia.w sp!, {sl, lr} + 800032a: 46d5 mov sp, sl + 800032c: f24e 0900 movw r9, #57344 ; 0xe000 + 8000330: f2c2 0909 movt r9, #8201 ; 0x2009 + 8000334: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 8000338: 44ca add sl, r9 + +0800033a : + 800033a: f849 0b04 str.w r0, [r9], #4 + 800033e: 45d1 cmp r9, sl + 8000340: d1fb bne.n 800033a + 8000342: 4770 bx lr + +08000344 <__NVIC_SystemReset>: + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); + 8000344: f3bf 8f4f dsb sy +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8000348: 4905 ldr r1, [pc, #20] ; (8000360 <__NVIC_SystemReset+0x1c>) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800034a: 4b06 ldr r3, [pc, #24] ; (8000364 <__NVIC_SystemReset+0x20>) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 800034c: 68ca ldr r2, [r1, #12] + 800034e: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8000352: 4313 orrs r3, r2 + 8000354: 60cb str r3, [r1, #12] + 8000356: f3bf 8f4f dsb sy + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + 800035a: bf00 nop + for(;;) /* wait until reset */ + 800035c: e7fd b.n 800035a <__NVIC_SystemReset+0x16> + 800035e: bf00 nop + 8000360: e000ed00 .word 0xe000ed00 + 8000364: 05fa0004 .word 0x05fa0004 + +08000368 : +good_addr(const uint8_t *b, int minlen, int len, bool readonly) +{ + uint32_t x = (uint32_t)b; + + if(minlen) { + if(!b) return EFAULT; // gave no buffer + 8000368: b198 cbz r0, 8000392 + if(len < minlen) return ERANGE; // too small + 800036a: 4291 cmp r1, r2 + 800036c: dc13 bgt.n 8000396 + } + + if((x >= SRAM1_BASE) && ((x+len) <= BL_SRAM_BASE)) { + 800036e: f1b0 5f00 cmp.w r0, #536870912 ; 0x20000000 + 8000372: d303 bcc.n 800037c + 8000374: 490b ldr r1, [pc, #44] ; (80003a4 ) + 8000376: 4402 add r2, r0 + 8000378: 428a cmp r2, r1 + 800037a: d90e bls.n 800039a + // ok: it's inside the SRAM areas, up to where we start + return 0; + } + + if(!readonly) { + 800037c: b17b cbz r3, 800039e + return EPERM; + } + + if((x >= FIRMWARE_START) && (x - FIRMWARE_START) < FW_MAX_LENGTH_MK4) { + 800037e: f100 4077 add.w r0, r0, #4143972352 ; 0xf7000000 + 8000382: f500 007e add.w r0, r0, #16646144 ; 0xfe0000 + // inside flash of main firmware (happens for QSTR's) + return 0; + } + + return EACCES; + 8000386: f5b0 1ff0 cmp.w r0, #1966080 ; 0x1e0000 + 800038a: bf34 ite cc + 800038c: 2000 movcc r0, #0 + 800038e: 200d movcs r0, #13 + 8000390: 4770 bx lr + if(!b) return EFAULT; // gave no buffer + 8000392: 200e movs r0, #14 + 8000394: 4770 bx lr + if(len < minlen) return ERANGE; // too small + 8000396: 2022 movs r0, #34 ; 0x22 + 8000398: 4770 bx lr + return 0; + 800039a: 2000 movs r0, #0 + 800039c: 4770 bx lr + return EPERM; + 800039e: 2001 movs r0, #1 +} + 80003a0: 4770 bx lr + 80003a2: bf00 nop + 80003a4: 2009e000 .word 0x2009e000 + +080003a8 : +// + __attribute__ ((used)) + int +firewall_dispatch(int method_num, uint8_t *buf_io, int len_in, + uint32_t arg2, uint32_t incoming_sp, uint32_t incoming_lr) +{ + 80003a8: b570 push {r4, r5, r6, lr} + 80003aa: b09e sub sp, #120 ; 0x78 + 80003ac: 460d mov r5, r1 + 80003ae: 9c23 ldr r4, [sp, #140] ; 0x8c + 80003b0: 9301 str r3, [sp, #4] + __ASM volatile ("cpsid i" : : : "memory"); + 80003b2: b672 cpsid i + // in case the caller didn't already, but would just lead to a crash anyway + __disable_irq(); + + // "1=any code executed outside the protected segment will close the Firewall" + // "0=.. will reset the processor" + __HAL_FIREWALL_PREARM_DISABLE(); + 80003b4: 4ba5 ldr r3, [pc, #660] ; (800064c ) + 80003b6: 6a19 ldr r1, [r3, #32] + 80003b8: f021 0101 bic.w r1, r1, #1 + 80003bc: 6219 str r1, [r3, #32] + 80003be: 6a1b ldr r3, [r3, #32] + 80003c0: f003 0301 and.w r3, r3, #1 + 80003c4: 9302 str r3, [sp, #8] + // using read/write in place. + // - use arg2 use when a simple number is needed; never a pointer! + // - mpy may provide a pointer to flash if we give it a qstr or small value, and if + // we're reading only, that's fine. + + if(len_in > 1024) { // arbitrary max, increase as needed + 80003c6: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + __HAL_FIREWALL_PREARM_DISABLE(); + 80003ca: 9b02 ldr r3, [sp, #8] + if(len_in > 1024) { // arbitrary max, increase as needed + 80003cc: f300 82e3 bgt.w 8000996 + + // Use these macros +#define REQUIRE_IN_ONLY(x) if((rv = good_addr(buf_io, (x), len_in, true))) { goto fail; } +#define REQUIRE_OUT(x) if((rv = good_addr(buf_io, (x), len_in, false))) { goto fail; } + + switch(method_num) { + 80003d0: 3001 adds r0, #1 + 80003d2: 281c cmp r0, #28 + 80003d4: f200 81b6 bhi.w 8000744 + 80003d8: e8df f010 tbh [pc, r0, lsl #1] + 80003dc: 001d02f9 .word 0x001d02f9 + 80003e0: 00800034 .word 0x00800034 + 80003e4: 00d100bd .word 0x00d100bd + 80003e8: 01f300f2 .word 0x01f300f2 + 80003ec: 01b401b4 .word 0x01b401b4 + 80003f0: 01b401b4 .word 0x01b401b4 + 80003f4: 00fa01b4 .word 0x00fa01b4 + 80003f8: 01b401b4 .word 0x01b401b4 + 80003fc: 01240105 .word 0x01240105 + 8000400: 01670154 .word 0x01670154 + 8000404: 01f701ab .word 0x01f701ab + 8000408: 025f0206 .word 0x025f0206 + 800040c: 02b702a2 .word 0x02b702a2 + 8000410: 02cf02bf .word 0x02cf02bf + 8000414: 02eb .short 0x02eb + case 0: { + REQUIRE_OUT(64); + 8000416: 2300 movs r3, #0 + 8000418: 2140 movs r1, #64 ; 0x40 + 800041a: 4628 mov r0, r5 + 800041c: 9200 str r2, [sp, #0] + 800041e: f7ff ffa3 bl 8000368 + 8000422: 4604 mov r4, r0 + 8000424: bb48 cbnz r0, 800047a + + // Return my version string + memset(buf_io, 0, len_in); + 8000426: 4601 mov r1, r0 + 8000428: 9a00 ldr r2, [sp, #0] + 800042a: 4628 mov r0, r5 + 800042c: f00d f922 bl 800d674 + strlcpy((char *)buf_io, version_string, len_in); + 8000430: 9a00 ldr r2, [sp, #0] + 8000432: 4987 ldr r1, [pc, #540] ; (8000650 ) + 8000434: 4628 mov r0, r5 + 8000436: f00d f93b bl 800d6b0 + + rv = strlen(version_string); + 800043a: 4885 ldr r0, [pc, #532] ; (8000650 ) + 800043c: f00d f94d bl 800d6da + ae_setup(); + ae_keep_alive(); + switch(arg2) { + default: + case 0: // read state + rv = ae_get_gpio(); + 8000440: 4604 mov r4, r0 + break; + 8000442: e01a b.n 800047a + REQUIRE_OUT(32); + 8000444: 2300 movs r3, #0 + 8000446: 2120 movs r1, #32 + 8000448: 4628 mov r0, r5 + 800044a: f7ff ff8d bl 8000368 + 800044e: 4604 mov r4, r0 + 8000450: b998 cbnz r0, 800047a + sha256_init(&ctx); + 8000452: a80b add r0, sp, #44 ; 0x2c + 8000454: f005 f81a bl 800548c + sha256_update(&ctx, (void *)&arg2, 4); + 8000458: 2204 movs r2, #4 + 800045a: eb0d 0102 add.w r1, sp, r2 + 800045e: a80b add r0, sp, #44 ; 0x2c + 8000460: f005 f822 bl 80054a8 + sha256_update(&ctx, (void *)BL_FLASH_BASE, BL_FLASH_SIZE); + 8000464: f04f 6100 mov.w r1, #134217728 ; 0x8000000 + 8000468: a80b add r0, sp, #44 ; 0x2c + 800046a: f44f 32e0 mov.w r2, #114688 ; 0x1c000 + 800046e: f005 f81b bl 80054a8 + sha256_final(&ctx, buf_io); + 8000472: 4629 mov r1, r5 + 8000474: a80b add r0, sp, #44 ; 0x2c + 8000476: f005 f85d bl 8005534 + +fail: + + // Precaution: we don't want to leave SE1 authorized for any specific keys, + // perhaps due to an error path we didn't see. Always reset the chip. + ae_reset_chip(); + 800047a: f002 fa95 bl 80029a8 + + // Unlikely it matters, but clear flash memory cache. + __HAL_FLASH_DATA_CACHE_DISABLE(); + 800047e: 4b75 ldr r3, [pc, #468] ; (8000654 ) + 8000480: 681a ldr r2, [r3, #0] + 8000482: f422 6280 bic.w r2, r2, #1024 ; 0x400 + 8000486: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_RESET(); + 8000488: 681a ldr r2, [r3, #0] + 800048a: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800048e: 601a str r2, [r3, #0] + 8000490: 681a ldr r2, [r3, #0] + 8000492: f422 5280 bic.w r2, r2, #4096 ; 0x1000 + 8000496: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); + 8000498: 681a ldr r2, [r3, #0] + 800049a: f442 6280 orr.w r2, r2, #1024 ; 0x400 + 800049e: 601a str r2, [r3, #0] + + // .. and instruction memory (flash cache too?) + __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); + 80004a0: 681a ldr r2, [r3, #0] + 80004a2: f422 7200 bic.w r2, r2, #512 ; 0x200 + 80004a6: 601a str r2, [r3, #0] + __HAL_FLASH_INSTRUCTION_CACHE_RESET(); + 80004a8: 681a ldr r2, [r3, #0] + 80004aa: f442 6200 orr.w r2, r2, #2048 ; 0x800 + 80004ae: 601a str r2, [r3, #0] + 80004b0: 681a ldr r2, [r3, #0] + 80004b2: f422 6200 bic.w r2, r2, #2048 ; 0x800 + 80004b6: 601a str r2, [r3, #0] + __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); + 80004b8: 681a ldr r2, [r3, #0] + 80004ba: f442 7200 orr.w r2, r2, #512 ; 0x200 + 80004be: 601a str r2, [r3, #0] + + // authorize return from firewall into user's code + __HAL_FIREWALL_PREARM_ENABLE(); + 80004c0: f5a3 3382 sub.w r3, r3, #66560 ; 0x10400 + + return rv; +} + 80004c4: 4620 mov r0, r4 + __HAL_FIREWALL_PREARM_ENABLE(); + 80004c6: 6a1a ldr r2, [r3, #32] + 80004c8: f042 0201 orr.w r2, r2, #1 + 80004cc: 621a str r2, [r3, #32] + 80004ce: 6a1b ldr r3, [r3, #32] + 80004d0: f003 0301 and.w r3, r3, #1 + 80004d4: 930b str r3, [sp, #44] ; 0x2c + 80004d6: 9b0b ldr r3, [sp, #44] ; 0x2c +} + 80004d8: b01e add sp, #120 ; 0x78 + 80004da: bd70 pop {r4, r5, r6, pc} +// Write bag number (probably a string) +void flash_save_bag_number(const uint8_t new_number[32]); + +// Are we operating in level2? +static inline bool flash_is_security_level2(void) { + rng_delay(); + 80004dc: f002 f94e bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 80004e0: 4b5c ldr r3, [pc, #368] ; (8000654 ) + 80004e2: 6a1b ldr r3, [r3, #32] + 80004e4: b2db uxtb r3, r3 + 80004e6: f1a3 02cc sub.w r2, r3, #204 ; 0xcc + 80004ea: 4255 negs r5, r2 + 80004ec: 4155 adcs r5, r2 + switch(arg2) { + 80004ee: 9a01 ldr r2, [sp, #4] + 80004f0: 2a02 cmp r2, #2 + 80004f2: d01c beq.n 800052e + 80004f4: 2a03 cmp r2, #3 + 80004f6: d01f beq.n 8000538 + 80004f8: 2a01 cmp r2, #1 + 80004fa: d013 beq.n 8000524 + if(secure) { + 80004fc: 2bcc cmp r3, #204 ; 0xcc + 80004fe: f000 8216 beq.w 800092e + puts("Die: DFU"); + 8000502: 4855 ldr r0, [pc, #340] ; (8000658 ) + scr = screen_upgrading; // was screen_dfu, but limited audience + 8000504: 4c55 ldr r4, [pc, #340] ; (800065c ) + puts("Die: DFU"); + 8000506: f004 fc51 bl 8004dac + bool secure = flash_is_security_level2(); + 800050a: 2500 movs r5, #0 + oled_setup(); + 800050c: f000 fc0a bl 8000d24 + oled_show(scr); + 8000510: 4620 mov r0, r4 + 8000512: f000 fc97 bl 8000e44 + wipe_all_sram(); + 8000516: f000 fa77 bl 8000a08 + psram_wipe(); + 800051a: f004 fd6f bl 8004ffc + if(secure) { + 800051e: b18d cbz r5, 8000544 + LOCKUP_FOREVER(); + 8000520: bf30 wfi + 8000522: e7fd b.n 8000520 + puts("Die: Downgrade"); + 8000524: 484e ldr r0, [pc, #312] ; (8000660 ) + scr = screen_downgrade; + 8000526: 4c4f ldr r4, [pc, #316] ; (8000664 ) + puts("Die: Downgrade"); + 8000528: f004 fc40 bl 8004dac + break; + 800052c: e7ee b.n 800050c + puts("Die: Blankish"); + 800052e: 484e ldr r0, [pc, #312] ; (8000668 ) + scr = screen_blankish; + 8000530: 4c4e ldr r4, [pc, #312] ; (800066c ) + puts("Die: Blankish"); + 8000532: f004 fc3b bl 8004dac + break; + 8000536: e7e9 b.n 800050c + puts("Die: Brick"); + 8000538: 484d ldr r0, [pc, #308] ; (8000670 ) + scr = screen_brick; + 800053a: 4c4e ldr r4, [pc, #312] ; (8000674 ) + puts("Die: Brick"); + 800053c: f004 fc36 bl 8004dac + secure = true; // no point going into DFU, if even possible + 8000540: 2501 movs r5, #1 + break; + 8000542: e7e3 b.n 800050c + memcpy(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)); + 8000544: 494c ldr r1, [pc, #304] ; (8000678 ) + 8000546: 4a4d ldr r2, [pc, #308] ; (800067c ) + 8000548: 6808 ldr r0, [r1, #0] + 800054a: 6849 ldr r1, [r1, #4] + 800054c: 4613 mov r3, r2 + 800054e: c303 stmia r3!, {r0, r1} + dfu_flag->screen = scr; + 8000550: 6094 str r4, [r2, #8] + NVIC_SystemReset(); + 8000552: f7ff fef7 bl 8000344 <__NVIC_SystemReset> + switch(arg2) { + 8000556: 9b01 ldr r3, [sp, #4] + 8000558: f033 0302 bics.w r3, r3, #2 + 800055c: d102 bne.n 8000564 + oled_show(screen_logout); + 800055e: 4848 ldr r0, [pc, #288] ; (8000680 ) + 8000560: f000 fc70 bl 8000e44 + wipe_all_sram(); + 8000564: f000 fa50 bl 8000a08 + psram_wipe(); + 8000568: f004 fd48 bl 8004ffc + if(arg2 == 2) { + 800056c: 9b01 ldr r3, [sp, #4] + 800056e: 2b02 cmp r3, #2 + 8000570: d103 bne.n 800057a + delay_ms(100); + 8000572: 2064 movs r0, #100 ; 0x64 + 8000574: f003 f9c0 bl 80038f8 + 8000578: e7eb b.n 8000552 + LOCKUP_FOREVER(); + 800057a: bf30 wfi + 800057c: e7fd b.n 800057a + ae_setup(); + 800057e: f002 fa21 bl 80029c4 + ae_keep_alive(); + 8000582: f002 fa51 bl 8002a28 + switch(arg2) { + 8000586: 9b01 ldr r3, [sp, #4] + 8000588: 2b02 cmp r3, #2 + 800058a: d00a beq.n 80005a2 + 800058c: 2b03 cmp r3, #3 + 800058e: d00a beq.n 80005a6 + 8000590: 2b01 cmp r3, #1 + 8000592: d002 beq.n 800059a + rv = ae_get_gpio(); + 8000594: f002 ffc6 bl 8003524 + 8000598: e752 b.n 8000440 + rv = ae_set_gpio(0); + 800059a: 2000 movs r0, #0 + rv = ae_set_gpio(1); + 800059c: f002 ff94 bl 80034c8 + 80005a0: e74e b.n 8000440 + 80005a2: 2001 movs r0, #1 + 80005a4: e7fa b.n 800059c + checksum_flash(fw_digest, world_digest, 0); + 80005a6: 2200 movs r2, #0 + 80005a8: a90b add r1, sp, #44 ; 0x2c + 80005aa: a803 add r0, sp, #12 + 80005ac: f001 fa44 bl 8001a38 + rv = ae_set_gpio_secure(world_digest); + 80005b0: a80b add r0, sp, #44 ; 0x2c + 80005b2: f002 ff9f bl 80034f4 + 80005b6: 4604 mov r4, r0 + oled_show(screen_blankish); + 80005b8: 482c ldr r0, [pc, #176] ; (800066c ) + 80005ba: f000 fc43 bl 8000e44 + break; + 80005be: e75c b.n 800047a + ae_setup(); + 80005c0: f002 fa00 bl 80029c4 + rv = (ae_pair_unlock() != 0); + 80005c4: f002 fbf4 bl 8002db0 + 80005c8: 1e04 subs r4, r0, #0 + 80005ca: bf18 it ne + 80005cc: 2401 movne r4, #1 + break; + 80005ce: e754 b.n 800047a + REQUIRE_OUT(1); + 80005d0: 2300 movs r3, #0 + 80005d2: 2101 movs r1, #1 + 80005d4: 4628 mov r0, r5 + 80005d6: f7ff fec7 bl 8000368 + 80005da: 4604 mov r4, r0 + 80005dc: 2800 cmp r0, #0 + 80005de: f47f af4c bne.w 800047a + buf_io[0] = 0; // NOT SUPPORTED on Mk4 + 80005e2: 7028 strb r0, [r5, #0] + break; + 80005e4: e749 b.n 800047a + if(len_in != 4 && len_in != 32 && len_in != 72) { + 80005e6: 2a04 cmp r2, #4 + 80005e8: d004 beq.n 80005f4 + 80005ea: 2a20 cmp r2, #32 + 80005ec: d002 beq.n 80005f4 + 80005ee: 2a48 cmp r2, #72 ; 0x48 + 80005f0: f040 81d1 bne.w 8000996 + REQUIRE_OUT(4); + 80005f4: 2300 movs r3, #0 + 80005f6: 2104 movs r1, #4 + 80005f8: 4628 mov r0, r5 + 80005fa: 9200 str r2, [sp, #0] + 80005fc: f7ff feb4 bl 8000368 + 8000600: 4604 mov r4, r0 + 8000602: 2800 cmp r0, #0 + 8000604: f47f af39 bne.w 800047a + ae_setup(); + 8000608: f002 f9dc bl 80029c4 + if(ae_read_data_slot(arg2 & 0xf, buf_io, len_in)) { + 800060c: 9801 ldr r0, [sp, #4] + 800060e: 9a00 ldr r2, [sp, #0] + 8000610: 4629 mov r1, r5 + 8000612: f000 000f and.w r0, r0, #15 + 8000616: f002 ff11 bl 800343c + if(rv) { + 800061a: 2800 cmp r0, #0 + 800061c: f000 80d1 beq.w 80007c2 + rv = EIO; + 8000620: 2405 movs r4, #5 + 8000622: e72a b.n 800047a + REQUIRE_OUT(MAX_PIN_LEN); + 8000624: 2300 movs r3, #0 + 8000626: 2120 movs r1, #32 + 8000628: 4628 mov r0, r5 + 800062a: f7ff fe9d bl 8000368 + 800062e: 4604 mov r4, r0 + 8000630: 2800 cmp r0, #0 + 8000632: f47f af22 bne.w 800047a + if((arg2 < 1) || (arg2 > MAX_PIN_LEN)) { + 8000636: 9901 ldr r1, [sp, #4] + 8000638: 1e4b subs r3, r1, #1 + 800063a: 2b1f cmp r3, #31 + 800063c: f200 81ab bhi.w 8000996 + if(pin_prefix_words((char *)buf_io, arg2, (uint32_t *)buf_io)) { + 8000640: 462a mov r2, r5 + 8000642: 4628 mov r0, r5 + 8000644: f003 fc5c bl 8003f00 + 8000648: e7e7 b.n 800061a + 800064a: bf00 nop + 800064c: 40011c00 .word 0x40011c00 + 8000650: 0800e720 .word 0x0800e720 + 8000654: 40022000 .word 0x40022000 + 8000658: 0800d706 .word 0x0800d706 + 800065c: 0800e18b .word 0x0800e18b + 8000660: 0800d70f .word 0x0800d70f + 8000664: 0800da7a .word 0x0800da7a + 8000668: 0800d71e .word 0x0800d71e + 800066c: 0800d7de .word 0x0800d7de + 8000670: 0800d72c .word 0x0800d72c + 8000674: 0800d80b .word 0x0800d80b + 8000678: 0800d737 .word 0x0800d737 + 800067c: 20008000 .word 0x20008000 + 8000680: 0800db96 .word 0x0800db96 + REQUIRE_OUT(32); + 8000684: 2300 movs r3, #0 + 8000686: 2120 movs r1, #32 + 8000688: 4628 mov r0, r5 + 800068a: f7ff fe6d bl 8000368 + 800068e: 4604 mov r4, r0 + 8000690: 2800 cmp r0, #0 + 8000692: f47f aef2 bne.w 800047a + memset(buf_io, 0x55, 32); // to help show errors + 8000696: 2220 movs r2, #32 + 8000698: 2155 movs r1, #85 ; 0x55 + 800069a: 4628 mov r0, r5 + 800069c: f00c ffea bl 800d674 + rng_buffer(buf_io, 32); + 80006a0: 2120 movs r1, #32 + 80006a2: 4628 mov r0, r5 + 80006a4: f002 f854 bl 8002750 + break; + 80006a8: e6e7 b.n 800047a + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2); + 80006aa: 2300 movs r3, #0 + 80006ac: f44f 718c mov.w r1, #280 ; 0x118 + 80006b0: 4628 mov r0, r5 + 80006b2: 9200 str r2, [sp, #0] + 80006b4: f7ff fe58 bl 8000368 + 80006b8: 4604 mov r4, r0 + 80006ba: 2800 cmp r0, #0 + 80006bc: f47f aedd bne.w 800047a + switch(arg2) { + 80006c0: e9dd 2300 ldrd r2, r3, [sp] + 80006c4: 2b08 cmp r3, #8 + 80006c6: d83d bhi.n 8000744 + 80006c8: e8df f003 tbb [pc, r3] + 80006cc: 110d0905 .word 0x110d0905 + 80006d0: 221d1915 .word 0x221d1915 + 80006d4: 26 .byte 0x26 + 80006d5: 00 .byte 0x00 + rv = pin_setup_attempt(args); + 80006d6: 4628 mov r0, r5 + 80006d8: f003 fc30 bl 8003f3c + 80006dc: e6b0 b.n 8000440 + rv = pin_delay(args); + 80006de: 4628 mov r0, r5 + 80006e0: f003 fc9a bl 8004018 + 80006e4: e6ac b.n 8000440 + rv = pin_login_attempt(args); + 80006e6: 4628 mov r0, r5 + 80006e8: f003 fc98 bl 800401c + 80006ec: e6a8 b.n 8000440 + rv = pin_change(args); + 80006ee: 4628 mov r0, r5 + 80006f0: f003 fda2 bl 8004238 + 80006f4: e6a4 b.n 8000440 + rv = pin_fetch_secret(args); + 80006f6: 4628 mov r0, r5 + 80006f8: f003 fe56 bl 80043a8 + 80006fc: e6a0 b.n 8000440 + rv = pin_firmware_greenlight(args); + 80006fe: 4628 mov r0, r5 + 8000700: f004 f812 bl 8004728 + 8000704: e69c b.n 8000440 + rv = pin_long_secret(args, NULL); + 8000706: 2100 movs r1, #0 + rv = pin_long_secret(args, &buf_io[PIN_ATTEMPT_SIZE_V2]); + 8000708: 4628 mov r0, r5 + 800070a: f003 ff4f bl 80045ac + 800070e: e697 b.n 8000440 + rv = pin_firmware_upgrade(args); + 8000710: 4628 mov r0, r5 + 8000712: f004 f849 bl 80047a8 + 8000716: e693 b.n 8000440 + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2 + AE_LONG_SECRET_LEN); + 8000718: 2300 movs r3, #0 + 800071a: f44f 712e mov.w r1, #696 ; 0x2b8 + 800071e: 4628 mov r0, r5 + 8000720: f7ff fe22 bl 8000368 + 8000724: 4604 mov r4, r0 + 8000726: 2800 cmp r0, #0 + 8000728: f47f aea7 bne.w 800047a + rv = pin_long_secret(args, &buf_io[PIN_ATTEMPT_SIZE_V2]); + 800072c: f505 718c add.w r1, r5, #280 ; 0x118 + 8000730: e7ea b.n 8000708 + switch(arg2) { + 8000732: 9b01 ldr r3, [sp, #4] + 8000734: 2b64 cmp r3, #100 ; 0x64 + 8000736: d041 beq.n 80007bc + 8000738: d806 bhi.n 8000748 + 800073a: 2b01 cmp r3, #1 + 800073c: d01e beq.n 800077c + 800073e: 2b02 cmp r3, #2 + 8000740: d028 beq.n 8000794 + 8000742: b13b cbz r3, 8000754 + 8000744: 2402 movs r4, #2 + 8000746: e698 b.n 800047a + 8000748: 2b65 cmp r3, #101 ; 0x65 + 800074a: d03c beq.n 80007c6 + 800074c: 2b66 cmp r3, #102 ; 0x66 + 800074e: d1f9 bne.n 8000744 + flash_lockdown_hard(OB_RDP_LEVEL_2); // No change possible after this. + 8000750: 20cc movs r0, #204 ; 0xcc + 8000752: e034 b.n 80007be + REQUIRE_OUT(32); + 8000754: 2120 movs r1, #32 + 8000756: 4628 mov r0, r5 + 8000758: f7ff fe06 bl 8000368 + 800075c: 4604 mov r4, r0 + 800075e: 2800 cmp r0, #0 + 8000760: f47f ae8b bne.w 800047a + memcpy(buf_io, rom_secrets->bag_number, 32); + 8000764: 4aa1 ldr r2, [pc, #644] ; (80009ec ) + 8000766: 4ea2 ldr r6, [pc, #648] ; (80009f0 ) + 8000768: 4613 mov r3, r2 + 800076a: cb03 ldmia r3!, {r0, r1} + 800076c: 42b3 cmp r3, r6 + 800076e: 6028 str r0, [r5, #0] + 8000770: 6069 str r1, [r5, #4] + 8000772: 461a mov r2, r3 + 8000774: f105 0508 add.w r5, r5, #8 + 8000778: d1f6 bne.n 8000768 + 800077a: e67e b.n 800047a + REQUIRE_IN_ONLY(32); + 800077c: 2120 movs r1, #32 + 800077e: 4628 mov r0, r5 + 8000780: f7ff fdf2 bl 8000368 + 8000784: 4604 mov r4, r0 + 8000786: 2800 cmp r0, #0 + 8000788: f47f ae77 bne.w 800047a + flash_save_bag_number(buf_io); + 800078c: 4628 mov r0, r5 + 800078e: f001 fcf9 bl 8002184 + break; + 8000792: e672 b.n 800047a + REQUIRE_OUT(1); + 8000794: 2300 movs r3, #0 + 8000796: 2101 movs r1, #1 + 8000798: 4628 mov r0, r5 + 800079a: f7ff fde5 bl 8000368 + 800079e: 4604 mov r4, r0 + 80007a0: 2800 cmp r0, #0 + 80007a2: f47f ae6a bne.w 800047a + rng_delay(); + 80007a6: f001 ffe9 bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 80007aa: 4b92 ldr r3, [pc, #584] ; (80009f4 ) + 80007ac: 6a1b ldr r3, [r3, #32] + 80007ae: b2db uxtb r3, r3 + buf_io[0] = (flash_is_security_level2() ? 2 : 0xff); + 80007b0: 2bcc cmp r3, #204 ; 0xcc + 80007b2: bf0c ite eq + 80007b4: 2302 moveq r3, #2 + 80007b6: 23ff movne r3, #255 ; 0xff + buf_io[0] = 32; + 80007b8: 702b strb r3, [r5, #0] + break; + 80007ba: e65e b.n 800047a + flash_lockdown_hard(OB_RDP_LEVEL_0); // wipes contents of flash (1->0) + 80007bc: 20aa movs r0, #170 ; 0xaa + flash_lockdown_hard(OB_RDP_LEVEL_2); // No change possible after this. + 80007be: f001 fde3 bl 8002388 + int rv = 0; + 80007c2: 2400 movs r4, #0 + break; + 80007c4: e659 b.n 800047a + flash_lockdown_hard(OB_RDP_LEVEL_1); // Can only do 0->1 (experiments) + 80007c6: 20bb movs r0, #187 ; 0xbb + 80007c8: e7f9 b.n 80007be + REQUIRE_OUT(128); + 80007ca: 2300 movs r3, #0 + 80007cc: 2180 movs r1, #128 ; 0x80 + 80007ce: 4628 mov r0, r5 + 80007d0: f7ff fdca bl 8000368 + 80007d4: 4604 mov r4, r0 + 80007d6: 2800 cmp r0, #0 + 80007d8: f47f ae4f bne.w 800047a + ae_setup(); + 80007dc: f002 f8f2 bl 80029c4 + rv = ae_config_read(buf_io); + 80007e0: 4628 mov r0, r5 + 80007e2: f002 fef0 bl 80035c6 + 80007e6: e718 b.n 800061a + switch(arg2) { + 80007e8: 9b01 ldr r3, [sp, #4] + 80007ea: 2b03 cmp r3, #3 + 80007ec: d8aa bhi.n 8000744 + 80007ee: e8df f003 tbb [pc, r3] + 80007f2: 0f02 .short 0x0f02 + 80007f4: 441d .short 0x441d + REQUIRE_OUT(8); + 80007f6: 2300 movs r3, #0 + 80007f8: 2108 movs r1, #8 + 80007fa: 4628 mov r0, r5 + 80007fc: f7ff fdb4 bl 8000368 + 8000800: 4604 mov r4, r0 + 8000802: 2800 cmp r0, #0 + 8000804: f47f ae39 bne.w 800047a + get_min_version(buf_io); + 8000808: 4628 mov r0, r5 + 800080a: f001 f9a5 bl 8001b58 + break; + 800080e: e634 b.n 800047a + REQUIRE_IN_ONLY(8); + 8000810: 2301 movs r3, #1 + 8000812: 2108 movs r1, #8 + 8000814: 4628 mov r0, r5 + 8000816: f7ff fda7 bl 8000368 + 800081a: 4604 mov r4, r0 + 800081c: 2800 cmp r0, #0 + 800081e: f47f ae2c bne.w 800047a + rv = check_is_downgrade(buf_io, NULL); + 8000822: 4601 mov r1, r0 + 8000824: 4628 mov r0, r5 + 8000826: f001 f9b7 bl 8001b98 + 800082a: e609 b.n 8000440 + REQUIRE_IN_ONLY(8); + 800082c: 2301 movs r3, #1 + 800082e: 2108 movs r1, #8 + 8000830: 4628 mov r0, r5 + 8000832: f7ff fd99 bl 8000368 + 8000836: 4604 mov r4, r0 + 8000838: 2800 cmp r0, #0 + 800083a: f47f ae1e bne.w 800047a + if(buf_io[0] < 0x10 || buf_io[0] >= 0x40) { + 800083e: 782b ldrb r3, [r5, #0] + 8000840: 3b10 subs r3, #16 + rv = ERANGE; + 8000842: 2b2f cmp r3, #47 ; 0x2f + } if(check_is_downgrade(buf_io, NULL)) { + 8000844: 4601 mov r1, r0 + 8000846: 4628 mov r0, r5 + rv = ERANGE; + 8000848: bf88 it hi + 800084a: 2422 movhi r4, #34 ; 0x22 + } if(check_is_downgrade(buf_io, NULL)) { + 800084c: f001 f9a4 bl 8001b98 + 8000850: 2800 cmp r0, #0 + 8000852: f040 80c8 bne.w 80009e6 + get_min_version(min); + 8000856: a80b add r0, sp, #44 ; 0x2c + 8000858: f001 f97e bl 8001b58 + if(memcmp(min, buf_io, 8) == 0) { + 800085c: 2208 movs r2, #8 + 800085e: 4629 mov r1, r5 + 8000860: a80b add r0, sp, #44 ; 0x2c + 8000862: f00c fecf bl 800d604 + 8000866: 2800 cmp r0, #0 + 8000868: f000 80bd beq.w 80009e6 + if(record_highwater_version(buf_io)) { + 800086c: 4628 mov r0, r5 + 800086e: f001 fda5 bl 80023bc + rv = ENOMEM; + 8000872: 2800 cmp r0, #0 + 8000874: bf18 it ne + 8000876: 240c movne r4, #12 + 8000878: e5ff b.n 800047a + REQUIRE_OUT(4); + 800087a: 2300 movs r3, #0 + 800087c: 2104 movs r1, #4 + 800087e: 4628 mov r0, r5 + 8000880: f7ff fd72 bl 8000368 + 8000884: 4604 mov r4, r0 + 8000886: 2800 cmp r0, #0 + 8000888: f47f adf7 bne.w 800047a + ae_setup(); + 800088c: f002 f89a bl 80029c4 + rv = ae_get_counter((uint32_t *)buf_io, 0) ? EIO: 0; + 8000890: 4621 mov r1, r4 + 8000892: 4628 mov r0, r5 + 8000894: f002 fc87 bl 80031a6 + 8000898: e6bf b.n 800061a + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2 + sizeof(trick_slot_t)); + 800089a: 2300 movs r3, #0 + 800089c: f44f 71cc mov.w r1, #408 ; 0x198 + 80008a0: 4628 mov r0, r5 + 80008a2: f7ff fd61 bl 8000368 + 80008a6: 4604 mov r4, r0 + 80008a8: 2800 cmp r0, #0 + 80008aa: f47f ade6 bne.w 800047a + rv = pin_check_logged_in(args, &trick_mode); + 80008ae: a90b add r1, sp, #44 ; 0x2c + 80008b0: 4628 mov r0, r5 + 80008b2: f003 fc8f bl 80041d4 + if(rv) goto fail; + 80008b6: 4604 mov r4, r0 + 80008b8: 2800 cmp r0, #0 + 80008ba: f47f adde bne.w 800047a + if(trick_mode) { + 80008be: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 80008c2: b10b cbz r3, 80008c8 + mcu_key_clear(NULL); + 80008c4: f001 fdc8 bl 8002458 + switch(arg2) { + 80008c8: 9b01 ldr r3, [sp, #4] + 80008ca: 2b01 cmp r3, #1 + trick_slot_t *slot = (trick_slot_t *)(&buf_io[PIN_ATTEMPT_SIZE_V2]); + 80008cc: f505 728c add.w r2, r5, #280 ; 0x118 + switch(arg2) { + 80008d0: d00c beq.n 80008ec + 80008d2: 2b02 cmp r3, #2 + 80008d4: d01b beq.n 800090e + 80008d6: 2b00 cmp r3, #0 + 80008d8: f47f af34 bne.w 8000744 + if(!trick_mode) { + 80008dc: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 80008e0: 2b00 cmp r3, #0 + 80008e2: f47f adca bne.w 800047a + se2_clear_tricks(); + 80008e6: f007 fa31 bl 8007d4c + 80008ea: e5c6 b.n 800047a + if(trick_mode) { + 80008ec: f89d 102c ldrb.w r1, [sp, #44] ; 0x2c + 80008f0: 2900 cmp r1, #0 + 80008f2: f47f af27 bne.w 8000744 + if(slot->pin_len > 16) { + 80008f6: f8d5 1170 ldr.w r1, [r5, #368] ; 0x170 + 80008fa: 2910 cmp r1, #16 + 80008fc: dc4b bgt.n 8000996 + if(se2_test_trick_pin(slot->pin, slot->pin_len, slot, true)) { + 80008fe: f505 70b0 add.w r0, r5, #352 ; 0x160 + 8000902: f007 fa89 bl 8007e18 + 8000906: 2800 cmp r0, #0 + 8000908: f47f adb7 bne.w 800047a + 800090c: e71a b.n 8000744 + if(!trick_mode) { + 800090e: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 8000912: 2b00 cmp r3, #0 + 8000914: f47f adb1 bne.w 800047a + rv = se2_save_trick(slot); + 8000918: 4610 mov r0, r2 + 800091a: f007 fb9d bl 8008058 + 800091e: e58f b.n 8000440 + if(arg2 == 0xBeef) { + 8000920: 9b01 ldr r3, [sp, #4] + 8000922: f64b 62ef movw r2, #48879 ; 0xbeef + 8000926: 4293 cmp r3, r2 + 8000928: d103 bne.n 8000932 + fast_wipe(); + 800092a: f001 fe87 bl 800263c + rv = EPERM; + 800092e: 2401 movs r4, #1 + 8000930: e5a3 b.n 800047a + } else if(arg2 == 0xDead) { + 8000932: f64d 62ad movw r2, #57005 ; 0xdead + 8000936: 4293 cmp r3, r2 + 8000938: d1f9 bne.n 800092e + mcu_key_clear(NULL); + 800093a: 2000 movs r0, #0 + 800093c: f001 fd8c bl 8002458 + oled_show(screen_wiped); + 8000940: 482d ldr r0, [pc, #180] ; (80009f8 ) + 8000942: f000 fa7f bl 8000e44 + LOCKUP_FOREVER(); + 8000946: bf30 wfi + 8000948: e7fd b.n 8000946 + if(arg2 == 0xDead) fast_brick(); + 800094a: 9a01 ldr r2, [sp, #4] + 800094c: f64d 63ad movw r3, #57005 ; 0xdead + 8000950: 429a cmp r2, r3 + 8000952: d1ec bne.n 800092e + 8000954: f001 fe44 bl 80025e0 + 8000958: e7e9 b.n 800092e + REQUIRE_OUT(8); + 800095a: 2300 movs r3, #0 + 800095c: 2108 movs r1, #8 + 800095e: 4628 mov r0, r5 + 8000960: f7ff fd02 bl 8000368 + 8000964: 4604 mov r4, r0 + 8000966: 2800 cmp r0, #0 + 8000968: f47f ad87 bne.w 800047a + mcu_key_usage(avail, consumed, total); + 800096c: f105 0208 add.w r2, r5, #8 + 8000970: 1d29 adds r1, r5, #4 + 8000972: 4628 mov r0, r5 + 8000974: f001 fd9e bl 80024b4 + break; + 8000978: e57f b.n 800047a + REQUIRE_OUT(33); + 800097a: 2300 movs r3, #0 + 800097c: 2121 movs r1, #33 ; 0x21 + 800097e: 4628 mov r0, r5 + 8000980: f7ff fcf2 bl 8000368 + 8000984: 4604 mov r4, r0 + 8000986: 2800 cmp r0, #0 + 8000988: f47f ad77 bne.w 800047a + switch(arg2) { + 800098c: 9b01 ldr r3, [sp, #4] + 800098e: 2b01 cmp r3, #1 + 8000990: d003 beq.n 800099a + 8000992: 2b02 cmp r3, #2 + 8000994: d008 beq.n 80009a8 + rv = ERANGE; + 8000996: 2422 movs r4, #34 ; 0x22 + 8000998: e56f b.n 800047a + ae_setup(); + 800099a: f002 f813 bl 80029c4 + ae_secure_random(&buf_io[1]); + 800099e: 1c68 adds r0, r5, #1 + 80009a0: f002 fb78 bl 8003094 + buf_io[0] = 32; + 80009a4: 2320 movs r3, #32 + 80009a6: e707 b.n 80007b8 + se2_read_rng(&buf_io[1]); + 80009a8: 1c68 adds r0, r5, #1 + 80009aa: f007 fd39 bl 8008420 + buf_io[0] = 8; + 80009ae: 2308 movs r3, #8 + 80009b0: e702 b.n 80007b8 + REQUIRE_OUT(80); + 80009b2: 2300 movs r3, #0 + 80009b4: 2150 movs r1, #80 ; 0x50 + 80009b6: 4628 mov r0, r5 + 80009b8: f7ff fcd6 bl 8000368 + 80009bc: 4604 mov r4, r0 + 80009be: 2800 cmp r0, #0 + 80009c0: f47f ad5b bne.w 800047a + strcpy((char *)buf_io, "ATECC608B\nDS28C36B"); + 80009c4: 490d ldr r1, [pc, #52] ; (80009fc ) + 80009c6: 4628 mov r0, r5 + 80009c8: f00c fe6a bl 800d6a0 + break; + 80009cc: e555 b.n 800047a + if(incoming_lr <= BL_FLASH_BASE || incoming_lr >= (uint32_t)&firewall_starts) { + 80009ce: f1b4 6f00 cmp.w r4, #134217728 ; 0x8000000 + 80009d2: d902 bls.n 80009da + 80009d4: 4b0a ldr r3, [pc, #40] ; (8000a00 ) + 80009d6: 429c cmp r4, r3 + 80009d8: d302 bcc.n 80009e0 + fatal_error("LR"); + 80009da: 480a ldr r0, [pc, #40] ; (8000a04 ) + 80009dc: f000 f834 bl 8000a48 + system_startup(); + 80009e0: f000 f890 bl 8000b04 + break; + 80009e4: e6ed b.n 80007c2 + rv = EAGAIN; + 80009e6: 240b movs r4, #11 + 80009e8: e547 b.n 800047a + 80009ea: bf00 nop + 80009ec: 0801c050 .word 0x0801c050 + 80009f0: 0801c070 .word 0x0801c070 + 80009f4: 40022000 .word 0x40022000 + 80009f8: 0800e310 .word 0x0800e310 + 80009fc: 0800d740 .word 0x0800d740 + 8000a00: 08000300 .word 0x08000300 + 8000a04: 0800d753 .word 0x0800d753 + +08000a08 : +// + static inline void +memset4(uint32_t *dest, uint32_t value, uint32_t byte_len) +{ + for(; byte_len; byte_len-=4, dest++) { + *dest = value; + 8000a08: 4a0a ldr r2, [pc, #40] ; (8000a34 ) + for(; byte_len; byte_len-=4, dest++) { + 8000a0a: 490b ldr r1, [pc, #44] ; (8000a38 ) + +// wipe_all_sram() +// + void +wipe_all_sram(void) +{ + 8000a0c: f04f 5300 mov.w r3, #536870912 ; 0x20000000 + *dest = value; + 8000a10: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a14: 428b cmp r3, r1 + 8000a16: d1fb bne.n 8000a10 + 8000a18: 4908 ldr r1, [pc, #32] ; (8000a3c ) + 8000a1a: f04f 5380 mov.w r3, #268435456 ; 0x10000000 + *dest = value; + 8000a1e: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a22: 428b cmp r3, r1 + 8000a24: d1fb bne.n 8000a1e + 8000a26: 4b06 ldr r3, [pc, #24] ; (8000a40 ) + 8000a28: 4906 ldr r1, [pc, #24] ; (8000a44 ) + *dest = value; + 8000a2a: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a2e: 428b cmp r3, r1 + 8000a30: d1fb bne.n 8000a2a + STATIC_ASSERT((SRAM3_BASE + SRAM3_SIZE) - BL_SRAM_BASE == 8192); + + memset4((void *)SRAM1_BASE, noise, SRAM1_SIZE_MAX); + memset4((void *)SRAM2_BASE, noise, SRAM2_SIZE); + memset4((void *)SRAM3_BASE, noise, SRAM3_SIZE - (BL_SRAM_BASE - SRAM3_BASE)); +} + 8000a32: 4770 bx lr + 8000a34: deadbeef .word 0xdeadbeef + 8000a38: 20030000 .word 0x20030000 + 8000a3c: 10010000 .word 0x10010000 + 8000a40: 20040000 .word 0x20040000 + 8000a44: 20042000 .word 0x20042000 + +08000a48 : + +// fatal_error(const char *msg) +// + void __attribute__((noreturn)) +fatal_error(const char *msgvoid) +{ + 8000a48: b508 push {r3, lr} + oled_setup(); + 8000a4a: f000 f96b bl 8000d24 + oled_show(screen_fatal); + 8000a4e: 4802 ldr r0, [pc, #8] ; (8000a58 ) + 8000a50: f000 f9f8 bl 8000e44 + BREAKPOINT; +#endif + + // Maybe should do a reset after a delay, like with + // the watchdog timer or something. + LOCKUP_FOREVER(); + 8000a54: bf30 wfi + 8000a56: e7fd b.n 8000a54 + 8000a58: 0800db52 .word 0x0800db52 + +08000a5c : + +// fatal_mitm() +// + void __attribute__((noreturn)) +fatal_mitm(void) +{ + 8000a5c: b508 push {r3, lr} + oled_setup(); + 8000a5e: f000 f961 bl 8000d24 + oled_show(screen_mitm); + 8000a62: 4803 ldr r0, [pc, #12] ; (8000a70 ) + 8000a64: f000 f9ee bl 8000e44 + +#ifdef RELEASE + wipe_all_sram(); + 8000a68: f7ff ffce bl 8000a08 +#endif + + LOCKUP_FOREVER(); + 8000a6c: bf30 wfi + 8000a6e: e7fd b.n 8000a6c + 8000a70: 0800dc56 .word 0x0800dc56 + +08000a74 : + +// enter_dfu() +// + void __attribute__((noreturn)) +enter_dfu(void) +{ + 8000a74: b507 push {r0, r1, r2, lr} + puts("enter_dfu()"); + 8000a76: 481f ldr r0, [pc, #124] ; (8000af4 ) + 8000a78: f004 f998 bl 8004dac + + // clear the green light, if set + ae_setup(); + 8000a7c: f001 ffa2 bl 80029c4 + ae_set_gpio(0); + 8000a80: 2000 movs r0, #0 + 8000a82: f002 fd21 bl 80034c8 + + // Reset huge parts of the chip + __HAL_RCC_APB1_FORCE_RESET(); + 8000a86: 4b1c ldr r3, [pc, #112] ; (8000af8 ) + 8000a88: f04f 31ff mov.w r1, #4294967295 ; 0xffffffff + __HAL_RCC_APB1_RELEASE_RESET(); + 8000a8c: 2200 movs r2, #0 + __HAL_RCC_APB1_FORCE_RESET(); + 8000a8e: 6399 str r1, [r3, #56] ; 0x38 + 8000a90: 63d9 str r1, [r3, #60] ; 0x3c + __HAL_RCC_APB1_RELEASE_RESET(); + 8000a92: 639a str r2, [r3, #56] ; 0x38 + 8000a94: 63da str r2, [r3, #60] ; 0x3c + + __HAL_RCC_APB2_FORCE_RESET(); + 8000a96: 6419 str r1, [r3, #64] ; 0x40 + __HAL_RCC_APB2_RELEASE_RESET(); + 8000a98: 641a str r2, [r3, #64] ; 0x40 + + __HAL_RCC_AHB1_FORCE_RESET(); + 8000a9a: 6299 str r1, [r3, #40] ; 0x28 + __HAL_RCC_AHB1_RELEASE_RESET(); + 8000a9c: 629a str r2, [r3, #40] ; 0x28 + // But not this; it borks things. + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); +#endif + + __HAL_RCC_AHB3_FORCE_RESET(); + 8000a9e: 6319 str r1, [r3, #48] ; 0x30 + __HAL_RCC_AHB3_RELEASE_RESET(); + 8000aa0: 631a str r2, [r3, #48] ; 0x30 + + __HAL_FIREWALL_PREARM_ENABLE(); + 8000aa2: f5a3 4374 sub.w r3, r3, #62464 ; 0xf400 + 8000aa6: 6a1a ldr r2, [r3, #32] + 8000aa8: f042 0201 orr.w r2, r2, #1 + 8000aac: 621a str r2, [r3, #32] + 8000aae: 6a1b ldr r3, [r3, #32] + 8000ab0: f003 0301 and.w r3, r3, #1 + 8000ab4: 9301 str r3, [sp, #4] + 8000ab6: 9b01 ldr r3, [sp, #4] + + // Wipe all of memory SRAM, just in case + // there is some way to trick us into DFU + // after sensitive content in place. + wipe_all_sram(); + 8000ab8: f7ff ffa6 bl 8000a08 + rng_delay(); + 8000abc: f001 fe5e bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000ac0: 4b0e ldr r3, [pc, #56] ; (8000afc ) + 8000ac2: 6a1b ldr r3, [r3, #32] + 8000ac4: b2db uxtb r3, r3 + + if(flash_is_security_level2()) { + 8000ac6: 2bcc cmp r3, #204 ; 0xcc + 8000ac8: d101 bne.n 8000ace + // cannot do DFU in RDP=2, so just die. Helps to preserve screen + LOCKUP_FOREVER(); + 8000aca: bf30 wfi + 8000acc: e7fd b.n 8000aca + } + + // Reset clocks. + HAL_RCC_DeInit(); + 8000ace: f007 fde5 bl 800869c + + // move system ROM into 0x0 + __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); + 8000ad2: 4a0b ldr r2, [pc, #44] ; (8000b00 ) + 8000ad4: 6813 ldr r3, [r2, #0] + 8000ad6: f023 0307 bic.w r3, r3, #7 + 8000ada: f043 0301 orr.w r3, r3, #1 + 8000ade: 6013 str r3, [r2, #0] + + // need this here?! + asm("nop; nop; nop; nop;"); + 8000ae0: bf00 nop + 8000ae2: bf00 nop + 8000ae4: bf00 nop + 8000ae6: bf00 nop + + // simulate a reset vector + __ASM volatile ("movs r0, #0\n" + 8000ae8: 2000 movs r0, #0 + 8000aea: 6803 ldr r3, [r0, #0] + 8000aec: f383 8808 msr MSP, r3 + 8000af0: 6843 ldr r3, [r0, #4] + 8000af2: 4798 blx r3 + "ldr r3, [r0, #4]\n" + "blx r3" + : : : "r0", "r3"); // also SP + + // NOT-REACHED. + __builtin_unreachable(); + 8000af4: 0800d756 .word 0x0800d756 + 8000af8: 40021000 .word 0x40021000 + 8000afc: 40022000 .word 0x40022000 + 8000b00: 40010000 .word 0x40010000 + +08000b04 : +{ + 8000b04: b510 push {r4, lr} + system_init0(); + 8000b06: f001 f985 bl 8001e14 + clocks_setup(); + 8000b0a: f001 f9a5 bl 8001e58 + rng_setup(); // needs to be super early + 8000b0e: f001 fdf3 bl 80026f8 + rng_delay(); + 8000b12: f001 fe33 bl 800277c + if(!check_all_ones(rom_secrets->bag_number, sizeof(rom_secrets->bag_number)) + 8000b16: 4838 ldr r0, [pc, #224] ; (8000bf8 ) + 8000b18: 2120 movs r1, #32 + 8000b1a: f001 fdb1 bl 8002680 + 8000b1e: b948 cbnz r0, 8000b34 + rng_delay(); + 8000b20: f001 fe2c bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000b24: 4b35 ldr r3, [pc, #212] ; (8000bfc ) + 8000b26: 6a1b ldr r3, [r3, #32] + 8000b28: b2db uxtb r3, r3 + && !flash_is_security_level2() + 8000b2a: 2bcc cmp r3, #204 ; 0xcc + 8000b2c: d002 beq.n 8000b34 + flash_lockdown_hard(OB_RDP_LEVEL_2); + 8000b2e: 20cc movs r0, #204 ; 0xcc + 8000b30: f001 fc2a bl 8002388 + gpio_setup(); + 8000b34: f002 fef0 bl 8003918 + uint32_t reset_reason = RCC->CSR; + 8000b38: 4c31 ldr r4, [pc, #196] ; (8000c00 ) + console_setup(); + 8000b3a: f004 f85d bl 8004bf8 + puts2(BOOT_BANNER); + 8000b3e: 4831 ldr r0, [pc, #196] ; (8000c04 ) + 8000b40: f004 f8a6 bl 8004c90 + puts(version_string); + 8000b44: 4830 ldr r0, [pc, #192] ; (8000c08 ) + 8000b46: f004 f931 bl 8004dac + uint32_t reset_reason = RCC->CSR; + 8000b4a: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + if(reset_reason & RCC_CSR_FWRSTF) { + 8000b4e: 01db lsls r3, r3, #7 + 8000b50: d502 bpl.n 8000b58 + puts(">FIREWALLED<"); + 8000b52: 482e ldr r0, [pc, #184] ; (8000c0c ) + 8000b54: f004 f92a bl 8004dac + SET_BIT(RCC->CSR, RCC_CSR_RMVF); + 8000b58: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8000b5c: f443 0300 orr.w r3, r3, #8388608 ; 0x800000 + 8000b60: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + if(memcmp(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)) == 0) { + 8000b64: 4c2a ldr r4, [pc, #168] ; (8000c10 ) + pin_setup0(); + 8000b66: f003 f935 bl 8003dd4 + rng_delay(); + 8000b6a: f001 fe07 bl 800277c + oled_setup(); + 8000b6e: f000 f8d9 bl 8000d24 + if(memcmp(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)) == 0) { + 8000b72: 4928 ldr r1, [pc, #160] ; (8000c14 ) + 8000b74: 2208 movs r2, #8 + 8000b76: 4620 mov r0, r4 + 8000b78: f00c fd44 bl 800d604 + 8000b7c: b928 cbnz r0, 8000b8a + dfu_flag->magic[0] = 0; + 8000b7e: 7020 strb r0, [r4, #0] + oled_show(dfu_flag->screen); + 8000b80: 68a0 ldr r0, [r4, #8] + 8000b82: f000 f95f bl 8000e44 + enter_dfu(); + 8000b86: f7ff ff75 bl 8000a74 + rng_delay(); + 8000b8a: f001 fdf7 bl 800277c + oled_show_progress(screen_verify, 0); + 8000b8e: 2100 movs r1, #0 + 8000b90: 4821 ldr r0, [pc, #132] ; (8000c18 ) + 8000b92: f000 f999 bl 8000ec8 + wipe_all_sram(); + 8000b96: f7ff ff37 bl 8000a08 + ae_setup(); + 8000b9a: f001 ff13 bl 80029c4 + ae_set_gpio(0); // turn light red + 8000b9e: 2000 movs r0, #0 + 8000ba0: f002 fc92 bl 80034c8 + se2_setup(); + 8000ba4: f007 f88c bl 8007cc0 + se2_probe(); + 8000ba8: f006 fe10 bl 80077cc + flash_setup(); + 8000bac: f001 fb56 bl 800225c + psram_setup(); + 8000bb0: f004 f934 bl 8004e1c + if(ae_pair_unlock() != 0) { + 8000bb4: f002 f8fc bl 8002db0 + 8000bb8: b138 cbz r0, 8000bca + oled_show(screen_brick); + 8000bba: 4818 ldr r0, [pc, #96] ; (8000c1c ) + 8000bbc: f000 f942 bl 8000e44 + puts("pair-bricked"); + 8000bc0: 4817 ldr r0, [pc, #92] ; (8000c20 ) + 8000bc2: f004 f8f3 bl 8004dac + LOCKUP_FOREVER(); + 8000bc6: bf30 wfi + 8000bc8: e7fd b.n 8000bc6 + puts2("Verify: "); + 8000bca: 4816 ldr r0, [pc, #88] ; (8000c24 ) + 8000bcc: f004 f860 bl 8004c90 + bool main_ok = verify_firmware(); + 8000bd0: f001 f8a4 bl 8001d1c + if(main_ok) { + 8000bd4: b120 cbz r0, 8000be0 +} + 8000bd6: e8bd 4010 ldmia.w sp!, {r4, lr} + oled_show(screen_blankish); + 8000bda: 4813 ldr r0, [pc, #76] ; (8000c28 ) + 8000bdc: f000 b932 b.w 8000e44 + psram_recover_firmware(); + 8000be0: f004 fa6a bl 80050b8 + rng_delay(); + 8000be4: f001 fdca bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000be8: 4b04 ldr r3, [pc, #16] ; (8000bfc ) + 8000bea: 6a1b ldr r3, [r3, #32] + 8000bec: b2db uxtb r3, r3 + if(!flash_is_security_level2()) { + 8000bee: 2bcc cmp r3, #204 ; 0xcc + 8000bf0: d1c9 bne.n 8000b86 + while(1) sdcard_recovery(); + 8000bf2: f004 fc11 bl 8005418 + 8000bf6: e7fc b.n 8000bf2 + 8000bf8: 0801c050 .word 0x0801c050 + 8000bfc: 40022000 .word 0x40022000 + 8000c00: 40021000 .word 0x40021000 + 8000c04: 0800d762 .word 0x0800d762 + 8000c08: 0800e720 .word 0x0800e720 + 8000c0c: 0800d776 .word 0x0800d776 + 8000c10: 20008000 .word 0x20008000 + 8000c14: 0800d737 .word 0x0800d737 + 8000c18: 0800e242 .word 0x0800e242 + 8000c1c: 0800d80b .word 0x0800d80b + 8000c20: 0800d783 .word 0x0800d783 + 8000c24: 0800d790 .word 0x0800d790 + 8000c28: 0800d7de .word 0x0800d7de + +08000c2c : + static inline void +write_bytes(int len, const uint8_t *buf) +{ +#ifndef DISABLE_OLED + // send via SPI(1) + HAL_SPI_Transmit(&spi_port, (uint8_t *)buf, len, HAL_MAX_DELAY); + 8000c2c: b282 uxth r2, r0 + 8000c2e: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8000c32: 4801 ldr r0, [pc, #4] ; (8000c38 ) + 8000c34: f000 bc06 b.w 8001444 + 8000c38: 2009e154 .word 0x2009e154 + +08000c3c : + +// oled_write_cmd() +// + void +oled_write_cmd(uint8_t cmd) +{ + 8000c3c: b507 push {r0, r1, r2, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c3e: 2201 movs r2, #1 +{ + 8000c40: f88d 0007 strb.w r0, [sp, #7] + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c44: 2110 movs r1, #16 + 8000c46: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c4a: f000 fb5b bl 8001304 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 0); + 8000c4e: 2200 movs r2, #0 + 8000c50: f44f 7180 mov.w r1, #256 ; 0x100 + 8000c54: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c58: f000 fb54 bl 8001304 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000c5c: 2200 movs r2, #0 + 8000c5e: 2110 movs r1, #16 + 8000c60: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c64: f000 fb4e bl 8001304 + + write_bytes(1, &cmd); + 8000c68: f10d 0107 add.w r1, sp, #7 + 8000c6c: 2001 movs r0, #1 + 8000c6e: f7ff ffdd bl 8000c2c + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c72: 2201 movs r2, #1 + 8000c74: 2110 movs r1, #16 + 8000c76: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c7a: f000 fb43 bl 8001304 +} + 8000c7e: b003 add sp, #12 + 8000c80: f85d fb04 ldr.w pc, [sp], #4 + +08000c84 : + +// oled_write_cmd_sequence() +// + void +oled_write_cmd_sequence(int len, const uint8_t *cmds) +{ + 8000c84: b570 push {r4, r5, r6, lr} + 8000c86: 4605 mov r5, r0 + 8000c88: 460e mov r6, r1 + for(int i=0; i + oled_write_cmd(cmds[i]); + } +} + 8000c90: bd70 pop {r4, r5, r6, pc} + oled_write_cmd(cmds[i]); + 8000c92: 5d30 ldrb r0, [r6, r4] + 8000c94: f7ff ffd2 bl 8000c3c + for(int i=0; i + +08000c9c : + +// oled_write_data() +// + void +oled_write_data(int len, const uint8_t *pixels) +{ + 8000c9c: b538 push {r3, r4, r5, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c9e: 2201 movs r2, #1 +{ + 8000ca0: 4604 mov r4, r0 + 8000ca2: 460d mov r5, r1 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000ca4: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000ca8: 2110 movs r1, #16 + 8000caa: f000 fb2b bl 8001304 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 1); + 8000cae: 2201 movs r2, #1 + 8000cb0: f44f 7180 mov.w r1, #256 ; 0x100 + 8000cb4: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cb8: f000 fb24 bl 8001304 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000cbc: 2200 movs r2, #0 + 8000cbe: 2110 movs r1, #16 + 8000cc0: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cc4: f000 fb1e bl 8001304 + + write_bytes(len, pixels); + 8000cc8: 4629 mov r1, r5 + 8000cca: 4620 mov r0, r4 + 8000ccc: f7ff ffae bl 8000c2c + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); +} + 8000cd0: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000cd4: 2201 movs r2, #1 + 8000cd6: 2110 movs r1, #16 + 8000cd8: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cdc: f000 bb12 b.w 8001304 + +08000ce0 : +// +// Just setup SPI, do not reset display, etc. +// + void +oled_spi_setup(void) +{ + 8000ce0: b538 push {r3, r4, r5, lr} +#ifndef DISABLE_OLED + // might already be setup + if(spi_port.Instance == SPI1) return; + 8000ce2: 4c0e ldr r4, [pc, #56] ; (8000d1c ) + 8000ce4: 4d0e ldr r5, [pc, #56] ; (8000d20 ) + 8000ce6: 6823 ldr r3, [r4, #0] + 8000ce8: 42ab cmp r3, r5 + 8000cea: d016 beq.n 8000d1a + + memset(&spi_port, 0, sizeof(spi_port)); + 8000cec: f104 0008 add.w r0, r4, #8 + 8000cf0: 225c movs r2, #92 ; 0x5c + 8000cf2: 2100 movs r1, #0 + 8000cf4: f00c fcbe bl 800d674 + + spi_port.Instance = SPI1; + + // see SPI_InitTypeDef + spi_port.Init.Mode = SPI_MODE_MASTER; + 8000cf8: f44f 7382 mov.w r3, #260 ; 0x104 + 8000cfc: 6063 str r3, [r4, #4] + spi_port.Init.Direction = SPI_DIRECTION_2LINES; + spi_port.Init.DataSize = SPI_DATASIZE_8BIT; + 8000cfe: f44f 63e0 mov.w r3, #1792 ; 0x700 + 8000d02: 60e3 str r3, [r4, #12] + spi_port.Init.CLKPolarity = SPI_POLARITY_LOW; + spi_port.Init.CLKPhase = SPI_PHASE_1EDGE; + spi_port.Init.NSS = SPI_NSS_SOFT; + spi_port.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; // conservative + 8000d04: f44f 7000 mov.w r0, #512 ; 0x200 + 8000d08: 2318 movs r3, #24 + 8000d0a: e9c4 0306 strd r0, r3, [r4, #24] + spi_port.Instance = SPI1; + 8000d0e: 6025 str r5, [r4, #0] + spi_port.Init.FirstBit = SPI_FIRSTBIT_MSB; + spi_port.Init.TIMode = SPI_TIMODE_DISABLED; + spi_port.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + + HAL_SPI_Init(&spi_port); + 8000d10: 4620 mov r0, r4 +#endif +} + 8000d12: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + HAL_SPI_Init(&spi_port); + 8000d16: f000 bb37 b.w 8001388 +} + 8000d1a: bd38 pop {r3, r4, r5, pc} + 8000d1c: 2009e154 .word 0x2009e154 + 8000d20: 40013000 .word 0x40013000 + +08000d24 : +// +// Ok to call this lots. +// + void +oled_setup(void) +{ + 8000d24: b530 push {r4, r5, lr} + puts("oled disabled");return; // disable so I can use MCO +#endif + + static uint32_t inited; + + if(inited == 0x238a572F) { + 8000d26: 4b2c ldr r3, [pc, #176] ; (8000dd8 ) + 8000d28: 4a2c ldr r2, [pc, #176] ; (8000ddc ) + 8000d2a: 6819 ldr r1, [r3, #0] + 8000d2c: 4291 cmp r1, r2 +{ + 8000d2e: b089 sub sp, #36 ; 0x24 + if(inited == 0x238a572F) { + 8000d30: d050 beq.n 8000dd4 + return; + } + inited = 0x238a572F; + 8000d32: 601a str r2, [r3, #0] + + // enable some internal clocks + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8000d34: 4b2a ldr r3, [pc, #168] ; (8000de0 ) + __HAL_RCC_SPI1_CLK_ENABLE(); + + // simple pins + GPIO_InitTypeDef setup = { + 8000d36: 4d2b ldr r5, [pc, #172] ; (8000de4 ) + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8000d38: 6cda ldr r2, [r3, #76] ; 0x4c + 8000d3a: f042 0201 orr.w r2, r2, #1 + 8000d3e: 64da str r2, [r3, #76] ; 0x4c + 8000d40: 6cda ldr r2, [r3, #76] ; 0x4c + 8000d42: f002 0201 and.w r2, r2, #1 + 8000d46: 9201 str r2, [sp, #4] + 8000d48: 9a01 ldr r2, [sp, #4] + __HAL_RCC_SPI1_CLK_ENABLE(); + 8000d4a: 6e1a ldr r2, [r3, #96] ; 0x60 + 8000d4c: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8000d50: 661a str r2, [r3, #96] ; 0x60 + 8000d52: 6e1b ldr r3, [r3, #96] ; 0x60 + 8000d54: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 8000d58: 9302 str r3, [sp, #8] + 8000d5a: 9b02 ldr r3, [sp, #8] + GPIO_InitTypeDef setup = { + 8000d5c: cd0f ldmia r5!, {r0, r1, r2, r3} + 8000d5e: ac03 add r4, sp, #12 + 8000d60: c40f stmia r4!, {r0, r1, r2, r3} + 8000d62: 682b ldr r3, [r5, #0] + 8000d64: 6023 str r3, [r4, #0] + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = 0, + }; + HAL_GPIO_Init(GPIOA, &setup); + 8000d66: a903 add r1, sp, #12 + 8000d68: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000d6c: f000 f950 bl 8001010 + + // starting values + HAL_GPIO_WritePin(GPIOA, RESET_PIN | CS_PIN | DC_PIN, 1); + 8000d70: 2201 movs r2, #1 + 8000d72: f44f 71a8 mov.w r1, #336 ; 0x150 + 8000d76: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000d7a: f000 fac3 bl 8001304 + + // SPI pins + setup.Pin = SPI_SCK | SPI_MOSI; + setup.Mode = GPIO_MODE_AF_PP; + 8000d7e: 22a0 movs r2, #160 ; 0xa0 + 8000d80: 2302 movs r3, #2 + 8000d82: e9cd 2303 strd r2, r3, [sp, #12] + setup.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &setup); + 8000d86: a903 add r1, sp, #12 + setup.Alternate = GPIO_AF5_SPI1; + 8000d88: 2305 movs r3, #5 + HAL_GPIO_Init(GPIOA, &setup); + 8000d8a: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + setup.Alternate = GPIO_AF5_SPI1; + 8000d8e: 9307 str r3, [sp, #28] + HAL_GPIO_Init(GPIOA, &setup); + 8000d90: f000 f93e bl 8001010 + + // lock the RESET pin so that St's DFU code doesn't clear screen + // it might be trying to use it a MISO signal for SPI loading + HAL_GPIO_LockPin(GPIOA, RESET_PIN | CS_PIN | DC_PIN); + 8000d94: f44f 71a8 mov.w r1, #336 ; 0x150 + 8000d98: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000d9c: f000 fabb bl 8001316 + + // 10ms low-going pulse on reset pin + delay_ms(1); + 8000da0: 2001 movs r0, #1 + 8000da2: f002 fda9 bl 80038f8 + HAL_GPIO_WritePin(GPIOA, RESET_PIN, 0); + 8000da6: 2200 movs r2, #0 + 8000da8: 2140 movs r1, #64 ; 0x40 + 8000daa: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000dae: f000 faa9 bl 8001304 + delay_ms(10); + 8000db2: 200a movs r0, #10 + 8000db4: f002 fda0 bl 80038f8 + HAL_GPIO_WritePin(GPIOA, RESET_PIN, 1); + 8000db8: 2201 movs r2, #1 + 8000dba: 2140 movs r1, #64 ; 0x40 + 8000dbc: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000dc0: f000 faa0 bl 8001304 + + oled_spi_setup(); + 8000dc4: f7ff ff8c bl 8000ce0 + // this code: + // '0x37c', '0x1700', '0x603' + //SPI1->CR1 = 0x354; + + // write a sequence to reset things + oled_write_cmd_sequence(sizeof(reset_commands), reset_commands); + 8000dc8: 4907 ldr r1, [pc, #28] ; (8000de8 ) + 8000dca: 2019 movs r0, #25 + 8000dcc: f7ff ff5a bl 8000c84 + + rng_delay(); + 8000dd0: f001 fcd4 bl 800277c +} + 8000dd4: b009 add sp, #36 ; 0x24 + 8000dd6: bd30 pop {r4, r5, pc} + 8000dd8: 2009e150 .word 0x2009e150 + 8000ddc: 238a572f .word 0x238a572f + 8000de0: 40021000 .word 0x40021000 + 8000de4: 0800d79c .word 0x0800d79c + 8000de8: 0800d7bf .word 0x0800d7bf + +08000dec : +// +// No decompression. +// + void +oled_show_raw(uint32_t len, const uint8_t *pixels) +{ + 8000dec: b538 push {r3, r4, r5, lr} + 8000dee: 4604 mov r4, r0 + 8000df0: 460d mov r5, r1 + oled_setup(); + 8000df2: f7ff ff97 bl 8000d24 + + oled_write_cmd_sequence(sizeof(before_show), before_show); + 8000df6: 4912 ldr r1, [pc, #72] ; (8000e40 ) + 8000df8: 2006 movs r0, #6 + 8000dfa: f7ff ff43 bl 8000c84 + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000dfe: 2201 movs r2, #1 + 8000e00: 2110 movs r1, #16 + 8000e02: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e06: f000 fa7d bl 8001304 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 1); + 8000e0a: 2201 movs r2, #1 + 8000e0c: f44f 7180 mov.w r1, #256 ; 0x100 + 8000e10: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e14: f000 fa76 bl 8001304 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000e18: 2200 movs r2, #0 + 8000e1a: 2110 movs r1, #16 + 8000e1c: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e20: f000 fa70 bl 8001304 + + write_bytes(len, pixels); + 8000e24: 4629 mov r1, r5 + 8000e26: 4620 mov r0, r4 + 8000e28: f7ff ff00 bl 8000c2c + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000e2c: 2201 movs r2, #1 + 8000e2e: 2110 movs r1, #16 + 8000e30: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e34: f000 fa66 bl 8001304 + rng_delay(); +} + 8000e38: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + rng_delay(); + 8000e3c: f001 bc9e b.w 800277c + 8000e40: 0800d7b9 .word 0x0800d7b9 + +08000e44 : +// +// Perform simple RLE decompression. +// + void +oled_show(const uint8_t *pixels) +{ + 8000e44: b530 push {r4, r5, lr} + 8000e46: b0a1 sub sp, #132 ; 0x84 + 8000e48: 4604 mov r4, r0 + oled_setup(); + 8000e4a: f7ff ff6b bl 8000d24 + + oled_write_cmd_sequence(sizeof(before_show), before_show); + 8000e4e: 491d ldr r1, [pc, #116] ; (8000ec4 ) + 8000e50: 2006 movs r0, #6 + 8000e52: f7ff ff17 bl 8000c84 + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000e56: 2201 movs r2, #1 + 8000e58: 2110 movs r1, #16 + 8000e5a: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e5e: f000 fa51 bl 8001304 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 1); + 8000e62: 2201 movs r2, #1 + 8000e64: f44f 7180 mov.w r1, #256 ; 0x100 + 8000e68: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e6c: f000 fa4a bl 8001304 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000e70: 2200 movs r2, #0 + 8000e72: 2110 movs r1, #16 + 8000e74: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e78: f000 fa44 bl 8001304 + uint8_t buf[127]; + const uint8_t *p = pixels; + + // NOTE: must also update code in oled_show_progress, which dups this heavily. + while(1) { + uint8_t hdr = *(p++); + 8000e7c: 7823 ldrb r3, [r4, #0] + if(!hdr) break; + 8000e7e: b1b3 cbz r3, 8000eae + + uint8_t len = hdr & 0x7f; + 8000e80: f003 057f and.w r5, r3, #127 ; 0x7f + if(hdr & 0x80) { + 8000e84: 061b lsls r3, r3, #24 + 8000e86: d50b bpl.n 8000ea0 + uint8_t hdr = *(p++); + 8000e88: 3401 adds r4, #1 + // random bytes follow + memcpy(buf, p, len); + 8000e8a: 4621 mov r1, r4 + 8000e8c: 462a mov r2, r5 + 8000e8e: 4668 mov r0, sp + 8000e90: f00c fbc8 bl 800d624 + p += len; + 8000e94: 442c add r4, r5 + // repeat same byte + memset(buf, *p, len); + p++; + } + + write_bytes(len, buf); + 8000e96: 4669 mov r1, sp + 8000e98: 4628 mov r0, r5 + 8000e9a: f7ff fec7 bl 8000c2c + while(1) { + 8000e9e: e7ed b.n 8000e7c + memset(buf, *p, len); + 8000ea0: 7861 ldrb r1, [r4, #1] + 8000ea2: 462a mov r2, r5 + 8000ea4: 4668 mov r0, sp + 8000ea6: f00c fbe5 bl 800d674 + p++; + 8000eaa: 3402 adds r4, #2 + 8000eac: e7f3 b.n 8000e96 + } + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000eae: 2201 movs r2, #1 + 8000eb0: 2110 movs r1, #16 + 8000eb2: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000eb6: f000 fa25 bl 8001304 + rng_delay(); + 8000eba: f001 fc5f bl 800277c +} + 8000ebe: b021 add sp, #132 ; 0x84 + 8000ec0: bd30 pop {r4, r5, pc} + 8000ec2: bf00 nop + 8000ec4: 0800d7b9 .word 0x0800d7b9 + +08000ec8 : +// +// Perform simple RLE decompression, and add a bar on final screen line. +// + void +oled_show_progress(const uint8_t *pixels, int progress) +{ + 8000ec8: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8000ecc: b0a1 sub sp, #132 ; 0x84 + 8000ece: 460d mov r5, r1 + 8000ed0: 4606 mov r6, r0 + oled_setup(); + 8000ed2: f7ff ff27 bl 8000d24 + + oled_write_cmd_sequence(sizeof(before_show), before_show); + 8000ed6: 493b ldr r1, [pc, #236] ; (8000fc4 ) + 8000ed8: 2006 movs r0, #6 + 8000eda: f7ff fed3 bl 8000c84 + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000ede: 2201 movs r2, #1 + 8000ee0: 2110 movs r1, #16 + 8000ee2: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000ee6: f000 fa0d bl 8001304 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 1); + 8000eea: 2201 movs r2, #1 + 8000eec: f44f 7180 mov.w r1, #256 ; 0x100 + 8000ef0: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000ef4: f000 fa06 bl 8001304 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000ef8: 2110 movs r1, #16 + 8000efa: 2200 movs r2, #0 + 8000efc: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000f00: f000 fa00 bl 8001304 + + uint8_t buf[127]; + const uint8_t *p = pixels; + + const uint16_t p_start = 896; + uint32_t p_count = 1280 * progress / 1000; + 8000f04: f44f 61a0 mov.w r1, #1280 ; 0x500 + 8000f08: 434d muls r5, r1 + 8000f0a: 2400 movs r4, #0 + 8000f0c: f44f 717a mov.w r1, #1000 ; 0x3e8 + 8000f10: fb95 f5f1 sdiv r5, r5, r1 + + if(p_count > 128) p_count = 128; + 8000f14: 2d80 cmp r5, #128 ; 0x80 + 8000f16: bf28 it cs + 8000f18: 2580 movcs r5, #128 ; 0x80 + uint32_t p_count = 1280 * progress / 1000; + 8000f1a: 46a0 mov r8, r4 + + bool last_line = false; + + uint16_t offset = 0; + while(1) { + uint8_t hdr = *(p++); + 8000f1c: 7833 ldrb r3, [r6, #0] + if(hdr == 0) break; + 8000f1e: 2b00 cmp r3, #0 + 8000f20: d045 beq.n 8000fae + + uint8_t len = hdr & 0x7f; + 8000f22: f003 097f and.w r9, r3, #127 ; 0x7f + if(hdr & 0x80) { + 8000f26: 061b lsls r3, r3, #24 + 8000f28: d524 bpl.n 8000f74 + uint8_t hdr = *(p++); + 8000f2a: 3601 adds r6, #1 + // random bytes follow + memcpy(buf, p, len); + 8000f2c: 4631 mov r1, r6 + 8000f2e: 464a mov r2, r9 + 8000f30: 4668 mov r0, sp + 8000f32: f00c fb77 bl 800d624 + p += len; + 8000f36: 444e add r6, r9 + // repeat same byte + memset(buf, *p, len); + p++; + } + + if(!last_line && (offset+len) >= p_start) { + 8000f38: f1b8 0f00 cmp.w r8, #0 + 8000f3c: d117 bne.n 8000f6e + 8000f3e: eb04 0309 add.w r3, r4, r9 + 8000f42: f5b3 7f60 cmp.w r3, #896 ; 0x380 + 8000f46: db29 blt.n 8000f9c + last_line = true; + + // adjust so we're aligned w/ last line + int h = p_start - offset; + if(h) { + 8000f48: f5d4 7460 rsbs r4, r4, #896 ; 0x380 + 8000f4c: d00d beq.n 8000f6a + write_bytes(h, buf); + 8000f4e: 4669 mov r1, sp + 8000f50: 4620 mov r0, r4 + memmove(buf, buf+h, len-h); + 8000f52: eba9 0904 sub.w r9, r9, r4 + write_bytes(h, buf); + 8000f56: f7ff fe69 bl 8000c2c + memmove(buf, buf+h, len-h); + 8000f5a: 464a mov r2, r9 + 8000f5c: eb0d 0104 add.w r1, sp, r4 + 8000f60: 4668 mov r0, sp + 8000f62: f00c fb6d bl 800d640 + len -= h; + 8000f66: fa5f f989 uxtb.w r9, r9 + offset += h; + 8000f6a: f44f 7460 mov.w r4, #896 ; 0x380 + } + } + + if(last_line) { + 8000f6e: 466b mov r3, sp + while(1) { + 8000f70: 462f mov r7, r5 + 8000f72: e00c b.n 8000f8e + memset(buf, *p, len); + 8000f74: 7871 ldrb r1, [r6, #1] + 8000f76: 464a mov r2, r9 + 8000f78: 4668 mov r0, sp + 8000f7a: f00c fb7b bl 800d674 + p++; + 8000f7e: 3602 adds r6, #2 + 8000f80: e7da b.n 8000f38 + for(int j=0; (p_count > 0) && (j 0) && (j + 8000f90: 1bea subs r2, r5, r7 + 8000f92: 454a cmp r2, r9 + 8000f94: dbf5 blt.n 8000f82 + 8000f96: f04f 0801 mov.w r8, #1 + 8000f9a: e000 b.n 8000f9e + 8000f9c: 462f mov r7, r5 + } + } + + write_bytes(len, buf); + 8000f9e: 4669 mov r1, sp + 8000fa0: 4648 mov r0, r9 + offset += len; + 8000fa2: 444c add r4, r9 + write_bytes(len, buf); + 8000fa4: f7ff fe42 bl 8000c2c + offset += len; + 8000fa8: b2a4 uxth r4, r4 + while(1) { + 8000faa: 463d mov r5, r7 + 8000fac: e7b6 b.n 8000f1c + } + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000fae: 2201 movs r2, #1 + 8000fb0: 2110 movs r1, #16 + 8000fb2: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000fb6: f000 f9a5 bl 8001304 + rng_delay(); + 8000fba: f001 fbdf bl 800277c +} + 8000fbe: b021 add sp, #132 ; 0x84 + 8000fc0: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 8000fc4: 0800d7b9 .word 0x0800d7b9 + +08000fc8 : + +// oled_factory_busy() +// + void +oled_factory_busy(void) +{ + 8000fc8: b510 push {r4, lr} + 8000fca: b0a0 sub sp, #128 ; 0x80 + 8000fcc: 466a mov r2, sp + 8000fce: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8000fd2: 4614 mov r4, r2 + }; + uint8_t data[128]; + + for(int x=0; x<128; x++) { + // each byte here is a vertical column, 8 pixels tall, MSB at bottom + data[x] = (1<<(7 - (x%8))); + 8000fd4: 2001 movs r0, #1 + 8000fd6: f003 0107 and.w r1, r3, #7 + for(int x=0; x<128; x++) { + 8000fda: 3b01 subs r3, #1 + data[x] = (1<<(7 - (x%8))); + 8000fdc: fa00 f101 lsl.w r1, r0, r1 + for(int x=0; x<128; x++) { + 8000fe0: f113 0f81 cmn.w r3, #129 ; 0x81 + data[x] = (1<<(7 - (x%8))); + 8000fe4: f802 1b01 strb.w r1, [r2], #1 + for(int x=0; x<128; x++) { + 8000fe8: d1f5 bne.n 8000fd6 + } + + oled_write_cmd_sequence(sizeof(setup), setup); + 8000fea: 4907 ldr r1, [pc, #28] ; (8001008 ) + 8000fec: 2006 movs r0, #6 + 8000fee: f7ff fe49 bl 8000c84 + oled_write_data(sizeof(data), data); + 8000ff2: 4621 mov r1, r4 + 8000ff4: 2080 movs r0, #128 ; 0x80 + 8000ff6: f7ff fe51 bl 8000c9c + oled_write_cmd_sequence(sizeof(animate), animate); + 8000ffa: 4904 ldr r1, [pc, #16] ; (800100c ) + 8000ffc: 2009 movs r0, #9 + 8000ffe: f7ff fe41 bl 8000c84 +} + 8001002: b020 add sp, #128 ; 0x80 + 8001004: bd10 pop {r4, pc} + 8001006: bf00 nop + 8001008: 0800d7d8 .word 0x0800d7d8 + 800100c: 0800d7b0 .word 0x0800d7b0 + +08001010 : + * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + 8001010: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 8001014: f8df 81b4 ldr.w r8, [pc, #436] ; 80011cc + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + SYSCFG->EXTICR[position >> 2] = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->IMR1; + 8001018: 4c6a ldr r4, [pc, #424] ; (80011c4 ) + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 800101a: f8df 91b4 ldr.w r9, [pc, #436] ; 80011d0 +{ + 800101e: b085 sub sp, #20 + uint32_t position = 0x00; + 8001020: 2300 movs r3, #0 + while (((GPIO_Init->Pin) >> position) != RESET) + 8001022: 680a ldr r2, [r1, #0] + 8001024: fa32 f503 lsrs.w r5, r2, r3 + 8001028: d102 bne.n 8001030 + } + } + + position++; + } +} + 800102a: b005 add sp, #20 + 800102c: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + iocurrent = (GPIO_Init->Pin) & (1U << position); + 8001030: 2701 movs r7, #1 + 8001032: 409f lsls r7, r3 + if(iocurrent) + 8001034: 403a ands r2, r7 + 8001036: f000 80b4 beq.w 80011a2 + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 800103a: 684d ldr r5, [r1, #4] + 800103c: f025 0a10 bic.w sl, r5, #16 + 8001040: f1ba 0f02 cmp.w sl, #2 + 8001044: d116 bne.n 8001074 + temp = GPIOx->AFR[position >> 3]; + 8001046: ea4f 0ed3 mov.w lr, r3, lsr #3 + 800104a: eb00 0e8e add.w lr, r0, lr, lsl #2 + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 800104e: f003 0b07 and.w fp, r3, #7 + temp = GPIOx->AFR[position >> 3]; + 8001052: f8de 6020 ldr.w r6, [lr, #32] + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 8001056: ea4f 0b8b mov.w fp, fp, lsl #2 + 800105a: f04f 0c0f mov.w ip, #15 + 800105e: fa0c fc0b lsl.w ip, ip, fp + 8001062: ea26 0c0c bic.w ip, r6, ip + temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4)); + 8001066: 690e ldr r6, [r1, #16] + 8001068: fa06 f60b lsl.w r6, r6, fp + 800106c: ea46 060c orr.w r6, r6, ip + GPIOx->AFR[position >> 3] = temp; + 8001070: f8ce 6020 str.w r6, [lr, #32] + temp = GPIOx->MODER; + 8001074: f8d0 b000 ldr.w fp, [r0] + temp &= ~(GPIO_MODER_MODE0 << (position * 2)); + 8001078: ea4f 0e43 mov.w lr, r3, lsl #1 + 800107c: f04f 0c03 mov.w ip, #3 + 8001080: fa0c fc0e lsl.w ip, ip, lr + 8001084: ea6f 060c mvn.w r6, ip + 8001088: ea2b 0b0c bic.w fp, fp, ip + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + 800108c: f005 0c03 and.w ip, r5, #3 + 8001090: fa0c fc0e lsl.w ip, ip, lr + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 8001094: f10a 3aff add.w sl, sl, #4294967295 ; 0xffffffff + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + 8001098: ea4c 0c0b orr.w ip, ip, fp + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 800109c: f1ba 0f01 cmp.w sl, #1 + temp &= ~(GPIO_MODER_MODE0 << (position * 2)); + 80010a0: 9601 str r6, [sp, #4] + GPIOx->MODER = temp; + 80010a2: f8c0 c000 str.w ip, [r0] + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 80010a6: d815 bhi.n 80010d4 + temp = GPIOx->OSPEEDR; + 80010a8: f8d0 c008 ldr.w ip, [r0, #8] + temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2)); + 80010ac: ea06 0c0c and.w ip, r6, ip + temp |= (GPIO_Init->Speed << (position * 2)); + 80010b0: 68ce ldr r6, [r1, #12] + 80010b2: fa06 fa0e lsl.w sl, r6, lr + 80010b6: ea4a 0c0c orr.w ip, sl, ip + GPIOx->OSPEEDR = temp; + 80010ba: f8c0 c008 str.w ip, [r0, #8] + temp = GPIOx->OTYPER; + 80010be: f8d0 c004 ldr.w ip, [r0, #4] + temp &= ~(GPIO_OTYPER_OT0 << position) ; + 80010c2: ea2c 0707 bic.w r7, ip, r7 + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position); + 80010c6: f3c5 1c00 ubfx ip, r5, #4, #1 + 80010ca: fa0c fc03 lsl.w ip, ip, r3 + 80010ce: ea4c 0707 orr.w r7, ip, r7 + GPIOx->OTYPER = temp; + 80010d2: 6047 str r7, [r0, #4] + temp = GPIOx->PUPDR; + 80010d4: 68c7 ldr r7, [r0, #12] + temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2)); + 80010d6: 9e01 ldr r6, [sp, #4] + 80010d8: 4037 ands r7, r6 + temp |= ((GPIO_Init->Pull) << (position * 2)); + 80010da: 688e ldr r6, [r1, #8] + 80010dc: fa06 f60e lsl.w r6, r6, lr + 80010e0: 433e orrs r6, r7 + GPIOx->PUPDR = temp; + 80010e2: 60c6 str r6, [r0, #12] + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + 80010e4: 00ee lsls r6, r5, #3 + 80010e6: d55c bpl.n 80011a2 + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80010e8: f8d8 6060 ldr.w r6, [r8, #96] ; 0x60 + 80010ec: f046 0601 orr.w r6, r6, #1 + 80010f0: f8c8 6060 str.w r6, [r8, #96] ; 0x60 + 80010f4: f8d8 6060 ldr.w r6, [r8, #96] ; 0x60 + 80010f8: f023 0703 bic.w r7, r3, #3 + 80010fc: f107 4780 add.w r7, r7, #1073741824 ; 0x40000000 + 8001100: f006 0601 and.w r6, r6, #1 + 8001104: f507 3780 add.w r7, r7, #65536 ; 0x10000 + 8001108: 9603 str r6, [sp, #12] + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 800110a: f003 0c03 and.w ip, r3, #3 + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 800110e: 9e03 ldr r6, [sp, #12] + temp = SYSCFG->EXTICR[position >> 2]; + 8001110: f8d7 a008 ldr.w sl, [r7, #8] + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001114: f04f 0e0f mov.w lr, #15 + 8001118: ea4f 0c8c mov.w ip, ip, lsl #2 + 800111c: fa0e f60c lsl.w r6, lr, ip + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 8001120: f1b0 4f90 cmp.w r0, #1207959552 ; 0x48000000 + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001124: ea2a 0e06 bic.w lr, sl, r6 + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 8001128: d03d beq.n 80011a6 + 800112a: 4e27 ldr r6, [pc, #156] ; (80011c8 ) + 800112c: 42b0 cmp r0, r6 + 800112e: d03c beq.n 80011aa + 8001130: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001134: 42b0 cmp r0, r6 + 8001136: d03a beq.n 80011ae + 8001138: f506 6680 add.w r6, r6, #1024 ; 0x400 + 800113c: 42b0 cmp r0, r6 + 800113e: d038 beq.n 80011b2 + 8001140: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001144: 42b0 cmp r0, r6 + 8001146: d036 beq.n 80011b6 + 8001148: f506 6680 add.w r6, r6, #1024 ; 0x400 + 800114c: 42b0 cmp r0, r6 + 800114e: d034 beq.n 80011ba + 8001150: 4548 cmp r0, r9 + 8001152: d034 beq.n 80011be + 8001154: f506 6600 add.w r6, r6, #2048 ; 0x800 + 8001158: 42b0 cmp r0, r6 + 800115a: bf0c ite eq + 800115c: 2607 moveq r6, #7 + 800115e: 2608 movne r6, #8 + 8001160: fa06 f60c lsl.w r6, r6, ip + 8001164: ea46 060e orr.w r6, r6, lr + SYSCFG->EXTICR[position >> 2] = temp; + 8001168: 60be str r6, [r7, #8] + temp = EXTI->IMR1; + 800116a: 6826 ldr r6, [r4, #0] + temp &= ~((uint32_t)iocurrent); + 800116c: 43d7 mvns r7, r2 + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + 800116e: f415 3f80 tst.w r5, #65536 ; 0x10000 + temp &= ~((uint32_t)iocurrent); + 8001172: bf0c ite eq + 8001174: 403e andeq r6, r7 + temp |= iocurrent; + 8001176: 4316 orrne r6, r2 + EXTI->IMR1 = temp; + 8001178: 6026 str r6, [r4, #0] + temp = EXTI->EMR1; + 800117a: 6866 ldr r6, [r4, #4] + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + 800117c: f415 3f00 tst.w r5, #131072 ; 0x20000 + temp &= ~((uint32_t)iocurrent); + 8001180: bf0c ite eq + 8001182: 403e andeq r6, r7 + temp |= iocurrent; + 8001184: 4316 orrne r6, r2 + EXTI->EMR1 = temp; + 8001186: 6066 str r6, [r4, #4] + temp = EXTI->RTSR1; + 8001188: 68a6 ldr r6, [r4, #8] + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + 800118a: f415 1f80 tst.w r5, #1048576 ; 0x100000 + temp &= ~((uint32_t)iocurrent); + 800118e: bf0c ite eq + 8001190: 403e andeq r6, r7 + temp |= iocurrent; + 8001192: 4316 orrne r6, r2 + EXTI->RTSR1 = temp; + 8001194: 60a6 str r6, [r4, #8] + temp = EXTI->FTSR1; + 8001196: 68e6 ldr r6, [r4, #12] + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + 8001198: 02ad lsls r5, r5, #10 + temp &= ~((uint32_t)iocurrent); + 800119a: bf54 ite pl + 800119c: 403e andpl r6, r7 + temp |= iocurrent; + 800119e: 4316 orrmi r6, r2 + EXTI->FTSR1 = temp; + 80011a0: 60e6 str r6, [r4, #12] + position++; + 80011a2: 3301 adds r3, #1 + 80011a4: e73d b.n 8001022 + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 80011a6: 2600 movs r6, #0 + 80011a8: e7da b.n 8001160 + 80011aa: 2601 movs r6, #1 + 80011ac: e7d8 b.n 8001160 + 80011ae: 2602 movs r6, #2 + 80011b0: e7d6 b.n 8001160 + 80011b2: 2603 movs r6, #3 + 80011b4: e7d4 b.n 8001160 + 80011b6: 2604 movs r6, #4 + 80011b8: e7d2 b.n 8001160 + 80011ba: 2605 movs r6, #5 + 80011bc: e7d0 b.n 8001160 + 80011be: 2606 movs r6, #6 + 80011c0: e7ce b.n 8001160 + 80011c2: bf00 nop + 80011c4: 40010400 .word 0x40010400 + 80011c8: 48000400 .word 0x48000400 + 80011cc: 40021000 .word 0x40021000 + 80011d0: 48001800 .word 0x48001800 + +080011d4 : + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + 80011d4: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + { + tmp = ((uint32_t)0x0F) << (4 * (position & 0x03)); + SYSCFG->EXTICR[position >> 2] &= ~tmp; + + /* Clear EXTI line configuration */ + EXTI->IMR1 &= ~((uint32_t)iocurrent); + 80011d8: 4c43 ldr r4, [pc, #268] ; (80012e8 ) + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 80011da: f8df a114 ldr.w sl, [pc, #276] ; 80012f0 + 80011de: f8df b114 ldr.w fp, [pc, #276] ; 80012f4 + uint32_t position = 0x00; + 80011e2: 2200 movs r2, #0 + iocurrent = (GPIO_Pin) & (1U << position); + 80011e4: f04f 0901 mov.w r9, #1 + while ((GPIO_Pin >> position) != RESET) + 80011e8: fa31 f302 lsrs.w r3, r1, r2 + 80011ec: d101 bne.n 80011f2 + } + } + + position++; + } +} + 80011ee: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + iocurrent = (GPIO_Pin) & (1U << position); + 80011f2: fa09 f802 lsl.w r8, r9, r2 + if (iocurrent) + 80011f6: ea18 0c01 ands.w ip, r8, r1 + 80011fa: d064 beq.n 80012c6 + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2)); + 80011fc: 6805 ldr r5, [r0, #0] + 80011fe: 2303 movs r3, #3 + 8001200: 0056 lsls r6, r2, #1 + 8001202: fa03 f606 lsl.w r6, r3, r6 + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 8001206: fa22 fe03 lsr.w lr, r2, r3 + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2)); + 800120a: 4335 orrs r5, r6 + 800120c: eb00 0e8e add.w lr, r0, lr, lsl #2 + 8001210: 6005 str r5, [r0, #0] + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 8001212: f8de 5020 ldr.w r5, [lr, #32] + 8001216: f002 0707 and.w r7, r2, #7 + 800121a: 462b mov r3, r5 + 800121c: 00bf lsls r7, r7, #2 + 800121e: 250f movs r5, #15 + 8001220: fa05 f707 lsl.w r7, r5, r7 + 8001224: ea23 0707 bic.w r7, r3, r7 + 8001228: f8ce 7020 str.w r7, [lr, #32] + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2)); + 800122c: 6887 ldr r7, [r0, #8] + 800122e: ea27 0706 bic.w r7, r7, r6 + 8001232: 6087 str r7, [r0, #8] + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ; + 8001234: 6847 ldr r7, [r0, #4] + 8001236: ea27 0708 bic.w r7, r7, r8 + 800123a: 6047 str r7, [r0, #4] + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2)); + 800123c: 68c7 ldr r7, [r0, #12] + 800123e: ea27 0606 bic.w r6, r7, r6 + 8001242: 60c6 str r6, [r0, #12] + tmp = SYSCFG->EXTICR[position >> 2]; + 8001244: f022 0603 bic.w r6, r2, #3 + 8001248: f106 4680 add.w r6, r6, #1073741824 ; 0x40000000 + 800124c: f506 3680 add.w r6, r6, #65536 ; 0x10000 + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001250: f002 0703 and.w r7, r2, #3 + tmp = SYSCFG->EXTICR[position >> 2]; + 8001254: f8d6 e008 ldr.w lr, [r6, #8] + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001258: 00bf lsls r7, r7, #2 + 800125a: 40bd lsls r5, r7 + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 800125c: f1b0 4f90 cmp.w r0, #1207959552 ; 0x48000000 + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001260: ea05 0e0e and.w lr, r5, lr + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 8001264: d031 beq.n 80012ca + 8001266: 4b21 ldr r3, [pc, #132] ; (80012ec ) + 8001268: 4298 cmp r0, r3 + 800126a: d030 beq.n 80012ce + 800126c: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001270: 4298 cmp r0, r3 + 8001272: d02e beq.n 80012d2 + 8001274: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001278: 4298 cmp r0, r3 + 800127a: d02c beq.n 80012d6 + 800127c: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001280: 4298 cmp r0, r3 + 8001282: d02a beq.n 80012da + 8001284: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001288: 4298 cmp r0, r3 + 800128a: d028 beq.n 80012de + 800128c: 4550 cmp r0, sl + 800128e: d028 beq.n 80012e2 + 8001290: 4558 cmp r0, fp + 8001292: bf0c ite eq + 8001294: 2307 moveq r3, #7 + 8001296: 2308 movne r3, #8 + 8001298: 40bb lsls r3, r7 + 800129a: 4573 cmp r3, lr + 800129c: d113 bne.n 80012c6 + SYSCFG->EXTICR[position >> 2] &= ~tmp; + 800129e: 68b3 ldr r3, [r6, #8] + 80012a0: ea23 0505 bic.w r5, r3, r5 + 80012a4: 60b5 str r5, [r6, #8] + EXTI->IMR1 &= ~((uint32_t)iocurrent); + 80012a6: 6823 ldr r3, [r4, #0] + 80012a8: ea23 030c bic.w r3, r3, ip + 80012ac: 6023 str r3, [r4, #0] + EXTI->EMR1 &= ~((uint32_t)iocurrent); + 80012ae: 6863 ldr r3, [r4, #4] + 80012b0: ea23 030c bic.w r3, r3, ip + 80012b4: 6063 str r3, [r4, #4] + EXTI->RTSR1 &= ~((uint32_t)iocurrent); + 80012b6: 68a3 ldr r3, [r4, #8] + 80012b8: ea23 030c bic.w r3, r3, ip + 80012bc: 60a3 str r3, [r4, #8] + EXTI->FTSR1 &= ~((uint32_t)iocurrent); + 80012be: 68e3 ldr r3, [r4, #12] + 80012c0: ea23 030c bic.w r3, r3, ip + 80012c4: 60e3 str r3, [r4, #12] + position++; + 80012c6: 3201 adds r2, #1 + 80012c8: e78e b.n 80011e8 + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 80012ca: 2300 movs r3, #0 + 80012cc: e7e4 b.n 8001298 + 80012ce: 2301 movs r3, #1 + 80012d0: e7e2 b.n 8001298 + 80012d2: 2302 movs r3, #2 + 80012d4: e7e0 b.n 8001298 + 80012d6: 2303 movs r3, #3 + 80012d8: e7de b.n 8001298 + 80012da: 2304 movs r3, #4 + 80012dc: e7dc b.n 8001298 + 80012de: 2305 movs r3, #5 + 80012e0: e7da b.n 8001298 + 80012e2: 2306 movs r3, #6 + 80012e4: e7d8 b.n 8001298 + 80012e6: bf00 nop + 80012e8: 40010400 .word 0x40010400 + 80012ec: 48000400 .word 0x48000400 + 80012f0: 48001800 .word 0x48001800 + 80012f4: 48001c00 .word 0x48001c00 + +080012f8 : + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + 80012f8: 6903 ldr r3, [r0, #16] + 80012fa: 4219 tst r1, r3 + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + 80012fc: bf14 ite ne + 80012fe: 2001 movne r0, #1 + 8001300: 2000 moveq r0, #0 + 8001302: 4770 bx lr + +08001304 : +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if(PinState != GPIO_PIN_RESET) + 8001304: b10a cbz r2, 800130a + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + 8001306: 6181 str r1, [r0, #24] + 8001308: 4770 bx lr + } + else + { + GPIOx->BRR = (uint32_t)GPIO_Pin; + 800130a: 6281 str r1, [r0, #40] ; 0x28 + } +} + 800130c: 4770 bx lr + +0800130e : +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->ODR ^= GPIO_Pin; + 800130e: 6943 ldr r3, [r0, #20] + 8001310: 4059 eors r1, r3 + 8001312: 6141 str r1, [r0, #20] +} + 8001314: 4770 bx lr + +08001316 : + * @param GPIO_Pin: specifies the port bits to be locked. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + 8001316: b082 sub sp, #8 + __IO uint32_t tmp = GPIO_LCKR_LCKK; + 8001318: f44f 3380 mov.w r3, #65536 ; 0x10000 + 800131c: 9301 str r3, [sp, #4] + /* Check the parameters */ + assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + tmp |= GPIO_Pin; + 800131e: 9b01 ldr r3, [sp, #4] + 8001320: 430b orrs r3, r1 + 8001322: 9301 str r3, [sp, #4] + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + 8001324: 9b01 ldr r3, [sp, #4] + 8001326: 61c3 str r3, [r0, #28] + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + 8001328: 61c1 str r1, [r0, #28] + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + 800132a: 9b01 ldr r3, [sp, #4] + 800132c: 61c3 str r3, [r0, #28] + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + 800132e: 69c3 ldr r3, [r0, #28] + 8001330: 9301 str r3, [sp, #4] + + if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET) + 8001332: 69c0 ldr r0, [r0, #28] + 8001334: f480 3080 eor.w r0, r0, #65536 ; 0x10000 + } + else + { + return HAL_ERROR; + } +} + 8001338: f3c0 4000 ubfx r0, r0, #16, #1 + 800133c: b002 add sp, #8 + 800133e: 4770 bx lr + +08001340 : + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + 8001340: 4770 bx lr + ... + +08001344 : + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + 8001344: 4a04 ldr r2, [pc, #16] ; (8001358 ) + 8001346: 6951 ldr r1, [r2, #20] + 8001348: 4201 tst r1, r0 +{ + 800134a: b508 push {r3, lr} + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + 800134c: d002 beq.n 8001354 + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + 800134e: 6150 str r0, [r2, #20] + HAL_GPIO_EXTI_Callback(GPIO_Pin); + 8001350: f7ff fff6 bl 8001340 +} + 8001354: bd08 pop {r3, pc} + 8001356: bf00 nop + 8001358: 40010400 .word 0x40010400 + +0800135c : +static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, uint32_t State, + uint32_t Timeout, uint32_t Tickstart) +{ + __IO uint8_t tmpreg; + + while ((hspi->Instance->SR & Fifo) != State) + 800135c: 6803 ldr r3, [r0, #0] +static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) + 800135e: b082 sub sp, #8 + while ((hspi->Instance->SR & Fifo) != State) + 8001360: 689a ldr r2, [r3, #8] + 8001362: f412 5fc0 tst.w r2, #6144 ; 0x1800 + 8001366: d1fb bne.n 8001360 + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, + uint32_t Timeout, uint32_t Tickstart) +{ + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001368: 689a ldr r2, [r3, #8] + 800136a: 0612 lsls r2, r2, #24 + 800136c: d4fc bmi.n 8001368 + while ((hspi->Instance->SR & Fifo) != State) + 800136e: 6898 ldr r0, [r3, #8] + 8001370: f410 60c0 ands.w r0, r0, #1536 ; 0x600 + 8001374: d101 bne.n 800137a +} + 8001376: b002 add sp, #8 + 8001378: 4770 bx lr + tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); + 800137a: 7b1a ldrb r2, [r3, #12] + 800137c: b2d2 uxtb r2, r2 + 800137e: f88d 2007 strb.w r2, [sp, #7] + UNUSED(tmpreg); + 8001382: f89d 2007 ldrb.w r2, [sp, #7] + 8001386: e7f2 b.n 800136e + +08001388 : +{ + 8001388: b5f0 push {r4, r5, r6, r7, lr} + if (hspi == NULL) + 800138a: 2800 cmp r0, #0 + 800138c: d054 beq.n 8001438 + if (hspi->State == HAL_SPI_STATE_RESET) + 800138e: f890 305d ldrb.w r3, [r0, #93] ; 0x5d + if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) + 8001392: f8d0 c024 ldr.w ip, [r0, #36] ; 0x24 + if (hspi->State == HAL_SPI_STATE_RESET) + 8001396: f003 02ff and.w r2, r3, #255 ; 0xff + 800139a: b90b cbnz r3, 80013a0 + hspi->Lock = HAL_UNLOCKED; + 800139c: f880 205c strb.w r2, [r0, #92] ; 0x5c + __HAL_SPI_DISABLE(hspi); + 80013a0: 6801 ldr r1, [r0, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80013a2: 68c2 ldr r2, [r0, #12] + hspi->State = HAL_SPI_STATE_BUSY; + 80013a4: 2302 movs r3, #2 + 80013a6: f880 305d strb.w r3, [r0, #93] ; 0x5d + __HAL_SPI_DISABLE(hspi); + 80013aa: 680b ldr r3, [r1, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80013ac: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + __HAL_SPI_DISABLE(hspi); + 80013b0: f023 0340 bic.w r3, r3, #64 ; 0x40 + 80013b4: 600b str r3, [r1, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80013b6: f04f 0300 mov.w r3, #0 + 80013ba: d83f bhi.n 800143c + frxth = SPI_RXFIFO_THRESHOLD_QF; + 80013bc: f44f 5580 mov.w r5, #4096 ; 0x1000 + if ((hspi->Init.DataSize != SPI_DATASIZE_16BIT) && (hspi->Init.DataSize != SPI_DATASIZE_8BIT)) + 80013c0: d000 beq.n 80013c4 + hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + 80013c2: 6283 str r3, [r0, #40] ; 0x28 + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE) + 80013c4: 6b03 ldr r3, [r0, #48] ; 0x30 + 80013c6: b92b cbnz r3, 80013d4 + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80013c8: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT; + 80013cc: bf8c ite hi + 80013ce: 2302 movhi r3, #2 + hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT; + 80013d0: 2301 movls r3, #1 + 80013d2: 6303 str r3, [r0, #48] ; 0x30 + WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | + 80013d4: e9d0 3701 ldrd r3, r7, [r0, #4] + 80013d8: 433b orrs r3, r7 + 80013da: 6907 ldr r7, [r0, #16] + 80013dc: 6984 ldr r4, [r0, #24] + 80013de: 6a86 ldr r6, [r0, #40] ; 0x28 + 80013e0: 433b orrs r3, r7 + 80013e2: 6947 ldr r7, [r0, #20] + 80013e4: 433b orrs r3, r7 + 80013e6: 69c7 ldr r7, [r0, #28] + 80013e8: 433b orrs r3, r7 + 80013ea: 6a07 ldr r7, [r0, #32] + 80013ec: 433b orrs r3, r7 + 80013ee: 4333 orrs r3, r6 + 80013f0: f404 7700 and.w r7, r4, #512 ; 0x200 + 80013f4: 433b orrs r3, r7 + 80013f6: 600b str r3, [r1, #0] + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + 80013f8: 6b03 ldr r3, [r0, #48] ; 0x30 + 80013fa: 2b02 cmp r3, #2 + hspi->Instance->CR1 |= SPI_CR1_CRCL; + 80013fc: bf02 ittt eq + 80013fe: 680b ldreq r3, [r1, #0] + 8001400: f443 6300 orreq.w r3, r3, #2048 ; 0x800 + 8001404: 600b streq r3, [r1, #0] + WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode | + 8001406: 6b43 ldr r3, [r0, #52] ; 0x34 + 8001408: ea4c 0202 orr.w r2, ip, r2 + 800140c: 0c24 lsrs r4, r4, #16 + 800140e: 431a orrs r2, r3 + 8001410: f004 0404 and.w r4, r4, #4 + 8001414: 4322 orrs r2, r4 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001416: f5b6 5f00 cmp.w r6, #8192 ; 0x2000 + WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial); + 800141a: bf08 it eq + 800141c: 6ac3 ldreq r3, [r0, #44] ; 0x2c + WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode | + 800141e: ea45 0502 orr.w r5, r5, r2 + 8001422: 604d str r5, [r1, #4] + hspi->State = HAL_SPI_STATE_READY; + 8001424: f04f 0201 mov.w r2, #1 + WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial); + 8001428: bf08 it eq + 800142a: 610b streq r3, [r1, #16] + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 800142c: 2300 movs r3, #0 + 800142e: 6603 str r3, [r0, #96] ; 0x60 + hspi->State = HAL_SPI_STATE_READY; + 8001430: f880 205d strb.w r2, [r0, #93] ; 0x5d + return HAL_OK; + 8001434: 4618 mov r0, r3 +} + 8001436: bdf0 pop {r4, r5, r6, r7, pc} + return HAL_ERROR; + 8001438: 2001 movs r0, #1 + 800143a: e7fc b.n 8001436 + frxth = SPI_RXFIFO_THRESHOLD_HF; + 800143c: 461d mov r5, r3 + if ((hspi->Init.DataSize != SPI_DATASIZE_16BIT) && (hspi->Init.DataSize != SPI_DATASIZE_8BIT)) + 800143e: f5b2 6f70 cmp.w r2, #3840 ; 0xf00 + 8001442: e7bd b.n 80013c0 + +08001444 : +{ + 8001444: e92d 41f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, lr} + 8001448: 461e mov r6, r3 + __HAL_LOCK(hspi); + 800144a: f890 305c ldrb.w r3, [r0, #92] ; 0x5c + 800144e: 2b01 cmp r3, #1 +{ + 8001450: 4604 mov r4, r0 + 8001452: 460d mov r5, r1 + 8001454: 4690 mov r8, r2 + __HAL_LOCK(hspi); + 8001456: f000 809c beq.w 8001592 + 800145a: 2301 movs r3, #1 + 800145c: f880 305c strb.w r3, [r0, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8001460: f005 fe44 bl 80070ec + if (hspi->State != HAL_SPI_STATE_READY) + 8001464: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + 8001468: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 800146a: 4607 mov r7, r0 + if (hspi->State != HAL_SPI_STATE_READY) + 800146c: b2d8 uxtb r0, r3 + 800146e: f040 808e bne.w 800158e + if ((pData == NULL) || (Size == 0U)) + 8001472: 2d00 cmp r5, #0 + 8001474: d07a beq.n 800156c + 8001476: f1b8 0f00 cmp.w r8, #0 + 800147a: d077 beq.n 800156c + hspi->State = HAL_SPI_STATE_BUSY_TX; + 800147c: 2303 movs r3, #3 + 800147e: f884 305d strb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001482: 68a3 ldr r3, [r4, #8] + SPI_1LINE_TX(hspi); + 8001484: 6822 ldr r2, [r4, #0] + hspi->pTxBuffPtr = (uint8_t *)pData; + 8001486: 63a5 str r5, [r4, #56] ; 0x38 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001488: 2100 movs r1, #0 + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 800148a: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 800148e: 6621 str r1, [r4, #96] ; 0x60 + hspi->TxXferCount = Size; + 8001490: f8a4 803e strh.w r8, [r4, #62] ; 0x3e + hspi->RxXferCount = 0U; + 8001494: f8a4 1046 strh.w r1, [r4, #70] ; 0x46 + SPI_1LINE_TX(hspi); + 8001498: bf08 it eq + 800149a: 6813 ldreq r3, [r2, #0] + hspi->TxXferSize = Size; + 800149c: f8a4 803c strh.w r8, [r4, #60] ; 0x3c + SPI_1LINE_TX(hspi); + 80014a0: bf08 it eq + 80014a2: f443 4380 orreq.w r3, r3, #16384 ; 0x4000 + hspi->RxISR = NULL; + 80014a6: e9c4 1113 strd r1, r1, [r4, #76] ; 0x4c + hspi->pRxBuffPtr = (uint8_t *)NULL; + 80014aa: 6421 str r1, [r4, #64] ; 0x40 + hspi->RxXferSize = 0U; + 80014ac: f8a4 1044 strh.w r1, [r4, #68] ; 0x44 + SPI_1LINE_TX(hspi); + 80014b0: bf08 it eq + 80014b2: 6013 streq r3, [r2, #0] + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80014b4: 6aa3 ldr r3, [r4, #40] ; 0x28 + 80014b6: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 80014ba: d107 bne.n 80014cc + SPI_RESET_CRC(hspi); + 80014bc: 6813 ldr r3, [r2, #0] + 80014be: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 80014c2: 6013 str r3, [r2, #0] + 80014c4: 6813 ldr r3, [r2, #0] + 80014c6: f443 5300 orr.w r3, r3, #8192 ; 0x2000 + 80014ca: 6013 str r3, [r2, #0] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 80014cc: 6813 ldr r3, [r2, #0] + 80014ce: 0659 lsls r1, r3, #25 + __HAL_SPI_ENABLE(hspi); + 80014d0: bf5e ittt pl + 80014d2: 6813 ldrpl r3, [r2, #0] + 80014d4: f043 0340 orrpl.w r3, r3, #64 ; 0x40 + 80014d8: 6013 strpl r3, [r2, #0] + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) + 80014da: 6863 ldr r3, [r4, #4] + 80014dc: b11b cbz r3, 80014e6 + 80014de: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80014e0: b29b uxth r3, r3 + 80014e2: 2b01 cmp r3, #1 + 80014e4: d110 bne.n 8001508 + if (hspi->TxXferCount > 1U) + 80014e6: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80014e8: b29b uxth r3, r3 + 80014ea: 2b01 cmp r3, #1 + 80014ec: d905 bls.n 80014fa + hspi->Instance->DR = *((uint16_t *)pData); + 80014ee: f835 3b02 ldrh.w r3, [r5], #2 + 80014f2: 60d3 str r3, [r2, #12] + hspi->TxXferCount -= 2U; + 80014f4: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80014f6: 3b02 subs r3, #2 + 80014f8: e004 b.n 8001504 + *((__IO uint8_t *)&hspi->Instance->DR) = (*pData++); + 80014fa: f815 3b01 ldrb.w r3, [r5], #1 + 80014fe: 7313 strb r3, [r2, #12] + hspi->TxXferCount--; + 8001500: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 8001502: 3b01 subs r3, #1 + 8001504: b29b uxth r3, r3 + 8001506: 87e3 strh r3, [r4, #62] ; 0x3e + while (hspi->TxXferCount > 0U) + 8001508: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 800150a: b29b uxth r3, r3 + 800150c: b9e3 cbnz r3, 8001548 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 800150e: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8001510: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 8001514: bf01 itttt eq + 8001516: 6822 ldreq r2, [r4, #0] + 8001518: 6813 ldreq r3, [r2, #0] + 800151a: f443 5380 orreq.w r3, r3, #4096 ; 0x1000 + 800151e: 6013 streq r3, [r2, #0] + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + 8001520: 4620 mov r0, r4 + 8001522: f7ff ff1b bl 800135c + 8001526: b108 cbz r0, 800152c + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + 8001528: 2320 movs r3, #32 + 800152a: 6623 str r3, [r4, #96] ; 0x60 + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + 800152c: 68a3 ldr r3, [r4, #8] + 800152e: b933 cbnz r3, 800153e + __HAL_SPI_CLEAR_OVRFLAG(hspi); + 8001530: 9301 str r3, [sp, #4] + 8001532: 6823 ldr r3, [r4, #0] + 8001534: 68da ldr r2, [r3, #12] + 8001536: 9201 str r2, [sp, #4] + 8001538: 689b ldr r3, [r3, #8] + 800153a: 9301 str r3, [sp, #4] + 800153c: 9b01 ldr r3, [sp, #4] + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 800153e: 6e20 ldr r0, [r4, #96] ; 0x60 + errorcode = HAL_BUSY; + 8001540: 3800 subs r0, #0 + 8001542: bf18 it ne + 8001544: 2001 movne r0, #1 +error: + 8001546: e011 b.n 800156c + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) + 8001548: 6823 ldr r3, [r4, #0] + 800154a: 689a ldr r2, [r3, #8] + 800154c: 0792 lsls r2, r2, #30 + 800154e: d50b bpl.n 8001568 + if (hspi->TxXferCount > 1U) + 8001550: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001552: b292 uxth r2, r2 + 8001554: 2a01 cmp r2, #1 + 8001556: d903 bls.n 8001560 + hspi->Instance->DR = *((uint16_t *)pData); + 8001558: f835 2b02 ldrh.w r2, [r5], #2 + 800155c: 60da str r2, [r3, #12] + 800155e: e7c9 b.n 80014f4 + *((__IO uint8_t *)&hspi->Instance->DR) = (*pData++); + 8001560: f815 2b01 ldrb.w r2, [r5], #1 + 8001564: 731a strb r2, [r3, #12] + hspi->TxXferCount--; + 8001566: e7cb b.n 8001500 + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 8001568: b94e cbnz r6, 800157e + errorcode = HAL_TIMEOUT; + 800156a: 2003 movs r0, #3 + hspi->State = HAL_SPI_STATE_READY; + 800156c: 2301 movs r3, #1 + 800156e: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 8001572: 2300 movs r3, #0 + 8001574: f884 305c strb.w r3, [r4, #92] ; 0x5c +} + 8001578: b002 add sp, #8 + 800157a: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 800157e: 1c73 adds r3, r6, #1 + 8001580: d0c2 beq.n 8001508 + 8001582: f005 fdb3 bl 80070ec + 8001586: 1bc0 subs r0, r0, r7 + 8001588: 42b0 cmp r0, r6 + 800158a: d3bd bcc.n 8001508 + 800158c: e7ed b.n 800156a + errorcode = HAL_BUSY; + 800158e: 2002 movs r0, #2 + 8001590: e7ec b.n 800156c + __HAL_LOCK(hspi); + 8001592: 2002 movs r0, #2 + 8001594: e7f0 b.n 8001578 + +08001596 : + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, + uint32_t Timeout) +{ + 8001596: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + 800159a: 461e mov r6, r3 + uint32_t tmp = 0U, tmp1 = 0U; +#if (USE_SPI_CRC != 0U) + __IO uint16_t tmpreg = 0U; + 800159c: 2300 movs r3, #0 + 800159e: f8ad 3006 strh.w r3, [sp, #6] + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + 80015a2: f890 305c ldrb.w r3, [r0, #92] ; 0x5c +{ + 80015a6: f8dd 8028 ldr.w r8, [sp, #40] ; 0x28 + __HAL_LOCK(hspi); + 80015aa: 2b01 cmp r3, #1 +{ + 80015ac: 4604 mov r4, r0 + 80015ae: 460d mov r5, r1 + 80015b0: 4617 mov r7, r2 + __HAL_LOCK(hspi); + 80015b2: f000 8124 beq.w 80017fe + 80015b6: 2301 movs r3, #1 + 80015b8: f880 305c strb.w r3, [r0, #92] ; 0x5c + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + 80015bc: f005 fd96 bl 80070ec + + tmp = hspi->State; + 80015c0: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + tmp1 = hspi->Init.Mode; + 80015c4: 6861 ldr r1, [r4, #4] + + if (!((tmp == HAL_SPI_STATE_READY) || \ + 80015c6: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 80015c8: 4681 mov r9, r0 + tmp = hspi->State; + 80015ca: b2da uxtb r2, r3 + if (!((tmp == HAL_SPI_STATE_READY) || \ + 80015cc: d00a beq.n 80015e4 + 80015ce: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 80015d2: f040 8112 bne.w 80017fa + ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX)))) + 80015d6: 68a3 ldr r3, [r4, #8] + 80015d8: 2b00 cmp r3, #0 + 80015da: f040 810e bne.w 80017fa + 80015de: 2a04 cmp r2, #4 + 80015e0: f040 810b bne.w 80017fa + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + 80015e4: b955 cbnz r5, 80015fc + { + errorcode = HAL_ERROR; + 80015e6: 2101 movs r1, #1 + { + errorcode = HAL_ERROR; + } + +error : + hspi->State = HAL_SPI_STATE_READY; + 80015e8: 2301 movs r3, #1 + 80015ea: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 80015ee: 2300 movs r3, #0 + 80015f0: f884 305c strb.w r3, [r4, #92] ; 0x5c + return errorcode; +} + 80015f4: 4608 mov r0, r1 + 80015f6: b003 add sp, #12 + 80015f8: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + 80015fc: 2f00 cmp r7, #0 + 80015fe: d0f2 beq.n 80015e6 + 8001600: 2e00 cmp r6, #0 + 8001602: d0f0 beq.n 80015e6 + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + 8001604: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001608: 6aa2 ldr r2, [r4, #40] ; 0x28 + hspi->pRxBuffPtr = (uint8_t *)pRxData; + 800160a: 6427 str r7, [r4, #64] ; 0x40 + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + 800160c: 2b04 cmp r3, #4 + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + 800160e: bf1c itt ne + 8001610: 2305 movne r3, #5 + 8001612: f884 305d strbne.w r3, [r4, #93] ; 0x5d + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001616: 2300 movs r3, #0 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001618: f5b2 5f00 cmp.w r2, #8192 ; 0x2000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 800161c: 6623 str r3, [r4, #96] ; 0x60 + hspi->TxISR = NULL; + 800161e: e9c4 3313 strd r3, r3, [r4, #76] ; 0x4c + hspi->RxXferCount = Size; + 8001622: f8a4 6046 strh.w r6, [r4, #70] ; 0x46 + SPI_RESET_CRC(hspi); + 8001626: 6823 ldr r3, [r4, #0] + hspi->RxXferSize = Size; + 8001628: f8a4 6044 strh.w r6, [r4, #68] ; 0x44 + hspi->pTxBuffPtr = (uint8_t *)pTxData; + 800162c: 63a5 str r5, [r4, #56] ; 0x38 + hspi->TxXferCount = Size; + 800162e: 87e6 strh r6, [r4, #62] ; 0x3e + hspi->TxXferSize = Size; + 8001630: 87a6 strh r6, [r4, #60] ; 0x3c + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001632: d107 bne.n 8001644 + SPI_RESET_CRC(hspi); + 8001634: 681a ldr r2, [r3, #0] + 8001636: f422 5200 bic.w r2, r2, #8192 ; 0x2000 + 800163a: 601a str r2, [r3, #0] + 800163c: 681a ldr r2, [r3, #0] + 800163e: f442 5200 orr.w r2, r2, #8192 ; 0x2000 + 8001642: 601a str r2, [r3, #0] + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount > 1U)) + 8001644: 68e2 ldr r2, [r4, #12] + 8001646: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + 800164a: d804 bhi.n 8001656 + 800164c: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001650: b292 uxth r2, r2 + 8001652: 2a01 cmp r2, #1 + 8001654: d94e bls.n 80016f4 + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 8001656: 685a ldr r2, [r3, #4] + 8001658: f422 5280 bic.w r2, r2, #4096 ; 0x1000 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 800165c: 605a str r2, [r3, #4] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 800165e: 681a ldr r2, [r3, #0] + 8001660: 0650 lsls r0, r2, #25 + __HAL_SPI_ENABLE(hspi); + 8001662: bf5e ittt pl + 8001664: 681a ldrpl r2, [r3, #0] + 8001666: f042 0240 orrpl.w r2, r2, #64 ; 0x40 + 800166a: 601a strpl r2, [r3, #0] + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) + 800166c: b119 cbz r1, 8001676 + 800166e: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001670: b292 uxth r2, r2 + 8001672: 2a01 cmp r2, #1 + 8001674: d10a bne.n 800168c + if (hspi->TxXferCount > 1U) + 8001676: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001678: b292 uxth r2, r2 + 800167a: 2a01 cmp r2, #1 + 800167c: d93e bls.n 80016fc + hspi->Instance->DR = *((uint16_t *)pTxData); + 800167e: f835 2b02 ldrh.w r2, [r5], #2 + 8001682: 60da str r2, [r3, #12] + hspi->TxXferCount -= 2U; + 8001684: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 8001686: 3b02 subs r3, #2 + 8001688: b29b uxth r3, r3 + 800168a: 87e3 strh r3, [r4, #62] ; 0x3e + txallowed = 1U; + 800168c: 2601 movs r6, #1 + while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) + 800168e: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 8001690: b29b uxth r3, r3 + 8001692: 2b00 cmp r3, #0 + 8001694: d138 bne.n 8001708 + 8001696: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 800169a: b29b uxth r3, r3 + 800169c: 2b00 cmp r3, #0 + 800169e: d133 bne.n 8001708 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80016a0: 6aa2 ldr r2, [r4, #40] ; 0x28 + if (txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) + 80016a2: 6823 ldr r3, [r4, #0] + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80016a4: f5b2 5f00 cmp.w r2, #8192 ; 0x2000 + 80016a8: d10d bne.n 80016c6 + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 80016aa: 689a ldr r2, [r3, #8] + 80016ac: 07d1 lsls r1, r2, #31 + 80016ae: d5fc bpl.n 80016aa + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + 80016b0: 68e2 ldr r2, [r4, #12] + 80016b2: f5b2 6f70 cmp.w r2, #3840 ; 0xf00 + 80016b6: f040 8092 bne.w 80017de + tmpreg = hspi->Instance->DR; + 80016ba: 68da ldr r2, [r3, #12] + 80016bc: b292 uxth r2, r2 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80016be: f8ad 2006 strh.w r2, [sp, #6] + UNUSED(tmpreg); + 80016c2: f8bd 2006 ldrh.w r2, [sp, #6] + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + 80016c6: 6899 ldr r1, [r3, #8] + 80016c8: f011 0110 ands.w r1, r1, #16 + 80016cc: d007 beq.n 80016de + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + 80016ce: 6e22 ldr r2, [r4, #96] ; 0x60 + 80016d0: f042 0202 orr.w r2, r2, #2 + 80016d4: 6622 str r2, [r4, #96] ; 0x60 + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + 80016d6: f64f 72ef movw r2, #65519 ; 0xffef + 80016da: 609a str r2, [r3, #8] + errorcode = HAL_ERROR; + 80016dc: 2101 movs r1, #1 + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + 80016de: 4620 mov r0, r4 + 80016e0: f7ff fe3c bl 800135c + 80016e4: b108 cbz r0, 80016ea + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + 80016e6: 2320 movs r3, #32 + 80016e8: 6623 str r3, [r4, #96] ; 0x60 + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 80016ea: 6e23 ldr r3, [r4, #96] ; 0x60 + 80016ec: 2b00 cmp r3, #0 + 80016ee: f47f af7a bne.w 80015e6 + 80016f2: e779 b.n 80015e8 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 80016f4: 685a ldr r2, [r3, #4] + 80016f6: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 80016fa: e7af b.n 800165c + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 80016fc: f815 2b01 ldrb.w r2, [r5], #1 + 8001700: 731a strb r2, [r3, #12] + hspi->TxXferCount--; + 8001702: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 8001704: 3b01 subs r3, #1 + 8001706: e7bf b.n 8001688 + if (txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) + 8001708: 2e00 cmp r6, #0 + 800170a: d030 beq.n 800176e + 800170c: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 800170e: b29b uxth r3, r3 + 8001710: 2b00 cmp r3, #0 + 8001712: d02c beq.n 800176e + 8001714: 6823 ldr r3, [r4, #0] + 8001716: 689a ldr r2, [r3, #8] + 8001718: 0792 lsls r2, r2, #30 + 800171a: d528 bpl.n 800176e + if (hspi->TxXferCount > 1U) + 800171c: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 800171e: b292 uxth r2, r2 + 8001720: 2a01 cmp r2, #1 + hspi->Instance->DR = *((uint16_t *)pTxData); + 8001722: bf8b itete hi + 8001724: f835 2b02 ldrhhi.w r2, [r5], #2 + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 8001728: f815 2b01 ldrbls.w r2, [r5], #1 + hspi->Instance->DR = *((uint16_t *)pTxData); + 800172c: 60da strhi r2, [r3, #12] + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 800172e: 731a strbls r2, [r3, #12] + hspi->TxXferCount -= 2U; + 8001730: bf8b itete hi + 8001732: 8fe3 ldrhhi r3, [r4, #62] ; 0x3e + hspi->TxXferCount--; + 8001734: 8fe3 ldrhls r3, [r4, #62] ; 0x3e + hspi->TxXferCount -= 2U; + 8001736: 3b02 subhi r3, #2 + hspi->TxXferCount--; + 8001738: f103 33ff addls.w r3, r3, #4294967295 ; 0xffffffff + 800173c: b29b uxth r3, r3 + 800173e: 87e3 strh r3, [r4, #62] ; 0x3e + if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + 8001740: 8fe6 ldrh r6, [r4, #62] ; 0x3e + 8001742: b2b6 uxth r6, r6 + 8001744: b996 cbnz r6, 800176c + 8001746: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8001748: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 800174c: d10f bne.n 800176e + if (((hspi->Instance->CR1 & SPI_CR1_MSTR) == 0U) && ((hspi->Instance->CR2 & SPI_CR2_NSSP) == SPI_CR2_NSSP)) + 800174e: 6823 ldr r3, [r4, #0] + 8001750: 681a ldr r2, [r3, #0] + 8001752: 0756 lsls r6, r2, #29 + 8001754: d406 bmi.n 8001764 + 8001756: 685a ldr r2, [r3, #4] + 8001758: 0710 lsls r0, r2, #28 + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + 800175a: bf42 ittt mi + 800175c: 681a ldrmi r2, [r3, #0] + 800175e: f442 7200 orrmi.w r2, r2, #512 ; 0x200 + 8001762: 601a strmi r2, [r3, #0] + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 8001764: 681a ldr r2, [r3, #0] + 8001766: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800176a: 601a str r2, [r3, #0] + txallowed = 0U; + 800176c: 2600 movs r6, #0 + if ((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))) + 800176e: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 8001772: b29b uxth r3, r3 + 8001774: b1e3 cbz r3, 80017b0 + 8001776: 6821 ldr r1, [r4, #0] + 8001778: 688b ldr r3, [r1, #8] + 800177a: f013 0301 ands.w r3, r3, #1 + 800177e: d017 beq.n 80017b0 + if (hspi->RxXferCount > 1U) + 8001780: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001784: b292 uxth r2, r2 + 8001786: 2a01 cmp r2, #1 + 8001788: d91f bls.n 80017ca + *((uint16_t *)pRxData) = hspi->Instance->DR; + 800178a: 68ca ldr r2, [r1, #12] + 800178c: f827 2b02 strh.w r2, [r7], #2 + hspi->RxXferCount -= 2U; + 8001790: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001794: 3a02 subs r2, #2 + 8001796: b292 uxth r2, r2 + 8001798: f8a4 2046 strh.w r2, [r4, #70] ; 0x46 + if (hspi->RxXferCount <= 1U) + 800179c: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 80017a0: b292 uxth r2, r2 + 80017a2: 2a01 cmp r2, #1 + 80017a4: d803 bhi.n 80017ae + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 80017a6: 684a ldr r2, [r1, #4] + 80017a8: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 80017ac: 604a str r2, [r1, #4] + txallowed = 1U; + 80017ae: 461e mov r6, r3 + if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout)) + 80017b0: f1b8 3fff cmp.w r8, #4294967295 ; 0xffffffff + 80017b4: f43f af6b beq.w 800168e + 80017b8: f005 fc98 bl 80070ec + 80017bc: eba0 0009 sub.w r0, r0, r9 + 80017c0: 4540 cmp r0, r8 + 80017c2: f4ff af64 bcc.w 800168e + errorcode = HAL_TIMEOUT; + 80017c6: 2103 movs r1, #3 + 80017c8: e70e b.n 80015e8 + (*(uint8_t *)pRxData++) = *(__IO uint8_t *)&hspi->Instance->DR; + 80017ca: 7b0a ldrb r2, [r1, #12] + 80017cc: f807 2b01 strb.w r2, [r7], #1 + hspi->RxXferCount--; + 80017d0: f8b4 1046 ldrh.w r1, [r4, #70] ; 0x46 + 80017d4: 3901 subs r1, #1 + 80017d6: b289 uxth r1, r1 + 80017d8: f8a4 1046 strh.w r1, [r4, #70] ; 0x46 + 80017dc: e7e7 b.n 80017ae + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80017de: 7b1a ldrb r2, [r3, #12] + 80017e0: f8ad 2006 strh.w r2, [sp, #6] + UNUSED(tmpreg); + 80017e4: f8bd 2006 ldrh.w r2, [sp, #6] + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + 80017e8: 6b22 ldr r2, [r4, #48] ; 0x30 + 80017ea: 2a02 cmp r2, #2 + 80017ec: f47f af6b bne.w 80016c6 + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 80017f0: 689a ldr r2, [r3, #8] + 80017f2: 07d2 lsls r2, r2, #31 + 80017f4: d5fc bpl.n 80017f0 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80017f6: 7b1a ldrb r2, [r3, #12] + 80017f8: e761 b.n 80016be + errorcode = HAL_BUSY; + 80017fa: 2102 movs r1, #2 + 80017fc: e6f4 b.n 80015e8 + __HAL_LOCK(hspi); + 80017fe: 2102 movs r1, #2 + 8001800: e6f8 b.n 80015f4 + +08001802 : +{ + 8001802: e92d 41ff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr} + 8001806: 461f mov r7, r3 + __IO uint16_t tmpreg = 0U; + 8001808: 2300 movs r3, #0 + 800180a: f8ad 300e strh.w r3, [sp, #14] + if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + 800180e: 6843 ldr r3, [r0, #4] + 8001810: f5b3 7f82 cmp.w r3, #260 ; 0x104 +{ + 8001814: 4604 mov r4, r0 + 8001816: 460e mov r6, r1 + 8001818: 4615 mov r5, r2 + if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + 800181a: d10c bne.n 8001836 + 800181c: 6883 ldr r3, [r0, #8] + 800181e: b953 cbnz r3, 8001836 + hspi->State = HAL_SPI_STATE_BUSY_RX; + 8001820: 2304 movs r3, #4 + 8001822: f880 305d strb.w r3, [r0, #93] ; 0x5d + return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout); + 8001826: 4613 mov r3, r2 + 8001828: 9700 str r7, [sp, #0] + 800182a: 460a mov r2, r1 + 800182c: f7ff feb3 bl 8001596 +} + 8001830: b004 add sp, #16 + 8001832: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + __HAL_LOCK(hspi); + 8001836: f894 305c ldrb.w r3, [r4, #92] ; 0x5c + 800183a: 2b01 cmp r3, #1 + 800183c: f000 80dd beq.w 80019fa + 8001840: 2301 movs r3, #1 + 8001842: f884 305c strb.w r3, [r4, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8001846: f005 fc51 bl 80070ec + if (hspi->State != HAL_SPI_STATE_READY) + 800184a: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + 800184e: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 8001850: 4680 mov r8, r0 + if (hspi->State != HAL_SPI_STATE_READY) + 8001852: b2d8 uxtb r0, r3 + 8001854: f040 80cf bne.w 80019f6 + if ((pData == NULL) || (Size == 0U)) + 8001858: 2e00 cmp r6, #0 + 800185a: f000 8092 beq.w 8001982 + 800185e: 2d00 cmp r5, #0 + 8001860: f000 808f beq.w 8001982 + hspi->State = HAL_SPI_STATE_BUSY_RX; + 8001864: 2304 movs r3, #4 + 8001866: f884 305d strb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 800186a: 6aa3 ldr r3, [r4, #40] ; 0x28 + hspi->RxXferSize = Size; + 800186c: f8a4 5044 strh.w r5, [r4, #68] ; 0x44 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001870: 2100 movs r1, #0 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001872: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001876: 6621 str r1, [r4, #96] ; 0x60 + hspi->TxISR = NULL; + 8001878: e9c4 1113 strd r1, r1, [r4, #76] ; 0x4c + hspi->RxXferCount = Size; + 800187c: f8a4 5046 strh.w r5, [r4, #70] ; 0x46 + hspi->pRxBuffPtr = (uint8_t *)pData; + 8001880: 6426 str r6, [r4, #64] ; 0x40 + SPI_RESET_CRC(hspi); + 8001882: 6825 ldr r5, [r4, #0] + hspi->pTxBuffPtr = (uint8_t *)NULL; + 8001884: 63a1 str r1, [r4, #56] ; 0x38 + hspi->TxXferSize = 0U; + 8001886: 87a1 strh r1, [r4, #60] ; 0x3c + hspi->TxXferCount = 0U; + 8001888: 87e1 strh r1, [r4, #62] ; 0x3e + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 800188a: d10d bne.n 80018a8 + SPI_RESET_CRC(hspi); + 800188c: 682b ldr r3, [r5, #0] + 800188e: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 8001892: 602b str r3, [r5, #0] + 8001894: 682b ldr r3, [r5, #0] + 8001896: f443 5300 orr.w r3, r3, #8192 ; 0x2000 + 800189a: 602b str r3, [r5, #0] + hspi->RxXferCount--; + 800189c: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 80018a0: 3b01 subs r3, #1 + 80018a2: b29b uxth r3, r3 + 80018a4: f8a4 3046 strh.w r3, [r4, #70] ; 0x46 + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80018a8: 68e3 ldr r3, [r4, #12] + 80018aa: f5b3 6fe0 cmp.w r3, #1792 ; 0x700 + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 80018ae: 686b ldr r3, [r5, #4] + 80018b0: bf8c ite hi + 80018b2: f423 5380 bichi.w r3, r3, #4096 ; 0x1000 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 80018b6: f443 5380 orrls.w r3, r3, #4096 ; 0x1000 + 80018ba: 606b str r3, [r5, #4] + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 80018bc: 68a3 ldr r3, [r4, #8] + 80018be: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + SPI_1LINE_RX(hspi); + 80018c2: bf02 ittt eq + 80018c4: 682b ldreq r3, [r5, #0] + 80018c6: f423 4380 biceq.w r3, r3, #16384 ; 0x4000 + 80018ca: 602b streq r3, [r5, #0] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 80018cc: 682b ldr r3, [r5, #0] + 80018ce: 0658 lsls r0, r3, #25 + 80018d0: d403 bmi.n 80018da + __HAL_SPI_ENABLE(hspi); + 80018d2: 682b ldr r3, [r5, #0] + 80018d4: f043 0340 orr.w r3, r3, #64 ; 0x40 + 80018d8: 602b str r3, [r5, #0] + while (hspi->RxXferCount > 0U) + 80018da: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + 80018de: 6822 ldr r2, [r4, #0] + while (hspi->RxXferCount > 0U) + 80018e0: b29b uxth r3, r3 + 80018e2: 2b00 cmp r3, #0 + 80018e4: d13e bne.n 8001964 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80018e6: 6aa3 ldr r3, [r4, #40] ; 0x28 + 80018e8: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 80018ec: d11c bne.n 8001928 + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 80018ee: 6813 ldr r3, [r2, #0] + 80018f0: f443 5380 orr.w r3, r3, #4096 ; 0x1000 + 80018f4: 6013 str r3, [r2, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 80018f6: 6893 ldr r3, [r2, #8] + 80018f8: 07df lsls r7, r3, #31 + 80018fa: d5fc bpl.n 80018f6 + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80018fc: 68e3 ldr r3, [r4, #12] + 80018fe: f5b3 6fe0 cmp.w r3, #1792 ; 0x700 + (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 8001902: bf95 itete ls + 8001904: 7b13 ldrbls r3, [r2, #12] + *((uint16_t *)pData) = hspi->Instance->DR; + 8001906: 68d3 ldrhi r3, [r2, #12] + (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 8001908: 7033 strbls r3, [r6, #0] + *((uint16_t *)pData) = hspi->Instance->DR; + 800190a: 8033 strhhi r3, [r6, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 800190c: 6823 ldr r3, [r4, #0] + 800190e: 689a ldr r2, [r3, #8] + 8001910: 07d6 lsls r6, r2, #31 + 8001912: d5fc bpl.n 800190e + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + 8001914: 68e1 ldr r1, [r4, #12] + 8001916: f5b1 6f70 cmp.w r1, #3840 ; 0xf00 + 800191a: d142 bne.n 80019a2 + tmpreg = hspi->Instance->DR; + 800191c: 68db ldr r3, [r3, #12] + 800191e: b29b uxth r3, r3 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 8001920: f8ad 300e strh.w r3, [sp, #14] + UNUSED(tmpreg); + 8001924: f8bd 300e ldrh.w r3, [sp, #14] + * @param Tickstart: tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) +{ + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001928: 6861 ldr r1, [r4, #4] + 800192a: 6823 ldr r3, [r4, #0] + 800192c: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 8001930: d10a bne.n 8001948 + 8001932: 68a2 ldr r2, [r4, #8] + 8001934: f5b2 4f00 cmp.w r2, #32768 ; 0x8000 + 8001938: d002 beq.n 8001940 + || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + 800193a: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + 800193e: d103 bne.n 8001948 + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + 8001940: 681a ldr r2, [r3, #0] + 8001942: f022 0240 bic.w r2, r2, #64 ; 0x40 + 8001946: 601a str r2, [r3, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001948: 689a ldr r2, [r3, #8] + 800194a: 0610 lsls r0, r2, #24 + 800194c: d4fc bmi.n 8001948 + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 800194e: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 8001952: d036 beq.n 80019c2 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + 8001954: 689a ldr r2, [r3, #8] + 8001956: 06d2 lsls r2, r2, #27 + 8001958: d445 bmi.n 80019e6 + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 800195a: 6e20 ldr r0, [r4, #96] ; 0x60 + errorcode = HAL_BUSY; + 800195c: 3800 subs r0, #0 + 800195e: bf18 it ne + 8001960: 2001 movne r0, #1 +error : + 8001962: e00e b.n 8001982 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + 8001964: 6893 ldr r3, [r2, #8] + 8001966: 07d9 lsls r1, r3, #31 + 8001968: d509 bpl.n 800197e + (* (uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 800196a: 7b13 ldrb r3, [r2, #12] + 800196c: f806 3b01 strb.w r3, [r6], #1 + hspi->RxXferCount--; + 8001970: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 8001974: 3b01 subs r3, #1 + 8001976: b29b uxth r3, r3 + 8001978: f8a4 3046 strh.w r3, [r4, #70] ; 0x46 + 800197c: e7ad b.n 80018da + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 800197e: b93f cbnz r7, 8001990 + errorcode = HAL_TIMEOUT; + 8001980: 2003 movs r0, #3 + hspi->State = HAL_SPI_STATE_READY; + 8001982: 2301 movs r3, #1 + 8001984: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 8001988: 2300 movs r3, #0 + 800198a: f884 305c strb.w r3, [r4, #92] ; 0x5c + return errorcode; + 800198e: e74f b.n 8001830 + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 8001990: 1c7b adds r3, r7, #1 + 8001992: d0a2 beq.n 80018da + 8001994: f005 fbaa bl 80070ec + 8001998: eba0 0008 sub.w r0, r0, r8 + 800199c: 42b8 cmp r0, r7 + 800199e: d39c bcc.n 80018da + 80019a0: e7ee b.n 8001980 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80019a2: 7b1a ldrb r2, [r3, #12] + 80019a4: f8ad 200e strh.w r2, [sp, #14] + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + 80019a8: f5b1 6fe0 cmp.w r1, #1792 ; 0x700 + UNUSED(tmpreg); + 80019ac: f8bd 200e ldrh.w r2, [sp, #14] + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + 80019b0: d1ba bne.n 8001928 + 80019b2: 6b22 ldr r2, [r4, #48] ; 0x30 + 80019b4: 2a02 cmp r2, #2 + 80019b6: d1b7 bne.n 8001928 + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 80019b8: 689a ldr r2, [r3, #8] + 80019ba: 07d5 lsls r5, r2, #31 + 80019bc: d5fc bpl.n 80019b8 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80019be: 7b1b ldrb r3, [r3, #12] + 80019c0: e7ae b.n 8001920 + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 80019c2: 68a2 ldr r2, [r4, #8] + 80019c4: f5b2 4f00 cmp.w r2, #32768 ; 0x8000 + 80019c8: d002 beq.n 80019d0 + || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + 80019ca: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + 80019ce: d1c1 bne.n 8001954 + while ((hspi->Instance->SR & Fifo) != State) + 80019d0: 689a ldr r2, [r3, #8] + 80019d2: f412 6fc0 tst.w r2, #1536 ; 0x600 + 80019d6: d0bd beq.n 8001954 + tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); + 80019d8: 7b1a ldrb r2, [r3, #12] + 80019da: b2d2 uxtb r2, r2 + 80019dc: f88d 200d strb.w r2, [sp, #13] + UNUSED(tmpreg); + 80019e0: f89d 200d ldrb.w r2, [sp, #13] + 80019e4: e7f4 b.n 80019d0 + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + 80019e6: 6e22 ldr r2, [r4, #96] ; 0x60 + 80019e8: f042 0202 orr.w r2, r2, #2 + 80019ec: 6622 str r2, [r4, #96] ; 0x60 + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + 80019ee: f64f 72ef movw r2, #65519 ; 0xffef + 80019f2: 609a str r2, [r3, #8] + 80019f4: e7b1 b.n 800195a + errorcode = HAL_BUSY; + 80019f6: 2002 movs r0, #2 + 80019f8: e7c3 b.n 8001982 + __HAL_LOCK(hspi); + 80019fa: 2002 movs r0, #2 + 80019fc: e718 b.n 8001830 + ... + +08001a00 : + +// checksum_more() +// + static void +checksum_more(SHA256_CTX *ctx, uint32_t *total, const uint8_t *addr, int len) +{ + 8001a00: b5f8 push {r3, r4, r5, r6, r7, lr} + 8001a02: 460c mov r4, r1 + // mk4 has hardware hash engine, and no DFU button + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001a04: 6809 ldr r1, [r1, #0] +{ + 8001a06: 461d mov r5, r3 + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001a08: 2364 movs r3, #100 ; 0x64 +{ + 8001a0a: 4617 mov r7, r2 + 8001a0c: 4606 mov r6, r0 + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001a0e: 4359 muls r1, r3 + puts2("Verify %0x"); + puthex2(percent); + putchar('\n'); +#endif + + oled_show_progress(screen_verify, percent); + 8001a10: 4807 ldr r0, [pc, #28] ; (8001a30 ) + 8001a12: 4b08 ldr r3, [pc, #32] ; (8001a34 ) + 8001a14: fbb1 f1f3 udiv r1, r1, r3 + 8001a18: f7ff fa56 bl 8000ec8 + + sha256_update(ctx, addr, len); + 8001a1c: 462a mov r2, r5 + 8001a1e: 4639 mov r1, r7 + 8001a20: 4630 mov r0, r6 + 8001a22: f003 fd41 bl 80054a8 + *total += len; + 8001a26: 6823 ldr r3, [r4, #0] + 8001a28: 442b add r3, r5 + 8001a2a: 6023 str r3, [r4, #0] +} + 8001a2c: bdf8 pop {r3, r4, r5, r6, r7, pc} + 8001a2e: bf00 nop + 8001a30: 0800e242 .word 0x0800e242 + 8001a34: 0018541c .word 0x0018541c + +08001a38 : + +// checksum_flash() +// + void +checksum_flash(uint8_t fw_digest[32], uint8_t world_digest[32], uint32_t fw_length) +{ + 8001a38: b570 push {r4, r5, r6, lr} + 8001a3a: b09c sub sp, #112 ; 0x70 + 8001a3c: 4606 mov r6, r0 + 8001a3e: 460d mov r5, r1 + 8001a40: 4614 mov r4, r2 + const uint8_t *start = (const uint8_t *)FIRMWARE_START; + + rng_delay(); + 8001a42: f000 fe9b bl 800277c + + SHA256_CTX ctx; + uint32_t total_len = 0; + 8001a46: 2300 movs r3, #0 + 8001a48: 9300 str r3, [sp, #0] + + if(fw_length == 0) { + 8001a4a: 2c00 cmp r4, #0 + 8001a4c: d15f bne.n 8001b0e + uint8_t first[32]; + sha256_init(&ctx); + 8001a4e: a809 add r0, sp, #36 ; 0x24 + 8001a50: f003 fd1c bl 800548c + + // use length from header in flash + fw_length = FW_HDR->firmware_length; + 8001a54: 4b36 ldr r3, [pc, #216] ; (8001b30 ) + + // start of firmware (just after we end) to header + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001a56: 4a37 ldr r2, [pc, #220] ; (8001b34 ) + fw_length = FW_HDR->firmware_length; + 8001a58: f8d3 4098 ldr.w r4, [r3, #152] ; 0x98 + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001a5c: 4669 mov r1, sp + 8001a5e: f44f 537f mov.w r3, #16320 ; 0x3fc0 + 8001a62: a809 add r0, sp, #36 ; 0x24 + 8001a64: f7ff ffcc bl 8001a00 + + // from after header to end + checksum_more(&ctx, &total_len, start + FW_HEADER_OFFSET + FW_HEADER_SIZE, + 8001a68: 4a33 ldr r2, [pc, #204] ; (8001b38 ) + 8001a6a: f5a4 4380 sub.w r3, r4, #16384 ; 0x4000 + 8001a6e: 4669 mov r1, sp + 8001a70: a809 add r0, sp, #36 ; 0x24 + 8001a72: f7ff ffc5 bl 8001a00 + fw_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + + sha256_final(&ctx, first); + 8001a76: a901 add r1, sp, #4 + 8001a78: a809 add r0, sp, #36 ; 0x24 + 8001a7a: f003 fd5b bl 8005534 + + // double SHA256 + sha256_single(first, sizeof(first), fw_digest); + 8001a7e: 4632 mov r2, r6 + 8001a80: 2120 movs r1, #32 + 8001a82: a801 add r0, sp, #4 + 8001a84: f003 fd6a bl 800555c + // fw_digest should already be populated by caller + total_len = fw_length - 64; + } + + // start over, and get the rest of flash. All of it. + sha256_init(&ctx); + 8001a88: a809 add r0, sp, #36 ; 0x24 + 8001a8a: f003 fcff bl 800548c + + // .. and chain in what we have so far + sha256_update(&ctx, fw_digest, 32); + 8001a8e: 2220 movs r2, #32 + 8001a90: 4631 mov r1, r6 + 8001a92: a809 add r0, sp, #36 ; 0x24 + 8001a94: f003 fd08 bl 80054a8 + + // Bootloader, including pairing secret area, but excluding MCU keys. + const uint8_t *base = (const uint8_t *)BL_FLASH_BASE; + checksum_more(&ctx, &total_len, base, ((uint8_t *)MCU_KEYS)-base); + 8001a98: f44f 33f0 mov.w r3, #122880 ; 0x1e000 + 8001a9c: f04f 6200 mov.w r2, #134217728 ; 0x8000000 + 8001aa0: 4669 mov r1, sp + 8001aa2: a809 add r0, sp, #36 ; 0x24 + 8001aa4: f7ff ffac bl 8001a00 + + // Probably-blank area after firmware, and filesystem area. + // Important: firmware images (fw_length) must be aligned with flash erase unit size (4k). + const uint8_t *fs = start + fw_length; + const uint8_t *last = base + MAIN_FLASH_SIZE; + checksum_more(&ctx, &total_len, fs, last-fs); + 8001aa8: f104 6200 add.w r2, r4, #134217728 ; 0x8000000 + 8001aac: f5c4 13b0 rsb r3, r4, #1441792 ; 0x160000 + 8001ab0: f502 3200 add.w r2, r2, #131072 ; 0x20000 + 8001ab4: 4669 mov r1, sp + 8001ab6: a809 add r0, sp, #36 ; 0x24 + 8001ab8: f7ff ffa2 bl 8001a00 + + rng_delay(); + 8001abc: f000 fe5e bl 800277c + + // OTP area + checksum_more(&ctx, &total_len, (void *)0x1fff7000, 0x400); + 8001ac0: 4a1e ldr r2, [pc, #120] ; (8001b3c ) + 8001ac2: f44f 6380 mov.w r3, #1024 ; 0x400 + 8001ac6: 4669 mov r1, sp + 8001ac8: a809 add r0, sp, #36 ; 0x24 + 8001aca: f7ff ff99 bl 8001a00 + + // "just in case" ... the option bytes (2 banks) + checksum_more(&ctx, &total_len, (void *)0x1fff7800, 0x28); + 8001ace: 4a1c ldr r2, [pc, #112] ; (8001b40 ) + 8001ad0: 2328 movs r3, #40 ; 0x28 + 8001ad2: 4669 mov r1, sp + 8001ad4: a809 add r0, sp, #36 ; 0x24 + 8001ad6: f7ff ff93 bl 8001a00 + checksum_more(&ctx, &total_len, (void *)0x1ffff800, 0x28); + 8001ada: 4a1a ldr r2, [pc, #104] ; (8001b44 ) + 8001adc: 2328 movs r3, #40 ; 0x28 + 8001ade: 4669 mov r1, sp + 8001ae0: a809 add r0, sp, #36 ; 0x24 + 8001ae2: f7ff ff8d bl 8001a00 + + // System ROM (they say it can't change, but clearly + // implemented as flash cells) + checksum_more(&ctx, &total_len, (void *)0x1fff0000, 0x7000); + 8001ae6: 4a18 ldr r2, [pc, #96] ; (8001b48 ) + 8001ae8: f44f 43e0 mov.w r3, #28672 ; 0x7000 + 8001aec: 4669 mov r1, sp + 8001aee: a809 add r0, sp, #36 ; 0x24 + 8001af0: f7ff ff86 bl 8001a00 + + // device serial number, just for kicks + checksum_more(&ctx, &total_len, (void *)0x1fff7590, 12); + 8001af4: 4a15 ldr r2, [pc, #84] ; (8001b4c ) + 8001af6: 230c movs r3, #12 + 8001af8: 4669 mov r1, sp + 8001afa: a809 add r0, sp, #36 ; 0x24 + 8001afc: f7ff ff80 bl 8001a00 + + ASSERT(total_len == TOTAL_CHECKSUM_LEN); + 8001b00: 4b13 ldr r3, [pc, #76] ; (8001b50 ) + 8001b02: 9a00 ldr r2, [sp, #0] + 8001b04: 429a cmp r2, r3 + 8001b06: d006 beq.n 8001b16 + 8001b08: 4812 ldr r0, [pc, #72] ; (8001b54 ) + 8001b0a: f7fe ff9d bl 8000a48 + total_len = fw_length - 64; + 8001b0e: f1a4 0340 sub.w r3, r4, #64 ; 0x40 + 8001b12: 9300 str r3, [sp, #0] + 8001b14: e7b8 b.n 8001a88 + + sha256_final(&ctx, world_digest); + 8001b16: 4629 mov r1, r5 + 8001b18: a809 add r0, sp, #36 ; 0x24 + 8001b1a: f003 fd0b bl 8005534 + + // double SHA256 (a bitcoin fetish) + sha256_single(world_digest, 32, world_digest); + 8001b1e: 462a mov r2, r5 + 8001b20: 2120 movs r1, #32 + 8001b22: 4628 mov r0, r5 + 8001b24: f003 fd1a bl 800555c + + rng_delay(); + 8001b28: f000 fe28 bl 800277c +} + 8001b2c: b01c add sp, #112 ; 0x70 + 8001b2e: bd70 pop {r4, r5, r6, pc} + 8001b30: 08023f00 .word 0x08023f00 + 8001b34: 08020000 .word 0x08020000 + 8001b38: 08024000 .word 0x08024000 + 8001b3c: 1fff7000 .word 0x1fff7000 + 8001b40: 1fff7800 .word 0x1fff7800 + 8001b44: 1ffff800 .word 0x1ffff800 + 8001b48: 1fff0000 .word 0x1fff0000 + 8001b4c: 1fff7590 .word 0x1fff7590 + 8001b50: 0018541c .word 0x0018541c + 8001b54: 0800e3e0 .word 0x0800e3e0 + +08001b58 : +// Scan the OTP area and determine what the current min-version (timestamp) +// we can allow. All zeros if any if okay. +// + void +get_min_version(uint8_t min_version[8]) +{ + 8001b58: b570 push {r4, r5, r6, lr} + 8001b5a: 4604 mov r4, r0 + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + 8001b5c: 4d0c ldr r5, [pc, #48] ; (8001b90 ) + + rng_delay(); + memset(min_version, 0, 8); + + for(int i=0; i) + rng_delay(); + 8001b60: f000 fe0c bl 800277c + memset(min_version, 0, 8); + 8001b64: 2300 movs r3, #0 + 8001b66: 6023 str r3, [r4, #0] + 8001b68: 6063 str r3, [r4, #4] + // is it programmed? + if(otp[0] == 0xff) continue; + + // is it a timestamp value? + if(otp[0] >= 0x40) continue; + if(otp[0] < 0x10) continue; + 8001b6a: 782b ldrb r3, [r5, #0] + 8001b6c: 3b10 subs r3, #16 + 8001b6e: 2b2f cmp r3, #47 ; 0x2f + 8001b70: d80a bhi.n 8001b88 + + if(memcmp(otp, min_version, 8) > 0) { + 8001b72: 4621 mov r1, r4 + 8001b74: 2208 movs r2, #8 + 8001b76: 4628 mov r0, r5 + 8001b78: f00b fd44 bl 800d604 + 8001b7c: 2800 cmp r0, #0 + memcpy(min_version, otp, 8); + 8001b7e: bfc1 itttt gt + 8001b80: 462b movgt r3, r5 + 8001b82: cb03 ldmiagt r3!, {r0, r1} + 8001b84: 6020 strgt r0, [r4, #0] + 8001b86: 6061 strgt r1, [r4, #4] + for(int i=0; i + } + } +} + 8001b8e: bd70 pop {r4, r5, r6, pc} + 8001b90: 1fff7000 .word 0x1fff7000 + 8001b94: 1fff7400 .word 0x1fff7400 + +08001b98 : + +// check_is_downgrade() +// + bool +check_is_downgrade(const uint8_t timestamp[8], const char *version) +{ + 8001b98: b513 push {r0, r1, r4, lr} + 8001b9a: 4604 mov r4, r0 +#ifndef FOR_Q1_ONLY + if(version) { + 8001b9c: b129 cbz r1, 8001baa + int major = (version[1] == '.') ? (version[0]-'0') : 10; + 8001b9e: 784b ldrb r3, [r1, #1] + 8001ba0: 2b2e cmp r3, #46 ; 0x2e + 8001ba2: d102 bne.n 8001baa + if(major < 3) { + 8001ba4: 780b ldrb r3, [r1, #0] + 8001ba6: 2b32 cmp r3, #50 ; 0x32 + 8001ba8: d90a bls.n 8001bc0 + } +#endif + + // look at FW_HDR->timestamp and compare to a growing list in main flash OTP + uint8_t min[8]; + get_min_version(min); + 8001baa: 4668 mov r0, sp + 8001bac: f7ff ffd4 bl 8001b58 + + return (memcmp(timestamp, min, 8) < 0); + 8001bb0: 2208 movs r2, #8 + 8001bb2: 4669 mov r1, sp + 8001bb4: 4620 mov r0, r4 + 8001bb6: f00b fd25 bl 800d604 + 8001bba: 0fc0 lsrs r0, r0, #31 +} + 8001bbc: b002 add sp, #8 + 8001bbe: bd10 pop {r4, pc} + return true; + 8001bc0: 2001 movs r0, #1 + 8001bc2: e7fb b.n 8001bbc + +08001bc4 : + +// warn_fishy_firmware() +// + void +warn_fishy_firmware(const uint8_t *pixels) +{ + 8001bc4: b538 push {r3, r4, r5, lr} + 8001bc6: 4605 mov r5, r0 + const int wait = 100; +#else + const int wait = 10; +#endif + + for(int i=0; i < wait; i++) { + 8001bc8: 2400 movs r4, #0 + oled_show_progress(pixels, (i*100)/wait); + 8001bca: 4621 mov r1, r4 + 8001bcc: 4628 mov r0, r5 + 8001bce: f7ff f97b bl 8000ec8 + for(int i=0; i < wait; i++) { + 8001bd2: 3401 adds r4, #1 + + delay_ms(250); + 8001bd4: 20fa movs r0, #250 ; 0xfa + 8001bd6: f001 fe8f bl 80038f8 + for(int i=0; i < wait; i++) { + 8001bda: 2c64 cmp r4, #100 ; 0x64 + 8001bdc: d1f5 bne.n 8001bca + } +} + 8001bde: bd38 pop {r3, r4, r5, pc} + +08001be0 : + +// verify_header() +// + bool +verify_header(const coldcardFirmwareHeader_t *hdr) +{ + 8001be0: b510 push {r4, lr} + 8001be2: 4604 mov r4, r0 + rng_delay(); + 8001be4: f000 fdca bl 800277c + + if(hdr->magic_value != FW_HEADER_MAGIC) goto fail; + 8001be8: 6822 ldr r2, [r4, #0] + 8001bea: 4b0b ldr r3, [pc, #44] ; (8001c18 ) + 8001bec: 429a cmp r2, r3 + 8001bee: d110 bne.n 8001c12 + if(hdr->version_string[0] == 0x0) goto fail; + 8001bf0: 7b20 ldrb r0, [r4, #12] + 8001bf2: b168 cbz r0, 8001c10 + if(hdr->timestamp[0] >= 0x40) goto fail; // 22 yr product lifetime + 8001bf4: 7923 ldrb r3, [r4, #4] + 8001bf6: 2b3f cmp r3, #63 ; 0x3f + 8001bf8: d80b bhi.n 8001c12 + if(hdr->firmware_length < FW_MIN_LENGTH) goto fail; + 8001bfa: 69a3 ldr r3, [r4, #24] + 8001bfc: f5a3 2380 sub.w r3, r3, #262144 ; 0x40000 + 8001c00: f5b3 1fd0 cmp.w r3, #1703936 ; 0x1a0000 + 8001c04: d205 bcs.n 8001c12 + if(hdr->firmware_length >= FW_MAX_LENGTH_MK4) goto fail; + if(hdr->pubkey_num >= NUM_KNOWN_PUBKEYS) goto fail; + 8001c06: 6960 ldr r0, [r4, #20] + 8001c08: 2805 cmp r0, #5 + 8001c0a: bf8c ite hi + 8001c0c: 2000 movhi r0, #0 + 8001c0e: 2001 movls r0, #1 + + return true; +fail: + return false; +} + 8001c10: bd10 pop {r4, pc} + return false; + 8001c12: 2000 movs r0, #0 + 8001c14: e7fc b.n 8001c10 + 8001c16: bf00 nop + 8001c18: cc001234 .word 0xcc001234 + +08001c1c : +// +// Given double-sha256 over the firmware bytes, check the signature. +// + bool +verify_signature(const coldcardFirmwareHeader_t *hdr, const uint8_t fw_check[32]) +{ + 8001c1c: b530 push {r4, r5, lr} + // this takes a few ms at least, not fast. + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001c1e: 6943 ldr r3, [r0, #20] + 8001c20: 4d0b ldr r5, [pc, #44] ; (8001c50 ) +{ + 8001c22: b085 sub sp, #20 + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001c24: eb05 1583 add.w r5, r5, r3, lsl #6 +{ + 8001c28: 4604 mov r4, r0 + 8001c2a: 9103 str r1, [sp, #12] + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001c2c: f004 fe5a bl 80068e4 + 8001c30: f104 0340 add.w r3, r4, #64 ; 0x40 + 8001c34: 9903 ldr r1, [sp, #12] + 8001c36: 9000 str r0, [sp, #0] + 8001c38: 2220 movs r2, #32 + 8001c3a: 4628 mov r0, r5 + 8001c3c: f005 f8d9 bl 8006df2 + 8001c40: 4604 mov r4, r0 + hdr->signature, uECC_secp256k1()); + + //puts(ok ? "Sig ok" : "Sig fail"); + rng_delay(); + 8001c42: f000 fd9b bl 800277c + + return ok; +} + 8001c46: 1e20 subs r0, r4, #0 + 8001c48: bf18 it ne + 8001c4a: 2001 movne r0, #1 + 8001c4c: b005 add sp, #20 + 8001c4e: bd30 pop {r4, r5, pc} + 8001c50: 0800e45a .word 0x0800e45a + +08001c54 : +// Check hdr, and even signature of protential new firmware in PSRAM. +// Returns checksum needed for 608 +// + bool +verify_firmware_in_ram(const uint8_t *start, uint32_t len, uint8_t world_check[32]) +{ + 8001c54: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + const coldcardFirmwareHeader_t *hdr = (const coldcardFirmwareHeader_t *) + 8001c58: f500 567e add.w r6, r0, #16256 ; 0x3f80 +{ + 8001c5c: b09c sub sp, #112 ; 0x70 + 8001c5e: 4605 mov r5, r0 + (start + FW_HEADER_OFFSET); + uint8_t fw_digest[32]; + + // check basics like verison, hw compat, etc + if(!verify_header(hdr)) goto fail; + 8001c60: 4630 mov r0, r6 +{ + 8001c62: 4617 mov r7, r2 + if(!verify_header(hdr)) goto fail; + 8001c64: f7ff ffbc bl 8001be0 + 8001c68: 4604 mov r4, r0 + 8001c6a: b150 cbz r0, 8001c82 + + if(check_is_downgrade(hdr->timestamp, (const char *)hdr->version_string)) { + 8001c6c: f106 010c add.w r1, r6, #12 + 8001c70: 1d30 adds r0, r6, #4 + 8001c72: f7ff ff91 bl 8001b98 + 8001c76: 4604 mov r4, r0 + 8001c78: b138 cbz r0, 8001c8a + puts("downgrade"); + 8001c7a: 481e ldr r0, [pc, #120] ; (8001cf4 ) + 8001c7c: f003 f896 bl 8004dac + + checksum_flash(fw_digest, world_check, hdr->firmware_length); + + return true; +fail: + return false; + 8001c80: 2400 movs r4, #0 +} + 8001c82: 4620 mov r0, r4 + 8001c84: b01c add sp, #112 ; 0x70 + 8001c86: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + rng_delay(); + 8001c8a: f000 fd77 bl 800277c + hdr->firmware_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + 8001c8e: f505 5840 add.w r8, r5, #12288 ; 0x3000 + sha256_init(&ctx); + 8001c92: a809 add r0, sp, #36 ; 0x24 + uint32_t total_len = 0; + 8001c94: 9400 str r4, [sp, #0] + sha256_init(&ctx); + 8001c96: f003 fbf9 bl 800548c + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001c9a: f44f 537f mov.w r3, #16320 ; 0x3fc0 + 8001c9e: 462a mov r2, r5 + 8001ca0: 4669 mov r1, sp + 8001ca2: a809 add r0, sp, #36 ; 0x24 + 8001ca4: f7ff feac bl 8001a00 + hdr->firmware_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + 8001ca8: f8d8 3f98 ldr.w r3, [r8, #3992] ; 0xf98 + checksum_more(&ctx, &total_len, start + FW_HEADER_OFFSET + FW_HEADER_SIZE, + 8001cac: f505 4280 add.w r2, r5, #16384 ; 0x4000 + 8001cb0: f5a3 4380 sub.w r3, r3, #16384 ; 0x4000 + 8001cb4: 4669 mov r1, sp + 8001cb6: a809 add r0, sp, #36 ; 0x24 + 8001cb8: f7ff fea2 bl 8001a00 + sha256_final(&ctx, fw_digest); + 8001cbc: a901 add r1, sp, #4 + 8001cbe: a809 add r0, sp, #36 ; 0x24 + 8001cc0: f003 fc38 bl 8005534 + sha256_single(fw_digest, 32, fw_digest); + 8001cc4: aa01 add r2, sp, #4 + 8001cc6: 4610 mov r0, r2 + 8001cc8: 2120 movs r1, #32 + 8001cca: f003 fc47 bl 800555c + rng_delay(); + 8001cce: f000 fd55 bl 800277c + if(!verify_signature(hdr, fw_digest)) { + 8001cd2: a901 add r1, sp, #4 + 8001cd4: 4630 mov r0, r6 + 8001cd6: f7ff ffa1 bl 8001c1c + 8001cda: 4604 mov r4, r0 + 8001cdc: b918 cbnz r0, 8001ce6 + puts("sig fail"); + 8001cde: 4806 ldr r0, [pc, #24] ; (8001cf8 ) + 8001ce0: f003 f864 bl 8004dac + goto fail; + 8001ce4: e7cd b.n 8001c82 + checksum_flash(fw_digest, world_check, hdr->firmware_length); + 8001ce6: f8d8 2f98 ldr.w r2, [r8, #3992] ; 0xf98 + 8001cea: 4639 mov r1, r7 + 8001cec: a801 add r0, sp, #4 + 8001cee: f7ff fea3 bl 8001a38 + return true; + 8001cf2: e7c6 b.n 8001c82 + 8001cf4: 0800e3e7 .word 0x0800e3e7 + 8001cf8: 0800e3f1 .word 0x0800e3f1 + +08001cfc : +// - don't set the light at this point. +// - requires bootloader to have been unchanged since world_check recorded (debug issue) +// + bool +verify_world_checksum(const uint8_t world_check[32]) +{ + 8001cfc: b507 push {r0, r1, r2, lr} + 8001cfe: 9001 str r0, [sp, #4] + ae_setup(); + 8001d00: f000 fe60 bl 80029c4 + ae_pair_unlock(); + 8001d04: f001 f854 bl 8002db0 + + return (ae_checkmac_hard(KEYNUM_firmware, world_check) == 0); + 8001d08: 9901 ldr r1, [sp, #4] + 8001d0a: 200e movs r0, #14 + 8001d0c: f001 f9de bl 80030cc +} + 8001d10: fab0 f080 clz r0, r0 + 8001d14: 0940 lsrs r0, r0, #5 + 8001d16: b003 add sp, #12 + 8001d18: f85d fb04 ldr.w pc, [sp], #4 + +08001d1c : + +// verify_firmware() +// + bool +verify_firmware(void) +{ + 8001d1c: b570 push {r4, r5, r6, lr} + STATIC_ASSERT(sizeof(coldcardFirmwareHeader_t) == FW_HEADER_SIZE); + + rng_delay(); + + // watch for unprogrammed header. and some + if(FW_HDR->version_string[0] == 0xff) goto blank; + 8001d1e: 4e2a ldr r6, [pc, #168] ; (8001dc8 ) +{ + 8001d20: b090 sub sp, #64 ; 0x40 + rng_delay(); + 8001d22: f000 fd2b bl 800277c + if(FW_HDR->version_string[0] == 0xff) goto blank; + 8001d26: f896 308c ldrb.w r3, [r6, #140] ; 0x8c + 8001d2a: 2bff cmp r3, #255 ; 0xff + 8001d2c: d107 bne.n 8001d3e + puts("corrupt firmware"); + oled_show(screen_corrupt); + return false; + +blank: + puts("no firmware"); + 8001d2e: 4827 ldr r0, [pc, #156] ; (8001dcc ) + puts("corrupt firmware"); + 8001d30: f003 f83c bl 8004dac + oled_show(screen_corrupt); + 8001d34: 4826 ldr r0, [pc, #152] ; (8001dd0 ) + 8001d36: f7ff f885 bl 8000e44 + return false; + 8001d3a: 2400 movs r4, #0 + 8001d3c: e030 b.n 8001da0 + if(!verify_header(FW_HDR)) goto fail; + 8001d3e: 4825 ldr r0, [pc, #148] ; (8001dd4 ) + 8001d40: f7ff ff4e bl 8001be0 + 8001d44: 2800 cmp r0, #0 + 8001d46: d03c beq.n 8001dc2 + rng_delay(); + 8001d48: f000 fd18 bl 800277c + checksum_flash(fw_check, world_check, 0); + 8001d4c: 2200 movs r2, #0 + 8001d4e: a908 add r1, sp, #32 + 8001d50: 4668 mov r0, sp + 8001d52: f7ff fe71 bl 8001a38 + rng_delay(); + 8001d56: f000 fd11 bl 800277c + if(!verify_signature(FW_HDR, fw_check)) goto fail; + 8001d5a: 481e ldr r0, [pc, #120] ; (8001dd4 ) + 8001d5c: 4669 mov r1, sp + 8001d5e: f7ff ff5d bl 8001c1c + 8001d62: 4604 mov r4, r0 + 8001d64: b368 cbz r0, 8001dc2 + int not_green = ae_set_gpio_secure(world_check); + 8001d66: a808 add r0, sp, #32 + 8001d68: f001 fbc4 bl 80034f4 + 8001d6c: 4605 mov r5, r0 + rng_delay(); + 8001d6e: f000 fd05 bl 800277c + rng_delay(); + 8001d72: f000 fd03 bl 800277c + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8001d76: 4b18 ldr r3, [pc, #96] ; (8001dd8 ) + 8001d78: 6a1b ldr r3, [r3, #32] + 8001d7a: b2db uxtb r3, r3 + if(!flash_is_security_level2() && not_green) { + 8001d7c: 2bcc cmp r3, #204 ; 0xcc + 8001d7e: d008 beq.n 8001d92 + 8001d80: b18d cbz r5, 8001da6 + oled_show_progress(screen_verify, 100); + 8001d82: 4816 ldr r0, [pc, #88] ; (8001ddc ) + 8001d84: 2164 movs r1, #100 ; 0x64 + 8001d86: f7ff f89f bl 8000ec8 + puts("Factory boot"); + 8001d8a: 4815 ldr r0, [pc, #84] ; (8001de0 ) + puts("Good firmware"); + 8001d8c: f003 f80e bl 8004dac + 8001d90: e006 b.n 8001da0 + } else if(not_green) { + 8001d92: b145 cbz r5, 8001da6 + puts("WARN: Red light"); + 8001d94: 4813 ldr r0, [pc, #76] ; (8001de4 ) + 8001d96: f003 f809 bl 8004dac + warn_fishy_firmware(screen_red_light); + 8001d9a: 4813 ldr r0, [pc, #76] ; (8001de8 ) + warn_fishy_firmware(screen_devmode); + 8001d9c: f7ff ff12 bl 8001bc4 + oled_show(screen_corrupt); + + return false; +} + 8001da0: 4620 mov r0, r4 + 8001da2: b010 add sp, #64 ; 0x40 + 8001da4: bd70 pop {r4, r5, r6, pc} + } else if(FW_HDR->pubkey_num == 0) { + 8001da6: f8d6 3094 ldr.w r3, [r6, #148] ; 0x94 + 8001daa: b923 cbnz r3, 8001db6 + puts("WARN: Unsigned firmware"); + 8001dac: 480f ldr r0, [pc, #60] ; (8001dec ) + 8001dae: f002 fffd bl 8004dac + warn_fishy_firmware(screen_devmode); + 8001db2: 480f ldr r0, [pc, #60] ; (8001df0 ) + 8001db4: e7f2 b.n 8001d9c + oled_show_progress(screen_verify, 100); + 8001db6: 4809 ldr r0, [pc, #36] ; (8001ddc ) + 8001db8: 2164 movs r1, #100 ; 0x64 + 8001dba: f7ff f885 bl 8000ec8 + puts("Good firmware"); + 8001dbe: 480d ldr r0, [pc, #52] ; (8001df4 ) + 8001dc0: e7e4 b.n 8001d8c + puts("corrupt firmware"); + 8001dc2: 480d ldr r0, [pc, #52] ; (8001df8 ) + 8001dc4: e7b4 b.n 8001d30 + 8001dc6: bf00 nop + 8001dc8: 08023f00 .word 0x08023f00 + 8001dcc: 0800e3fa .word 0x0800e3fa + 8001dd0: 0800d875 .word 0x0800d875 + 8001dd4: 08023f80 .word 0x08023f80 + 8001dd8: 40022000 .word 0x40022000 + 8001ddc: 0800e242 .word 0x0800e242 + 8001de0: 0800e406 .word 0x0800e406 + 8001de4: 0800e413 .word 0x0800e413 + 8001de8: 0800dd72 .word 0x0800dd72 + 8001dec: 0800e423 .word 0x0800e423 + 8001df0: 0800d932 .word 0x0800d932 + 8001df4: 0800e43b .word 0x0800e43b + 8001df8: 0800e449 .word 0x0800e449 + +08001dfc : + void +systick_setup(void) +{ + const uint32_t ticks = HCLK_FREQUENCY/1000; + + SysTick->LOAD = (ticks - 1); + 8001dfc: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 8001e00: 4a03 ldr r2, [pc, #12] ; (8001e10 ) + 8001e02: 615a str r2, [r3, #20] + SysTick->VAL = 0; + 8001e04: 2200 movs r2, #0 + 8001e06: 619a str r2, [r3, #24] + SysTick->CTRL = SYSTICK_CLKSOURCE_HCLK | SysTick_CTRL_ENABLE_Msk; + 8001e08: 2205 movs r2, #5 + 8001e0a: 611a str r2, [r3, #16] +} + 8001e0c: 4770 bx lr + 8001e0e: bf00 nop + 8001e10: 0001d4bf .word 0x0001d4bf + +08001e14 : + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#endif + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + 8001e14: 4a0e ldr r2, [pc, #56] ; (8001e50 ) + 8001e16: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 8001e1a: f443 0370 orr.w r3, r3, #15728640 ; 0xf00000 + 8001e1e: f8c2 3088 str.w r3, [r2, #136] ; 0x88 +#endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + 8001e22: 4b0c ldr r3, [pc, #48] ; (8001e54 ) + 8001e24: 681a ldr r2, [r3, #0] + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + 8001e26: 2100 movs r1, #0 + RCC->CR |= RCC_CR_MSION; + 8001e28: f042 0201 orr.w r2, r2, #1 + 8001e2c: 601a str r2, [r3, #0] + RCC->CFGR = 0x00000000U; + 8001e2e: 6099 str r1, [r3, #8] + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + 8001e30: 681a ldr r2, [r3, #0] + 8001e32: f022 52a8 bic.w r2, r2, #352321536 ; 0x15000000 + 8001e36: f422 2210 bic.w r2, r2, #589824 ; 0x90000 + 8001e3a: 601a str r2, [r3, #0] + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + 8001e3c: f44f 5280 mov.w r2, #4096 ; 0x1000 + 8001e40: 60da str r2, [r3, #12] + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + 8001e42: 681a ldr r2, [r3, #0] + 8001e44: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 8001e48: 601a str r2, [r3, #0] + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + 8001e4a: 6199 str r1, [r3, #24] +} + 8001e4c: 4770 bx lr + 8001e4e: bf00 nop + 8001e50: e000ed00 .word 0xe000ed00 + 8001e54: 40021000 .word 0x40021000 + +08001e58 : + +// clocks_setup() +// + void +clocks_setup(void) +{ + 8001e58: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + + // setup power supplies + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + + // Configure LSE Drive Capability + __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); + 8001e5c: 4c41 ldr r4, [pc, #260] ; (8001f64 ) +{ + 8001e5e: b0c1 sub sp, #260 ; 0x104 + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + 8001e60: 2000 movs r0, #0 + 8001e62: f005 f959 bl 8007118 + __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); + 8001e66: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8001e6a: f023 0318 bic.w r3, r3, #24 + 8001e6e: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + + // Enable HSE Oscillator and activate PLL with HSE as source + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + 8001e72: 2201 movs r2, #1 + 8001e74: f44f 3380 mov.w r3, #65536 ; 0x10000 + 8001e78: e9cd 230a strd r2, r3, [sp, #40] ; 0x28 + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + RCC_OscInitStruct.MSIState = RCC_MSI_OFF; + + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 8001e7c: 2703 movs r7, #3 + + // Select PLL as system clock source and configure + // the HCLK, PCLK1 and PCLK2 clocks dividers + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK + 8001e7e: 230f movs r3, #15 + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + 8001e80: 2500 movs r5, #0 + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 8001e82: 2602 movs r6, #2 + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + 8001e84: e9cd 3705 strd r3, r7, [sp, #20] + + RCC_OscInitStruct.PLL.PLLM = CKCC_CLK_PLLM; + RCC_OscInitStruct.PLL.PLLN = CKCC_CLK_PLLN; + RCC_OscInitStruct.PLL.PLLP = CKCC_CLK_PLLP; + 8001e88: f04f 0807 mov.w r8, #7 + 8001e8c: 233c movs r3, #60 ; 0x3c + RCC_OscInitStruct.PLL.PLLQ = CKCC_CLK_PLLQ; + 8001e8e: f04f 0905 mov.w r9, #5 + + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_OscConfig(&RCC_OscInitStruct); + 8001e92: a80a add r0, sp, #40 ; 0x28 + RCC_OscInitStruct.PLL.PLLP = CKCC_CLK_PLLP; + 8001e94: e9cd 3817 strd r3, r8, [sp, #92] ; 0x5c + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 8001e98: e9cd 6714 strd r6, r7, [sp, #80] ; 0x50 + RCC_OscInitStruct.PLL.PLLR = CKCC_CLK_PLLR; + 8001e9c: e9cd 9619 strd r9, r6, [sp, #100] ; 0x64 + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + 8001ea0: e9cd 5507 strd r5, r5, [sp, #28] + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + 8001ea4: 950c str r5, [sp, #48] ; 0x30 + RCC_OscInitStruct.MSIState = RCC_MSI_OFF; + 8001ea6: 9510 str r5, [sp, #64] ; 0x40 + RCC_OscInitStruct.PLL.PLLM = CKCC_CLK_PLLM; + 8001ea8: 9616 str r6, [sp, #88] ; 0x58 + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + 8001eaa: 9509 str r5, [sp, #36] ; 0x24 + HAL_RCC_OscConfig(&RCC_OscInitStruct); + 8001eac: f006 fcdc bl 8008868 + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + 8001eb0: 4649 mov r1, r9 + 8001eb2: a805 add r0, sp, #20 + 8001eb4: f006 ff86 bl 8008dc4 + + // DIS-able MSI-Hardware auto calibration mode with LSE + CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN); + 8001eb8: 6823 ldr r3, [r4, #0] + 8001eba: f023 0304 bic.w r3, r3, #4 + 8001ebe: 6023 str r3, [r4, #0] + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_I2C2 + 8001ec0: 4b29 ldr r3, [pc, #164] ; (8001f68 ) + 8001ec2: 931b str r3, [sp, #108] ; 0x6c + + // PLLSAI is used to clock USB, ADC, I2C1 and RNG. The frequency is + // HSE(8MHz)/PLLM(2)*PLLSAI1N(24)/PLLSAIQ(2) = 48MHz. + // + PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1; + 8001ec4: f04f 5380 mov.w r3, #268435456 ; 0x10000000 + 8001ec8: 933b str r3, [sp, #236] ; 0xec + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; + 8001eca: f04f 6380 mov.w r3, #67108864 ; 0x4000000 + 8001ece: 9338 str r3, [sp, #224] ; 0xe0 + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1; + 8001ed0: 933a str r3, [sp, #232] ; 0xe8 + + PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE; + PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 2; + PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 24; + 8001ed2: 2318 movs r3, #24 + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + 8001ed4: f44f 7240 mov.w r2, #768 ; 0x300 + PeriphClkInitStruct.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; + 8001ed8: e9cd 381e strd r3, r8, [sp, #120] ; 0x78 + PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + |RCC_PLLSAI1_48M2CLK + |RCC_PLLSAI1_ADC1CLK; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + 8001edc: a81b add r0, sp, #108 ; 0x6c + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + 8001ede: 4b23 ldr r3, [pc, #140] ; (8001f6c ) + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + 8001ee0: 923f str r2, [sp, #252] ; 0xfc + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + 8001ee2: 9322 str r3, [sp, #136] ; 0x88 + PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 2; + 8001ee4: e9cd 761c strd r7, r6, [sp, #112] ; 0x70 + PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; + 8001ee8: e9cd 6620 strd r6, r6, [sp, #128] ; 0x80 + PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; + 8001eec: 9531 str r5, [sp, #196] ; 0xc4 + PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + 8001eee: 9536 str r5, [sp, #216] ; 0xd8 + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + 8001ef0: f007 fa8c bl 800940c + + __HAL_RCC_RTC_ENABLE(); + 8001ef4: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8001ef8: f443 4300 orr.w r3, r3, #32768 ; 0x8000 + 8001efc: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + __HAL_RCC_HASH_CLK_ENABLE(); // for SHA256 + 8001f00: 6ce3 ldr r3, [r4, #76] ; 0x4c + 8001f02: f443 3300 orr.w r3, r3, #131072 ; 0x20000 + 8001f06: 64e3 str r3, [r4, #76] ; 0x4c + 8001f08: 6ce3 ldr r3, [r4, #76] ; 0x4c + 8001f0a: f403 3300 and.w r3, r3, #131072 ; 0x20000 + 8001f0e: 9301 str r3, [sp, #4] + 8001f10: 9b01 ldr r3, [sp, #4] + __HAL_RCC_SPI1_CLK_ENABLE(); // for OLED + 8001f12: 6e23 ldr r3, [r4, #96] ; 0x60 + 8001f14: f443 5380 orr.w r3, r3, #4096 ; 0x1000 + 8001f18: 6623 str r3, [r4, #96] ; 0x60 + 8001f1a: 6e23 ldr r3, [r4, #96] ; 0x60 + 8001f1c: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 8001f20: 9302 str r3, [sp, #8] + 8001f22: 9b02 ldr r3, [sp, #8] + //__HAL_RCC_SPI2_CLK_ENABLE(); // for SPI flash + __HAL_RCC_DMAMUX1_CLK_ENABLE(); // (need this) because code missing in mpy? + 8001f24: 6ca3 ldr r3, [r4, #72] ; 0x48 + 8001f26: f043 0304 orr.w r3, r3, #4 + 8001f2a: 64a3 str r3, [r4, #72] ; 0x48 + 8001f2c: 6ca3 ldr r3, [r4, #72] ; 0x48 + 8001f2e: f003 0304 and.w r3, r3, #4 + 8001f32: 9303 str r3, [sp, #12] + 8001f34: 9b03 ldr r3, [sp, #12] + + // for SE2 + __HAL_RCC_I2C2_CLK_ENABLE(); + 8001f36: 6da3 ldr r3, [r4, #88] ; 0x58 + 8001f38: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 8001f3c: 65a3 str r3, [r4, #88] ; 0x58 + 8001f3e: 6da3 ldr r3, [r4, #88] ; 0x58 + 8001f40: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 8001f44: 9304 str r3, [sp, #16] + 8001f46: 9b04 ldr r3, [sp, #16] + __HAL_RCC_I2C2_FORCE_RESET(); + 8001f48: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8001f4a: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 8001f4e: 63a3 str r3, [r4, #56] ; 0x38 + __HAL_RCC_I2C2_RELEASE_RESET(); + 8001f50: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8001f52: f423 0380 bic.w r3, r3, #4194304 ; 0x400000 + 8001f56: 63a3 str r3, [r4, #56] ; 0x38 + + // setup SYSTICK, but we don't have the irq hooked up and not using HAL + // but we use it in polling mode for delay_ms() + systick_setup(); + 8001f58: f7ff ff50 bl 8001dfc + +} + 8001f5c: b041 add sp, #260 ; 0x104 + 8001f5e: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 8001f62: bf00 nop + 8001f64: 40021000 .word 0x40021000 + 8001f68: 00066880 .word 0x00066880 + 8001f6c: 01110000 .word 0x01110000 + +08001f70 : + } else { + + // write changes to OB flash bytes + + // Set OPTSTRT bit + SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT); + 8001f70: 4b13 ldr r3, [pc, #76] ; (8001fc0 ) + 8001f72: 695a ldr r2, [r3, #20] + 8001f74: f442 3200 orr.w r2, r2, #131072 ; 0x20000 + 8001f78: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { + 8001f7a: 691a ldr r2, [r3, #16] + 8001f7c: 03d2 lsls r2, r2, #15 + 8001f7e: d4fc bmi.n 8001f7a + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); + 8001f80: 6919 ldr r1, [r3, #16] + if(error) { + 8001f82: 4a10 ldr r2, [pc, #64] ; (8001fc4 ) + 8001f84: 4211 tst r1, r2 + 8001f86: d104 bne.n 8001f92 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { + 8001f88: 691a ldr r2, [r3, #16] + 8001f8a: 07d0 lsls r0, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + 8001f8c: bf44 itt mi + 8001f8e: 2201 movmi r2, #1 + 8001f90: 611a strmi r2, [r3, #16] + + /// Wait for update to complete + _flash_wait_done(); + + // lock OB again. + SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK); + 8001f92: 4b0b ldr r3, [pc, #44] ; (8001fc0 ) + 8001f94: 695a ldr r2, [r3, #20] + 8001f96: f042 4280 orr.w r2, r2, #1073741824 ; 0x40000000 + 8001f9a: 615a str r2, [r3, #20] + + // include "launch" to make them take effect NOW + SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH); + 8001f9c: 695a ldr r2, [r3, #20] + 8001f9e: f042 6200 orr.w r2, r2, #134217728 ; 0x8000000 + 8001fa2: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { + 8001fa4: 691a ldr r2, [r3, #16] + 8001fa6: 03d1 lsls r1, r2, #15 + 8001fa8: d4fc bmi.n 8001fa4 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); + 8001faa: 6919 ldr r1, [r3, #16] + if(error) { + 8001fac: 4a05 ldr r2, [pc, #20] ; (8001fc4 ) + 8001fae: 4211 tst r1, r2 + 8001fb0: d104 bne.n 8001fbc + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { + 8001fb2: 691a ldr r2, [r3, #16] + 8001fb4: 07d2 lsls r2, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + 8001fb6: bf44 itt mi + 8001fb8: 2201 movmi r2, #1 + 8001fba: 611a strmi r2, [r3, #16] + + _flash_wait_done(); + } +} + 8001fbc: 4770 bx lr + 8001fbe: bf00 nop + 8001fc0: 40022000 .word 0x40022000 + 8001fc4: 0002c3fa .word 0x0002c3fa + +08001fc8 : +{ + 8001fc8: b507 push {r0, r1, r2, lr} + memcpy(&_srelocate, &_etext, ((uint32_t)&_erelocate)-(uint32_t)&_srelocate); + 8001fca: 4809 ldr r0, [pc, #36] ; (8001ff0 ) + 8001fcc: 4a09 ldr r2, [pc, #36] ; (8001ff4 ) + 8001fce: 490a ldr r1, [pc, #40] ; (8001ff8 ) + 8001fd0: 1a12 subs r2, r2, r0 + 8001fd2: f00b fb27 bl 800d624 + __HAL_RCC_FLASH_CLK_ENABLE(); + 8001fd6: 4b09 ldr r3, [pc, #36] ; (8001ffc ) + 8001fd8: 6c9a ldr r2, [r3, #72] ; 0x48 + 8001fda: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8001fde: 649a str r2, [r3, #72] ; 0x48 + 8001fe0: 6c9b ldr r3, [r3, #72] ; 0x48 + 8001fe2: f403 7380 and.w r3, r3, #256 ; 0x100 + 8001fe6: 9301 str r3, [sp, #4] + 8001fe8: 9b01 ldr r3, [sp, #4] +} + 8001fea: b003 add sp, #12 + 8001fec: f85d fb04 ldr.w pc, [sp], #4 + 8001ff0: 2009e000 .word 0x2009e000 + 8001ff4: 2009e150 .word 0x2009e150 + 8001ff8: 0800ea48 .word 0x0800ea48 + 8001ffc: 40021000 .word 0x40021000 + +08002000 : + SET_BIT(FLASH->CR, FLASH_CR_LOCK); + 8002000: 4a02 ldr r2, [pc, #8] ; (800200c ) + 8002002: 6953 ldr r3, [r2, #20] + 8002004: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 8002008: 6153 str r3, [r2, #20] +} + 800200a: 4770 bx lr + 800200c: 40022000 .word 0x40022000 + +08002010 : +{ + 8002010: b508 push {r3, lr} + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { + 8002012: 4b08 ldr r3, [pc, #32] ; (8002034 ) + 8002014: 695a ldr r2, [r3, #20] + 8002016: 2a00 cmp r2, #0 + 8002018: da0a bge.n 8002030 + WRITE_REG(FLASH->KEYR, FLASH_KEY1); + 800201a: 4a07 ldr r2, [pc, #28] ; (8002038 ) + 800201c: 609a str r2, [r3, #8] + WRITE_REG(FLASH->KEYR, FLASH_KEY2); + 800201e: f102 3288 add.w r2, r2, #2290649224 ; 0x88888888 + 8002022: 609a str r2, [r3, #8] + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { + 8002024: 695b ldr r3, [r3, #20] + 8002026: 2b00 cmp r3, #0 + 8002028: da02 bge.n 8002030 + INCONSISTENT("failed to unlock"); + 800202a: 4804 ldr r0, [pc, #16] ; (800203c ) + 800202c: f7fe fd0c bl 8000a48 +} + 8002030: bd08 pop {r3, pc} + 8002032: bf00 nop + 8002034: 40022000 .word 0x40022000 + 8002038: 45670123 .word 0x45670123 + 800203c: 0800d700 .word 0x0800d700 + +08002040 : +{ + 8002040: b510 push {r4, lr} + if(!lock) { + 8002042: b980 cbnz r0, 8002066 + if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { + 8002044: 4c0a ldr r4, [pc, #40] ; (8002070 ) + 8002046: 6963 ldr r3, [r4, #20] + 8002048: 005a lsls r2, r3, #1 + 800204a: d510 bpl.n 800206e + flash_unlock(); + 800204c: f7ff ffe0 bl 8002010 + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); + 8002050: 4b08 ldr r3, [pc, #32] ; (8002074 ) + 8002052: 60e3 str r3, [r4, #12] + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); + 8002054: f103 3344 add.w r3, r3, #1145324612 ; 0x44444444 + 8002058: 60e3 str r3, [r4, #12] + if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { + 800205a: 6963 ldr r3, [r4, #20] + 800205c: 005b lsls r3, r3, #1 + 800205e: d506 bpl.n 800206e + INCONSISTENT("failed to OB unlock"); + 8002060: 4805 ldr r0, [pc, #20] ; (8002078 ) + 8002062: f7fe fcf1 bl 8000a48 +} + 8002066: e8bd 4010 ldmia.w sp!, {r4, lr} + 800206a: f7ff bf81 b.w 8001f70 + 800206e: bd10 pop {r4, pc} + 8002070: 40022000 .word 0x40022000 + 8002074: 08192a3b .word 0x08192a3b + 8002078: 0800d700 .word 0x0800d700 + +0800207c : + +// pick_pairing_secret() +// + static void +pick_pairing_secret(void) +{ + 800207c: b570 push {r4, r5, r6, lr} + 800207e: f5ad 6d85 sub.w sp, sp, #1064 ; 0x428 + // important the RNG works here. ok to call setup multiple times. + rng_setup(); + 8002082: f000 fb39 bl 80026f8 + 8002086: 24c8 movs r4, #200 ; 0xc8 +#else + // Demo to anyone watching that the RNG is working, but likely only + // to be seen by production team during initial powerup. + uint8_t tmp[1024]; + for(int i=0; i<200; i++) { + rng_buffer(tmp, sizeof(tmp)); + 8002088: f44f 6180 mov.w r1, #1024 ; 0x400 + 800208c: a80a add r0, sp, #40 ; 0x28 + 800208e: f000 fb5f bl 8002750 + + oled_show_raw(sizeof(tmp), (void *)tmp); + 8002092: a90a add r1, sp, #40 ; 0x28 + 8002094: f44f 6080 mov.w r0, #1024 ; 0x400 + 8002098: f7fe fea8 bl 8000dec + for(int i=0; i<200; i++) { + 800209c: 3c01 subs r4, #1 + 800209e: d1f3 bne.n 8002088 + } + + oled_factory_busy(); + 80020a0: f7fe ff92 bl 8000fc8 +#endif + + // .. but don't use those numbers, because those are semi-public now. + uint32_t secret[8]; + for(int i=0; i<8; i++) { + 80020a4: ad02 add r5, sp, #8 + oled_factory_busy(); + 80020a6: 462e mov r6, r5 + secret[i] = rng_sample(); + 80020a8: f000 fb14 bl 80026d4 + for(int i=0; i<8; i++) { + 80020ac: 3401 adds r4, #1 + 80020ae: 2c08 cmp r4, #8 + secret[i] = rng_sample(); + 80020b0: f846 0b04 str.w r0, [r6], #4 + for(int i=0; i<8; i++) { + 80020b4: d1f8 bne.n 80020a8 + } + + // enforce policy that first word is not all ones (so it never + // looks like unprogrammed flash). + while(secret[0] == ~0) { + 80020b6: 682b ldr r3, [r5, #0] + 80020b8: 3301 adds r3, #1 + 80020ba: d00c beq.n 80020d6 + + // Write pairing secret into flash + { + uint32_t dest = (uint32_t)&rom_secrets->pairing_secret; + + flash_unlock(); + 80020bc: f7ff ffa8 bl 8002010 + uint32_t dest = (uint32_t)&rom_secrets->pairing_secret; + 80020c0: 4c16 ldr r4, [pc, #88] ; (800211c ) + for(int i=0; i<8; i+=2, dest += 8) { + 80020c2: 4e17 ldr r6, [pc, #92] ; (8002120 ) + uint64_t val = (((uint64_t)secret[i]) << 32) | secret[i+1]; + + if(flash_burn(dest, val)) { + 80020c4: e9d5 3200 ldrd r3, r2, [r5] + 80020c8: 4620 mov r0, r4 + 80020ca: f00b fb11 bl 800d6f0 <__flash_burn_veneer> + 80020ce: b130 cbz r0, 80020de + INCONSISTENT("flash fail"); + 80020d0: 4814 ldr r0, [pc, #80] ; (8002124 ) + 80020d2: f7fe fcb9 bl 8000a48 + secret[0] = rng_sample(); + 80020d6: f000 fafd bl 80026d4 + 80020da: 6028 str r0, [r5, #0] + 80020dc: e7eb b.n 80020b6 + for(int i=0; i<8; i+=2, dest += 8) { + 80020de: 3408 adds r4, #8 + 80020e0: 42b4 cmp r4, r6 + 80020e2: f105 0508 add.w r5, r5, #8 + 80020e6: d1ed bne.n 80020c4 + } + } + flash_lock(); + 80020e8: f7ff ff8a bl 8002000 + + sizeof(rom_secrets->mcu_hmac_key); + + STATIC_ASSERT(offsetof(rom_secrets_t, hash_cache_secret) % 8 == 0); + STATIC_ASSERT(blen % 8 == 0); + + flash_unlock(); + 80020ec: f7ff ff90 bl 8002010 + uint32_t dest = (uint32_t)&rom_secrets->hash_cache_secret; + 80020f0: 4c0d ldr r4, [pc, #52] ; (8002128 ) + for(int i=0; i) + uint64_t val = ((uint64_t)rng_sample() << 32) | rng_sample(); + 80020f4: f000 faee bl 80026d4 + 80020f8: 9001 str r0, [sp, #4] + 80020fa: f000 faeb bl 80026d4 + + if(flash_burn(dest, val)) { + 80020fe: 9b01 ldr r3, [sp, #4] + uint64_t val = ((uint64_t)rng_sample() << 32) | rng_sample(); + 8002100: 4602 mov r2, r0 + if(flash_burn(dest, val)) { + 8002102: 4620 mov r0, r4 + 8002104: f00b faf4 bl 800d6f0 <__flash_burn_veneer> + 8002108: 2800 cmp r0, #0 + 800210a: d1e1 bne.n 80020d0 + for(int i=0; i + INCONSISTENT("flash fail"); + } + } + flash_lock(); + 8002112: f7ff ff75 bl 8002000 + } + +} + 8002116: f50d 6d85 add.w sp, sp, #1064 ; 0x428 + 800211a: bd70 pop {r4, r5, r6, pc} + 800211c: 0801c000 .word 0x0801c000 + 8002120: 0801c020 .word 0x0801c020 + 8002124: 0800d700 .word 0x0800d700 + 8002128: 0801c070 .word 0x0801c070 + 800212c: 0801c0b0 .word 0x0801c0b0 + +08002130 : +// +// Write the serial number of ATECC608 into flash forever. +// + void +flash_save_ae_serial(const uint8_t serial[9]) +{ + 8002130: b51f push {r0, r1, r2, r3, r4, lr} + 8002132: 4602 mov r2, r0 + uint64_t tmp[2]; + memset(&tmp, 0x0, sizeof(tmp)); + 8002134: 2300 movs r3, #0 + memcpy(&tmp, serial, 9); + 8002136: 6800 ldr r0, [r0, #0] + 8002138: 6851 ldr r1, [r2, #4] + 800213a: 7a12 ldrb r2, [r2, #8] + memset(&tmp, 0x0, sizeof(tmp)); + 800213c: e9cd 3302 strd r3, r3, [sp, #8] + memcpy(&tmp, serial, 9); + 8002140: 466b mov r3, sp + 8002142: c303 stmia r3!, {r0, r1} + 8002144: 701a strb r2, [r3, #0] + + flash_setup0(); + 8002146: f7ff ff3f bl 8001fc8 + flash_unlock(); + 800214a: f7ff ff61 bl 8002010 + + if(flash_burn((uint32_t)&rom_secrets->ae_serial_number[0], tmp[0])) { + 800214e: e9dd 2300 ldrd r2, r3, [sp] + 8002152: 4809 ldr r0, [pc, #36] ; (8002178 ) + 8002154: f00b facc bl 800d6f0 <__flash_burn_veneer> + 8002158: b110 cbz r0, 8002160 + INCONSISTENT("fail1"); + 800215a: 4808 ldr r0, [pc, #32] ; (800217c ) + 800215c: f7fe fc74 bl 8000a48 + } + if(flash_burn((uint32_t)&rom_secrets->ae_serial_number[1], tmp[1])) { + 8002160: e9dd 2302 ldrd r2, r3, [sp, #8] + 8002164: 4806 ldr r0, [pc, #24] ; (8002180 ) + 8002166: f00b fac3 bl 800d6f0 <__flash_burn_veneer> + 800216a: 2800 cmp r0, #0 + 800216c: d1f5 bne.n 800215a + INCONSISTENT("fail2"); + } + + flash_lock(); +} + 800216e: b005 add sp, #20 + 8002170: f85d eb04 ldr.w lr, [sp], #4 + flash_lock(); + 8002174: f7ff bf44 b.w 8002000 + 8002178: 0801c040 .word 0x0801c040 + 800217c: 0800d700 .word 0x0800d700 + 8002180: 0801c048 .word 0x0801c048 + +08002184 : +// +// Write bag number (probably a string) +// + void +flash_save_bag_number(const uint8_t new_number[32]) +{ + 8002184: b570 push {r4, r5, r6, lr} + 8002186: b088 sub sp, #32 + uint32_t dest = (uint32_t)&rom_secrets->bag_number[0]; + uint64_t tmp[4] = { 0 }; + uint64_t *src = tmp; + + STATIC_ASSERT(sizeof(tmp) == 32); + memcpy(tmp, new_number, 32); + 8002188: 4603 mov r3, r0 + 800218a: 466c mov r4, sp + 800218c: f100 0520 add.w r5, r0, #32 + 8002190: 6818 ldr r0, [r3, #0] + 8002192: 6859 ldr r1, [r3, #4] + 8002194: 4622 mov r2, r4 + 8002196: c203 stmia r2!, {r0, r1} + 8002198: 3308 adds r3, #8 + 800219a: 42ab cmp r3, r5 + 800219c: 4614 mov r4, r2 + 800219e: d1f7 bne.n 8002190 + + flash_setup0(); + 80021a0: f7ff ff12 bl 8001fc8 + flash_unlock(); + 80021a4: f7ff ff34 bl 8002010 + uint32_t dest = (uint32_t)&rom_secrets->bag_number[0]; + 80021a8: 4d09 ldr r5, [pc, #36] ; (80021d0 ) + + // NOTE: can only write once! No provision for read/check/update. + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80021aa: 4e0a ldr r6, [pc, #40] ; (80021d4 ) + 80021ac: 466c mov r4, sp + if(flash_burn(dest, *src)) { + 80021ae: e8f4 2302 ldrd r2, r3, [r4], #8 + 80021b2: 4628 mov r0, r5 + 80021b4: f00b fa9c bl 800d6f0 <__flash_burn_veneer> + 80021b8: b110 cbz r0, 80021c0 + INCONSISTENT("fail write"); + 80021ba: 4807 ldr r0, [pc, #28] ; (80021d8 ) + 80021bc: f7fe fc44 bl 8000a48 + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80021c0: 3508 adds r5, #8 + 80021c2: 42b5 cmp r5, r6 + 80021c4: d1f3 bne.n 80021ae + } + } + + flash_lock(); +} + 80021c6: b008 add sp, #32 + 80021c8: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + flash_lock(); + 80021cc: f7ff bf18 b.w 8002000 + 80021d0: 0801c050 .word 0x0801c050 + 80021d4: 0801c070 .word 0x0801c070 + 80021d8: 0800d700 .word 0x0800d700 + +080021dc : +// Save bunch of stuff related to SE2. Allow updates to sections that are +// given as ones at this point. +// + void +flash_save_se2_data(const se2_secrets_t *se2) +{ + 80021dc: e92d 41f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, lr} + 80021e0: 4605 mov r5, r0 + uint8_t *dest = (uint8_t *)&rom_secrets->se2; + 80021e2: 4c1a ldr r4, [pc, #104] ; (800224c ) + STATIC_ASSERT(offsetof(rom_secrets_t, se2) % 8 == 0); + + flash_setup0(); + flash_unlock(); + + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 80021e4: f8df 8070 ldr.w r8, [pc, #112] ; 8002258 + flash_setup0(); + 80021e8: f7ff feee bl 8001fc8 + flash_unlock(); + 80021ec: f7ff ff10 bl 8002010 + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 80021f0: 1b2d subs r5, r5, r4 + 80021f2: eb05 0c04 add.w ip, r5, r4 + uint64_t val; + memcpy(&val, src, sizeof(val)); + 80021f6: 5928 ldr r0, [r5, r4] + 80021f8: f8dc 1004 ldr.w r1, [ip, #4] + 80021fc: 466b mov r3, sp + + // don't write if all ones or already written correctly + if(val == ~0) continue; + 80021fe: f1b1 3fff cmp.w r1, #4294967295 ; 0xffffffff + 8002202: bf08 it eq + 8002204: f1b0 3fff cmpeq.w r0, #4294967295 ; 0xffffffff + memcpy(&val, src, sizeof(val)); + 8002208: c303 stmia r3!, {r0, r1} + if(val == ~0) continue; + 800220a: 4607 mov r7, r0 + 800220c: 460e mov r6, r1 + 800220e: d015 beq.n 800223c + if(check_equal(dest, src, 8)) continue; + 8002210: 2208 movs r2, #8 + 8002212: 4661 mov r1, ip + 8002214: 4620 mov r0, r4 + 8002216: f000 fa4c bl 80026b2 + 800221a: b978 cbnz r0, 800223c + + // can't write if not ones already + ASSERT(check_all_ones(dest, 8)); + 800221c: 2108 movs r1, #8 + 800221e: 4620 mov r0, r4 + 8002220: f000 fa2e bl 8002680 + 8002224: b910 cbnz r0, 800222c + 8002226: 480a ldr r0, [pc, #40] ; (8002250 ) + + if(flash_burn((uint32_t)dest, val)) { + INCONSISTENT("fail write"); + 8002228: f7fe fc0e bl 8000a48 + if(flash_burn((uint32_t)dest, val)) { + 800222c: 463a mov r2, r7 + 800222e: 4633 mov r3, r6 + 8002230: 4620 mov r0, r4 + 8002232: f00b fa5d bl 800d6f0 <__flash_burn_veneer> + 8002236: b108 cbz r0, 800223c + INCONSISTENT("fail write"); + 8002238: 4806 ldr r0, [pc, #24] ; (8002254 ) + 800223a: e7f5 b.n 8002228 + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 800223c: 3408 adds r4, #8 + 800223e: 4544 cmp r4, r8 + 8002240: d1d7 bne.n 80021f2 + } + } + + flash_lock(); +} + 8002242: b002 add sp, #8 + 8002244: e8bd 41f0 ldmia.w sp!, {r4, r5, r6, r7, r8, lr} + flash_lock(); + 8002248: f7ff beda b.w 8002000 + 800224c: 0801c0b0 .word 0x0801c0b0 + 8002250: 0800e3e0 .word 0x0800e3e0 + 8002254: 0800d700 .word 0x0800d700 + 8002258: 0801c190 .word 0x0801c190 + +0800225c : +// +// This is really a state-machine, to recover boards that are booted w/ missing AE chip. +// + void +flash_setup(void) +{ + 800225c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + + // see if we have picked a pairing secret yet. + // NOTE: critical section for glitching (at least in past versions) + // - check_all.. functions have a rng_delay in them already + rng_delay(); + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 8002260: 4d3e ldr r5, [pc, #248] ; (800235c ) +{ + 8002262: b088 sub sp, #32 + flash_setup0(); + 8002264: f7ff feb0 bl 8001fc8 + rng_delay(); + 8002268: f000 fa88 bl 800277c + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 800226c: 2120 movs r1, #32 + 800226e: 4628 mov r0, r5 + 8002270: f000 fa06 bl 8002680 + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 8002274: 2120 movs r1, #32 + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 8002276: 4606 mov r6, r0 + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 8002278: 4628 mov r0, r5 + 800227a: f000 fa0b bl 8002694 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 800227e: 2120 movs r1, #32 + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 8002280: 4607 mov r7, r0 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 8002282: 4837 ldr r0, [pc, #220] ; (8002360 ) + 8002284: f000 f9fc bl 8002680 + bool blank_ae = (~rom_secrets->ae_serial_number[0] == 0); + 8002288: e9d5 8510 ldrd r8, r5, [r5, #64] ; 0x40 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 800228c: 4604 mov r4, r0 + rng_delay(); + 800228e: f000 fa75 bl 800277c + + if(zeroed_ps) { + 8002292: b127 cbz r7, 800229e + // fast brick process leaves us w/ zero pairing secret + oled_show(screen_brick); + 8002294: 4833 ldr r0, [pc, #204] ; (8002364 ) + 8002296: f7fe fdd5 bl 8000e44 + LOCKUP_FOREVER(); + 800229a: bf30 wfi + 800229c: e7fd b.n 800229a + } + + if(blank_ps) { + 800229e: b10e cbz r6, 80022a4 + // get some good entropy, save it. + pick_pairing_secret(); + 80022a0: f7ff feec bl 800207c + + blank_ps = false; + } + + if(blank_xor || blank_ae) { + 80022a4: b92c cbnz r4, 80022b2 + 80022a6: f1b5 3fff cmp.w r5, #4294967295 ; 0xffffffff + 80022aa: bf08 it eq + 80022ac: f1b8 3fff cmpeq.w r8, #4294967295 ; 0xffffffff + 80022b0: d12f bne.n 8002312 + + // setup the SE2 (mostly). handles failures by dying + se2_setup_config(); + 80022b2: f005 faeb bl 800788c + + // configure and lock-down the SE1 + int rv = ae_setup_config(); + 80022b6: f001 f99b bl 80035f0 + 80022ba: 4605 mov r5, r0 + + rng_delay(); + 80022bc: f000 fa5e bl 800277c + if(rv) { + 80022c0: b13d cbz r5, 80022d2 + // Hardware fail speaking to AE chip ... be careful not to brick here. + // Do not continue!! We might fix the board, or add missing pullup, etc. + oled_show(screen_se1_issue); + 80022c2: 4829 ldr r0, [pc, #164] ; (8002368 ) + 80022c4: f7fe fdbe bl 8000e44 + puts("SE1 config fail"); + 80022c8: 4828 ldr r0, [pc, #160] ; (800236c ) + 80022ca: f002 fd6f bl 8004dac + + LOCKUP_FOREVER(); + 80022ce: bf30 wfi + 80022d0: e7fd b.n 80022ce + } + + rng_delay(); + 80022d2: f000 fa53 bl 800277c + if(blank_xor) { + 80022d6: b1a4 cbz r4, 8002302 + flash_unlock(); + 80022d8: f7ff fe9a bl 8002010 + uint64_t *src = (uint64_t *)&rom_secrets->pairing_secret; + 80022dc: 4c1f ldr r4, [pc, #124] ; (800235c ) + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80022de: 4d20 ldr r5, [pc, #128] ; (8002360 ) + uint64_t val = ~(*src); + 80022e0: e9d4 2300 ldrd r2, r3, [r4] + if(flash_burn(dest, val)) { + 80022e4: f104 0020 add.w r0, r4, #32 + 80022e8: 43d2 mvns r2, r2 + 80022ea: 43db mvns r3, r3 + 80022ec: f00b fa00 bl 800d6f0 <__flash_burn_veneer> + 80022f0: b110 cbz r0, 80022f8 + INCONSISTENT("flash xor fail"); + 80022f2: 481f ldr r0, [pc, #124] ; (8002370 ) + 80022f4: f7fe fba8 bl 8000a48 + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80022f8: 3408 adds r4, #8 + 80022fa: 42ac cmp r4, r5 + 80022fc: d1f0 bne.n 80022e0 + flash_lock(); + 80022fe: f7ff fe7f bl 8002000 + // Q: just do it (we warned them) + extern void turn_power_off(void); + turn_power_off(); +#else + // Mk: operator must do it + oled_show(screen_replug); + 8002302: 481c ldr r0, [pc, #112] ; (8002374 ) + 8002304: f7fe fd9e bl 8000e44 + puts("replug required"); + 8002308: 481b ldr r0, [pc, #108] ; (8002378 ) + 800230a: f002 fd4f bl 8004dac + LOCKUP_FOREVER(); + 800230e: bf30 wfi + 8002310: e7fd b.n 800230e + + rng_delay(); + if(!blank_ps && !blank_xor) { + // check the XOR value also written: 2 phase commit + uint8_t tmp[32]; + memcpy(tmp, rom_secrets->pairing_secret, 32); + 8002312: 4d12 ldr r5, [pc, #72] ; (800235c ) + rng_delay(); + 8002314: f000 fa32 bl 800277c + memcpy(tmp, rom_secrets->pairing_secret, 32); + 8002318: cd0f ldmia r5!, {r0, r1, r2, r3} + 800231a: 466c mov r4, sp + 800231c: c40f stmia r4!, {r0, r1, r2, r3} + 800231e: e895 000f ldmia.w r5, {r0, r1, r2, r3} + 8002322: e884 000f stmia.w r4, {r0, r1, r2, r3} + 8002326: 466b mov r3, sp + 8002328: 4a0d ldr r2, [pc, #52] ; (8002360 ) +bool check_equal(const void *aV, const void *bV, int len); + +// XOR-mixin more bytes; acc = acc XOR more for each byte +void static inline xor_mixin(uint8_t *acc, const uint8_t *more, int len) +{ + for(; len; len--, more++, acc++) { + 800232a: 4c14 ldr r4, [pc, #80] ; (800237c ) + 800232c: 4618 mov r0, r3 + *(acc) ^= *(more); + 800232e: 7819 ldrb r1, [r3, #0] + 8002330: f812 5b01 ldrb.w r5, [r2], #1 + 8002334: 4069 eors r1, r5 + for(; len; len--, more++, acc++) { + 8002336: 42a2 cmp r2, r4 + *(acc) ^= *(more); + 8002338: f803 1b01 strb.w r1, [r3], #1 + for(; len; len--, more++, acc++) { + 800233c: d1f7 bne.n 800232e + xor_mixin(tmp, rom_secrets->pairing_secret_xor, 32); + + if(!check_all_ones(tmp, 32)) { + 800233e: 2120 movs r1, #32 + 8002340: f000 f99e bl 8002680 + 8002344: b938 cbnz r0, 8002356 + oled_show(screen_corrupt); + 8002346: 480e ldr r0, [pc, #56] ; (8002380 ) + 8002348: f7fe fd7c bl 8000e44 + puts("corrupt pair sec"); + 800234c: 480d ldr r0, [pc, #52] ; (8002384 ) + 800234e: f002 fd2d bl 8004dac + + // dfu won't save them here, so just die + LOCKUP_FOREVER(); + 8002352: bf30 wfi + 8002354: e7fd b.n 8002352 + // That's fine if we intend to ship units locked already. + + // Do NOT do write every boot, as it might wear-out + // the flash bits in OB. + +} + 8002356: b008 add sp, #32 + 8002358: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + 800235c: 0801c000 .word 0x0801c000 + 8002360: 0801c020 .word 0x0801c020 + 8002364: 0800d80b .word 0x0800d80b + 8002368: 0800df27 .word 0x0800df27 + 800236c: 0800e5da .word 0x0800e5da + 8002370: 0800d700 .word 0x0800d700 + 8002374: 0800dec6 .word 0x0800dec6 + 8002378: 0800e5ea .word 0x0800e5ea + 800237c: 0801c040 .word 0x0801c040 + 8002380: 0800d875 .word 0x0800d875 + 8002384: 0800e5fa .word 0x0800e5fa + +08002388 : +// +// This is a one-way trip. Might need power cycle to (fully?) take effect. +// + void +flash_lockdown_hard(uint8_t rdp_level_code) +{ + 8002388: b510 push {r4, lr} + 800238a: 4604 mov r4, r0 +#if RELEASE + flash_setup0(); + 800238c: f7ff fe1c bl 8001fc8 + + // see FLASH_OB_WRPConfig() + + flash_ob_lock(false); + 8002390: 2000 movs r0, #0 + 8002392: f7ff fe55 bl 8002040 + // lock first 128k-8k against any writes + FLASH->WRP1AR = (num_pages_locked << 16); + 8002396: 4b08 ldr r3, [pc, #32] ; (80023b8 ) + 8002398: f44f 2260 mov.w r2, #917504 ; 0xe0000 + 800239c: 62da str r2, [r3, #44] ; 0x2c + FLASH->WRP1BR = 0xff; // unused. + 800239e: 22ff movs r2, #255 ; 0xff + 80023a0: 631a str r2, [r3, #48] ; 0x30 + FLASH->WRP2AR = 0xff; // unused. + 80023a2: 64da str r2, [r3, #76] ; 0x4c + FLASH->WRP2BR = 0xff; // unused. + 80023a4: 651a str r2, [r3, #80] ; 0x50 + // the RDP level is decreased from Level 1 to Level 0)." + // - D-bus access blocked, even for code running inside the PCROP area! (AN4758) + // So literal values and constant tables and such would need special linking. + + // set protection level + uint32_t was = FLASH->OPTR & ~0xff; + 80023a6: 6a1a ldr r2, [r3, #32] + 80023a8: f022 02ff bic.w r2, r2, #255 ; 0xff + FLASH->OPTR = was | rdp_level_code; // select level X, other values as observed + 80023ac: 4322 orrs r2, r4 + 80023ae: 621a str r2, [r3, #32] +#else + puts2("flash_lockdown_hard("); + puthex2(rdp_level_code); + puts(") skipped"); +#endif +} + 80023b0: e8bd 4010 ldmia.w sp!, {r4, lr} + 80023b4: f7ff bddc b.w 8001f70 + 80023b8: 40022000 .word 0x40022000 + +080023bc : + +// record_highwater_version() +// + int +record_highwater_version(const uint8_t timestamp[8]) +{ + 80023bc: b537 push {r0, r1, r2, r4, r5, lr} + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + + ASSERT(timestamp[0] < 0x40); + ASSERT(timestamp[0] >= 0x10); + 80023be: 7802 ldrb r2, [r0, #0] + 80023c0: 3a10 subs r2, #16 + 80023c2: 2a2f cmp r2, #47 ; 0x2f +{ + 80023c4: 4603 mov r3, r0 + ASSERT(timestamp[0] >= 0x10); + 80023c6: d902 bls.n 80023ce + ASSERT(timestamp[0] < 0x40); + 80023c8: 4810 ldr r0, [pc, #64] ; (800240c ) + 80023ca: f7fe fb3d bl 8000a48 + + uint64_t val = 0; + memcpy(&val, timestamp, 8); + 80023ce: 6800 ldr r0, [r0, #0] + 80023d0: 6859 ldr r1, [r3, #4] + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + 80023d2: 4c0f ldr r4, [pc, #60] ; (8002410 ) + + // just write to first blank slot we can find. + for(int i=0; i) + memcpy(&val, timestamp, 8); + 80023d6: 466a mov r2, sp + 80023d8: c203 stmia r2!, {r0, r1} + if(check_all_ones(otp, 8)) { + 80023da: 2108 movs r1, #8 + 80023dc: 4620 mov r0, r4 + 80023de: f000 f94f bl 8002680 + 80023e2: b168 cbz r0, 8002400 + // write here. + flash_setup0(); + 80023e4: f7ff fdf0 bl 8001fc8 + flash_unlock(); + 80023e8: f7ff fe12 bl 8002010 + flash_burn((uint32_t)otp, val); + 80023ec: e9dd 2300 ldrd r2, r3, [sp] + 80023f0: 4620 mov r0, r4 + 80023f2: f00b f97d bl 800d6f0 <__flash_burn_veneer> + flash_lock(); + 80023f6: f7ff fe03 bl 8002000 + + return 0; + 80023fa: 2000 movs r0, #0 + } + } + + // no space. + return 1; +} + 80023fc: b003 add sp, #12 + 80023fe: bd30 pop {r4, r5, pc} + for(int i=0; i + return 1; + 8002406: 2001 movs r0, #1 + 8002408: e7f8 b.n 80023fc + 800240a: bf00 nop + 800240c: 0800e3e0 .word 0x0800e3e0 + 8002410: 1fff7000 .word 0x1fff7000 + 8002414: 1fff7400 .word 0x1fff7400 + +08002418 : + +// mcu_key_get() +// + const mcu_key_t * +mcu_key_get(bool *valid) +{ + 8002418: b570 push {r4, r5, r6, lr} + // get current "mcu_key" value; first byte will never be 0x0 or 0xff + // - except if no key set yet/recently wiped + // - if none set, returns ptr to first available slot which will be all ones + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + + for(int i=0; i) + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + 800241c: 4c0d ldr r4, [pc, #52] ; (8002454 ) +{ + 800241e: 4606 mov r6, r0 + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + 8002420: 2500 movs r5, #0 + if(ptr->value[0] == 0xff) { + 8002422: 7823 ldrb r3, [r4, #0] + 8002424: 2bff cmp r3, #255 ; 0xff + 8002426: d10b bne.n 8002440 + if(!avail) { + 8002428: 2d00 cmp r5, #0 + 800242a: bf08 it eq + 800242c: 4625 moveq r5, r4 + for(int i=0; i + *valid = true; + return ptr; + } + } + + rng_delay(); + 8002434: f000 f9a2 bl 800277c + *valid = false; + 8002438: 2300 movs r3, #0 + 800243a: 7033 strb r3, [r6, #0] + return avail; + 800243c: 462c mov r4, r5 + 800243e: e005 b.n 800244c + } else if(ptr->value[0] != 0x00) { + 8002440: 2b00 cmp r3, #0 + 8002442: d0f4 beq.n 800242e + rng_delay(); + 8002444: f000 f99a bl 800277c + *valid = true; + 8002448: 2301 movs r3, #1 + 800244a: 7033 strb r3, [r6, #0] +} + 800244c: 4620 mov r0, r4 + 800244e: bd70 pop {r4, r5, r6, pc} + 8002450: 08020000 .word 0x08020000 + 8002454: 0801e000 .word 0x0801e000 + +08002458 : + +// mcu_key_clear() +// + void +mcu_key_clear(const mcu_key_t *cur) +{ + 8002458: b513 push {r0, r1, r4, lr} + if(!cur) { + 800245a: 4604 mov r4, r0 + 800245c: b938 cbnz r0, 800246e + bool valid; + cur = mcu_key_get(&valid); + 800245e: f10d 0007 add.w r0, sp, #7 + 8002462: f7ff ffd9 bl 8002418 + + if(!valid) return; + 8002466: f89d 3007 ldrb.w r3, [sp, #7] + cur = mcu_key_get(&valid); + 800246a: 4604 mov r4, r0 + if(!valid) return; + 800246c: b1fb cbz r3, 80024ae + } + + // no delays here since decision has been made, and don't + // want to give them more time to interrupt us + flash_setup0(); + 800246e: f7ff fdab bl 8001fc8 + flash_unlock(); + 8002472: f7ff fdcd bl 8002010 + uint32_t pos = (uint32_t)cur; + flash_burn(pos, 0); pos += 8; + 8002476: 2200 movs r2, #0 + 8002478: 2300 movs r3, #0 + 800247a: 4620 mov r0, r4 + 800247c: f00b f938 bl 800d6f0 <__flash_burn_veneer> + flash_burn(pos, 0); pos += 8; + 8002480: 2200 movs r2, #0 + 8002482: 2300 movs r3, #0 + 8002484: f104 0008 add.w r0, r4, #8 + 8002488: f00b f932 bl 800d6f0 <__flash_burn_veneer> + flash_burn(pos, 0); pos += 8; + 800248c: 2200 movs r2, #0 + 800248e: 2300 movs r3, #0 + 8002490: f104 0010 add.w r0, r4, #16 + 8002494: f00b f92c bl 800d6f0 <__flash_burn_veneer> + flash_burn(pos, 0); + 8002498: 2200 movs r2, #0 + 800249a: 2300 movs r3, #0 + 800249c: f104 0018 add.w r0, r4, #24 + 80024a0: f00b f926 bl 800d6f0 <__flash_burn_veneer> + flash_lock(); +} + 80024a4: b002 add sp, #8 + 80024a6: e8bd 4010 ldmia.w sp!, {r4, lr} + flash_lock(); + 80024aa: f7ff bda9 b.w 8002000 +} + 80024ae: b002 add sp, #8 + 80024b0: bd10 pop {r4, pc} + ... + +080024b4 : + +// mcu_key_usage() +// + void +mcu_key_usage(int *avail_out, int *consumed_out, int *total_out) +{ + 80024b4: b5f0 push {r4, r5, r6, r7, lr} + const mcu_key_t *ptr = MCU_KEYS; + int avail = 0, used = 0; + 80024b6: 2300 movs r3, #0 + const mcu_key_t *ptr = MCU_KEYS; + 80024b8: 4c09 ldr r4, [pc, #36] ; (80024e0 ) + + for(int i=0; i) + int avail = 0, used = 0; + 80024bc: 461d mov r5, r3 + if(ptr->value[0] == 0xff) { + 80024be: 7826 ldrb r6, [r4, #0] + 80024c0: 2eff cmp r6, #255 ; 0xff + 80024c2: d109 bne.n 80024d8 + avail ++; + 80024c4: 3501 adds r5, #1 + for(int i=0; i + } else if(ptr->value[0] == 0x00) { + used ++; + } + } + + *avail_out = avail; + 80024cc: 6005 str r5, [r0, #0] + *consumed_out = used; + 80024ce: 600b str r3, [r1, #0] + *total_out = NUM_MCU_KEYS; + 80024d0: f44f 7380 mov.w r3, #256 ; 0x100 + 80024d4: 6013 str r3, [r2, #0] +} + 80024d6: bdf0 pop {r4, r5, r6, r7, pc} + } else if(ptr->value[0] == 0x00) { + 80024d8: 2e00 cmp r6, #0 + 80024da: d1f4 bne.n 80024c6 + used ++; + 80024dc: 3301 adds r3, #1 + 80024de: e7f2 b.n 80024c6 + 80024e0: 0801e000 .word 0x0801e000 + 80024e4: 08020000 .word 0x08020000 + +080024e8 : + +// mcu_key_pick() +// + const mcu_key_t * +mcu_key_pick(void) +{ + 80024e8: b5f0 push {r4, r5, r6, r7, lr} + 80024ea: b08b sub sp, #44 ; 0x2c + mcu_key_t n; + + // get some good entropy, and whiten it just in case. + do { + rng_buffer(n.value, 32); + 80024ec: ad02 add r5, sp, #8 + 80024ee: 2120 movs r1, #32 + 80024f0: 4628 mov r0, r5 + 80024f2: f000 f92d bl 8002750 + sha256_single(n.value, 32, n.value); + 80024f6: 462a mov r2, r5 + 80024f8: 2120 movs r1, #32 + 80024fa: 4628 mov r0, r5 + 80024fc: f003 f82e bl 800555c + sha256_single(n.value, 32, n.value); + 8002500: 462a mov r2, r5 + 8002502: 2120 movs r1, #32 + 8002504: 4628 mov r0, r5 + 8002506: f003 f829 bl 800555c + } while(n.value[0] == 0x0 || n.value[0] == 0xff); + 800250a: f89d 3008 ldrb.w r3, [sp, #8] + 800250e: 3b01 subs r3, #1 + 8002510: b2db uxtb r3, r3 + 8002512: 2bfd cmp r3, #253 ; 0xfd + 8002514: d8eb bhi.n 80024ee + + int err = 0; + const mcu_key_t *cur; + + do { + bool valid = false; + 8002516: 2300 movs r3, #0 + cur = mcu_key_get(&valid); + 8002518: 4668 mov r0, sp + bool valid = false; + 800251a: f88d 3000 strb.w r3, [sp] + cur = mcu_key_get(&valid); + 800251e: f7ff ff7b bl 8002418 + + if(!cur) { + 8002522: 4604 mov r4, r0 + 8002524: b938 cbnz r0, 8002536 + // no free slots. we are brick. + puts("mcu full"); + 8002526: 4828 ldr r0, [pc, #160] ; (80025c8 ) + 8002528: f002 fc40 bl 8004dac + oled_show(screen_brick); + 800252c: 4827 ldr r0, [pc, #156] ; (80025cc ) + 800252e: f7fe fc89 bl 8000e44 + + LOCKUP_FOREVER(); + 8002532: bf30 wfi + 8002534: e7fd b.n 8002532 + } + + if(valid) { + 8002536: f89d 3000 ldrb.w r3, [sp] + 800253a: b14b cbz r3, 8002550 + // clear existing key, if it's defined. + ASSERT(cur->value[0] != 0x00); + 800253c: 7803 ldrb r3, [r0, #0] + 800253e: 3b01 subs r3, #1 + 8002540: b2db uxtb r3, r3 + 8002542: 2bfd cmp r3, #253 ; 0xfd + 8002544: d902 bls.n 800254c + 8002546: 4822 ldr r0, [pc, #136] ; (80025d0 ) + 8002548: f7fe fa7e bl 8000a48 + ASSERT(cur->value[0] != 0xff); + + mcu_key_clear(cur); + 800254c: f7ff ff84 bl 8002458 + continue; + } + } while(0); + + // burn it + flash_setup0(); + 8002550: f7ff fd3a bl 8001fc8 + flash_unlock(); + 8002554: f7ff fd5c bl 8002010 + uint32_t pos = (uint32_t)cur; + const uint8_t *fr = n.value; + + for(int i=0; i<32; i+= 8, pos += 8, fr += 8) { + 8002558: 2700 movs r7, #0 + uint64_t v; + memcpy(&v, fr, sizeof(v)); + 800255a: 19ea adds r2, r5, r7 + 800255c: 59e8 ldr r0, [r5, r7] + 800255e: 6851 ldr r1, [r2, #4] + 8002560: 466b mov r3, sp + 8002562: c303 stmia r3!, {r0, r1} + + err = flash_burn(pos, v); + 8002564: 19e0 adds r0, r4, r7 + 8002566: e9dd 2300 ldrd r2, r3, [sp] + 800256a: f00b f8c1 bl 800d6f0 <__flash_burn_veneer> + if(err) break; + 800256e: 4606 mov r6, r0 + 8002570: b910 cbnz r0, 8002578 + for(int i=0; i<32; i+= 8, pos += 8, fr += 8) { + 8002572: 3708 adds r7, #8 + 8002574: 2f20 cmp r7, #32 + 8002576: d1f0 bne.n 800255a + } + flash_lock(); + 8002578: f7ff fd42 bl 8002000 + + // NOTE: Errors not expected, but lets be graceful about them. + + if(err) { + 800257c: b166 cbz r6, 8002598 + // what to do? + puts("burn fail: "); + 800257e: 4815 ldr r0, [pc, #84] ; (80025d4 ) + 8002580: f002 fc14 bl 8004dac + puthex2(err); + 8002584: b2f0 uxtb r0, r6 + 8002586: f002 fbb5 bl 8004cf4 + putchar('\n'); + 800258a: 200a movs r0, #10 + 800258c: f002 fb94 bl 8004cb8 + return NULL; + } + + if(after != cur || !check_equal(after->value, n.value, 32)) { + puts("bad val?"); + return NULL; + 8002590: 2400 movs r4, #0 + } + + return cur; +} + 8002592: 4620 mov r0, r4 + 8002594: b00b add sp, #44 ; 0x2c + 8002596: bdf0 pop {r4, r5, r6, r7, pc} + const mcu_key_t *after = mcu_key_get(&valid); + 8002598: 4668 mov r0, sp + bool valid = false; + 800259a: f88d 6000 strb.w r6, [sp] + const mcu_key_t *after = mcu_key_get(&valid); + 800259e: f7ff ff3b bl 8002418 + if(!valid) { + 80025a2: f89d 2000 ldrb.w r2, [sp] + 80025a6: b91a cbnz r2, 80025b0 + puts("!valid?"); + 80025a8: 480b ldr r0, [pc, #44] ; (80025d8 ) + puts("bad val?"); + 80025aa: f002 fbff bl 8004dac + 80025ae: e7ef b.n 8002590 + if(after != cur || !check_equal(after->value, n.value, 32)) { + 80025b0: 4284 cmp r4, r0 + 80025b2: d001 beq.n 80025b8 + puts("bad val?"); + 80025b4: 4809 ldr r0, [pc, #36] ; (80025dc ) + 80025b6: e7f8 b.n 80025aa + if(after != cur || !check_equal(after->value, n.value, 32)) { + 80025b8: 2220 movs r2, #32 + 80025ba: 4629 mov r1, r5 + 80025bc: f000 f879 bl 80026b2 + 80025c0: 2800 cmp r0, #0 + 80025c2: d1e6 bne.n 8002592 + 80025c4: e7f6 b.n 80025b4 + 80025c6: bf00 nop + 80025c8: 0800e60b .word 0x0800e60b + 80025cc: 0800d80b .word 0x0800d80b + 80025d0: 0800e3e0 .word 0x0800e3e0 + 80025d4: 0800e614 .word 0x0800e614 + 80025d8: 0800e620 .word 0x0800e620 + 80025dc: 0800e628 .word 0x0800e628 + +080025e0 : + +// fast_brick() +// + void +fast_brick(void) +{ + 80025e0: b538 push {r3, r4, r5, lr} +#ifndef RELEASE + puts2("DISABLED fast brick... "); + oled_show(screen_brick); +#else + // do a fast wipe of our key + mcu_key_clear(NULL); + 80025e2: 2000 movs r0, #0 + 80025e4: f7ff ff38 bl 8002458 + + // brick SE1 for future + ae_brick_myself(); + 80025e8: f001 f970 bl 80038cc + + // NOTE: could brick SE1 (somewhat) by dec'ing the counter, which will + // invalidate all PIN hashes + + // no going back from that -- but for privacy, wipe more stuff + oled_show(screen_brick); + 80025ec: 480e ldr r0, [pc, #56] ; (8002628 ) + uint32_t bot = (uint32_t)MCU_KEYS; + flash_page_erase(bot); + + // 2: LFS area first, since holds settings (AES'ed w/ lost key, but yeah) + // 3: the firmware, not a secret anyway + for(uint32_t pos=(FLASH_BASE + 0x200000 - FLASH_ERASE_SIZE); + 80025ee: 4c0f ldr r4, [pc, #60] ; (800262c ) + 80025f0: 4d0f ldr r5, [pc, #60] ; (8002630 ) + oled_show(screen_brick); + 80025f2: f7fe fc27 bl 8000e44 + puts2("fast brick... "); + 80025f6: 480f ldr r0, [pc, #60] ; (8002634 ) + 80025f8: f002 fb4a bl 8004c90 + flash_setup0(); + 80025fc: f7ff fce4 bl 8001fc8 + flash_unlock(); + 8002600: f7ff fd06 bl 8002010 + flash_page_erase(bot); + 8002604: 480a ldr r0, [pc, #40] ; (8002630 ) + 8002606: f00b f877 bl 800d6f8 <__flash_page_erase_veneer> + pos > bot; pos -= FLASH_ERASE_SIZE) { + flash_page_erase(pos); + 800260a: 4620 mov r0, r4 + pos > bot; pos -= FLASH_ERASE_SIZE) { + 800260c: f5a4 5480 sub.w r4, r4, #4096 ; 0x1000 + flash_page_erase(pos); + 8002610: f00b f872 bl 800d6f8 <__flash_page_erase_veneer> + for(uint32_t pos=(FLASH_BASE + 0x200000 - FLASH_ERASE_SIZE); + 8002614: 42ac cmp r4, r5 + 8002616: d1f8 bne.n 800260a + } + flash_lock(); + puts(" done"); + 8002618: 4807 ldr r0, [pc, #28] ; (8002638 ) + flash_lock(); + 800261a: f7ff fcf1 bl 8002000 + puts(" done"); + 800261e: f002 fbc5 bl 8004dac +#endif + + LOCKUP_FOREVER(); + 8002622: bf30 wfi + 8002624: e7fd b.n 8002622 + 8002626: bf00 nop + 8002628: 0800d80b .word 0x0800d80b + 800262c: 081ff000 .word 0x081ff000 + 8002630: 0801e000 .word 0x0801e000 + 8002634: 0800e631 .word 0x0800e631 + 8002638: 0800e640 .word 0x0800e640 + +0800263c : + +// fast_wipe() +// + void +fast_wipe(void) +{ + 800263c: b508 push {r3, lr} + // dump (part of) the main seed key and become a new Coldcard + // - lots of other code can and will detect a missing MCU key as "blank" + // - and the check value on main seed will be garbage now + mcu_key_clear(NULL); + 800263e: 2000 movs r0, #0 + 8002640: f7ff ff0a bl 8002458 + __ASM volatile ("dsb 0xF":::"memory"); + 8002644: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8002648: 4905 ldr r1, [pc, #20] ; (8002660 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800264a: 4b06 ldr r3, [pc, #24] ; (8002664 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 800264c: 68ca ldr r2, [r1, #12] + 800264e: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8002652: 4313 orrs r3, r2 + 8002654: 60cb str r3, [r1, #12] + 8002656: f3bf 8f4f dsb sy + __NOP(); + 800265a: bf00 nop + for(;;) /* wait until reset */ + 800265c: e7fd b.n 800265a + 800265e: bf00 nop + 8002660: e000ed00 .word 0xe000ed00 + 8002664: 05fa0004 .word 0x05fa0004 + +08002668 : +check_all_ones_raw(const void *ptrV, int len) +{ + uint8_t rv = 0xff; + const uint8_t *ptr = (const uint8_t *)ptrV; + + for(; len; len--, ptr++) { + 8002668: 4401 add r1, r0 + uint8_t rv = 0xff; + 800266a: 23ff movs r3, #255 ; 0xff + for(; len; len--, ptr++) { + 800266c: 4288 cmp r0, r1 + 800266e: d103 bne.n 8002678 + rv &= *ptr; + } + + return (rv == 0xff); +} + 8002670: 3bff subs r3, #255 ; 0xff + 8002672: 4258 negs r0, r3 + 8002674: 4158 adcs r0, r3 + 8002676: 4770 bx lr + rv &= *ptr; + 8002678: f810 2b01 ldrb.w r2, [r0], #1 + 800267c: 4013 ands r3, r2 + for(; len; len--, ptr++) { + 800267e: e7f5 b.n 800266c + +08002680 : +// +// Return T if all bytes are 0xFF +// + bool +check_all_ones(const void *ptrV, int len) +{ + 8002680: b507 push {r0, r1, r2, lr} + bool rv = check_all_ones_raw(ptrV, len); + 8002682: f7ff fff1 bl 8002668 + 8002686: 9001 str r0, [sp, #4] + + rng_delay(); + 8002688: f000 f878 bl 800277c + + return rv; +} + 800268c: 9801 ldr r0, [sp, #4] + 800268e: b003 add sp, #12 + 8002690: f85d fb04 ldr.w pc, [sp], #4 + +08002694 : +// +// Return T if all bytes are 0x00 +// + bool +check_all_zeros(const void *ptrV, int len) +{ + 8002694: b510 push {r4, lr} + 8002696: 4401 add r1, r0 + uint8_t rv = 0x0; + 8002698: 2400 movs r4, #0 + const uint8_t *ptr = (const uint8_t *)ptrV; + + for(; len; len--, ptr++) { + 800269a: 4288 cmp r0, r1 + 800269c: d105 bne.n 80026aa + rv |= *ptr; + } + + rng_delay(); + 800269e: f000 f86d bl 800277c + return (rv == 0x00); +} + 80026a2: fab4 f084 clz r0, r4 + 80026a6: 0940 lsrs r0, r0, #5 + 80026a8: bd10 pop {r4, pc} + rv |= *ptr; + 80026aa: f810 3b01 ldrb.w r3, [r0], #1 + 80026ae: 431c orrs r4, r3 + for(; len; len--, ptr++) { + 80026b0: e7f3 b.n 800269a + +080026b2 : + const uint8_t *left = (const uint8_t *)aV; + const uint8_t *right = (const uint8_t *)bV; + uint8_t diff = 0; + int i; + + for (i = 0; i < len; i++) { + 80026b2: 2300 movs r3, #0 +{ + 80026b4: b570 push {r4, r5, r6, lr} + uint8_t diff = 0; + 80026b6: 461c mov r4, r3 + for (i = 0; i < len; i++) { + 80026b8: 4293 cmp r3, r2 + 80026ba: db05 blt.n 80026c8 + diff |= (left[i] ^ right[i]); + } + + rng_delay(); + 80026bc: f000 f85e bl 800277c + return (diff == 0); +} + 80026c0: fab4 f084 clz r0, r4 + 80026c4: 0940 lsrs r0, r0, #5 + 80026c6: bd70 pop {r4, r5, r6, pc} + diff |= (left[i] ^ right[i]); + 80026c8: 5cc5 ldrb r5, [r0, r3] + 80026ca: 5cce ldrb r6, [r1, r3] + 80026cc: 4075 eors r5, r6 + 80026ce: 432c orrs r4, r5 + for (i = 0; i < len; i++) { + 80026d0: 3301 adds r3, #1 + 80026d2: e7f1 b.n 80026b8 + +080026d4 : + } + + // Get the new number + uint32_t rv = RNG->DR; + + if(rv != last_rng_result && rv) { + 80026d4: 4b06 ldr r3, [pc, #24] ; (80026f0 ) + while(!(RNG->SR & RNG_FLAG_DRDY)) { + 80026d6: 4a07 ldr r2, [pc, #28] ; (80026f4 ) + if(rv != last_rng_result && rv) { + 80026d8: 6819 ldr r1, [r3, #0] + while(!(RNG->SR & RNG_FLAG_DRDY)) { + 80026da: 6850 ldr r0, [r2, #4] + 80026dc: 07c0 lsls r0, r0, #31 + 80026de: d5fc bpl.n 80026da + uint32_t rv = RNG->DR; + 80026e0: 6890 ldr r0, [r2, #8] + if(rv != last_rng_result && rv) { + 80026e2: 4281 cmp r1, r0 + 80026e4: d0f9 beq.n 80026da + 80026e6: 2800 cmp r0, #0 + 80026e8: d0f7 beq.n 80026da + last_rng_result = rv; + 80026ea: 6018 str r0, [r3, #0] + + // keep trying if not a new number + } + + // NOT-REACHED +} + 80026ec: 4770 bx lr + 80026ee: bf00 nop + 80026f0: 2009e1b8 .word 0x2009e1b8 + 80026f4: 50060800 .word 0x50060800 + +080026f8 : + if(RNG->CR & RNG_CR_RNGEN) { + 80026f8: 4b12 ldr r3, [pc, #72] ; (8002744 ) + 80026fa: 681a ldr r2, [r3, #0] + 80026fc: 0752 lsls r2, r2, #29 +{ + 80026fe: b513 push {r0, r1, r4, lr} + if(RNG->CR & RNG_CR_RNGEN) { + 8002700: d41d bmi.n 800273e + __HAL_RCC_RNG_CLK_ENABLE(); + 8002702: 4a11 ldr r2, [pc, #68] ; (8002748 ) + 8002704: 6cd1 ldr r1, [r2, #76] ; 0x4c + 8002706: f441 2180 orr.w r1, r1, #262144 ; 0x40000 + 800270a: 64d1 str r1, [r2, #76] ; 0x4c + 800270c: 6cd2 ldr r2, [r2, #76] ; 0x4c + 800270e: f402 2280 and.w r2, r2, #262144 ; 0x40000 + 8002712: 9201 str r2, [sp, #4] + 8002714: 9a01 ldr r2, [sp, #4] + RNG->CR |= RNG_CR_RNGEN; + 8002716: 681a ldr r2, [r3, #0] + 8002718: f042 0204 orr.w r2, r2, #4 + 800271c: 601a str r2, [r3, #0] + uint32_t chk = rng_sample(); + 800271e: f7ff ffd9 bl 80026d4 + 8002722: 4604 mov r4, r0 + uint32_t chk2 = rng_sample(); + 8002724: f7ff ffd6 bl 80026d4 + if(chk == 0 || chk == ~0 + 8002728: 1e63 subs r3, r4, #1 + 800272a: 3303 adds r3, #3 + 800272c: d804 bhi.n 8002738 + || chk2 == 0 || chk2 == ~0 + 800272e: 1e43 subs r3, r0, #1 + 8002730: 3303 adds r3, #3 + 8002732: d801 bhi.n 8002738 + || chk == chk2 + 8002734: 4284 cmp r4, r0 + 8002736: d102 bne.n 800273e + INCONSISTENT("bad rng"); + 8002738: 4804 ldr r0, [pc, #16] ; (800274c ) + 800273a: f7fe f985 bl 8000a48 +} + 800273e: b002 add sp, #8 + 8002740: bd10 pop {r4, pc} + 8002742: bf00 nop + 8002744: 50060800 .word 0x50060800 + 8002748: 40021000 .word 0x40021000 + 800274c: 0800d700 .word 0x0800d700 + +08002750 : + +// rng_buffer() +// + void +rng_buffer(uint8_t *result, int len) +{ + 8002750: b573 push {r0, r1, r4, r5, r6, lr} + 8002752: 460c mov r4, r1 + 8002754: 1845 adds r5, r0, r1 + while(len > 0) { + 8002756: 2c00 cmp r4, #0 + 8002758: eba5 0604 sub.w r6, r5, r4 + 800275c: dc01 bgt.n 8002762 + memcpy(result, &t, MIN(4, len)); + + len -= 4; + result += 4; + } +} + 800275e: b002 add sp, #8 + 8002760: bd70 pop {r4, r5, r6, pc} + uint32_t t = rng_sample(); + 8002762: f7ff ffb7 bl 80026d4 + memcpy(result, &t, MIN(4, len)); + 8002766: 2c04 cmp r4, #4 + 8002768: 4622 mov r2, r4 + uint32_t t = rng_sample(); + 800276a: 9001 str r0, [sp, #4] + memcpy(result, &t, MIN(4, len)); + 800276c: bfa8 it ge + 800276e: 2204 movge r2, #4 + 8002770: a901 add r1, sp, #4 + 8002772: 4630 mov r0, r6 + 8002774: f00a ff56 bl 800d624 + len -= 4; + 8002778: 3c04 subs r4, #4 + result += 4; + 800277a: e7ec b.n 8002756 + +0800277c : +// +// Call anytime. Delays for a random time period to fustrate glitchers. +// + void +rng_delay(void) +{ + 800277c: b508 push {r3, lr} + uint32_t r = rng_sample() % 8; + 800277e: f7ff ffa9 bl 80026d4 + uint32_t cnt = (1< + cnt--; + } +} + 8002792: bd08 pop {r3, pc} + +08002794 <_send_byte>: + static inline void +_send_byte(uint8_t ch) +{ + // reset timeout timer (Systick) + uint32_t ticks = 0; + SysTick->VAL = 0; + 8002794: f04f 22e0 mov.w r2, #3758153728 ; 0xe000e000 +{ + 8002798: b510 push {r4, lr} + SysTick->VAL = 0; + 800279a: 2300 movs r3, #0 + + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 800279c: 4c07 ldr r4, [pc, #28] ; (80027bc <_send_byte+0x28>) + SysTick->VAL = 0; + 800279e: 6193 str r3, [r2, #24] + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 80027a0: 230b movs r3, #11 + 80027a2: 69e1 ldr r1, [r4, #28] + 80027a4: 0609 lsls r1, r1, #24 + 80027a6: d404 bmi.n 80027b2 <_send_byte+0x1e> + // busy-wait until able to send (no fifo?) + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 80027a8: 6911 ldr r1, [r2, #16] + 80027aa: 03c9 lsls r1, r1, #15 + 80027ac: d5f9 bpl.n 80027a2 <_send_byte+0xe> + // failsafe timeout + ticks += 1; + if(ticks > 10) break; + 80027ae: 3b01 subs r3, #1 + 80027b0: d1f7 bne.n 80027a2 <_send_byte+0xe> + } + } + MY_UART->TDR = ch; + 80027b2: 4b02 ldr r3, [pc, #8] ; (80027bc <_send_byte+0x28>) + 80027b4: b280 uxth r0, r0 + 80027b6: 8518 strh r0, [r3, #40] ; 0x28 +} + 80027b8: bd10 pop {r4, pc} + 80027ba: bf00 nop + 80027bc: 40004c00 .word 0x40004c00 + +080027c0 <_send_bits>: + +// _send_bits() +// + static void +_send_bits(uint8_t tx) +{ + 80027c0: b570 push {r4, r5, r6, lr} + 80027c2: 4606 mov r6, r0 + 80027c4: 2508 movs r5, #8 + // serialize and send one byte + uint8_t mask = 0x1; + 80027c6: 2401 movs r4, #1 + + for(int i=0; i<8; i++, mask <<= 1) { + uint8_t h = (tx & mask) ? BIT1 : BIT0; + 80027c8: 4226 tst r6, r4 + + _send_byte(h); + 80027ca: bf14 ite ne + 80027cc: 207f movne r0, #127 ; 0x7f + 80027ce: 207d moveq r0, #125 ; 0x7d + 80027d0: f7ff ffe0 bl 8002794 <_send_byte> + for(int i=0; i<8; i++, mask <<= 1) { + 80027d4: 0064 lsls r4, r4, #1 + 80027d6: 3d01 subs r5, #1 + 80027d8: b2e4 uxtb r4, r4 + 80027da: d1f5 bne.n 80027c8 <_send_bits+0x8> + } +} + 80027dc: bd70 pop {r4, r5, r6, pc} + +080027de <_send_serialized>: + +// _send_serialized() +// + static void +_send_serialized(const uint8_t *buf, int len) +{ + 80027de: b538 push {r3, r4, r5, lr} + 80027e0: 4604 mov r4, r0 + 80027e2: 1845 adds r5, r0, r1 + for(int i=0; i + for(int i=0; i + } +} + 80027f0: bd38 pop {r3, r4, r5, pc} + ... + +080027f4 <_flush_rx>: +// + static inline void +_flush_rx(void) +{ + // reset timeout timer (Systick) + SysTick->VAL = 0; + 80027f4: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 80027f8: 2200 movs r2, #0 + + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 80027fa: 490b ldr r1, [pc, #44] ; (8002828 <_flush_rx+0x34>) + SysTick->VAL = 0; + 80027fc: 619a str r2, [r3, #24] + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 80027fe: 69ca ldr r2, [r1, #28] + 8002800: 0652 lsls r2, r2, #25 + 8002802: d402 bmi.n 800280a <_flush_rx+0x16> + // wait for last bit(byte) to be serialized and sent + + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8002804: 691a ldr r2, [r3, #16] + 8002806: 03d0 lsls r0, r2, #15 + 8002808: d5f9 bpl.n 80027fe <_flush_rx+0xa> + break; + } + } + + // We actually need this delay here! + __NOP(); + 800280a: bf00 nop + __NOP(); + 800280c: bf00 nop + __NOP(); + 800280e: bf00 nop + __NOP(); + 8002810: bf00 nop + __NOP(); + 8002812: bf00 nop + __NOP(); + 8002814: bf00 nop + __NOP(); + 8002816: bf00 nop + __NOP(); + 8002818: bf00 nop + + // clear junk in rx buffer + MY_UART->RQR = USART_RQR_RXFRQ; + 800281a: 4b03 ldr r3, [pc, #12] ; (8002828 <_flush_rx+0x34>) + 800281c: 2208 movs r2, #8 + 800281e: 831a strh r2, [r3, #24] + + // clear overrun error + // clear rx timeout flag + // clear framing error + MY_UART->ICR = USART_ICR_ORECF | USART_ICR_RTOCF | USART_ICR_FECF; + 8002820: f640 020a movw r2, #2058 ; 0x80a + 8002824: 621a str r2, [r3, #32] +} + 8002826: 4770 bx lr + 8002828: 40004c00 .word 0x40004c00 + +0800282c : + uint16_t crc_register = 0; + uint16_t polynom = 0x8005; + uint8_t shift_register; + uint8_t data_bit, crc_bit; + + crc_register = (((uint16_t) crc[0]) & 0x00FF) | (((uint16_t) crc[1]) << 8); + 800282c: 8813 ldrh r3, [r2, #0] +{ + 800282e: b5f0 push {r4, r5, r6, r7, lr} + 8002830: 4408 add r0, r1 + + // Shift CRC to the left by 1. + crc_register <<= 1; + + if ((data_bit ^ crc_bit) != 0) + crc_register ^= polynom; + 8002832: f248 0605 movw r6, #32773 ; 0x8005 + for (counter = 0; counter < length; counter++) { + 8002836: 4281 cmp r1, r0 + 8002838: d103 bne.n 8002842 + } + } + + crc[0] = (uint8_t) (crc_register & 0x00FF); + 800283a: 7013 strb r3, [r2, #0] + crc[1] = (uint8_t) (crc_register >> 8); + 800283c: 0a1b lsrs r3, r3, #8 + 800283e: 7053 strb r3, [r2, #1] +} + 8002840: bdf0 pop {r4, r5, r6, r7, pc} + data_bit = (data[counter] & shift_register) ? 1 : 0; + 8002842: f811 7b01 ldrb.w r7, [r1], #1 + 8002846: 2508 movs r5, #8 + for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) { + 8002848: 2401 movs r4, #1 + data_bit = (data[counter] & shift_register) ? 1 : 0; + 800284a: 4227 tst r7, r4 + crc_bit = crc_register >> 15; + 800284c: ea4f 3cd3 mov.w ip, r3, lsr #15 + if ((data_bit ^ crc_bit) != 0) + 8002850: bf18 it ne + 8002852: f04f 0e01 movne.w lr, #1 + crc_register <<= 1; + 8002856: ea4f 0343 mov.w r3, r3, lsl #1 + if ((data_bit ^ crc_bit) != 0) + 800285a: bf08 it eq + 800285c: f04f 0e00 moveq.w lr, #0 + 8002860: 45e6 cmp lr, ip + crc_register <<= 1; + 8002862: b29b uxth r3, r3 + crc_register ^= polynom; + 8002864: bf18 it ne + 8002866: 4073 eorne r3, r6 + for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) { + 8002868: 0064 lsls r4, r4, #1 + 800286a: 3d01 subs r5, #1 + 800286c: b2e4 uxtb r4, r4 + 800286e: d1ec bne.n 800284a + 8002870: e7e1 b.n 8002836 + +08002872 : + +// ae_check_crc() +// + static bool +ae_check_crc(const uint8_t *data, uint8_t length) +{ + 8002872: b573 push {r0, r1, r4, r5, r6, lr} + uint8_t obs[2] = { 0, 0 }; + + if(data[0] != length) { + 8002874: 7806 ldrb r6, [r0, #0] + uint8_t obs[2] = { 0, 0 }; + 8002876: 2400 movs r4, #0 + if(data[0] != length) { + 8002878: 428e cmp r6, r1 +{ + 800287a: 4605 mov r5, r0 + uint8_t obs[2] = { 0, 0 }; + 800287c: f8ad 4004 strh.w r4, [sp, #4] + if(data[0] != length) { + 8002880: d113 bne.n 80028aa + // length is wrong + STATS(crc_len_error++); + return false; + } + + crc16_chain(length-2, data, obs); + 8002882: 4629 mov r1, r5 + 8002884: 1eb0 subs r0, r6, #2 + + return (obs[0] == data[length-2] && obs[1] == data[length-1]); + 8002886: 4435 add r5, r6 + crc16_chain(length-2, data, obs); + 8002888: aa01 add r2, sp, #4 + 800288a: b2c0 uxtb r0, r0 + 800288c: f7ff ffce bl 800282c + return (obs[0] == data[length-2] && obs[1] == data[length-1]); + 8002890: f89d 2004 ldrb.w r2, [sp, #4] + 8002894: f815 3c02 ldrb.w r3, [r5, #-2] + 8002898: 429a cmp r2, r3 + 800289a: d106 bne.n 80028aa + 800289c: f815 4c01 ldrb.w r4, [r5, #-1] + 80028a0: f89d 0005 ldrb.w r0, [sp, #5] + 80028a4: 1a23 subs r3, r4, r0 + 80028a6: 425c negs r4, r3 + 80028a8: 415c adcs r4, r3 + return false; + 80028aa: 4620 mov r0, r4 +} + 80028ac: b002 add sp, #8 + 80028ae: bd70 pop {r4, r5, r6, pc} + +080028b0 : +{ + 80028b0: b508 push {r3, lr} + _send_byte(0x00); + 80028b2: 2000 movs r0, #0 + 80028b4: f7ff ff6e bl 8002794 <_send_byte> + delay_ms(3); // measured: ~2.9ms + 80028b8: 2003 movs r0, #3 + 80028ba: f001 f81d bl 80038f8 +} + 80028be: e8bd 4008 ldmia.w sp!, {r3, lr} + _flush_rx(); + 80028c2: f7ff bf97 b.w 80027f4 <_flush_rx> + +080028c6 : +{ + 80028c6: b508 push {r3, lr} + ae_wake(); + 80028c8: f7ff fff2 bl 80028b0 +} + 80028cc: e8bd 4008 ldmia.w sp!, {r3, lr} + _send_bits(IOFLAG_IDLE); + 80028d0: 20bb movs r0, #187 ; 0xbb + 80028d2: f7ff bf75 b.w 80027c0 <_send_bits> + ... + +080028d8 : +{ + 80028d8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + int max_expect = (max_len+1) * 8; + 80028dc: 3101 adds r1, #1 + uint8_t raw[max_expect]; + 80028de: 466b mov r3, sp + 80028e0: eba3 03c1 sub.w r3, r3, r1, lsl #3 +{ + 80028e4: af00 add r7, sp, #0 + 80028e6: 4606 mov r6, r0 + uint8_t raw[max_expect]; + 80028e8: 469d mov sp, r3 + _send_bits(IOFLAG_TX); + 80028ea: 2088 movs r0, #136 ; 0x88 + int max_expect = (max_len+1) * 8; + 80028ec: 00cd lsls r5, r1, #3 + _send_bits(IOFLAG_TX); + 80028ee: f7ff ff67 bl 80027c0 <_send_bits> + _flush_rx(); + 80028f2: f7ff ff7f bl 80027f4 <_flush_rx> + int actual = 0; + 80028f6: 2200 movs r2, #0 + while(!(MY_UART->ISR & UART_FLAG_RXNE) && !(MY_UART->ISR & UART_FLAG_RTOF)) { + 80028f8: 4829 ldr r0, [pc, #164] ; (80029a0 ) + uint8_t raw[max_expect]; + 80028fa: 466c mov r4, sp + for(uint8_t *p = raw; ; actual++) { + 80028fc: 4669 mov r1, sp + SysTick->VAL = 0; + 80028fe: f04f 2ce0 mov.w ip, #3758153728 ; 0xe000e000 + 8002902: 4696 mov lr, r2 + 8002904: f8cc e018 str.w lr, [ip, #24] + while(!(MY_UART->ISR & UART_FLAG_RXNE) && !(MY_UART->ISR & UART_FLAG_RTOF)) { + 8002908: 2305 movs r3, #5 + 800290a: f8d0 801c ldr.w r8, [r0, #28] + 800290e: f018 0f20 tst.w r8, #32 + 8002912: d104 bne.n 800291e + 8002914: f8d0 801c ldr.w r8, [r0, #28] + 8002918: f418 6f00 tst.w r8, #2048 ; 0x800 + 800291c: d008 beq.n 8002930 + if(MY_UART->ISR & UART_FLAG_RXNE) { + 800291e: 69c3 ldr r3, [r0, #28] + 8002920: 069b lsls r3, r3, #26 + 8002922: d52e bpl.n 8002982 + return MY_UART->RDR & 0x7f; + 8002924: 8c83 ldrh r3, [r0, #36] ; 0x24 + if(actual < max_expect) { + 8002926: 42aa cmp r2, r5 + return MY_UART->RDR & 0x7f; + 8002928: b29b uxth r3, r3 + if(actual < max_expect) { + 800292a: db34 blt.n 8002996 + for(uint8_t *p = raw; ; actual++) { + 800292c: 3201 adds r2, #1 + 800292e: e7e9 b.n 8002904 + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8002930: f8dc 8010 ldr.w r8, [ip, #16] + 8002934: f418 3f80 tst.w r8, #65536 ; 0x10000 + 8002938: d0e7 beq.n 800290a + if(ticks >= 5) { + 800293a: 3b01 subs r3, #1 + 800293c: d1e5 bne.n 800290a + actual &= ~7; + 800293e: f022 0107 bic.w r1, r2, #7 + while(from_len > 0) { + 8002942: 3d08 subs r5, #8 + 8002944: 4425 add r5, r4 + 8002946: 4623 mov r3, r4 + 8002948: 4421 add r1, r4 + 800294a: 1ac8 subs r0, r1, r3 + 800294c: 2800 cmp r0, #0 + 800294e: dd14 ble.n 800297a + 8002950: f103 3cff add.w ip, r3, #4294967295 ; 0xffffffff + uint8_t rv = 0, mask = 0x1; + 8002954: 2001 movs r0, #1 + 8002956: 2400 movs r4, #0 + for(int i=0; i<8; i++, mask <<= 1) { + 8002958: f103 0e07 add.w lr, r3, #7 + if(from[i] == BIT1) { + 800295c: f81c 8f01 ldrb.w r8, [ip, #1]! + 8002960: f1b8 0f7f cmp.w r8, #127 ; 0x7f + rv |= mask; + 8002964: bf08 it eq + 8002966: 4304 orreq r4, r0 + for(int i=0; i<8; i++, mask <<= 1) { + 8002968: 0040 lsls r0, r0, #1 + 800296a: 45f4 cmp ip, lr + 800296c: b2c0 uxtb r0, r0 + 800296e: d1f5 bne.n 800295c + from += 8; + 8002970: 3308 adds r3, #8 + if(max_into <= 0) break; + 8002972: 42ab cmp r3, r5 + *(into++) = rv; + 8002974: f806 4b01 strb.w r4, [r6], #1 + if(max_into <= 0) break; + 8002978: d1e7 bne.n 800294a + return actual / 8; + 800297a: 10d0 asrs r0, r2, #3 +} + 800297c: 46bd mov sp, r7 + 800297e: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if(MY_UART->ISR & UART_FLAG_RTOF) { + 8002982: 69c3 ldr r3, [r0, #28] + 8002984: 051b lsls r3, r3, #20 + 8002986: d503 bpl.n 8002990 + MY_UART->ICR = USART_ICR_RTOCF; + 8002988: f44f 6300 mov.w r3, #2048 ; 0x800 + 800298c: 6203 str r3, [r0, #32] + if(ch < 0) { + 800298e: e7d6 b.n 800293e + INCONSISTENT("rxf"); + 8002990: 4804 ldr r0, [pc, #16] ; (80029a4 ) + 8002992: f7fe f859 bl 8000a48 + *(p++) = ch; + 8002996: f003 037f and.w r3, r3, #127 ; 0x7f + 800299a: f801 3b01 strb.w r3, [r1], #1 + 800299e: e7c5 b.n 800292c + 80029a0: 40004c00 .word 0x40004c00 + 80029a4: 0800d700 .word 0x0800d700 + +080029a8 : + if(ae_chip_is_setup == AE_CHIP_IS_SETUP) { + 80029a8: 4b04 ldr r3, [pc, #16] ; (80029bc ) + 80029aa: 681a ldr r2, [r3, #0] + 80029ac: 4b04 ldr r3, [pc, #16] ; (80029c0 ) + 80029ae: 429a cmp r2, r3 + 80029b0: d102 bne.n 80029b8 + _send_bits(IOFLAG_SLEEP); + 80029b2: 20cc movs r0, #204 ; 0xcc + 80029b4: f7ff bf04 b.w 80027c0 <_send_bits> +} + 80029b8: 4770 bx lr + 80029ba: bf00 nop + 80029bc: 2009e1bc .word 0x2009e1bc + 80029c0: 35d25d63 .word 0x35d25d63 + +080029c4 : + __HAL_RCC_UART4_CLK_ENABLE(); + 80029c4: 4b13 ldr r3, [pc, #76] ; (8002a14 ) + 80029c6: 6d9a ldr r2, [r3, #88] ; 0x58 + 80029c8: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 80029cc: 659a str r2, [r3, #88] ; 0x58 + 80029ce: 6d9b ldr r3, [r3, #88] ; 0x58 +{ + 80029d0: b082 sub sp, #8 + __HAL_RCC_UART4_CLK_ENABLE(); + 80029d2: f403 2300 and.w r3, r3, #524288 ; 0x80000 + 80029d6: 9301 str r3, [sp, #4] + 80029d8: 9b01 ldr r3, [sp, #4] + MY_UART->CR1 = 0; + 80029da: 4b0f ldr r3, [pc, #60] ; (8002a18 ) + 80029dc: 2200 movs r2, #0 + 80029de: 601a str r2, [r3, #0] + MY_UART->CR1 = 0x1000002d & ~(0 + 80029e0: 4a0e ldr r2, [pc, #56] ; (8002a1c ) + 80029e2: 601a str r2, [r3, #0] + MY_UART->RTOR = 24; // timeout in bit periods: 3 chars or so + 80029e4: 2218 movs r2, #24 + 80029e6: 615a str r2, [r3, #20] + MY_UART->CR2 = USART_CR2_RTOEN; // rx timeout enable + 80029e8: f44f 0200 mov.w r2, #8388608 ; 0x800000 + 80029ec: 605a str r2, [r3, #4] + MY_UART->CR3 = USART_CR3_HDSEL | USART_CR3_ONEBIT; + 80029ee: f640 0208 movw r2, #2056 ; 0x808 + 80029f2: 609a str r2, [r3, #8] + MY_UART->BRR = 521; // 230400 bps @ 120 Mhz SYSCLK + 80029f4: f240 2209 movw r2, #521 ; 0x209 + 80029f8: 60da str r2, [r3, #12] + MY_UART->ICR = USART_ICR_RTOCF; + 80029fa: f44f 6200 mov.w r2, #2048 ; 0x800 + 80029fe: 621a str r2, [r3, #32] + MY_UART->CR1 |= USART_CR1_UE; + 8002a00: 681a ldr r2, [r3, #0] + 8002a02: f042 0201 orr.w r2, r2, #1 + 8002a06: 601a str r2, [r3, #0] + ae_chip_is_setup = AE_CHIP_IS_SETUP; + 8002a08: 4b05 ldr r3, [pc, #20] ; (8002a20 ) + 8002a0a: 4a06 ldr r2, [pc, #24] ; (8002a24 ) + 8002a0c: 601a str r2, [r3, #0] +} + 8002a0e: b002 add sp, #8 + 8002a10: 4770 bx lr + 8002a12: bf00 nop + 8002a14: 40021000 .word 0x40021000 + 8002a18: 40004c00 .word 0x40004c00 + 8002a1c: 1000002c .word 0x1000002c + 8002a20: 2009e1bc .word 0x2009e1bc + 8002a24: 35d25d63 .word 0x35d25d63 + +08002a28 : + ae_send_idle(); + 8002a28: f7ff bf4d b.w 80028c6 + +08002a2c : +// Read a one-byte status/error code response from chip. It's wrapped as 4 bytes: +// (len=4) (value) (crc16) (crc16) +// + int +ae_read1(void) +{ + 8002a2c: b513 push {r0, r1, r4, lr} + 8002a2e: 2408 movs r4, #8 + uint8_t msg[4]; + + for(int retry=7; retry >= 0; retry--) { + // tell it we want to read a response, read it, and deserialize + int rv = ae_read_response(msg, 4); + 8002a30: 2104 movs r1, #4 + 8002a32: eb0d 0001 add.w r0, sp, r1 + 8002a36: f7ff ff4f bl 80028d8 + + if(rv == 0) { + 8002a3a: 4601 mov r1, r0 + 8002a3c: b938 cbnz r0, 8002a4e + // nothing heard, it's probably still processing + ERR("not rdy"); + STATS(not_ready++); + + delay_ms(5); + 8002a3e: 2005 movs r0, #5 + 8002a40: f000 ff5a bl 80038f8 + for(int retry=7; retry >= 0; retry--) { + 8002a44: 3c01 subs r4, #1 + 8002a46: d1f3 bne.n 8002a30 + try_again: + STATS(l1_retry++); + } + + // fail. + return -1; + 8002a48: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8002a4c: e008 b.n 8002a60 + if(rv != 4) { + 8002a4e: 2804 cmp r0, #4 + 8002a50: d1f8 bne.n 8002a44 + if(!ae_check_crc(msg, 4)) { + 8002a52: a801 add r0, sp, #4 + 8002a54: f7ff ff0d bl 8002872 + 8002a58: 2800 cmp r0, #0 + 8002a5a: d0f3 beq.n 8002a44 + return msg[1]; + 8002a5c: f89d 0005 ldrb.w r0, [sp, #5] +} + 8002a60: b002 add sp, #8 + 8002a62: bd10 pop {r4, pc} + +08002a64 : +// Read and check CRC over N bytes, wrapped in 3-bytes of framing overhead. +// Return -1 for timeout, zero for normal, and one-byte error code otherwise. +// + int +ae_read_n(uint8_t len, uint8_t *body) +{ + 8002a64: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + uint8_t tmp[1+len+2]; + 8002a68: f100 030a add.w r3, r0, #10 + 8002a6c: f403 73fc and.w r3, r3, #504 ; 0x1f8 +{ + 8002a70: af00 add r7, sp, #0 + uint8_t tmp[1+len+2]; + 8002a72: ebad 0d03 sub.w sp, sp, r3 +{ + 8002a76: 460d mov r5, r1 + uint8_t tmp[1+len+2]; + 8002a78: 1cc6 adds r6, r0, #3 + 8002a7a: 46e8 mov r8, sp + 8002a7c: f04f 0908 mov.w r9, #8 + + for(int retry=7; retry >= 0; retry--) { + + int actual = ae_read_response(tmp, len+3); + 8002a80: 4631 mov r1, r6 + 8002a82: 4640 mov r0, r8 + 8002a84: f7ff ff28 bl 80028d8 + if(actual < 4) { + 8002a88: 2803 cmp r0, #3 + int actual = ae_read_response(tmp, len+3); + 8002a8a: 4604 mov r4, r0 + if(actual < 4) { + 8002a8c: dc0b bgt.n 8002aa6 + + if(actual == 0) { + 8002a8e: b910 cbnz r0, 8002a96 + // nothing heard, it's probably still processing + delay_ms(5); + 8002a90: 2005 movs r0, #5 + 8002a92: f000 ff31 bl 80038f8 + + return 0; + + try_again: + STATS(ln_retry++); + ae_wake(); + 8002a96: f7ff ff0b bl 80028b0 + for(int retry=7; retry >= 0; retry--) { + 8002a9a: f1b9 0901 subs.w r9, r9, #1 + 8002a9e: d1ef bne.n 8002a80 + } + + return -1; + 8002aa0: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8002aa4: e007 b.n 8002ab6 + uint8_t resp_len = tmp[0]; + 8002aa6: f898 3000 ldrb.w r3, [r8] + if(resp_len != (len + 3)) { + 8002aaa: 42b3 cmp r3, r6 + 8002aac: d006 beq.n 8002abc + if(resp_len == 4) { + 8002aae: 2b04 cmp r3, #4 + 8002ab0: d1f1 bne.n 8002a96 + return tmp[1]; + 8002ab2: f898 0001 ldrb.w r0, [r8, #1] +} + 8002ab6: 46bd mov sp, r7 + 8002ab8: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + if(!ae_check_crc(tmp, actual)) { + 8002abc: b2c1 uxtb r1, r0 + 8002abe: 4640 mov r0, r8 + 8002ac0: f7ff fed7 bl 8002872 + 8002ac4: 2800 cmp r0, #0 + 8002ac6: d0e6 beq.n 8002a96 + memcpy(body, tmp+1, actual-3); + 8002ac8: 1ee2 subs r2, r4, #3 + 8002aca: f108 0101 add.w r1, r8, #1 + 8002ace: 4628 mov r0, r5 + 8002ad0: f00a fda8 bl 800d624 + return 0; + 8002ad4: 2000 movs r0, #0 + 8002ad6: e7ee b.n 8002ab6 + +08002ad8 : + +// ae_send_n() +// + void +ae_send_n(aeopcode_t opcode, uint8_t p1, uint16_t p2, const uint8_t *data, uint8_t data_len) +{ + 8002ad8: b530 push {r4, r5, lr} + 8002ada: b085 sub sp, #20 + 8002adc: 461d mov r5, r3 + 8002ade: f89d 4020 ldrb.w r4, [sp, #32] + uint8_t framed_len; + uint8_t op; + uint8_t p1; + uint8_t p2_lsb; + uint8_t p2_msb; + } known = { + 8002ae2: f88d 200c strb.w r2, [sp, #12] + 8002ae6: 2377 movs r3, #119 ; 0x77 + 8002ae8: 0a12 lsrs r2, r2, #8 + 8002aea: f88d 3008 strb.w r3, [sp, #8] + .ioflag = IOFLAG_CMD, + .framed_len = (data_len + 7), // 7 = (1 len) + (4 bytes of msg) + (2 crc) + 8002aee: 1de3 adds r3, r4, #7 + } known = { + 8002af0: f88d 3009 strb.w r3, [sp, #9] + 8002af4: f88d 200d strb.w r2, [sp, #13] + 8002af8: f88d 000a strb.w r0, [sp, #10] + 8002afc: f88d 100b strb.w r1, [sp, #11] + STATS(last_op = opcode); + STATS(last_p1 = p1); + STATS(last_p2 = p2); + + // important to wake chip at this point. + ae_wake(); + 8002b00: f7ff fed6 bl 80028b0 + + _send_serialized((const uint8_t *)&known, sizeof(known)); + 8002b04: 2106 movs r1, #6 + 8002b06: a802 add r0, sp, #8 + 8002b08: f7ff fe69 bl 80027de <_send_serialized> + + // CRC will start from frame_len onwards + uint8_t crc[2] = {0, 0}; + 8002b0c: 2300 movs r3, #0 + crc16_chain(sizeof(known)-1, &known.framed_len, crc); + 8002b0e: aa01 add r2, sp, #4 + 8002b10: f10d 0109 add.w r1, sp, #9 + 8002b14: 2005 movs r0, #5 + uint8_t crc[2] = {0, 0}; + 8002b16: f8ad 3004 strh.w r3, [sp, #4] + crc16_chain(sizeof(known)-1, &known.framed_len, crc); + 8002b1a: f7ff fe87 bl 800282c + + // insert a variable-length body area (sometimes) + if(data_len) { + 8002b1e: b144 cbz r4, 8002b32 + _send_serialized(data, data_len); + 8002b20: 4621 mov r1, r4 + 8002b22: 4628 mov r0, r5 + 8002b24: f7ff fe5b bl 80027de <_send_serialized> + + crc16_chain(data_len, data, crc); + 8002b28: aa01 add r2, sp, #4 + 8002b2a: 4629 mov r1, r5 + 8002b2c: 4620 mov r0, r4 + 8002b2e: f7ff fe7d bl 800282c + } + + // send final CRC bytes + _send_serialized(crc, 2); + 8002b32: 2102 movs r1, #2 + 8002b34: a801 add r0, sp, #4 + 8002b36: f7ff fe52 bl 80027de <_send_serialized> +} + 8002b3a: b005 add sp, #20 + 8002b3c: bd30 pop {r4, r5, pc} + +08002b3e : +{ + 8002b3e: b507 push {r0, r1, r2, lr} + ae_send_n(opcode, p1, p2, NULL, 0); + 8002b40: 2300 movs r3, #0 + 8002b42: 9300 str r3, [sp, #0] + 8002b44: f7ff ffc8 bl 8002ad8 +} + 8002b48: b003 add sp, #12 + 8002b4a: f85d fb04 ldr.w pc, [sp], #4 + +08002b4e : +// +// Do Info(p1=2) command, and return result. +// + uint16_t +ae_get_info(void) +{ + 8002b4e: b507 push {r0, r1, r2, lr} + // not doing error checking here + ae_send(OP_Info, 0x2, 0); + 8002b50: 2200 movs r2, #0 + 8002b52: 2102 movs r1, #2 + 8002b54: 2030 movs r0, #48 ; 0x30 + 8002b56: f7ff fff2 bl 8002b3e + + // note: always returns 4 bytes, but most are garbage and unused. + uint8_t tmp[4]; + ae_read_n(4, tmp); + 8002b5a: a901 add r1, sp, #4 + 8002b5c: 2004 movs r0, #4 + 8002b5e: f7ff ff81 bl 8002a64 + + return (tmp[0] << 8) | tmp[1]; + 8002b62: f8bd 0004 ldrh.w r0, [sp, #4] + 8002b66: ba40 rev16 r0, r0 +} + 8002b68: b280 uxth r0, r0 + 8002b6a: b003 add sp, #12 + 8002b6c: f85d fb04 ldr.w pc, [sp], #4 + +08002b70 : +// Load Tempkey with a specific value. Resulting Tempkey cannot be +// used with many commands/keys, but is needed for signing. +// + int +ae_load_nonce(const uint8_t nonce[32]) +{ + 8002b70: b507 push {r0, r1, r2, lr} + // p1=3 + ae_send_n(OP_Nonce, 3, 0, nonce, 32); // 608a ok + 8002b72: 2220 movs r2, #32 +{ + 8002b74: 4603 mov r3, r0 + ae_send_n(OP_Nonce, 3, 0, nonce, 32); // 608a ok + 8002b76: 9200 str r2, [sp, #0] + 8002b78: 2103 movs r1, #3 + 8002b7a: 2200 movs r2, #0 + 8002b7c: 2016 movs r0, #22 + 8002b7e: f7ff ffab bl 8002ad8 + + return ae_read1(); +} + 8002b82: b003 add sp, #12 + 8002b84: f85d eb04 ldr.w lr, [sp], #4 + return ae_read1(); + 8002b88: f7ff bf50 b.w 8002a2c + +08002b8c : +// Load 32bytes of message digest with a specific value. +// Needed for signing. +// + int +ae_load_msgdigest(const uint8_t md[32]) +{ + 8002b8c: b507 push {r0, r1, r2, lr} + ae_send_n(OP_Nonce, (1<<6) | 3, 0, md, 32); + 8002b8e: 2220 movs r2, #32 +{ + 8002b90: 4603 mov r3, r0 + ae_send_n(OP_Nonce, (1<<6) | 3, 0, md, 32); + 8002b92: 9200 str r2, [sp, #0] + 8002b94: 2143 movs r1, #67 ; 0x43 + 8002b96: 2200 movs r2, #0 + 8002b98: 2016 movs r0, #22 + 8002b9a: f7ff ff9d bl 8002ad8 + + return ae_read1(); +} + 8002b9e: b003 add sp, #12 + 8002ba0: f85d eb04 ldr.w lr, [sp], #4 + return ae_read1(); + 8002ba4: f7ff bf42 b.w 8002a2c + +08002ba8 : +// Load Tempkey with a nonce value that we both know, but +// is random and we both know is random! Tricky! +// + int +ae_pick_nonce(const uint8_t num_in[20], uint8_t tempkey[32]) +{ + 8002ba8: b5f0 push {r4, r5, r6, r7, lr} + 8002baa: b09f sub sp, #124 ; 0x7c + // We provide some 20 bytes of randomness to chip + // The chip must provide 32-bytes of random-ness, + // so no choice in args to OP.Nonce here (due to ReqRandom). + ae_send_n(OP_Nonce, 0, 0, num_in, 20); + 8002bac: 2200 movs r2, #0 + 8002bae: 2714 movs r7, #20 + 8002bb0: 4603 mov r3, r0 +{ + 8002bb2: 4605 mov r5, r0 + 8002bb4: 460e mov r6, r1 + ae_send_n(OP_Nonce, 0, 0, num_in, 20); + 8002bb6: 2016 movs r0, #22 + 8002bb8: 4611 mov r1, r2 + 8002bba: 9700 str r7, [sp, #0] + 8002bbc: f7ff ff8c bl 8002ad8 + + // Nonce command returns the RNG result, but not contents of TempKey + uint8_t randout[32]; + int rv = ae_read_n(32, randout); + 8002bc0: a903 add r1, sp, #12 + 8002bc2: 2020 movs r0, #32 + 8002bc4: f7ff ff4e bl 8002a64 + RET_IF_BAD(rv); + 8002bc8: 4604 mov r4, r0 + 8002bca: b9e0 cbnz r0, 8002c06 + // + // return sha256(rndout + num_in + b'\x16\0\0').digest() + // + SHA256_CTX ctx; + + sha256_init(&ctx); + 8002bcc: a80b add r0, sp, #44 ; 0x2c + 8002bce: f002 fc5d bl 800548c + sha256_update(&ctx, randout, 32); + 8002bd2: 2220 movs r2, #32 + 8002bd4: a903 add r1, sp, #12 + 8002bd6: a80b add r0, sp, #44 ; 0x2c + 8002bd8: f002 fc66 bl 80054a8 + sha256_update(&ctx, num_in, 20); + 8002bdc: 463a mov r2, r7 + 8002bde: 4629 mov r1, r5 + 8002be0: a80b add r0, sp, #44 ; 0x2c + 8002be2: f002 fc61 bl 80054a8 + const uint8_t fixed[3] = { 0x16, 0, 0 }; + 8002be6: 4b09 ldr r3, [pc, #36] ; (8002c0c ) + 8002be8: 881a ldrh r2, [r3, #0] + 8002bea: f8ad 2008 strh.w r2, [sp, #8] + 8002bee: 789b ldrb r3, [r3, #2] + 8002bf0: f88d 300a strb.w r3, [sp, #10] + sha256_update(&ctx, fixed, 3); + 8002bf4: a902 add r1, sp, #8 + 8002bf6: a80b add r0, sp, #44 ; 0x2c + 8002bf8: 2203 movs r2, #3 + 8002bfa: f002 fc55 bl 80054a8 + + sha256_final(&ctx, tempkey); + 8002bfe: 4631 mov r1, r6 + 8002c00: a80b add r0, sp, #44 ; 0x2c + 8002c02: f002 fc97 bl 8005534 + + return 0; +} + 8002c06: 4620 mov r0, r4 + 8002c08: b01f add sp, #124 ; 0x7c + 8002c0a: bdf0 pop {r4, r5, r6, r7, pc} + 8002c0c: 0800e674 .word 0x0800e674 + +08002c10 : +// Check that TempKey is holding what we think it does. Uses the MAC +// command over contents of Tempkey and our shared secret. +// + bool +ae_is_correct_tempkey(const uint8_t expected_tempkey[32]) +{ + 8002c10: b570 push {r4, r5, r6, lr} + const uint8_t mode = (1<<6) // include full serial number + | (0<<2) // TempKey.SourceFlag == 0 == 'rand' + | (0<<1) // first 32 bytes are the shared secret + | (1<<0); // second 32 bytes are tempkey + + ae_send(OP_MAC, mode, KEYNUM_pairing); + 8002c12: 2141 movs r1, #65 ; 0x41 +{ + 8002c14: b0a8 sub sp, #160 ; 0xa0 + 8002c16: 4604 mov r4, r0 + ae_send(OP_MAC, mode, KEYNUM_pairing); + 8002c18: 2201 movs r2, #1 + 8002c1a: 2008 movs r0, #8 + 8002c1c: f7ff ff8f bl 8002b3e + + // read chip's answer + uint8_t resp[32]; + int rv = ae_read_n(32, resp); + 8002c20: a905 add r1, sp, #20 + 8002c22: 2020 movs r0, #32 + 8002c24: f7ff ff1e bl 8002a64 + if(rv) return false; + 8002c28: 2800 cmp r0, #0 + 8002c2a: d135 bne.n 8002c98 + ae_send_idle(); + 8002c2c: f7ff fe4b bl 80028c6 + ae_keep_alive(); + + // Duplicate the hash process, and then compare. + SHA256_CTX ctx; + + sha256_init(&ctx); + 8002c30: a815 add r0, sp, #84 ; 0x54 + 8002c32: f002 fc2b bl 800548c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8002c36: 4919 ldr r1, [pc, #100] ; (8002c9c ) + 8002c38: 2220 movs r2, #32 + 8002c3a: a815 add r0, sp, #84 ; 0x54 + 8002c3c: f002 fc34 bl 80054a8 + sha256_update(&ctx, expected_tempkey, 32); + 8002c40: 2220 movs r2, #32 + 8002c42: 4621 mov r1, r4 + 8002c44: a815 add r0, sp, #84 ; 0x54 + 8002c46: f002 fc2f bl 80054a8 + + const uint8_t fixed[16] = { OP_MAC, mode, KEYNUM_pairing, 0x0, + 8002c4a: 4b15 ldr r3, [pc, #84] ; (8002ca0 ) + 8002c4c: aa01 add r2, sp, #4 + 8002c4e: f103 0610 add.w r6, r3, #16 + 8002c52: 4615 mov r5, r2 + 8002c54: 6818 ldr r0, [r3, #0] + 8002c56: 6859 ldr r1, [r3, #4] + 8002c58: 4614 mov r4, r2 + 8002c5a: c403 stmia r4!, {r0, r1} + 8002c5c: 3308 adds r3, #8 + 8002c5e: 42b3 cmp r3, r6 + 8002c60: 4622 mov r2, r4 + 8002c62: d1f7 bne.n 8002c54 + 0,0,0,0, 0,0,0,0, // eight zeros + 0,0,0, // three zeros + 0xEE }; + sha256_update(&ctx, fixed, sizeof(fixed)); + 8002c64: 2210 movs r2, #16 + 8002c66: 4629 mov r1, r5 + 8002c68: a815 add r0, sp, #84 ; 0x54 + 8002c6a: f002 fc1d bl 80054a8 + + sha256_update(&ctx, ((const uint8_t *)rom_secrets->ae_serial_number)+4, 4); + 8002c6e: 490d ldr r1, [pc, #52] ; (8002ca4 ) + 8002c70: 2204 movs r2, #4 + 8002c72: a815 add r0, sp, #84 ; 0x54 + 8002c74: f002 fc18 bl 80054a8 + sha256_update(&ctx, ((const uint8_t *)rom_secrets->ae_serial_number)+0, 4); + 8002c78: 2204 movs r2, #4 + 8002c7a: 490b ldr r1, [pc, #44] ; (8002ca8 ) + 8002c7c: a815 add r0, sp, #84 ; 0x54 + 8002c7e: f002 fc13 bl 80054a8 + // this verifies no problem. + ASSERT(ctx.datalen + (ctx.bitlen/8) == 32+32+1+1+2+8+3+1+4+2+2); // == 88 +#endif + + uint8_t actual[32]; + sha256_final(&ctx, actual); + 8002c82: a90d add r1, sp, #52 ; 0x34 + 8002c84: a815 add r0, sp, #84 ; 0x54 + 8002c86: f002 fc55 bl 8005534 + + return check_equal(actual, resp, 32); + 8002c8a: 2220 movs r2, #32 + 8002c8c: a905 add r1, sp, #20 + 8002c8e: a80d add r0, sp, #52 ; 0x34 + 8002c90: f7ff fd0f bl 80026b2 +} + 8002c94: b028 add sp, #160 ; 0xa0 + 8002c96: bd70 pop {r4, r5, r6, pc} + if(rv) return false; + 8002c98: 2000 movs r0, #0 + 8002c9a: e7fb b.n 8002c94 + 8002c9c: 0801c000 .word 0x0801c000 + 8002ca0: 0800e677 .word 0x0800e677 + 8002ca4: 0801c044 .word 0x0801c044 + 8002ca8: 0801c040 .word 0x0801c040 + +08002cac : +// inside the 508a/608a, like use of a specific key, but not for us to +// authenticate the 508a/608a or its contents/state. +// + int +ae_checkmac(uint8_t keynum, const uint8_t secret[32]) +{ + 8002cac: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8002cb0: b0c2 sub sp, #264 ; 0x108 + + // Since this is part of the hash, we want random bytes + // for our "other data". Also a number for "numin" of nonce + uint8_t od[32], numin[20]; + + rng_buffer(od, sizeof(od)); + 8002cb2: ad0b add r5, sp, #44 ; 0x2c +{ + 8002cb4: 4607 mov r7, r0 + 8002cb6: 460e mov r6, r1 + rng_buffer(od, sizeof(od)); + 8002cb8: 4628 mov r0, r5 + 8002cba: 2120 movs r1, #32 + 8002cbc: f7ff fd48 bl 8002750 + rng_buffer(numin, sizeof(numin)); + 8002cc0: 2114 movs r1, #20 + 8002cc2: a806 add r0, sp, #24 + 8002cc4: f7ff fd44 bl 8002750 + ae_send_idle(); + 8002cc8: f7ff fdfd bl 80028c6 + + // need this one, want to reset watchdog to this point. + ae_keep_alive(); + + // - load tempkey with a known nonce value + uint8_t zeros[8] = {0}; + 8002ccc: 2300 movs r3, #0 + uint8_t tempkey[32]; + rv = ae_pick_nonce(numin, tempkey); + 8002cce: a913 add r1, sp, #76 ; 0x4c + 8002cd0: a806 add r0, sp, #24 + uint8_t zeros[8] = {0}; + 8002cd2: e9cd 3304 strd r3, r3, [sp, #16] + rv = ae_pick_nonce(numin, tempkey); + 8002cd6: f7ff ff67 bl 8002ba8 + RET_IF_BAD(rv); + 8002cda: 4604 mov r4, r0 + 8002cdc: 2800 cmp r0, #0 + 8002cde: d15d bne.n 8002d9c + + // - hash nonce and lots of other bits together + SHA256_CTX ctx; + sha256_init(&ctx); + 8002ce0: a81b add r0, sp, #108 ; 0x6c + 8002ce2: f002 fbd3 bl 800548c + + // shared secret is 32 bytes from flash + sha256_update(&ctx, secret, 32); + 8002ce6: 2220 movs r2, #32 + 8002ce8: 4631 mov r1, r6 + 8002cea: a81b add r0, sp, #108 ; 0x6c + 8002cec: f002 fbdc bl 80054a8 + + sha256_update(&ctx, tempkey, 32); + 8002cf0: 2220 movs r2, #32 + 8002cf2: a913 add r1, sp, #76 ; 0x4c + 8002cf4: a81b add r0, sp, #108 ; 0x6c + 8002cf6: f002 fbd7 bl 80054a8 + sha256_update(&ctx, &od[0], 4); + 8002cfa: 2204 movs r2, #4 + 8002cfc: 4629 mov r1, r5 + 8002cfe: a81b add r0, sp, #108 ; 0x6c + 8002d00: f002 fbd2 bl 80054a8 + + sha256_update(&ctx, zeros, 8); + 8002d04: 2208 movs r2, #8 + 8002d06: a904 add r1, sp, #16 + 8002d08: a81b add r0, sp, #108 ; 0x6c + 8002d0a: f002 fbcd bl 80054a8 + + sha256_update(&ctx, &od[4], 3); + 8002d0e: 2203 movs r2, #3 + 8002d10: a90c add r1, sp, #48 ; 0x30 + 8002d12: a81b add r0, sp, #108 ; 0x6c + 8002d14: f002 fbc8 bl 80054a8 + + uint8_t ee = 0xEE; + 8002d18: 23ee movs r3, #238 ; 0xee + sha256_update(&ctx, &ee, 1); + 8002d1a: 2201 movs r2, #1 + 8002d1c: f10d 010b add.w r1, sp, #11 + 8002d20: a81b add r0, sp, #108 ; 0x6c + uint8_t ee = 0xEE; + 8002d22: f88d 300b strb.w r3, [sp, #11] + sha256_update(&ctx, &ee, 1); + 8002d26: f002 fbbf bl 80054a8 + sha256_update(&ctx, &od[7], 4); + 8002d2a: 2204 movs r2, #4 + 8002d2c: f10d 0133 add.w r1, sp, #51 ; 0x33 + 8002d30: a81b add r0, sp, #108 ; 0x6c + 8002d32: f002 fbb9 bl 80054a8 + + uint8_t snp[2] = { 0x01, 0x23 }; + 8002d36: f242 3301 movw r3, #8961 ; 0x2301 + sha256_update(&ctx, snp, 2); + 8002d3a: 2202 movs r2, #2 + 8002d3c: a903 add r1, sp, #12 + 8002d3e: a81b add r0, sp, #108 ; 0x6c + uint8_t snp[2] = { 0x01, 0x23 }; + 8002d40: f8ad 300c strh.w r3, [sp, #12] + sha256_update(&ctx, snp, 2); + 8002d44: f002 fbb0 bl 80054a8 + sha256_update(&ctx, &od[11], 2); + 8002d48: 2202 movs r2, #2 + 8002d4a: f10d 0137 add.w r1, sp, #55 ; 0x37 + 8002d4e: a81b add r0, sp, #108 ; 0x6c + 8002d50: f002 fbaa bl 80054a8 + uint8_t resp[32]; + uint8_t od[13]; + } req; + + // content doesn't matter, but nice and visible: + memcpy(req.ch3, copyright_msg, 32); + 8002d54: 4b15 ldr r3, [pc, #84] ; (8002dac ) + 8002d56: ac2e add r4, sp, #184 ; 0xb8 + 8002d58: f103 0220 add.w r2, r3, #32 + 8002d5c: 46a0 mov r8, r4 + 8002d5e: 6818 ldr r0, [r3, #0] + 8002d60: 6859 ldr r1, [r3, #4] + 8002d62: 4626 mov r6, r4 + 8002d64: c603 stmia r6!, {r0, r1} + 8002d66: 3308 adds r3, #8 + 8002d68: 4293 cmp r3, r2 + 8002d6a: 4634 mov r4, r6 + 8002d6c: d1f7 bne.n 8002d5e + // this verifies no problem. + int l = (ctx.blocks * 64) + ctx.npartial; + ASSERT(l == 32+32+4+8+3+1+4+2+2); // == 88 +#endif + + sha256_final(&ctx, req.resp); + 8002d6e: a936 add r1, sp, #216 ; 0xd8 + 8002d70: a81b add r0, sp, #108 ; 0x6c + 8002d72: f002 fbdf bl 8005534 + memcpy(req.od, od, 13); + 8002d76: e895 000f ldmia.w r5, {r0, r1, r2, r3} + 8002d7a: ac3e add r4, sp, #248 ; 0xf8 + 8002d7c: c407 stmia r4!, {r0, r1, r2} + 8002d7e: 7023 strb r3, [r4, #0] + + STATIC_ASSERT(sizeof(req) == 32 + 32 + 13); + + // Give our answer to the chip. + ae_send_n(OP_CheckMac, 0x01, keynum, (uint8_t *)&req, sizeof(req)); + 8002d80: 234d movs r3, #77 ; 0x4d + 8002d82: 9300 str r3, [sp, #0] + 8002d84: 463a mov r2, r7 + 8002d86: 4643 mov r3, r8 + 8002d88: 2101 movs r1, #1 + 8002d8a: 2028 movs r0, #40 ; 0x28 + 8002d8c: f7ff fea4 bl 8002ad8 + + rv = ae_read1(); + 8002d90: f7ff fe4c bl 8002a2c + if(rv != 0) { + 8002d94: 4604 mov r4, r0 + 8002d96: b928 cbnz r0, 8002da4 + ae_send_idle(); + 8002d98: f7ff fd95 bl 80028c6 + + // just in case ... always restart watchdog timer. + ae_keep_alive(); + + return 0; +} + 8002d9c: 4620 mov r0, r4 + 8002d9e: b042 add sp, #264 ; 0x108 + 8002da0: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + return -1; + 8002da4: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 8002da8: e7f8 b.n 8002d9c + 8002daa: bf00 nop + 8002dac: 0800e646 .word 0x0800e646 + +08002db0 : + return ae_checkmac(KEYNUM_pairing, rom_secrets->pairing_secret); + 8002db0: 4901 ldr r1, [pc, #4] ; (8002db8 ) + 8002db2: 2001 movs r0, #1 + 8002db4: f7ff bf7a b.w 8002cac + 8002db8: 0801c000 .word 0x0801c000 + +08002dbc : +// Sign a message (already digested) +// + int +ae_sign_authed(uint8_t keynum, const uint8_t msg_hash[32], + uint8_t signature[64], int auth_kn, const uint8_t auth_digest[32]) +{ + 8002dbc: b570 push {r4, r5, r6, lr} + 8002dbe: 460e mov r6, r1 + 8002dc0: 4604 mov r4, r0 + 8002dc2: 4615 mov r5, r2 + // indicate we know the PIN + ae_pair_unlock(); + 8002dc4: f7ff fff4 bl 8002db0 + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + 8002dc8: 9904 ldr r1, [sp, #16] + 8002dca: 2003 movs r0, #3 + 8002dcc: f7ff ff6e bl 8002cac + RET_IF_BAD(rv); + 8002dd0: b990 cbnz r0, 8002df8 + + // send what we need signed + rv = ae_load_msgdigest(msg_hash); + 8002dd2: 4630 mov r0, r6 + 8002dd4: f7ff feda bl 8002b8c + RET_IF_BAD(rv); + 8002dd8: b970 cbnz r0, 8002df8 + + do { + ae_send(OP_Sign, (7<<5), keynum); + 8002dda: b2a4 uxth r4, r4 + 8002ddc: 4622 mov r2, r4 + 8002dde: 21e0 movs r1, #224 ; 0xe0 + 8002de0: 2041 movs r0, #65 ; 0x41 + 8002de2: f7ff feac bl 8002b3e + + delay_ms(60); // min time for processing + 8002de6: 203c movs r0, #60 ; 0x3c + 8002de8: f000 fd86 bl 80038f8 + + rv = ae_read_n(64, signature); + 8002dec: 4629 mov r1, r5 + 8002dee: 2040 movs r0, #64 ; 0x40 + 8002df0: f7ff fe38 bl 8002a64 + } while(rv == AE_ECC_FAULT); + 8002df4: 2805 cmp r0, #5 + 8002df6: d0f1 beq.n 8002ddc + + return rv; +} + 8002df8: bd70 pop {r4, r5, r6, pc} + ... + +08002dfc : + +// ae_gen_ecc_key() +// + int +ae_gen_ecc_key(uint8_t keynum, uint8_t pubkey_out[64]) +{ + 8002dfc: b530 push {r4, r5, lr} + int rv; + uint8_t junk[3] = { 0 }; + 8002dfe: 4b0f ldr r3, [pc, #60] ; (8002e3c ) +{ + 8002e00: b085 sub sp, #20 + uint8_t junk[3] = { 0 }; + 8002e02: f8b3 3013 ldrh.w r3, [r3, #19] + 8002e06: f8ad 300c strh.w r3, [sp, #12] + 8002e0a: 2300 movs r3, #0 +{ + 8002e0c: 460c mov r4, r1 + uint8_t junk[3] = { 0 }; + 8002e0e: f88d 300e strb.w r3, [sp, #14] + + do { + ae_send_n(OP_GenKey, (1<<2), keynum, junk, 3); + 8002e12: 4605 mov r5, r0 + 8002e14: 2303 movs r3, #3 + 8002e16: 462a mov r2, r5 + 8002e18: 2104 movs r1, #4 + 8002e1a: 9300 str r3, [sp, #0] + 8002e1c: 2040 movs r0, #64 ; 0x40 + 8002e1e: ab03 add r3, sp, #12 + 8002e20: f7ff fe5a bl 8002ad8 + + delay_ms(100); // to avoid timeouts + 8002e24: 2064 movs r0, #100 ; 0x64 + 8002e26: f000 fd67 bl 80038f8 + + rv = ae_read_n(64, pubkey_out); + 8002e2a: 4621 mov r1, r4 + 8002e2c: 2040 movs r0, #64 ; 0x40 + 8002e2e: f7ff fe19 bl 8002a64 + } while(rv == AE_ECC_FAULT); + 8002e32: 2805 cmp r0, #5 + 8002e34: d0ee beq.n 8002e14 + + return rv; +} + 8002e36: b005 add sp, #20 + 8002e38: bd30 pop {r4, r5, pc} + 8002e3a: bf00 nop + 8002e3c: 0800e674 .word 0x0800e674 + +08002e40 : +// 508a: Different opcode, OP_HMAC does exactly 32 bytes w/ less steps. +// 608a: Use old SHA256 command, but with new flags. +// + int +ae_hmac32(uint8_t keynum, const uint8_t msg[32], uint8_t digest[32]) +{ + 8002e40: b530 push {r4, r5, lr} + 8002e42: b085 sub sp, #20 + 8002e44: 4615 mov r5, r2 + 8002e46: 9103 str r1, [sp, #12] + // Start SHA w/ HMAC setup + ae_send(OP_SHA, 4, keynum); // 4 = HMAC_Init + 8002e48: 4602 mov r2, r0 + 8002e4a: 2104 movs r1, #4 + 8002e4c: 2047 movs r0, #71 ; 0x47 + 8002e4e: f7ff fe76 bl 8002b3e + + // expect zero, meaning "ready" + int rv = ae_read1(); + 8002e52: f7ff fdeb bl 8002a2c + RET_IF_BAD(rv); + 8002e56: b970 cbnz r0, 8002e76 + + // send the contents to be hashed + ae_send_n(OP_SHA, (3<<6) | 2, 32, msg, 32); // 2 = Finalize, 3=Place output + 8002e58: 2420 movs r4, #32 + 8002e5a: 9b03 ldr r3, [sp, #12] + 8002e5c: 9400 str r4, [sp, #0] + 8002e5e: 4622 mov r2, r4 + 8002e60: 21c2 movs r1, #194 ; 0xc2 + 8002e62: 2047 movs r0, #71 ; 0x47 + 8002e64: f7ff fe38 bl 8002ad8 + + // read result + return ae_read_n(32, digest); + 8002e68: 4629 mov r1, r5 + 8002e6a: 4620 mov r0, r4 +} + 8002e6c: b005 add sp, #20 + 8002e6e: e8bd 4030 ldmia.w sp!, {r4, r5, lr} + return ae_read_n(32, digest); + 8002e72: f7ff bdf7 b.w 8002a64 +} + 8002e76: b005 add sp, #20 + 8002e78: bd30 pop {r4, r5, pc} + +08002e7a : +// +// Return the serial number: it's 9 bytes, altho 3 are fixed. +// + int +ae_get_serial(uint8_t serial[6]) +{ + 8002e7a: b510 push {r4, lr} + ae_send(OP_Read, 0x80, 0x0); + 8002e7c: 2200 movs r2, #0 +{ + 8002e7e: b08c sub sp, #48 ; 0x30 + ae_send(OP_Read, 0x80, 0x0); + 8002e80: 2180 movs r1, #128 ; 0x80 +{ + 8002e82: 4604 mov r4, r0 + ae_send(OP_Read, 0x80, 0x0); + 8002e84: 2002 movs r0, #2 + 8002e86: f7ff fe5a bl 8002b3e + + uint8_t temp[32]; + int rv = ae_read_n(32, temp); + 8002e8a: a904 add r1, sp, #16 + 8002e8c: 2020 movs r0, #32 + 8002e8e: f7ff fde9 bl 8002a64 + RET_IF_BAD(rv); + 8002e92: 4603 mov r3, r0 + 8002e94: b9b8 cbnz r0, 8002ec6 + + // reformat to 9 bytes. + uint8_t ts[9]; + memcpy(ts, &temp[0], 4); + memcpy(&ts[4], &temp[8], 5); + 8002e96: e9dd 0106 ldrd r0, r1, [sp, #24] + 8002e9a: 9a04 ldr r2, [sp, #16] + 8002e9c: f88d 100c strb.w r1, [sp, #12] + + // check the hard-coded values + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 8002ea0: b2d1 uxtb r1, r2 + 8002ea2: 2901 cmp r1, #1 + memcpy(ts, &temp[0], 4); + 8002ea4: 9201 str r2, [sp, #4] + memcpy(&ts[4], &temp[8], 5); + 8002ea6: 9002 str r0, [sp, #8] + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 8002ea8: d110 bne.n 8002ecc + 8002eaa: f3c2 2207 ubfx r2, r2, #8, #8 + 8002eae: 2a23 cmp r2, #35 ; 0x23 + 8002eb0: d10c bne.n 8002ecc + 8002eb2: f89d 200c ldrb.w r2, [sp, #12] + 8002eb6: 2aee cmp r2, #238 ; 0xee + 8002eb8: d10a bne.n 8002ed0 + + // save only the unique bits. + memcpy(serial, ts+2, 6); + 8002eba: f8dd 2006 ldr.w r2, [sp, #6] + 8002ebe: 6022 str r2, [r4, #0] + 8002ec0: f8bd 200a ldrh.w r2, [sp, #10] + 8002ec4: 80a2 strh r2, [r4, #4] + + return 0; +} + 8002ec6: 4618 mov r0, r3 + 8002ec8: b00c add sp, #48 ; 0x30 + 8002eca: bd10 pop {r4, pc} + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 8002ecc: 2301 movs r3, #1 + 8002ece: e7fa b.n 8002ec6 + 8002ed0: 460b mov r3, r1 + 8002ed2: e7f8 b.n 8002ec6 + +08002ed4 : +{ + 8002ed4: b513 push {r0, r1, r4, lr} + ae_wake(); + 8002ed6: f7ff fceb bl 80028b0 + _send_bits(IOFLAG_SLEEP); + 8002eda: 20cc movs r0, #204 ; 0xcc + 8002edc: f7ff fc70 bl 80027c0 <_send_bits> + ae_wake(); + 8002ee0: f7ff fce6 bl 80028b0 + ae_read1(); + 8002ee4: f7ff fda2 bl 8002a2c + uint8_t chk = ae_read1(); + 8002ee8: f7ff fda0 bl 8002a2c + if(chk != AE_AFTER_WAKE) return "wk fl"; + 8002eec: b2c0 uxtb r0, r0 + 8002eee: 2811 cmp r0, #17 + 8002ef0: d10e bne.n 8002f10 + if(ae_get_serial(serial)) return "no ser"; + 8002ef2: 4668 mov r0, sp + 8002ef4: f7ff ffc1 bl 8002e7a + 8002ef8: 4604 mov r4, r0 + 8002efa: b938 cbnz r0, 8002f0c + ae_wake(); + 8002efc: f7ff fcd8 bl 80028b0 + _send_bits(IOFLAG_SLEEP); + 8002f00: 20cc movs r0, #204 ; 0xcc + 8002f02: f7ff fc5d bl 80027c0 <_send_bits> + return NULL; + 8002f06: 4620 mov r0, r4 +} + 8002f08: b002 add sp, #8 + 8002f0a: bd10 pop {r4, pc} + if(ae_get_serial(serial)) return "no ser"; + 8002f0c: 4801 ldr r0, [pc, #4] ; (8002f14 ) + 8002f0e: e7fb b.n 8002f08 + if(chk != AE_AFTER_WAKE) return "wk fl"; + 8002f10: 4801 ldr r0, [pc, #4] ; (8002f18 ) + 8002f12: e7f9 b.n 8002f08 + 8002f14: 0800e667 .word 0x0800e667 + 8002f18: 0800e66e .word 0x0800e66e + +08002f1c : +// +// -- can also lock it. +// + int +ae_write_data_slot(int slot_num, const uint8_t *data, int len, bool lock_it) +{ + 8002f1c: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8002f20: 4699 mov r9, r3 + ASSERT(len >= 32); + 8002f22: f1a2 0320 sub.w r3, r2, #32 +{ + 8002f26: b085 sub sp, #20 + ASSERT(len >= 32); + 8002f28: f5b3 7fc0 cmp.w r3, #384 ; 0x180 +{ + 8002f2c: 4604 mov r4, r0 + 8002f2e: af02 add r7, sp, #8 + 8002f30: 460d mov r5, r1 + 8002f32: 4690 mov r8, r2 + ASSERT(len >= 32); + 8002f34: d902 bls.n 8002f3c + 8002f36: 482d ldr r0, [pc, #180] ; (8002fec ) + 8002f38: f7fd fd86 bl 8000a48 + ASSERT(len <= 416); + + for(int blk=0, xlen=len; xlen>0; blk++, xlen-=32) { + // have to write each "block" of 32-bytes, separately + // zone => data + ae_send_n(OP_Write, 0x80|2, (blk<<8) | (slot_num<<3), data+(blk*32), 32); + 8002f3c: ea4f 0ac0 mov.w sl, r0, lsl #3 + 8002f40: fa0f fa8a sxth.w sl, sl + 8002f44: 2600 movs r6, #0 + 8002f46: f04f 0b20 mov.w fp, #32 + 8002f4a: ebc6 3246 rsb r2, r6, r6, lsl #13 + 8002f4e: ea4a 02c2 orr.w r2, sl, r2, lsl #3 + 8002f52: b292 uxth r2, r2 + 8002f54: 1bab subs r3, r5, r6 + 8002f56: 2182 movs r1, #130 ; 0x82 + 8002f58: 2012 movs r0, #18 + 8002f5a: f8cd b000 str.w fp, [sp] + 8002f5e: f7ff fdbb bl 8002ad8 + + int rv = ae_read1(); + 8002f62: f7ff fd63 bl 8002a2c + RET_IF_BAD(rv); + 8002f66: 2800 cmp r0, #0 + 8002f68: d13c bne.n 8002fe4 + for(int blk=0, xlen=len; xlen>0; blk++, xlen-=32) { + 8002f6a: 3e20 subs r6, #32 + 8002f6c: eb06 0308 add.w r3, r6, r8 + 8002f70: 2b00 cmp r3, #0 + 8002f72: dcea bgt.n 8002f4a + } + + if(lock_it) { + 8002f74: f1b9 0f00 cmp.w r9, #0 + 8002f78: d034 beq.n 8002fe4 + ASSERT(slot_num != 8); // no support for mega slot 8 + 8002f7a: 2c08 cmp r4, #8 + if(lock_it) { + 8002f7c: 466e mov r6, sp + ASSERT(slot_num != 8); // no support for mega slot 8 + 8002f7e: d0da beq.n 8002f36 + ASSERT(len == 32); // probably not a limitation here + 8002f80: f1b8 0f20 cmp.w r8, #32 + 8002f84: d1d7 bne.n 8002f36 + + // Assume 36/72-byte long slot, which will be partially written, and rest + // should be ones. + const int slot_len = (slot_num <= 7) ? 36 : 72; + 8002f86: 2c08 cmp r4, #8 + 8002f88: bfb4 ite lt + 8002f8a: f04f 0824 movlt.w r8, #36 ; 0x24 + 8002f8e: f04f 0848 movge.w r8, #72 ; 0x48 + uint8_t copy[slot_len]; + 8002f92: f108 0307 add.w r3, r8, #7 + 8002f96: f003 03f8 and.w r3, r3, #248 ; 0xf8 + 8002f9a: ebad 0d03 sub.w sp, sp, r3 + 8002f9e: ab02 add r3, sp, #8 + + memset(copy, 0xff, slot_len); + 8002fa0: 4642 mov r2, r8 + 8002fa2: 21ff movs r1, #255 ; 0xff + 8002fa4: 4618 mov r0, r3 + 8002fa6: f00a fb65 bl 800d674 + memcpy(copy, data, len); + 8002faa: f105 0120 add.w r1, r5, #32 + memset(copy, 0xff, slot_len); + 8002fae: 4603 mov r3, r0 + memcpy(copy, data, len); + 8002fb0: 4602 mov r2, r0 + 8002fb2: f855 0b04 ldr.w r0, [r5], #4 + 8002fb6: f842 0b04 str.w r0, [r2], #4 + 8002fba: 428d cmp r5, r1 + 8002fbc: d1f9 bne.n 8002fb2 + + // calc expected CRC + uint8_t crc[2] = {0, 0}; + 8002fbe: 2200 movs r2, #0 + crc16_chain(slot_len, copy, crc); + 8002fc0: 4619 mov r1, r3 + uint8_t crc[2] = {0, 0}; + 8002fc2: 80ba strh r2, [r7, #4] + crc16_chain(slot_len, copy, crc); + 8002fc4: 4640 mov r0, r8 + 8002fc6: 1d3a adds r2, r7, #4 + 8002fc8: f7ff fc30 bl 800282c + + // do the lock + ae_send(OP_Lock, 2 | (slot_num << 2), (crc[1]<<8) | crc[0]); + 8002fcc: 00a1 lsls r1, r4, #2 + 8002fce: f041 0102 orr.w r1, r1, #2 + 8002fd2: 88ba ldrh r2, [r7, #4] + 8002fd4: f001 01fe and.w r1, r1, #254 ; 0xfe + 8002fd8: 2017 movs r0, #23 + 8002fda: f7ff fdb0 bl 8002b3e + + int rv = ae_read1(); + 8002fde: f7ff fd25 bl 8002a2c + RET_IF_BAD(rv); + 8002fe2: 46b5 mov sp, r6 + } + + return 0; +} + 8002fe4: 370c adds r7, #12 + 8002fe6: 46bd mov sp, r7 + 8002fe8: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 8002fec: 0800e3e0 .word 0x0800e3e0 + +08002ff0 : + +// ae_gendig_slot() +// + int +ae_gendig_slot(int slot_num, const uint8_t slot_contents[32], uint8_t digest[32]) +{ + 8002ff0: b5f0 push {r4, r5, r6, r7, lr} + 8002ff2: b0ab sub sp, #172 ; 0xac + 8002ff4: 4605 mov r5, r0 + 8002ff6: 460f mov r7, r1 + // Construct a digest on the device (and here) that depends on the secret + // contents of a specific slot. + uint8_t num_in[20], tempkey[32]; + + rng_buffer(num_in, sizeof(num_in)); + 8002ff8: a803 add r0, sp, #12 + 8002ffa: 2114 movs r1, #20 +{ + 8002ffc: 4616 mov r6, r2 + rng_buffer(num_in, sizeof(num_in)); + 8002ffe: f7ff fba7 bl 8002750 + int rv = ae_pick_nonce(num_in, tempkey); + 8003002: a90f add r1, sp, #60 ; 0x3c + 8003004: a803 add r0, sp, #12 + 8003006: f7ff fdcf bl 8002ba8 + RET_IF_BAD(rv); + 800300a: 4604 mov r4, r0 + 800300c: 2800 cmp r0, #0 + 800300e: d13d bne.n 800308c + + //using Zone=2="Data" => "KeyID specifies a slot in the Data zone" + ae_send(OP_GenDig, 0x2, slot_num); + 8003010: b2aa uxth r2, r5 + 8003012: 2102 movs r1, #2 + 8003014: 2015 movs r0, #21 + 8003016: f7ff fd92 bl 8002b3e + + rv = ae_read1(); + 800301a: f7ff fd07 bl 8002a2c + RET_IF_BAD(rv); + 800301e: 4604 mov r4, r0 + 8003020: bba0 cbnz r0, 800308c + ae_send_idle(); + 8003022: f7ff fc50 bl 80028c6 + // msg = hkey + b'\x15\x02' + ustruct.pack(" + + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 800302c: 2302 movs r3, #2 + 800302e: f88d 3005 strb.w r3, [sp, #5] + 8003032: 23ee movs r3, #238 ; 0xee + 8003034: f88d 3008 strb.w r3, [sp, #8] + 8003038: 2301 movs r3, #1 + 800303a: 2215 movs r2, #21 + 800303c: f88d 3009 strb.w r3, [sp, #9] + uint8_t zeros[25] = { 0 }; + 8003040: 4621 mov r1, r4 + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 8003042: 2323 movs r3, #35 ; 0x23 + uint8_t zeros[25] = { 0 }; + 8003044: a809 add r0, sp, #36 ; 0x24 + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 8003046: f88d 300a strb.w r3, [sp, #10] + 800304a: f88d 2004 strb.w r2, [sp, #4] + 800304e: f88d 5006 strb.w r5, [sp, #6] + 8003052: f88d 4007 strb.w r4, [sp, #7] + uint8_t zeros[25] = { 0 }; + 8003056: 9408 str r4, [sp, #32] + 8003058: f00a fb0c bl 800d674 + + sha256_update(&ctx, slot_contents, 32); + 800305c: 2220 movs r2, #32 + 800305e: 4639 mov r1, r7 + 8003060: a817 add r0, sp, #92 ; 0x5c + 8003062: f002 fa21 bl 80054a8 + sha256_update(&ctx, args, sizeof(args)); + 8003066: 2207 movs r2, #7 + 8003068: a901 add r1, sp, #4 + 800306a: a817 add r0, sp, #92 ; 0x5c + 800306c: f002 fa1c bl 80054a8 + sha256_update(&ctx, zeros, sizeof(zeros)); + 8003070: 2219 movs r2, #25 + 8003072: a908 add r1, sp, #32 + 8003074: a817 add r0, sp, #92 ; 0x5c + 8003076: f002 fa17 bl 80054a8 + sha256_update(&ctx, tempkey, 32); + 800307a: a90f add r1, sp, #60 ; 0x3c + 800307c: a817 add r0, sp, #92 ; 0x5c + 800307e: 2220 movs r2, #32 + 8003080: f002 fa12 bl 80054a8 + + sha256_final(&ctx, digest); + 8003084: 4631 mov r1, r6 + 8003086: a817 add r0, sp, #92 ; 0x5c + 8003088: f002 fa54 bl 8005534 + + return 0; +} + 800308c: 4620 mov r0, r4 + 800308e: b02b add sp, #172 ; 0xac + 8003090: bdf0 pop {r4, r5, r6, r7, pc} + ... + +08003094 : +{ + 8003094: b507 push {r0, r1, r2, lr} + 8003096: 4602 mov r2, r0 + int rv = ae_gendig_slot(KEYNUM_pairing, rom_secrets->pairing_secret, randout); + 8003098: 9001 str r0, [sp, #4] + 800309a: 490b ldr r1, [pc, #44] ; (80030c8 ) + 800309c: 2001 movs r0, #1 + 800309e: f7ff ffa7 bl 8002ff0 + if(rv || !ae_is_correct_tempkey(randout)) { + 80030a2: 9a01 ldr r2, [sp, #4] + 80030a4: b108 cbz r0, 80030aa + fatal_mitm(); + 80030a6: f7fd fcd9 bl 8000a5c + if(rv || !ae_is_correct_tempkey(randout)) { + 80030aa: 4610 mov r0, r2 + 80030ac: 9201 str r2, [sp, #4] + 80030ae: f7ff fdaf bl 8002c10 + 80030b2: 2800 cmp r0, #0 + 80030b4: d0f7 beq.n 80030a6 + sha256_single(randout, 32, randout); + 80030b6: 9a01 ldr r2, [sp, #4] + 80030b8: 2120 movs r1, #32 + 80030ba: 4610 mov r0, r2 +} + 80030bc: b003 add sp, #12 + 80030be: f85d eb04 ldr.w lr, [sp], #4 + sha256_single(randout, 32, randout); + 80030c2: f002 ba4b b.w 800555c + 80030c6: bf00 nop + 80030c8: 0801c000 .word 0x0801c000 + +080030cc : +{ + 80030cc: b510 push {r4, lr} + 80030ce: b088 sub sp, #32 + int rv = ae_gendig_slot(keynum, secret, digest); + 80030d0: 466a mov r2, sp + 80030d2: f7ff ff8d bl 8002ff0 + RET_IF_BAD(rv); + 80030d6: 4604 mov r4, r0 + 80030d8: b930 cbnz r0, 80030e8 + if(!ae_is_correct_tempkey(digest)) return -2; + 80030da: 4668 mov r0, sp + 80030dc: f7ff fd98 bl 8002c10 + 80030e0: 2800 cmp r0, #0 + 80030e2: bf08 it eq + 80030e4: f06f 0401 mvneq.w r4, #1 +} + 80030e8: 4620 mov r0, r4 + 80030ea: b008 add sp, #32 + 80030ec: bd10 pop {r4, pc} + +080030ee : +// the digest should be, and ask the chip to do the same. Verify we match +// using MAC command (done elsewhere). +// + int +ae_gendig_counter(int counter_num, const uint32_t expected_value, uint8_t digest[32]) +{ + 80030ee: b5f0 push {r4, r5, r6, r7, lr} + 80030f0: b0ad sub sp, #180 ; 0xb4 + 80030f2: 4605 mov r5, r0 + 80030f4: 9101 str r1, [sp, #4] + uint8_t num_in[20], tempkey[32]; + + rng_buffer(num_in, sizeof(num_in)); + 80030f6: a804 add r0, sp, #16 + 80030f8: 2114 movs r1, #20 +{ + 80030fa: 4616 mov r6, r2 + rng_buffer(num_in, sizeof(num_in)); + 80030fc: f7ff fb28 bl 8002750 + int rv = ae_pick_nonce(num_in, tempkey); + 8003100: a909 add r1, sp, #36 ; 0x24 + 8003102: a804 add r0, sp, #16 + 8003104: f7ff fd50 bl 8002ba8 + RET_IF_BAD(rv); + 8003108: 4604 mov r4, r0 + 800310a: 2800 cmp r0, #0 + 800310c: d148 bne.n 80031a0 + + //using Zone=4="Counter" => "KeyID specifies the monotonic counter ID" + ae_send(OP_GenDig, 0x4, counter_num); + 800310e: b2aa uxth r2, r5 + 8003110: 2104 movs r1, #4 + 8003112: 2015 movs r0, #21 + 8003114: f7ff fd13 bl 8002b3e + + rv = ae_read1(); + 8003118: f7ff fc88 bl 8002a2c + RET_IF_BAD(rv); + 800311c: 4604 mov r4, r0 + 800311e: 2800 cmp r0, #0 + 8003120: d13e bne.n 80031a0 + ae_send_idle(); + 8003122: f7ff fbd0 bl 80028c6 + // msg = hkey + b'\x15\x02' + ustruct.pack(" + + uint8_t zeros[32] = { 0 }; + 800312c: 221c movs r2, #28 + 800312e: 4621 mov r1, r4 + 8003130: a812 add r0, sp, #72 ; 0x48 + 8003132: 9411 str r4, [sp, #68] ; 0x44 + 8003134: f00a fa9e bl 800d674 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 8003138: 2315 movs r3, #21 + 800313a: f88d 3008 strb.w r3, [sp, #8] + 800313e: 23ee movs r3, #238 ; 0xee + 8003140: f88d 300c strb.w r3, [sp, #12] + 8003144: 2301 movs r3, #1 + 8003146: 2704 movs r7, #4 + 8003148: f88d 300d strb.w r3, [sp, #13] + + sha256_update(&ctx, zeros, 32); + 800314c: 2220 movs r2, #32 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 800314e: 2323 movs r3, #35 ; 0x23 + sha256_update(&ctx, zeros, 32); + 8003150: a911 add r1, sp, #68 ; 0x44 + 8003152: a819 add r0, sp, #100 ; 0x64 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 8003154: f88d 300e strb.w r3, [sp, #14] + 8003158: f88d 7009 strb.w r7, [sp, #9] + 800315c: f88d 500a strb.w r5, [sp, #10] + 8003160: f88d 400b strb.w r4, [sp, #11] + 8003164: f88d 400f strb.w r4, [sp, #15] + sha256_update(&ctx, zeros, 32); + 8003168: f002 f99e bl 80054a8 + sha256_update(&ctx, args, sizeof(args)); + 800316c: 2208 movs r2, #8 + 800316e: eb0d 0102 add.w r1, sp, r2 + 8003172: a819 add r0, sp, #100 ; 0x64 + 8003174: f002 f998 bl 80054a8 + sha256_update(&ctx, (const uint8_t *)&expected_value, 4); + 8003178: 463a mov r2, r7 + 800317a: eb0d 0107 add.w r1, sp, r7 + 800317e: a819 add r0, sp, #100 ; 0x64 + 8003180: f002 f992 bl 80054a8 + sha256_update(&ctx, zeros, 20); + 8003184: 2214 movs r2, #20 + 8003186: a911 add r1, sp, #68 ; 0x44 + 8003188: a819 add r0, sp, #100 ; 0x64 + 800318a: f002 f98d bl 80054a8 + sha256_update(&ctx, tempkey, 32); + 800318e: a909 add r1, sp, #36 ; 0x24 + 8003190: a819 add r0, sp, #100 ; 0x64 + 8003192: 2220 movs r2, #32 + 8003194: f002 f988 bl 80054a8 + + sha256_final(&ctx, digest); + 8003198: 4631 mov r1, r6 + 800319a: a819 add r0, sp, #100 ; 0x64 + 800319c: f002 f9ca bl 8005534 + + return 0; +} + 80031a0: 4620 mov r0, r4 + 80031a2: b02d add sp, #180 ; 0xb4 + 80031a4: bdf0 pop {r4, r5, r6, r7, pc} + +080031a6 : +{ + 80031a6: b570 push {r4, r5, r6, lr} + ae_send(OP_Counter, 0x0, counter_number); + 80031a8: 460a mov r2, r1 +{ + 80031aa: b088 sub sp, #32 + 80031ac: 4606 mov r6, r0 + 80031ae: 460d mov r5, r1 + ae_send(OP_Counter, 0x0, counter_number); + 80031b0: 2024 movs r0, #36 ; 0x24 + 80031b2: 2100 movs r1, #0 + 80031b4: f7ff fcc3 bl 8002b3e + int rv = ae_read_n(4, (uint8_t *)result); + 80031b8: 4631 mov r1, r6 + 80031ba: 2004 movs r0, #4 + 80031bc: f7ff fc52 bl 8002a64 + RET_IF_BAD(rv); + 80031c0: 4604 mov r4, r0 + 80031c2: b960 cbnz r0, 80031de + rv = ae_gendig_counter(counter_number, *result, digest); + 80031c4: 6831 ldr r1, [r6, #0] + 80031c6: 466a mov r2, sp + 80031c8: 4628 mov r0, r5 + 80031ca: f7ff ff90 bl 80030ee + RET_IF_BAD(rv); + 80031ce: 4604 mov r4, r0 + 80031d0: b928 cbnz r0, 80031de + if(!ae_is_correct_tempkey(digest)) { + 80031d2: 4668 mov r0, sp + 80031d4: f7ff fd1c bl 8002c10 + 80031d8: b908 cbnz r0, 80031de + fatal_mitm(); + 80031da: f7fd fc3f bl 8000a5c +} + 80031de: 4620 mov r0, r4 + 80031e0: b008 add sp, #32 + 80031e2: bd70 pop {r4, r5, r6, pc} + +080031e4 : +{ + 80031e4: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 80031e8: 4606 mov r6, r0 + 80031ea: b089 sub sp, #36 ; 0x24 + 80031ec: 460d mov r5, r1 + 80031ee: 4617 mov r7, r2 + for(int i=0; i + int rv = ae_gendig_counter(counter_number, *result, digest); + 80031fc: 6831 ldr r1, [r6, #0] + 80031fe: 466a mov r2, sp + 8003200: 4628 mov r0, r5 + 8003202: f7ff ff74 bl 80030ee + RET_IF_BAD(rv); + 8003206: 4604 mov r4, r0 + 8003208: b998 cbnz r0, 8003232 + if(!ae_is_correct_tempkey(digest)) { + 800320a: 4668 mov r0, sp + 800320c: f7ff fd00 bl 8002c10 + 8003210: b978 cbnz r0, 8003232 + fatal_mitm(); + 8003212: f7fd fc23 bl 8000a5c + ae_send(OP_Counter, 0x1, counter_number); + 8003216: 464a mov r2, r9 + 8003218: 2101 movs r1, #1 + 800321a: 2024 movs r0, #36 ; 0x24 + 800321c: f7ff fc8f bl 8002b3e + int rv = ae_read_n(4, (uint8_t *)result); + 8003220: 4631 mov r1, r6 + 8003222: 2004 movs r0, #4 + 8003224: f7ff fc1e bl 8002a64 + RET_IF_BAD(rv); + 8003228: 4604 mov r4, r0 + 800322a: b910 cbnz r0, 8003232 + for(int i=0; i +} + 8003232: 4620 mov r0, r4 + 8003234: b009 add sp, #36 ; 0x24 + 8003236: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + +0800323a : +// ae_encrypted_read32() +// + int +ae_encrypted_read32(int data_slot, int blk, + int read_kn, const uint8_t read_key[32], uint8_t data[32]) +{ + 800323a: b5f0 push {r4, r5, r6, r7, lr} + 800323c: b08b sub sp, #44 ; 0x2c + 800323e: 4617 mov r7, r2 + 8003240: 460e mov r6, r1 + 8003242: 9d10 ldr r5, [sp, #64] ; 0x40 + 8003244: 9301 str r3, [sp, #4] + 8003246: 4604 mov r4, r0 + uint8_t digest[32]; + + ae_pair_unlock(); + 8003248: f7ff fdb2 bl 8002db0 + + int rv = ae_gendig_slot(read_kn, read_key, digest); + 800324c: 9901 ldr r1, [sp, #4] + 800324e: aa02 add r2, sp, #8 + 8003250: 4638 mov r0, r7 + 8003252: f7ff fecd bl 8002ff0 + RET_IF_BAD(rv); + 8003256: b9c0 cbnz r0, 800328a + + // read nth 32-byte "block" + ae_send(OP_Read, 0x82, (blk << 8) | (data_slot<<3)); + 8003258: 00e4 lsls r4, r4, #3 + 800325a: ea44 2206 orr.w r2, r4, r6, lsl #8 + 800325e: 2182 movs r1, #130 ; 0x82 + 8003260: 2002 movs r0, #2 + 8003262: b292 uxth r2, r2 + 8003264: f7ff fc6b bl 8002b3e + + rv = ae_read_n(32, data); + 8003268: 4629 mov r1, r5 + 800326a: 2020 movs r0, #32 + 800326c: f7ff fbfa bl 8002a64 + RET_IF_BAD(rv); + 8003270: b958 cbnz r0, 800328a + 8003272: 1e6a subs r2, r5, #1 + 8003274: ab02 add r3, sp, #8 + 8003276: 351f adds r5, #31 + *(acc) ^= *(more); + 8003278: f812 1f01 ldrb.w r1, [r2, #1]! + 800327c: f813 4b01 ldrb.w r4, [r3], #1 + for(; len; len--, more++, acc++) { + 8003280: 4295 cmp r5, r2 + *(acc) ^= *(more); + 8003282: ea81 0104 eor.w r1, r1, r4 + 8003286: 7011 strb r1, [r2, #0] + for(; len; len--, more++, acc++) { + 8003288: d1f6 bne.n 8003278 + + xor_mixin(data, digest, 32); + + return 0; +} + 800328a: b00b add sp, #44 ; 0x2c + 800328c: bdf0 pop {r4, r5, r6, r7, pc} + ... + +08003290 : + +// ae_encrypted_read() +// + int +ae_encrypted_read(int data_slot, int read_kn, const uint8_t read_key[32], uint8_t *data, int len) +{ + 8003290: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8003294: b08b sub sp, #44 ; 0x2c + 8003296: 4607 mov r7, r0 + 8003298: 9d12 ldr r5, [sp, #72] ; 0x48 + // not clear if chip supports 4-byte encrypted reads + ASSERT((len == 32) || (len == 72)); + 800329a: 2d20 cmp r5, #32 +{ + 800329c: 4688 mov r8, r1 + 800329e: 4691 mov r9, r2 + 80032a0: 461e mov r6, r3 + ASSERT((len == 32) || (len == 72)); + 80032a2: d004 beq.n 80032ae + 80032a4: 2d48 cmp r5, #72 ; 0x48 + 80032a6: d002 beq.n 80032ae + 80032a8: 4815 ldr r0, [pc, #84] ; (8003300 ) + 80032aa: f7fd fbcd bl 8000a48 + + int rv = ae_encrypted_read32(data_slot, 0, read_kn, read_key, data); + 80032ae: 9600 str r6, [sp, #0] + 80032b0: 464b mov r3, r9 + 80032b2: 4642 mov r2, r8 + 80032b4: 2100 movs r1, #0 + 80032b6: 4638 mov r0, r7 + 80032b8: f7ff ffbf bl 800323a + RET_IF_BAD(rv); + 80032bc: 4604 mov r4, r0 + 80032be: b9d0 cbnz r0, 80032f6 + + if(len == 32) return 0; + 80032c0: 2d20 cmp r5, #32 + 80032c2: d018 beq.n 80032f6 + + rv = ae_encrypted_read32(data_slot, 1, read_kn, read_key, data+32); + 80032c4: f106 0320 add.w r3, r6, #32 + 80032c8: 9300 str r3, [sp, #0] + 80032ca: 4642 mov r2, r8 + 80032cc: 464b mov r3, r9 + 80032ce: 2101 movs r1, #1 + 80032d0: 4638 mov r0, r7 + 80032d2: f7ff ffb2 bl 800323a + RET_IF_BAD(rv); + 80032d6: 4604 mov r4, r0 + 80032d8: b968 cbnz r0, 80032f6 + + uint8_t tmp[32]; + rv = ae_encrypted_read32(data_slot, 2, read_kn, read_key, tmp); + 80032da: ad02 add r5, sp, #8 + 80032dc: 9500 str r5, [sp, #0] + 80032de: 464b mov r3, r9 + 80032e0: 4642 mov r2, r8 + 80032e2: 2102 movs r1, #2 + 80032e4: 4638 mov r0, r7 + 80032e6: f7ff ffa8 bl 800323a + RET_IF_BAD(rv); + 80032ea: 4604 mov r4, r0 + 80032ec: b918 cbnz r0, 80032f6 + + memcpy(data+64, tmp, 72-64); + 80032ee: 462a mov r2, r5 + 80032f0: ca03 ldmia r2!, {r0, r1} + 80032f2: 6430 str r0, [r6, #64] ; 0x40 + 80032f4: 6471 str r1, [r6, #68] ; 0x44 + + return 0; +} + 80032f6: 4620 mov r0, r4 + 80032f8: b00b add sp, #44 ; 0x2c + 80032fa: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 80032fe: bf00 nop + 8003300: 0800e3e0 .word 0x0800e3e0 + +08003304 : +// ae_encrypted_write() +// + int +ae_encrypted_write32(int data_slot, int blk, int write_kn, + const uint8_t write_key[32], const uint8_t data[32]) +{ + 8003304: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8003308: b0b8 sub sp, #224 ; 0xe0 + 800330a: 4617 mov r7, r2 + 800330c: 460d mov r5, r1 + 800330e: 9e3e ldr r6, [sp, #248] ; 0xf8 + 8003310: 9303 str r3, [sp, #12] + 8003312: 4604 mov r4, r0 + uint8_t digest[32]; + + ae_pair_unlock(); + 8003314: f7ff fd4c bl 8002db0 + + // generate a hash over shared secret and rng + int rv = ae_gendig_slot(write_kn, write_key, digest); + 8003318: 9903 ldr r1, [sp, #12] + 800331a: aa0d add r2, sp, #52 ; 0x34 + 800331c: 4638 mov r0, r7 + 800331e: f7ff fe67 bl 8002ff0 + RET_IF_BAD(rv); + 8003322: 2800 cmp r0, #0 + 8003324: d151 bne.n 80033ca + 8003326: 1e72 subs r2, r6, #1 + 8003328: af0d add r7, sp, #52 ; 0x34 + 800332a: a915 add r1, sp, #84 ; 0x54 + 800332c: f106 0c1f add.w ip, r6, #31 + + // encrypt the data to be written, and append an authenticating MAC + uint8_t body[32 + 32]; + + for(int i=0; i<32; i++) { + body[i] = data[i] ^ digest[i]; + 8003330: f812 ef01 ldrb.w lr, [r2, #1]! + 8003334: f817 0b01 ldrb.w r0, [r7], #1 + for(int i=0; i<32; i++) { + 8003338: 4562 cmp r2, ip + body[i] = data[i] ^ digest[i]; + 800333a: ea80 000e eor.w r0, r0, lr + 800333e: f801 0b01 strb.w r0, [r1], #1 + for(int i=0; i<32; i++) { + 8003342: d1f5 bne.n 8003330 + // + (b'\0'*25) + // + new_value) + // assert len(msg) == 32+1+1+2+1+2+25+32 + // + SHA256_CTX ctx; + sha256_init(&ctx); + 8003344: a825 add r0, sp, #148 ; 0x94 + 8003346: f002 f8a1 bl 800548c + + uint8_t p1 = 0x80|2; // 32 bytes into a data slot + uint8_t p2_lsb = (data_slot << 3); + uint8_t p2_msb = blk; + + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 800334a: 22ee movs r2, #238 ; 0xee + 800334c: f88d 2014 strb.w r2, [sp, #20] + 8003350: 2201 movs r2, #1 + 8003352: f88d 2015 strb.w r2, [sp, #21] + uint8_t p2_lsb = (data_slot << 3); + 8003356: 00e4 lsls r4, r4, #3 + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 8003358: 2223 movs r2, #35 ; 0x23 + uint8_t zeros[25] = { 0 }; + 800335a: 2100 movs r1, #0 + uint8_t p2_lsb = (data_slot << 3); + 800335c: b2e4 uxtb r4, r4 + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 800335e: 2712 movs r7, #18 + 8003360: f04f 0882 mov.w r8, #130 ; 0x82 + 8003364: f88d 2016 strb.w r2, [sp, #22] + uint8_t zeros[25] = { 0 }; + 8003368: a807 add r0, sp, #28 + 800336a: 2215 movs r2, #21 + 800336c: 9106 str r1, [sp, #24] + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 800336e: f88d 7010 strb.w r7, [sp, #16] + 8003372: f88d 8011 strb.w r8, [sp, #17] + 8003376: f88d 4012 strb.w r4, [sp, #18] + uint8_t p2_msb = blk; + 800337a: f88d 5013 strb.w r5, [sp, #19] + uint8_t zeros[25] = { 0 }; + 800337e: f00a f979 bl 800d674 + + sha256_update(&ctx, digest, 32); + 8003382: 2220 movs r2, #32 + 8003384: a90d add r1, sp, #52 ; 0x34 + 8003386: a825 add r0, sp, #148 ; 0x94 + 8003388: f002 f88e bl 80054a8 + sha256_update(&ctx, args, sizeof(args)); + 800338c: 2207 movs r2, #7 + 800338e: a904 add r1, sp, #16 + 8003390: a825 add r0, sp, #148 ; 0x94 + 8003392: f002 f889 bl 80054a8 + sha256_update(&ctx, zeros, sizeof(zeros)); + 8003396: 2219 movs r2, #25 + 8003398: a906 add r1, sp, #24 + 800339a: a825 add r0, sp, #148 ; 0x94 + 800339c: f002 f884 bl 80054a8 + sha256_update(&ctx, data, 32); + 80033a0: 2220 movs r2, #32 + 80033a2: 4631 mov r1, r6 + 80033a4: a825 add r0, sp, #148 ; 0x94 + 80033a6: f002 f87f bl 80054a8 + + sha256_final(&ctx, &body[32]); + 80033aa: a91d add r1, sp, #116 ; 0x74 + 80033ac: a825 add r0, sp, #148 ; 0x94 + 80033ae: f002 f8c1 bl 8005534 + + ae_send_n(OP_Write, p1, (p2_msb << 8) | p2_lsb, body, sizeof(body)); + 80033b2: 2140 movs r1, #64 ; 0x40 + 80033b4: ea44 2205 orr.w r2, r4, r5, lsl #8 + 80033b8: b292 uxth r2, r2 + 80033ba: 9100 str r1, [sp, #0] + 80033bc: ab15 add r3, sp, #84 ; 0x54 + 80033be: 4641 mov r1, r8 + 80033c0: 4638 mov r0, r7 + 80033c2: f7ff fb89 bl 8002ad8 + + return ae_read1(); + 80033c6: f7ff fb31 bl 8002a2c +} + 80033ca: b038 add sp, #224 ; 0xe0 + 80033cc: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +080033d0 : +// ae_encrypted_write() +// + int +ae_encrypted_write(int data_slot, int write_kn, const uint8_t write_key[32], + const uint8_t *data, int len) +{ + 80033d0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80033d4: b08a sub sp, #40 ; 0x28 + ASSERT(data_slot >= 0); + ASSERT(data_slot <= 15); + 80033d6: 280f cmp r0, #15 +{ + 80033d8: 9d12 ldr r5, [sp, #72] ; 0x48 + 80033da: 4606 mov r6, r0 + 80033dc: 460f mov r7, r1 + 80033de: 4690 mov r8, r2 + 80033e0: 4699 mov r9, r3 + ASSERT(data_slot <= 15); + 80033e2: d902 bls.n 80033ea + ASSERT(data_slot >= 0); + 80033e4: 4814 ldr r0, [pc, #80] ; (8003438 ) + 80033e6: f7fd fb2f bl 8000a48 + + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 80033ea: 2400 movs r4, #0 + int here = MIN(32, len); + + // be nice and don't read past end of input buffer + uint8_t tmp[32] = { 0 }; + 80033ec: 46a2 mov sl, r4 + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 80033ee: 2d00 cmp r5, #0 + 80033f0: dd1d ble.n 800342e + uint8_t tmp[32] = { 0 }; + 80033f2: 221c movs r2, #28 + 80033f4: 2100 movs r1, #0 + 80033f6: a803 add r0, sp, #12 + 80033f8: f8cd a008 str.w sl, [sp, #8] + 80033fc: f00a f93a bl 800d674 + memcpy(tmp, data+(32*blk), here); + 8003400: ab02 add r3, sp, #8 + 8003402: 2d20 cmp r5, #32 + 8003404: 462a mov r2, r5 + 8003406: eb09 1144 add.w r1, r9, r4, lsl #5 + 800340a: bfa8 it ge + 800340c: 2220 movge r2, #32 + 800340e: 4618 mov r0, r3 + 8003410: f00a f908 bl 800d624 + + int rv = ae_encrypted_write32(data_slot, blk, write_kn, write_key, tmp); + 8003414: 4643 mov r3, r8 + 8003416: 9000 str r0, [sp, #0] + 8003418: 463a mov r2, r7 + 800341a: 4621 mov r1, r4 + 800341c: 4630 mov r0, r6 + 800341e: f7ff ff71 bl 8003304 + RET_IF_BAD(rv); + 8003422: b928 cbnz r0, 8003430 + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 8003424: 3401 adds r4, #1 + 8003426: 2c03 cmp r4, #3 + 8003428: f1a5 0520 sub.w r5, r5, #32 + 800342c: d1df bne.n 80033ee + } + + return 0; + 800342e: 2000 movs r0, #0 +} + 8003430: b00a add sp, #40 ; 0x28 + 8003432: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 8003436: bf00 nop + 8003438: 0800e3e0 .word 0x0800e3e0 + +0800343c : + +// ae_read_data_slot() +// + int +ae_read_data_slot(int slot_num, uint8_t *data, int len) +{ + 800343c: b570 push {r4, r5, r6, lr} + ASSERT((len == 4) || (len == 32) || (len == 72)); + 800343e: 2a04 cmp r2, #4 +{ + 8003440: b088 sub sp, #32 + 8003442: 460d mov r5, r1 + 8003444: 4616 mov r6, r2 + ASSERT((len == 4) || (len == 32) || (len == 72)); + 8003446: d006 beq.n 8003456 + 8003448: 2a20 cmp r2, #32 + 800344a: d038 beq.n 80034be + 800344c: 2a48 cmp r2, #72 ; 0x48 + 800344e: d036 beq.n 80034be + 8003450: 481c ldr r0, [pc, #112] ; (80034c4 ) + 8003452: f7fd faf9 bl 8000a48 + + // zone => data + // only reading first block of 32 bytes. ignore the rest + ae_send(OP_Read, (len == 4 ? 0x00 : 0x80) | 2, (slot_num<<3)); + 8003456: 2102 movs r1, #2 + 8003458: 00c4 lsls r4, r0, #3 + 800345a: b2a2 uxth r2, r4 + 800345c: 2002 movs r0, #2 + 800345e: f7ff fb6e bl 8002b3e + + int rv = ae_read_n((len == 4) ? 4 : 32, data); + 8003462: 2e04 cmp r6, #4 + 8003464: 4629 mov r1, r5 + 8003466: bf0c ite eq + 8003468: 2004 moveq r0, #4 + 800346a: 2020 movne r0, #32 + 800346c: f7ff fafa bl 8002a64 + RET_IF_BAD(rv); + 8003470: 4603 mov r3, r0 + 8003472: bb08 cbnz r0, 80034b8 + + if(len == 72) { + 8003474: 2e48 cmp r6, #72 ; 0x48 + 8003476: d11f bne.n 80034b8 + // read second block + ae_send(OP_Read, 0x82, (1<<8) | (slot_num<<3)); + 8003478: b224 sxth r4, r4 + 800347a: f444 7280 orr.w r2, r4, #256 ; 0x100 + 800347e: b292 uxth r2, r2 + 8003480: 2182 movs r1, #130 ; 0x82 + 8003482: 2002 movs r0, #2 + 8003484: f7ff fb5b bl 8002b3e + + int rv = ae_read_n(32, data+32); + 8003488: f105 0120 add.w r1, r5, #32 + 800348c: 2020 movs r0, #32 + 800348e: f7ff fae9 bl 8002a64 + RET_IF_BAD(rv); + 8003492: 4603 mov r3, r0 + 8003494: b980 cbnz r0, 80034b8 + + // read third block, but only using part of it + uint8_t tmp[32]; + ae_send(OP_Read, 0x82, (2<<8) | (slot_num<<3)); + 8003496: f444 7400 orr.w r4, r4, #512 ; 0x200 + 800349a: b2a2 uxth r2, r4 + 800349c: 2182 movs r1, #130 ; 0x82 + 800349e: 2002 movs r0, #2 + 80034a0: f7ff fb4d bl 8002b3e + + rv = ae_read_n(32, tmp); + 80034a4: 4669 mov r1, sp + 80034a6: 2020 movs r0, #32 + 80034a8: f7ff fadc bl 8002a64 + RET_IF_BAD(rv); + 80034ac: 4603 mov r3, r0 + 80034ae: b918 cbnz r0, 80034b8 + + memcpy(data+64, tmp, 72-64); + 80034b0: 466a mov r2, sp + 80034b2: ca03 ldmia r2!, {r0, r1} + 80034b4: 6428 str r0, [r5, #64] ; 0x40 + 80034b6: 6469 str r1, [r5, #68] ; 0x44 + } + + return 0; +} + 80034b8: 4618 mov r0, r3 + 80034ba: b008 add sp, #32 + 80034bc: bd70 pop {r4, r5, r6, pc} + ae_send(OP_Read, (len == 4 ? 0x00 : 0x80) | 2, (slot_num<<3)); + 80034be: 2182 movs r1, #130 ; 0x82 + 80034c0: e7ca b.n 8003458 + 80034c2: bf00 nop + 80034c4: 0800e3e0 .word 0x0800e3e0 + +080034c8 : + +// ae_set_gpio() +// + int +ae_set_gpio(int state) +{ + 80034c8: b513 push {r0, r1, r4, lr} + // 1=turn on green, 0=red light (if not yet configured to be secure) + ae_send(OP_Info, 3, 2 | (!!state)); + 80034ca: 1e04 subs r4, r0, #0 + 80034cc: bf14 ite ne + 80034ce: 2203 movne r2, #3 + 80034d0: 2202 moveq r2, #2 + 80034d2: 2103 movs r1, #3 + 80034d4: 2030 movs r0, #48 ; 0x30 + 80034d6: f7ff fb32 bl 8002b3e + + // "Always return the current state in the first byte followed by three bytes of 0x00" + // - simple 1/0, in LSB. + uint8_t resp[4]; + + int rv = ae_read_n(4, resp); + 80034da: a901 add r1, sp, #4 + 80034dc: 2004 movs r0, #4 + 80034de: f7ff fac1 bl 8002a64 + RET_IF_BAD(rv); + 80034e2: b928 cbnz r0, 80034f0 + + return (resp[0] != state) ? -1 : 0; + 80034e4: f89d 0004 ldrb.w r0, [sp, #4] + 80034e8: 1b00 subs r0, r0, r4 + 80034ea: bf18 it ne + 80034ec: f04f 30ff movne.w r0, #4294967295 ; 0xffffffff +} + 80034f0: b002 add sp, #8 + 80034f2: bd10 pop {r4, pc} + +080034f4 : +// +// Set the GPIO using secure hash generated somehow already. +// + int +ae_set_gpio_secure(uint8_t digest[32]) +{ + 80034f4: b538 push {r3, r4, r5, lr} + 80034f6: 4605 mov r5, r0 + ae_pair_unlock(); + 80034f8: f7ff fc5a bl 8002db0 + ae_checkmac(KEYNUM_firmware, digest); + 80034fc: 4629 mov r1, r5 + 80034fe: 200e movs r0, #14 + 8003500: f7ff fbd4 bl 8002cac + + int rv = ae_set_gpio(1); + 8003504: 2001 movs r0, #1 + 8003506: f7ff ffdf bl 80034c8 + + if(rv == 0) { + 800350a: 4604 mov r4, r0 + 800350c: b940 cbnz r0, 8003520 + // trust that readback, and so do a verify that the chip has + // the digest we think it does. If MitM wanted to turn off the output, + // they can do that anytime regardless. We just don't want them to be + // able to fake it being set, and therefore bypass the + // "unsigned firmware" delay and warning. + ae_pair_unlock(); + 800350e: f7ff fc4f bl 8002db0 + + if(ae_checkmac_hard(KEYNUM_firmware, digest) != 0) { + 8003512: 4629 mov r1, r5 + 8003514: 200e movs r0, #14 + 8003516: f7ff fdd9 bl 80030cc + 800351a: b108 cbz r0, 8003520 + fatal_mitm(); + 800351c: f7fd fa9e bl 8000a5c + } + } + + return rv; +} + 8003520: 4620 mov r0, r4 + 8003522: bd38 pop {r3, r4, r5, pc} + +08003524 : +// +// IMPORTANT: do not trust this result, could be MitM'ed. +// + uint8_t +ae_get_gpio(void) +{ + 8003524: b507 push {r0, r1, r2, lr} + // not doing error checking here + ae_send(OP_Info, 0x3, 0); + 8003526: 2200 movs r2, #0 + 8003528: 2103 movs r1, #3 + 800352a: 2030 movs r0, #48 ; 0x30 + 800352c: f7ff fb07 bl 8002b3e + + // note: always returns 4 bytes, but most are garbage and unused. + uint8_t tmp[4]; + ae_read_n(4, tmp); + 8003530: a901 add r1, sp, #4 + 8003532: 2004 movs r0, #4 + 8003534: f7ff fa96 bl 8002a64 + + return tmp[0]; +} + 8003538: f89d 0004 ldrb.w r0, [sp, #4] + 800353c: b003 add sp, #12 + 800353e: f85d fb04 ldr.w pc, [sp], #4 + +08003542 : +// +// Read a 4-byte area from config area, or -1 if fail. +// + int +ae_read_config_word(int offset, uint8_t *dest) +{ + 8003542: b510 push {r4, lr} + offset &= 0x7f; + + // read 32 bits (aligned) + ae_send(OP_Read, 0x00, offset/4); + 8003544: f3c0 0284 ubfx r2, r0, #2, #5 +{ + 8003548: 460c mov r4, r1 + ae_send(OP_Read, 0x00, offset/4); + 800354a: 2002 movs r0, #2 + 800354c: 2100 movs r1, #0 + 800354e: f7ff faf6 bl 8002b3e + + int rv = ae_read_n(4, dest); + 8003552: 4621 mov r1, r4 + 8003554: 2004 movs r0, #4 + 8003556: f7ff fa85 bl 8002a64 + if(rv) return -1; + 800355a: 3800 subs r0, #0 + 800355c: bf18 it ne + 800355e: 2001 movne r0, #1 + + return 0; +} + 8003560: 4240 negs r0, r0 + 8003562: bd10 pop {r4, pc} + +08003564 : +{ + 8003564: b513 push {r0, r1, r4, lr} + 8003566: 4604 mov r4, r0 + ae_read_config_word(offset, tmp); + 8003568: a901 add r1, sp, #4 + 800356a: f7ff ffea bl 8003542 + return tmp[offset % 4]; + 800356e: 4263 negs r3, r4 + 8003570: f003 0303 and.w r3, r3, #3 + 8003574: f004 0403 and.w r4, r4, #3 + 8003578: bf58 it pl + 800357a: 425c negpl r4, r3 + 800357c: f104 0308 add.w r3, r4, #8 + 8003580: eb0d 0403 add.w r4, sp, r3 +} + 8003584: f814 0c04 ldrb.w r0, [r4, #-4] + 8003588: b002 add sp, #8 + 800358a: bd10 pop {r4, pc} + +0800358c : + +// ae_destroy_key() +// + int +ae_destroy_key(int keynum) +{ + 800358c: b510 push {r4, lr} + 800358e: b090 sub sp, #64 ; 0x40 + uint8_t numin[20]; + + // Load tempkey with a known (random) nonce value + rng_buffer(numin, sizeof(numin)); + 8003590: 2114 movs r1, #20 +{ + 8003592: 4604 mov r4, r0 + rng_buffer(numin, sizeof(numin)); + 8003594: a803 add r0, sp, #12 + 8003596: f7ff f8db bl 8002750 + ae_send_n(OP_Nonce, 0, 0, numin, 20); + 800359a: 2314 movs r3, #20 + 800359c: 2200 movs r2, #0 + 800359e: 9300 str r3, [sp, #0] + 80035a0: 4611 mov r1, r2 + 80035a2: 2016 movs r0, #22 + 80035a4: ab03 add r3, sp, #12 + 80035a6: f7ff fa97 bl 8002ad8 + + // Nonce command returns the RNG result, not contents of TempKey, + // but since we are destroying, no need to calculate what it is. + uint8_t randout[32]; + int rv = ae_read_n(32, randout); + 80035aa: a908 add r1, sp, #32 + 80035ac: 2020 movs r0, #32 + 80035ae: f7ff fa59 bl 8002a64 + RET_IF_BAD(rv); + 80035b2: b930 cbnz r0, 80035c2 + + // do a "DeriveKey" operation, based on that! + ae_send(OP_DeriveKey, 0x00, keynum); + 80035b4: 4601 mov r1, r0 + 80035b6: b2a2 uxth r2, r4 + 80035b8: 201c movs r0, #28 + 80035ba: f7ff fac0 bl 8002b3e + + return ae_read1(); + 80035be: f7ff fa35 bl 8002a2c +} + 80035c2: b010 add sp, #64 ; 0x40 + 80035c4: bd10 pop {r4, pc} + +080035c6 : + +// ae_config_read() +// + int +ae_config_read(uint8_t config[128]) +{ + 80035c6: b538 push {r3, r4, r5, lr} + 80035c8: 4605 mov r5, r0 + for(int blk=0; blk<4; blk++) { + 80035ca: 2400 movs r4, #0 + // read 32 bytes (aligned) from config "zone" + ae_send(OP_Read, 0x80, blk<<3); + 80035cc: 00e2 lsls r2, r4, #3 + 80035ce: 2180 movs r1, #128 ; 0x80 + 80035d0: 2002 movs r0, #2 + 80035d2: b292 uxth r2, r2 + 80035d4: f7ff fab3 bl 8002b3e + + int rv = ae_read_n(32, &config[32*blk]); + 80035d8: eb05 1144 add.w r1, r5, r4, lsl #5 + 80035dc: 2020 movs r0, #32 + 80035de: f7ff fa41 bl 8002a64 + if(rv) return EIO; + 80035e2: b918 cbnz r0, 80035ec + for(int blk=0; blk<4; blk++) { + 80035e4: 3401 adds r4, #1 + 80035e6: 2c04 cmp r4, #4 + 80035e8: d1f0 bne.n 80035cc + } + + return 0; +} + 80035ea: bd38 pop {r3, r4, r5, pc} + if(rv) return EIO; + 80035ec: 2005 movs r0, #5 + 80035ee: e7fc b.n 80035ea + +080035f0 : +// us to write the (existing) pairing secret into, they would see the pairing +// secret in cleartext. They could then restore original chip and access freely. +// + int +ae_setup_config(void) +{ + 80035f0: b5f0 push {r4, r5, r6, r7, lr} + 80035f2: 2405 movs r4, #5 + 80035f4: f5ad 7d41 sub.w sp, sp, #772 ; 0x304 + // Need to wake up AE, since many things happen before this point. + for(int retry=0; retry<5; retry++) { + if(!ae_probe()) break; + 80035f8: f7ff fc6c bl 8002ed4 + 80035fc: b108 cbz r0, 8003602 + for(int retry=0; retry<5; retry++) { + 80035fe: 3c01 subs r4, #1 + 8003600: d1fa bne.n 80035f8 + // Is data zone is locked? + // Allow rest of function to happen if it's not. + +#if 1 + // 0x55 = unlocked; 0x00 = locked + bool data_locked = (ae_read_config_byte(86) != 0x55); + 8003602: 2056 movs r0, #86 ; 0x56 + 8003604: f7ff ffae bl 8003564 + if(data_locked) return 0; // basically success + 8003608: 2855 cmp r0, #85 ; 0x55 + 800360a: f040 80df bne.w 80037cc + + // To lock, we need a CRC over whole thing, but we + // only set a few values... plus the serial number is + // in there, so start with some readout. + uint8_t config[128]; + int rv = ae_config_read(config); + 800360e: a838 add r0, sp, #224 ; 0xe0 + 8003610: f7ff ffd9 bl 80035c6 + if(rv) return rv; + 8003614: 4604 mov r4, r0 + 8003616: 2800 cmp r0, #0 + 8003618: f040 80d9 bne.w 80037ce + uint8_t config[128]; + while(ae_config_read(config)) ; +#endif + + // verify some fixed values + ASSERT(config[0] == 0x01); + 800361c: f89d 30e0 ldrb.w r3, [sp, #224] ; 0xe0 + 8003620: 2b01 cmp r3, #1 + 8003622: d002 beq.n 800362a + 8003624: 486f ldr r0, [pc, #444] ; (80037e4 ) + + ae_keep_alive(); + + // lock config zone + if(ae_lock_config_zone(config)) { + INCONSISTENT("conf lock"); + 8003626: f7fd fa0f bl 8000a48 + ASSERT(config[1] == 0x23); + 800362a: f89d 30e1 ldrb.w r3, [sp, #225] ; 0xe1 + 800362e: 2b23 cmp r3, #35 ; 0x23 + 8003630: d1f8 bne.n 8003624 + ASSERT(config[12] == 0xee); + 8003632: f89d 30ec ldrb.w r3, [sp, #236] ; 0xec + 8003636: 2bee cmp r3, #238 ; 0xee + 8003638: d1f4 bne.n 8003624 + int8_t partno = ((config[6]>>4)&0xf); + 800363a: f89d 30e6 ldrb.w r3, [sp, #230] ; 0xe6 + ASSERT(partno == 6); + 800363e: 091b lsrs r3, r3, #4 + 8003640: 2b06 cmp r3, #6 + 8003642: d1ef bne.n 8003624 + memcpy(serial, &config[0], 4); + 8003644: 9b38 ldr r3, [sp, #224] ; 0xe0 + 8003646: 9303 str r3, [sp, #12] + memcpy(&serial[4], &config[8], 5); + 8003648: ab3a add r3, sp, #232 ; 0xe8 + 800364a: e893 0003 ldmia.w r3, {r0, r1} + 800364e: 9004 str r0, [sp, #16] + 8003650: f88d 1014 strb.w r1, [sp, #20] + if(check_all_ones(rom_secrets->ae_serial_number, 9)) { + 8003654: 4864 ldr r0, [pc, #400] ; (80037e8 ) + 8003656: 2109 movs r1, #9 + 8003658: f7ff f812 bl 8002680 + 800365c: b110 cbz r0, 8003664 + flash_save_ae_serial(serial); + 800365e: a803 add r0, sp, #12 + 8003660: f7fe fd66 bl 8002130 + if(!check_equal(rom_secrets->ae_serial_number, serial, 9)) { + 8003664: 4860 ldr r0, [pc, #384] ; (80037e8 ) + 8003666: 2209 movs r2, #9 + 8003668: a903 add r1, sp, #12 + 800366a: f7ff f822 bl 80026b2 + 800366e: 2800 cmp r0, #0 + 8003670: f000 80b6 beq.w 80037e0 + if(config[87] == 0x55) { + 8003674: f89d 3137 ldrb.w r3, [sp, #311] ; 0x137 + 8003678: 2b55 cmp r3, #85 ; 0x55 + 800367a: d12b bne.n 80036d4 + memcpy(&config[16], config_1, sizeof(config_1)); + 800367c: 495b ldr r1, [pc, #364] ; (80037ec ) + 800367e: 2244 movs r2, #68 ; 0x44 + 8003680: a83c add r0, sp, #240 ; 0xf0 + 8003682: f009 ffcf bl 800d624 + memcpy(&config[90], config_2, sizeof(config_2)); + 8003686: 4b5a ldr r3, [pc, #360] ; (80037f0 ) + 8003688: f50d 729d add.w r2, sp, #314 ; 0x13a + 800368c: f103 0124 add.w r1, r3, #36 ; 0x24 + 8003690: f853 0b04 ldr.w r0, [r3], #4 + 8003694: f842 0b04 str.w r0, [r2], #4 + 8003698: 428b cmp r3, r1 + 800369a: d1f9 bne.n 8003690 + 800369c: 881b ldrh r3, [r3, #0] + 800369e: 8013 strh r3, [r2, #0] + for(int n=16; n<128; n+= 4) { + 80036a0: 2510 movs r5, #16 + ae_send_n(OP_Write, 0, n/4, &config[n], 4); + 80036a2: 2604 movs r6, #4 + if(n == 84) continue; // that word not writable + 80036a4: 2d54 cmp r5, #84 ; 0x54 + 80036a6: d130 bne.n 800370a + for(int n=16; n<128; n+= 4) { + 80036a8: 3504 adds r5, #4 + 80036aa: 2d80 cmp r5, #128 ; 0x80 + 80036ac: d1fa bne.n 80036a4 + ae_send_idle(); + 80036ae: f7ff f90a bl 80028c6 + uint8_t crc[2] = {0, 0}; + 80036b2: 2600 movs r6, #0 + crc16_chain(128, config, crc); + 80036b4: aa58 add r2, sp, #352 ; 0x160 + 80036b6: a938 add r1, sp, #224 ; 0xe0 + 80036b8: 4628 mov r0, r5 + uint8_t crc[2] = {0, 0}; + 80036ba: f8ad 6160 strh.w r6, [sp, #352] ; 0x160 + crc16_chain(128, config, crc); + 80036be: f7ff f8b5 bl 800282c + ae_send(OP_Lock, 0x0, (crc[1]<<8) | crc[0]); + 80036c2: f8bd 2160 ldrh.w r2, [sp, #352] ; 0x160 + 80036c6: 4631 mov r1, r6 + 80036c8: 2017 movs r0, #23 + 80036ca: f7ff fa38 bl 8002b3e + return ae_read1(); + 80036ce: f7ff f9ad bl 8002a2c + if(ae_lock_config_zone(config)) { + 80036d2: bb38 cbnz r0, 8003724 + // Load data zone with some known values. + // The datazone still unlocked, so no encryption needed (nor possible). + + // will use zeros for all PIN codes, and customer-defined-secret starting values + uint8_t zeros[72]; + memset(zeros, 0, sizeof(zeros)); + 80036d4: 2248 movs r2, #72 ; 0x48 + 80036d6: 2100 movs r1, #0 + 80036d8: a826 add r0, sp, #152 ; 0x98 + 80036da: f009 ffcb bl 800d674 + se2_save_auth_pubkey(pubkey); + break; + } + + case 0: + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 80036de: 4e45 ldr r6, [pc, #276] ; (80037f4 ) + 80036e0: f8bd 5138 ldrh.w r5, [sp, #312] ; 0x138 + if(ae_write_data_slot(kn, rom_secrets->pairing_secret, 32, false)) { + 80036e4: 4f44 ldr r7, [pc, #272] ; (80037f8 ) + ae_send_idle(); + 80036e6: f7ff f8ee bl 80028c6 + if(!(unlocked & (1< + switch(kn) { + 80036f2: 2c0e cmp r4, #14 + 80036f4: d85c bhi.n 80037b0 + 80036f6: e8df f004 tbb [pc, r4] + 80036fa: 176e .short 0x176e + 80036fc: 29202920 .word 0x29202920 + 8003700: 2d304c3e .word 0x2d304c3e + 8003704: 2d2d2d2d .word 0x2d2d2d2d + 8003708: 29 .byte 0x29 + 8003709: 00 .byte 0x00 + ae_send_n(OP_Write, 0, n/4, &config[n], 4); + 800370a: ab38 add r3, sp, #224 ; 0xe0 + 800370c: 442b add r3, r5 + 800370e: f3c5 028f ubfx r2, r5, #2, #16 + 8003712: 2100 movs r1, #0 + 8003714: 2012 movs r0, #18 + 8003716: 9600 str r6, [sp, #0] + 8003718: f7ff f9de bl 8002ad8 + int rv = ae_read1(); + 800371c: f7ff f986 bl 8002a2c + if(rv) return rv; + 8003720: 2800 cmp r0, #0 + 8003722: d0c1 beq.n 80036a8 + INCONSISTENT("conf lock"); + 8003724: 4835 ldr r0, [pc, #212] ; (80037fc ) + 8003726: e77e b.n 8003626 + if(ae_write_data_slot(kn, rom_secrets->pairing_secret, 32, false)) { + 8003728: 2300 movs r3, #0 + 800372a: 2220 movs r2, #32 + 800372c: 4639 mov r1, r7 + 800372e: 2001 movs r0, #1 + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 8003730: f7ff fbf4 bl 8002f1c + 8003734: 2800 cmp r0, #0 + 8003736: d03b beq.n 80037b0 + 8003738: e7f4 b.n 8003724 + rng_buffer(tmp, sizeof(tmp)); + 800373a: 2120 movs r1, #32 + 800373c: a806 add r0, sp, #24 + 800373e: f7ff f807 bl 8002750 + if(ae_write_data_slot(kn, tmp, 32, true)) { + 8003742: 2301 movs r3, #1 + 8003744: 2220 movs r2, #32 + 8003746: a906 add r1, sp, #24 + if(ae_write_data_slot(kn, zeros, 32, false)) { + 8003748: 4620 mov r0, r4 + 800374a: e7f1 b.n 8003730 + 800374c: 2300 movs r3, #0 + 800374e: 2220 movs r2, #32 + 8003750: a926 add r1, sp, #152 ; 0x98 + 8003752: e7f9 b.n 8003748 + if(ae_write_data_slot(kn, zeros, 72, false)) { + 8003754: 2300 movs r3, #0 + 8003756: 2248 movs r2, #72 ; 0x48 + 8003758: e7fa b.n 8003750 + uint8_t long_zeros[416] = {0}; + 800375a: 2300 movs r3, #0 + 800375c: 4619 mov r1, r3 + 800375e: f44f 72ce mov.w r2, #412 ; 0x19c + 8003762: a859 add r0, sp, #356 ; 0x164 + 8003764: 9358 str r3, [sp, #352] ; 0x160 + 8003766: f009 ff85 bl 800d674 + if(ae_write_data_slot(kn, long_zeros, 416, false)) { + 800376a: 2300 movs r3, #0 + 800376c: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 8003770: a958 add r1, sp, #352 ; 0x160 + 8003772: 2008 movs r0, #8 + 8003774: e7dc b.n 8003730 + uint32_t buf[32/4] = { 1024, 1024 }; + 8003776: 2218 movs r2, #24 + 8003778: 2100 movs r1, #0 + 800377a: a810 add r0, sp, #64 ; 0x40 + 800377c: f009 ff7a bl 800d674 + 8003780: f44f 6380 mov.w r3, #1024 ; 0x400 + 8003784: e9cd 330e strd r3, r3, [sp, #56] ; 0x38 + if(ae_write_data_slot(KEYNUM_match_count, (const uint8_t *)buf,sizeof(buf),false)) { + 8003788: 2220 movs r2, #32 + 800378a: 2300 movs r3, #0 + 800378c: a90e add r1, sp, #56 ; 0x38 + 800378e: 2006 movs r0, #6 + 8003790: e7ce b.n 8003730 + if(ae_checkmac_hard(KEYNUM_main_pin, zeros) != 0) { + 8003792: a926 add r1, sp, #152 ; 0x98 + 8003794: 2003 movs r0, #3 + 8003796: f7ff fc99 bl 80030cc + 800379a: 2800 cmp r0, #0 + 800379c: d1c2 bne.n 8003724 + if(ae_gen_ecc_key(KEYNUM_joiner_key, pubkey)) { + 800379e: a916 add r1, sp, #88 ; 0x58 + 80037a0: 2007 movs r0, #7 + 80037a2: f7ff fb2b bl 8002dfc + 80037a6: 2800 cmp r0, #0 + 80037a8: d1bc bne.n 8003724 + se2_save_auth_pubkey(pubkey); + 80037aa: a816 add r0, sp, #88 ; 0x58 + 80037ac: f004 f932 bl 8007a14 + for(int kn=0; kn<16; kn++) { + 80037b0: 3401 adds r4, #1 + 80037b2: 2c10 cmp r4, #16 + 80037b4: d197 bne.n 80036e6 + ae_send_idle(); + 80037b6: f7ff f886 bl 80028c6 + ae_send(OP_Lock, 0x81, 0x0000); + 80037ba: 2200 movs r2, #0 + 80037bc: 2181 movs r1, #129 ; 0x81 + 80037be: 2017 movs r0, #23 + 80037c0: f7ff f9bd bl 8002b3e + return ae_read1(); + 80037c4: f7ff f932 bl 8002a2c + } + } + + // lock the data zone and effectively enter normal operation. + ae_keep_alive(); + if(ae_lock_data_zone()) { + 80037c8: 2800 cmp r0, #0 + 80037ca: d1ab bne.n 8003724 + if(data_locked) return 0; // basically success + 80037cc: 2400 movs r4, #0 + INCONSISTENT("data lock"); + } + + return 0; +} + 80037ce: 4620 mov r0, r4 + 80037d0: f50d 7d41 add.w sp, sp, #772 ; 0x304 + 80037d4: bdf0 pop {r4, r5, r6, r7, pc} + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 80037d6: 2301 movs r3, #1 + 80037d8: 2220 movs r2, #32 + 80037da: 4631 mov r1, r6 + 80037dc: 2000 movs r0, #0 + 80037de: e7a7 b.n 8003730 + return EPERM; + 80037e0: 2401 movs r4, #1 + 80037e2: e7f4 b.n 80037ce + 80037e4: 0800e3e0 .word 0x0800e3e0 + 80037e8: 0801c040 .word 0x0801c040 + 80037ec: 0800e68a .word 0x0800e68a + 80037f0: 0800e6ce .word 0x0800e6ce + 80037f4: 0800e646 .word 0x0800e646 + 80037f8: 0801c000 .word 0x0801c000 + 80037fc: 0800d700 .word 0x0800d700 + +08003800 : +// - but our time to do each iteration is limited by software SHA256 in ae_pair_unlock +// + int +ae_stretch_iter(const uint8_t start[32], uint8_t end[32], int iterations) +{ + ASSERT(start != end); // we can't work inplace + 8003800: 4288 cmp r0, r1 +{ + 8003802: b570 push {r4, r5, r6, lr} + 8003804: 460c mov r4, r1 + 8003806: 4615 mov r5, r2 + ASSERT(start != end); // we can't work inplace + 8003808: d102 bne.n 8003810 + 800380a: 4810 ldr r0, [pc, #64] ; (800384c ) + 800380c: f7fd f91c bl 8000a48 + memcpy(end, start, 32); + 8003810: 460b mov r3, r1 + 8003812: f100 0220 add.w r2, r0, #32 + 8003816: f850 1b04 ldr.w r1, [r0], #4 + 800381a: f843 1b04 str.w r1, [r3], #4 + 800381e: 4290 cmp r0, r2 + 8003820: d1f9 bne.n 8003816 + + for(int i=0; i + + int rv = ae_hmac32(KEYNUM_pin_stretch, end, end); + RET_IF_BAD(rv); + } + + return 0; + 8003828: 2000 movs r0, #0 +} + 800382a: bd70 pop {r4, r5, r6, pc} + if(ae_pair_unlock()) return -2; + 800382c: f7ff fac0 bl 8002db0 + 8003830: b940 cbnz r0, 8003844 + int rv = ae_hmac32(KEYNUM_pin_stretch, end, end); + 8003832: 4622 mov r2, r4 + 8003834: 4621 mov r1, r4 + 8003836: 2002 movs r0, #2 + 8003838: f7ff fb02 bl 8002e40 + RET_IF_BAD(rv); + 800383c: 2800 cmp r0, #0 + 800383e: d1f4 bne.n 800382a + for(int i=0; i + if(ae_pair_unlock()) return -2; + 8003844: f06f 0001 mvn.w r0, #1 + 8003848: e7ef b.n 800382a + 800384a: bf00 nop + 800384c: 0800e3e0 .word 0x0800e3e0 + +08003850 : +// Apply HMAC using secret in chip as a HMAC key, then encrypt +// the result a little because read in clear over bus. +// + int +ae_mixin_key(uint8_t keynum, const uint8_t start[32], uint8_t end[32]) +{ + 8003850: b570 push {r4, r5, r6, lr} + 8003852: b096 sub sp, #88 ; 0x58 + ASSERT(start != end); // we can't work inplace + 8003854: 4291 cmp r1, r2 +{ + 8003856: 460e mov r6, r1 + 8003858: 4614 mov r4, r2 + 800385a: f88d 0007 strb.w r0, [sp, #7] + ASSERT(start != end); // we can't work inplace + 800385e: d102 bne.n 8003866 + 8003860: 4818 ldr r0, [pc, #96] ; (80038c4 ) + 8003862: f7fd f8f1 bl 8000a48 + + if(ae_pair_unlock()) return -1; + 8003866: f7ff faa3 bl 8002db0 + 800386a: bb40 cbnz r0, 80038be + + ASSERT(keynum != 0); + 800386c: f89d 0007 ldrb.w r0, [sp, #7] + 8003870: 2800 cmp r0, #0 + 8003872: d0f5 beq.n 8003860 + int rv = ae_hmac32(keynum, start, end); + 8003874: 4622 mov r2, r4 + 8003876: 4631 mov r1, r6 + 8003878: f7ff fae2 bl 8002e40 + RET_IF_BAD(rv); + 800387c: 4605 mov r5, r0 + 800387e: b9d8 cbnz r0, 80038b8 + // use the value provided in cleartext[sic--it's not] write back shortly (to test it). + // Solution: one more SHA256, and to be safe, mixin lots of values! + + SHA256_CTX ctx; + + sha256_init(&ctx); + 8003880: a803 add r0, sp, #12 + 8003882: f001 fe03 bl 800548c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003886: 4910 ldr r1, [pc, #64] ; (80038c8 ) + 8003888: 2220 movs r2, #32 + 800388a: a803 add r0, sp, #12 + 800388c: f001 fe0c bl 80054a8 + sha256_update(&ctx, start, 32); + 8003890: 2220 movs r2, #32 + 8003892: 4631 mov r1, r6 + 8003894: a803 add r0, sp, #12 + 8003896: f001 fe07 bl 80054a8 + sha256_update(&ctx, &keynum, 1); + 800389a: 2201 movs r2, #1 + 800389c: f10d 0107 add.w r1, sp, #7 + 80038a0: a803 add r0, sp, #12 + 80038a2: f001 fe01 bl 80054a8 + sha256_update(&ctx, end, 32); + 80038a6: 4621 mov r1, r4 + 80038a8: a803 add r0, sp, #12 + 80038aa: 2220 movs r2, #32 + 80038ac: f001 fdfc bl 80054a8 + sha256_final(&ctx, end); + 80038b0: 4621 mov r1, r4 + 80038b2: a803 add r0, sp, #12 + 80038b4: f001 fe3e bl 8005534 + + return 0; +} + 80038b8: 4628 mov r0, r5 + 80038ba: b016 add sp, #88 ; 0x58 + 80038bc: bd70 pop {r4, r5, r6, pc} + if(ae_pair_unlock()) return -1; + 80038be: f04f 35ff mov.w r5, #4294967295 ; 0xffffffff + 80038c2: e7f9 b.n 80038b8 + 80038c4: 0800e3e0 .word 0x0800e3e0 + 80038c8: 0801c000 .word 0x0801c000 + +080038cc : +// Immediately destroy the pairing secret so that we become +// a useless brick. Ignore errors but retry. +// + void +ae_brick_myself(void) +{ + 80038cc: b510 push {r4, lr} + for(int retry=0; retry<10; retry++) { + 80038ce: 2400 movs r4, #0 + ae_reset_chip(); + 80038d0: f7ff f86a bl 80029a8 + + if(retry) rng_delay(); + 80038d4: b10c cbz r4, 80038da + 80038d6: f7fe ff51 bl 800277c + + ae_pair_unlock(); + 80038da: f7ff fa69 bl 8002db0 + + // Concern: MitM could block this by trashing our write + // - but they have to do it without causing CRC or other comm error + // - ten times + int rv = ae_destroy_key(KEYNUM_pairing); + 80038de: 2001 movs r0, #1 + 80038e0: f7ff fe54 bl 800358c + if(rv == 0) break; + 80038e4: b120 cbz r0, 80038f0 + for(int retry=0; retry<10; retry++) { + 80038e6: 3401 adds r4, #1 + + rng_delay(); + 80038e8: f7fe ff48 bl 800277c + for(int retry=0; retry<10; retry++) { + 80038ec: 2c0a cmp r4, #10 + 80038ee: d1ef bne.n 80038d0 + } + + ae_reset_chip(); +} + 80038f0: e8bd 4010 ldmia.w sp!, {r4, lr} + ae_reset_chip(); + 80038f4: f7ff b858 b.w 80029a8 + +080038f8 : +// + void +delay_ms(int ms) +{ + // Clear the COUNTFLAG and reset value to zero + SysTick->VAL = 0; + 80038f8: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 80038fc: 2200 movs r2, #0 + 80038fe: 619a str r2, [r3, #24] + //SysTick->CTRL; + + // Wait for ticks to happen + while(ms > 0) { + 8003900: 2800 cmp r0, #0 + 8003902: dc00 bgt.n 8003906 + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + ms--; + } + } +} + 8003904: 4770 bx lr + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8003906: 691a ldr r2, [r3, #16] + 8003908: 03d2 lsls r2, r2, #15 + ms--; + 800390a: bf48 it mi + 800390c: f100 30ff addmi.w r0, r0, #4294967295 ; 0xffffffff + 8003910: e7f6 b.n 8003900 + +08003912 : +// Replace HAL version which needs interrupts +// + void +HAL_Delay(uint32_t Delay) +{ + delay_ms(Delay); + 8003912: f7ff bff1 b.w 80038f8 + ... + +08003918 : + // NOTES: + // - try not to limit PCB changes for future revs; leave unused unchanged. + // - oled_setup() uses pins on PA4 thru PA8 + + // enable clock to GPIO's ... we will be using them all at some point + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003918: 4b39 ldr r3, [pc, #228] ; (8003a00 ) +{ + 800391a: b570 push {r4, r5, r6, lr} + __HAL_RCC_GPIOA_CLK_ENABLE(); + 800391c: 6cda ldr r2, [r3, #76] ; 0x4c + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + { // Onewire bus pins used for ATECC608 comms + GPIO_InitTypeDef setup = { + 800391e: 4c39 ldr r4, [pc, #228] ; (8003a04 ) + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003920: f042 0201 orr.w r2, r2, #1 + 8003924: 64da str r2, [r3, #76] ; 0x4c + 8003926: 6cda ldr r2, [r3, #76] ; 0x4c +{ + 8003928: b08a sub sp, #40 ; 0x28 + __HAL_RCC_GPIOA_CLK_ENABLE(); + 800392a: f002 0201 and.w r2, r2, #1 + 800392e: 9200 str r2, [sp, #0] + 8003930: 9a00 ldr r2, [sp, #0] + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8003932: 6cda ldr r2, [r3, #76] ; 0x4c + 8003934: f042 0202 orr.w r2, r2, #2 + 8003938: 64da str r2, [r3, #76] ; 0x4c + 800393a: 6cda ldr r2, [r3, #76] ; 0x4c + 800393c: f002 0202 and.w r2, r2, #2 + 8003940: 9201 str r2, [sp, #4] + 8003942: 9a01 ldr r2, [sp, #4] + __HAL_RCC_GPIOC_CLK_ENABLE(); + 8003944: 6cda ldr r2, [r3, #76] ; 0x4c + 8003946: f042 0204 orr.w r2, r2, #4 + 800394a: 64da str r2, [r3, #76] ; 0x4c + 800394c: 6cda ldr r2, [r3, #76] ; 0x4c + 800394e: f002 0204 and.w r2, r2, #4 + 8003952: 9202 str r2, [sp, #8] + 8003954: 9a02 ldr r2, [sp, #8] + __HAL_RCC_GPIOD_CLK_ENABLE(); + 8003956: 6cda ldr r2, [r3, #76] ; 0x4c + 8003958: f042 0208 orr.w r2, r2, #8 + 800395c: 64da str r2, [r3, #76] ; 0x4c + 800395e: 6cda ldr r2, [r3, #76] ; 0x4c + 8003960: f002 0208 and.w r2, r2, #8 + 8003964: 9203 str r2, [sp, #12] + 8003966: 9a03 ldr r2, [sp, #12] + __HAL_RCC_GPIOE_CLK_ENABLE(); + 8003968: 6cda ldr r2, [r3, #76] ; 0x4c + 800396a: f042 0210 orr.w r2, r2, #16 + 800396e: 64da str r2, [r3, #76] ; 0x4c + 8003970: 6cdb ldr r3, [r3, #76] ; 0x4c + 8003972: f003 0310 and.w r3, r3, #16 + 8003976: 9304 str r3, [sp, #16] + 8003978: 9b04 ldr r3, [sp, #16] + GPIO_InitTypeDef setup = { + 800397a: cc0f ldmia r4!, {r0, r1, r2, r3} + 800397c: ad05 add r5, sp, #20 + 800397e: c50f stmia r5!, {r0, r1, r2, r3} + 8003980: 6823 ldr r3, [r4, #0] + 8003982: 602b str r3, [r5, #0] + .Mode = GPIO_MODE_AF_OD, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = GPIO_AF8_UART4, + }; + HAL_GPIO_Init(ONEWIRE_PORT, &setup); + 8003984: a905 add r1, sp, #20 + 8003986: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 800398a: f7fd fb41 bl 8001010 + } + + // Bugfix: re-init of console port pins seems to wreck + // the mpy uart code, so avoid after first time. + if(USART1->BRR == 0) { + 800398e: 4b1e ldr r3, [pc, #120] ; (8003a08 ) + 8003990: 68de ldr r6, [r3, #12] + 8003992: b9ae cbnz r6, 80039c0 + // debug console: USART1 = PA9=Tx & PA10=Rx + GPIO_InitTypeDef setup = { + 8003994: 3404 adds r4, #4 + 8003996: cc0f ldmia r4!, {r0, r1, r2, r3} + 8003998: ad05 add r5, sp, #20 + 800399a: c50f stmia r5!, {r0, r1, r2, r3} + 800399c: 6823 ldr r3, [r4, #0] + 800399e: 602b str r3, [r5, #0] + .Mode = GPIO_MODE_AF_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = GPIO_AF7_USART1, + }; + HAL_GPIO_Init(GPIOA, &setup); + 80039a0: a905 add r1, sp, #20 + 80039a2: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 80039a6: f7fd fb33 bl 8001010 + + setup.Pin = GPIO_PIN_10; + 80039aa: f44f 6380 mov.w r3, #1024 ; 0x400 + setup.Mode = GPIO_MODE_INPUT; + 80039ae: e9cd 3605 strd r3, r6, [sp, #20] + setup.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOA, &setup); + 80039b2: a905 add r1, sp, #20 + setup.Pull = GPIO_PULLUP; + 80039b4: 2301 movs r3, #1 + HAL_GPIO_Init(GPIOA, &setup); + 80039b6: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + setup.Pull = GPIO_PULLUP; + 80039ba: 9307 str r3, [sp, #28] + HAL_GPIO_Init(GPIOA, &setup); + 80039bc: f7fd fb28 bl 8001010 + } + + // SD active LED: PC7 + // USB active LED: PC6 + { GPIO_InitTypeDef setup = { + 80039c0: 2400 movs r4, #0 + 80039c2: 26c0 movs r6, #192 ; 0xc0 + 80039c4: 2501 movs r5, #1 + .Pin = GPIO_PIN_7 | GPIO_PIN_6, + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOC, &setup); + 80039c6: a905 add r1, sp, #20 + 80039c8: 4810 ldr r0, [pc, #64] ; (8003a0c ) + { GPIO_InitTypeDef setup = { + 80039ca: 9409 str r4, [sp, #36] ; 0x24 + 80039cc: e9cd 4407 strd r4, r4, [sp, #28] + 80039d0: e9cd 6505 strd r6, r5, [sp, #20] + HAL_GPIO_Init(GPIOC, &setup); + 80039d4: f7fd fb1c bl 8001010 + + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_6, 0); // turn LEDs off + 80039d8: 4622 mov r2, r4 + 80039da: 4631 mov r1, r6 + 80039dc: 480b ldr r0, [pc, #44] ; (8003a0c ) + 80039de: f7fd fc91 bl 8001304 + } + + // SD card detect switch: PC13 + { GPIO_InitTypeDef setup = { + 80039e2: 2210 movs r2, #16 + 80039e4: 4621 mov r1, r4 + 80039e6: a806 add r0, sp, #24 + 80039e8: f009 fe44 bl 800d674 + 80039ec: f44f 5300 mov.w r3, #8192 ; 0x2000 + .Pin = GPIO_PIN_13, + .Mode = GPIO_MODE_INPUT, + .Pull = GPIO_PULLUP, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOC, &setup); + 80039f0: 4806 ldr r0, [pc, #24] ; (8003a0c ) + { GPIO_InitTypeDef setup = { + 80039f2: 9305 str r3, [sp, #20] + HAL_GPIO_Init(GPIOC, &setup); + 80039f4: a905 add r1, sp, #20 + { GPIO_InitTypeDef setup = { + 80039f6: 9507 str r5, [sp, #28] + HAL_GPIO_Init(GPIOC, &setup); + 80039f8: f7fd fb0a bl 8001010 + + // elsewhere... + //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1); + //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0); +#endif +} + 80039fc: b00a add sp, #40 ; 0x28 + 80039fe: bd70 pop {r4, r5, r6, pc} + 8003a00: 40021000 .word 0x40021000 + 8003a04: 0800e6f4 .word 0x0800e6f4 + 8003a08: 40013800 .word 0x40013800 + 8003a0c: 48000800 .word 0x48000800 + +08003a10 : + +// reboot_nonce() +// + static inline void +reboot_nonce(SHA256_CTX *ctx) +{ + 8003a10: b537 push {r0, r1, r2, r4, r5, lr} + uint32_t a = CRC->INIT; + 8003a12: 4d09 ldr r5, [pc, #36] ; (8003a38 ) + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003a14: 2204 movs r2, #4 + uint32_t a = CRC->INIT; + 8003a16: 692b ldr r3, [r5, #16] + 8003a18: 9301 str r3, [sp, #4] + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003a1a: eb0d 0102 add.w r1, sp, r2 +{ + 8003a1e: 4604 mov r4, r0 + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003a20: f001 fd42 bl 80054a8 + + a = CRC->POL; + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003a24: 2204 movs r2, #4 + a = CRC->POL; + 8003a26: 696b ldr r3, [r5, #20] + 8003a28: 9301 str r3, [sp, #4] + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003a2a: eb0d 0102 add.w r1, sp, r2 + 8003a2e: 4620 mov r0, r4 + 8003a30: f001 fd3a bl 80054a8 +} + 8003a34: b003 add sp, #12 + 8003a36: bd30 pop {r4, r5, pc} + 8003a38: 40023000 .word 0x40023000 + +08003a3c : +// +// Hash up a string of digits into 32-bytes of goodness. +// + static void +pin_hash(const char *pin, int pin_len, uint8_t result[32], uint32_t purpose) +{ + 8003a3c: b570 push {r4, r5, r6, lr} + 8003a3e: b096 sub sp, #88 ; 0x58 + ASSERT(pin_len <= MAX_PIN_LEN); + 8003a40: 2920 cmp r1, #32 +{ + 8003a42: 4606 mov r6, r0 + 8003a44: 460d mov r5, r1 + 8003a46: 4614 mov r4, r2 + 8003a48: 9301 str r3, [sp, #4] + ASSERT(pin_len <= MAX_PIN_LEN); + 8003a4a: dd02 ble.n 8003a52 + 8003a4c: 4817 ldr r0, [pc, #92] ; (8003aac ) + 8003a4e: f7fc fffb bl 8000a48 + + if(pin_len == 0) { + 8003a52: b929 cbnz r1, 8003a60 + // zero-length PIN is considered the "blank" one: all zero + memset(result, 0, 32); + 8003a54: 2220 movs r2, #32 + 8003a56: 4620 mov r0, r4 + 8003a58: f009 fe0c bl 800d674 + // and run that thru SE2 as well + se2_pin_hash(result, purpose); + + // and a second-sha256 on that, just in case. + sha256_single(result, 32, result); +} + 8003a5c: b016 add sp, #88 ; 0x58 + 8003a5e: bd70 pop {r4, r5, r6, pc} + sha256_init(&ctx); + 8003a60: a803 add r0, sp, #12 + 8003a62: f001 fd13 bl 800548c + sha256_update(&ctx, rom_secrets->hash_cache_secret, 32); + 8003a66: a803 add r0, sp, #12 + 8003a68: 4911 ldr r1, [pc, #68] ; (8003ab0 ) + 8003a6a: 2220 movs r2, #32 + 8003a6c: f001 fd1c bl 80054a8 + sha256_update(&ctx, (uint8_t *)&purpose, 4); + 8003a70: 2204 movs r2, #4 + 8003a72: eb0d 0102 add.w r1, sp, r2 + 8003a76: a803 add r0, sp, #12 + 8003a78: f001 fd16 bl 80054a8 + sha256_update(&ctx, (uint8_t *)pin, pin_len); + 8003a7c: 462a mov r2, r5 + 8003a7e: 4631 mov r1, r6 + 8003a80: a803 add r0, sp, #12 + 8003a82: f001 fd11 bl 80054a8 + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003a86: 2220 movs r2, #32 + 8003a88: a803 add r0, sp, #12 + 8003a8a: 490a ldr r1, [pc, #40] ; (8003ab4 ) + 8003a8c: f001 fd0c bl 80054a8 + sha256_final(&ctx, result); + 8003a90: 4621 mov r1, r4 + 8003a92: a803 add r0, sp, #12 + 8003a94: f001 fd4e bl 8005534 + se2_pin_hash(result, purpose); + 8003a98: 9901 ldr r1, [sp, #4] + 8003a9a: 4620 mov r0, r4 + 8003a9c: f004 fc32 bl 8008304 + sha256_single(result, 32, result); + 8003aa0: 4622 mov r2, r4 + 8003aa2: 2120 movs r1, #32 + 8003aa4: 4620 mov r0, r4 + 8003aa6: f001 fd59 bl 800555c + 8003aaa: e7d7 b.n 8003a5c + 8003aac: 0800e3e0 .word 0x0800e3e0 + 8003ab0: 0801c070 .word 0x0801c070 + 8003ab4: 0801c000 .word 0x0801c000 + +08003ab8 <_hmac_attempt>: +// +// Maybe should be proper HMAC from fips std? Can be changed later. +// + static void +_hmac_attempt(const pinAttempt_t *args, uint8_t result[32]) +{ + 8003ab8: b530 push {r4, r5, lr} + 8003aba: b095 sub sp, #84 ; 0x54 + 8003abc: 4604 mov r4, r0 + SHA256_CTX ctx; + + sha256_init(&ctx); + 8003abe: a801 add r0, sp, #4 +{ + 8003ac0: 460d mov r5, r1 + sha256_init(&ctx); + 8003ac2: f001 fce3 bl 800548c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003ac6: 4911 ldr r1, [pc, #68] ; (8003b0c <_hmac_attempt+0x54>) + 8003ac8: 2220 movs r2, #32 + 8003aca: a801 add r0, sp, #4 + 8003acc: f001 fcec bl 80054a8 + reboot_nonce(&ctx); + 8003ad0: a801 add r0, sp, #4 + 8003ad2: f7ff ff9d bl 8003a10 + sha256_update(&ctx, (uint8_t *)args, offsetof(pinAttempt_t, hmac)); + 8003ad6: 2244 movs r2, #68 ; 0x44 + 8003ad8: 4621 mov r1, r4 + 8003ada: a801 add r0, sp, #4 + 8003adc: f001 fce4 bl 80054a8 + + if(args->magic_value == PA_MAGIC_V2) { + 8003ae0: 6822 ldr r2, [r4, #0] + 8003ae2: 4b0b ldr r3, [pc, #44] ; (8003b10 <_hmac_attempt+0x58>) + 8003ae4: 429a cmp r2, r3 + 8003ae6: d105 bne.n 8003af4 <_hmac_attempt+0x3c> + sha256_update(&ctx, (uint8_t *)args->cached_main_pin, + 8003ae8: 2220 movs r2, #32 + 8003aea: f104 01f8 add.w r1, r4, #248 ; 0xf8 + 8003aee: a801 add r0, sp, #4 + 8003af0: f001 fcda bl 80054a8 + msizeof(pinAttempt_t, cached_main_pin)); + } + + sha256_final(&ctx, result); + 8003af4: 4629 mov r1, r5 + 8003af6: a801 add r0, sp, #4 + 8003af8: f001 fd1c bl 8005534 + + // and a second-sha256 on that, just in case. + sha256_single(result, 32, result); + 8003afc: 462a mov r2, r5 + 8003afe: 2120 movs r1, #32 + 8003b00: 4628 mov r0, r5 + 8003b02: f001 fd2b bl 800555c +} + 8003b06: b015 add sp, #84 ; 0x54 + 8003b08: bd30 pop {r4, r5, pc} + 8003b0a: bf00 nop + 8003b0c: 0801c000 .word 0x0801c000 + 8003b10: 2eaf6312 .word 0x2eaf6312 + +08003b14 <_validate_attempt>: + +// _validate_attempt() +// + static int +_validate_attempt(const pinAttempt_t *args, bool first_time) +{ + 8003b14: b510 push {r4, lr} + 8003b16: 4604 mov r4, r0 + 8003b18: b088 sub sp, #32 + if(first_time) { + 8003b1a: b969 cbnz r1, 8003b38 <_validate_attempt+0x24> + // no hmac needed for setup call + } else { + // if hmac is defined, better be right. + uint8_t actual[32]; + + _hmac_attempt(args, actual); + 8003b1c: 4669 mov r1, sp + 8003b1e: f7ff ffcb bl 8003ab8 <_hmac_attempt> + + if(!check_equal(actual, args->hmac, 32)) { + 8003b22: 2220 movs r2, #32 + 8003b24: f104 0144 add.w r1, r4, #68 ; 0x44 + 8003b28: 4668 mov r0, sp + 8003b2a: f7fe fdc2 bl 80026b2 + 8003b2e: b918 cbnz r0, 8003b38 <_validate_attempt+0x24> + // hmac is wrong? + return EPIN_HMAC_FAIL; + 8003b30: f06f 0063 mvn.w r0, #99 ; 0x63 + if((args->change_flags & CHANGE__MASK) != args->change_flags) return EPIN_RANGE_ERR; + + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + + return 0; +} + 8003b34: b008 add sp, #32 + 8003b36: bd10 pop {r4, pc} + if(args->magic_value == PA_MAGIC_V2) { + 8003b38: 6822 ldr r2, [r4, #0] + 8003b3a: 4b10 ldr r3, [pc, #64] ; (8003b7c <_validate_attempt+0x68>) + 8003b3c: 429a cmp r2, r3 + 8003b3e: d117 bne.n 8003b70 <_validate_attempt+0x5c> + if(args->pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003b40: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8003b42: 2b20 cmp r3, #32 + 8003b44: dc17 bgt.n 8003b76 <_validate_attempt+0x62> + if(args->old_pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003b46: f8d4 3088 ldr.w r3, [r4, #136] ; 0x88 + 8003b4a: 2b20 cmp r3, #32 + 8003b4c: dc13 bgt.n 8003b76 <_validate_attempt+0x62> + if(args->new_pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003b4e: f8d4 30ac ldr.w r3, [r4, #172] ; 0xac + 8003b52: 2b20 cmp r3, #32 + 8003b54: dc0f bgt.n 8003b76 <_validate_attempt+0x62> + if((args->change_flags & CHANGE__MASK) != args->change_flags) return EPIN_RANGE_ERR; + 8003b56: 6e63 ldr r3, [r4, #100] ; 0x64 + 8003b58: f640 727f movw r2, #3967 ; 0xf7f + 8003b5c: 4393 bics r3, r2 + 8003b5e: d10a bne.n 8003b76 <_validate_attempt+0x62> + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + 8003b60: 6863 ldr r3, [r4, #4] + return 0; + 8003b62: f033 0301 bics.w r3, r3, #1 + 8003b66: bf14 ite ne + 8003b68: f06f 0066 mvnne.w r0, #102 ; 0x66 + 8003b6c: 2000 moveq r0, #0 + 8003b6e: e7e1 b.n 8003b34 <_validate_attempt+0x20> + return EPIN_BAD_MAGIC; + 8003b70: f06f 0065 mvn.w r0, #101 ; 0x65 + 8003b74: e7de b.n 8003b34 <_validate_attempt+0x20> + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + 8003b76: f06f 0066 mvn.w r0, #102 ; 0x66 + 8003b7a: e7db b.n 8003b34 <_validate_attempt+0x20> + 8003b7c: 2eaf6312 .word 0x2eaf6312 + +08003b80 : + +// warmup_ae() +// + static int +warmup_ae(void) +{ + 8003b80: b510 push {r4, lr} + ae_setup(); + 8003b82: f7fe ff1f bl 80029c4 + 8003b86: 2405 movs r4, #5 + + for(int retry=0; retry<5; retry++) { + if(!ae_probe()) break; + 8003b88: f7ff f9a4 bl 8002ed4 + 8003b8c: b108 cbz r0, 8003b92 + for(int retry=0; retry<5; retry++) { + 8003b8e: 3c01 subs r4, #1 + 8003b90: d1fa bne.n 8003b88 + } + + if(ae_pair_unlock()) return -1; + 8003b92: f7ff f90d bl 8002db0 + 8003b96: 4604 mov r4, r0 + 8003b98: b918 cbnz r0, 8003ba2 + + // reset watchdog timer + ae_keep_alive(); + 8003b9a: f7fe ff45 bl 8002a28 + + return 0; +} + 8003b9e: 4620 mov r0, r4 + 8003ba0: bd10 pop {r4, pc} + if(ae_pair_unlock()) return -1; + 8003ba2: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 8003ba6: e7fa b.n 8003b9e + +08003ba8 <_read_slot_as_counter>: +{ + 8003ba8: b530 push {r4, r5, lr} + 8003baa: b091 sub sp, #68 ; 0x44 + uint32_t padded[32/4] = { 0 }; + 8003bac: 2220 movs r2, #32 +{ + 8003bae: 4604 mov r4, r0 + 8003bb0: 460d mov r5, r1 + uint32_t padded[32/4] = { 0 }; + 8003bb2: 4668 mov r0, sp + 8003bb4: 2100 movs r1, #0 + 8003bb6: f009 fd5d bl 800d674 + ae_pair_unlock(); + 8003bba: f7ff f8f9 bl 8002db0 + if(ae_read_data_slot(slot, (uint8_t *)padded, 32)) return -1; + 8003bbe: 2220 movs r2, #32 + 8003bc0: 4669 mov r1, sp + 8003bc2: 4620 mov r0, r4 + 8003bc4: f7ff fc3a bl 800343c + 8003bc8: b120 cbz r0, 8003bd4 <_read_slot_as_counter+0x2c> + 8003bca: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff +} + 8003bce: 4620 mov r0, r4 + 8003bd0: b011 add sp, #68 ; 0x44 + 8003bd2: bd30 pop {r4, r5, pc} + ae_pair_unlock(); + 8003bd4: f7ff f8ec bl 8002db0 + if(ae_gendig_slot(slot, (const uint8_t *)padded, tempkey)) return -1; + 8003bd8: 4620 mov r0, r4 + 8003bda: aa08 add r2, sp, #32 + 8003bdc: 4669 mov r1, sp + 8003bde: f7ff fa07 bl 8002ff0 + 8003be2: 4604 mov r4, r0 + 8003be4: 2800 cmp r0, #0 + 8003be6: d1f0 bne.n 8003bca <_read_slot_as_counter+0x22> + if(!ae_is_correct_tempkey(tempkey)) fatal_mitm(); + 8003be8: a808 add r0, sp, #32 + 8003bea: f7ff f811 bl 8002c10 + 8003bee: b908 cbnz r0, 8003bf4 <_read_slot_as_counter+0x4c> + 8003bf0: f7fc ff34 bl 8000a5c + *dest = padded[0]; + 8003bf4: 9b00 ldr r3, [sp, #0] + 8003bf6: 602b str r3, [r5, #0] + return 0; + 8003bf8: e7e9 b.n 8003bce <_read_slot_as_counter+0x26> + +08003bfa : +{ + 8003bfa: b530 push {r4, r5, lr} + 8003bfc: b095 sub sp, #84 ; 0x54 + 8003bfe: 4605 mov r5, r0 + ae_pair_unlock(); + 8003c00: f7ff f8d6 bl 8002db0 + uint32_t padded[32/4] = { 0 }; + 8003c04: 2220 movs r2, #32 + 8003c06: 2100 movs r1, #0 + 8003c08: a804 add r0, sp, #16 + 8003c0a: f009 fd33 bl 800d674 + if(ae_read_data_slot(slot, (uint8_t *)padded, 32)) return -1; + 8003c0e: 2220 movs r2, #32 + 8003c10: a904 add r1, sp, #16 + 8003c12: 2005 movs r0, #5 + 8003c14: f7ff fc12 bl 800343c + 8003c18: b118 cbz r0, 8003c22 + 8003c1a: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff +} + 8003c1e: b015 add sp, #84 ; 0x54 + 8003c20: bd30 pop {r4, r5, pc} + ae_pair_unlock(); + 8003c22: f7ff f8c5 bl 8002db0 + if(ae_gendig_slot(slot, (const uint8_t *)padded, tempkey)) return -1; + 8003c26: aa0c add r2, sp, #48 ; 0x30 + 8003c28: a904 add r1, sp, #16 + 8003c2a: 2005 movs r0, #5 + 8003c2c: f7ff f9e0 bl 8002ff0 + 8003c30: 4604 mov r4, r0 + 8003c32: 2800 cmp r0, #0 + 8003c34: d1f1 bne.n 8003c1a + if(!ae_is_correct_tempkey(tempkey)) fatal_mitm(); + 8003c36: a80c add r0, sp, #48 ; 0x30 + 8003c38: f7fe ffea bl 8002c10 + 8003c3c: b908 cbnz r0, 8003c42 + 8003c3e: f7fc ff0d bl 8000a5c + if(_read_slot_as_counter(KEYNUM_lastgood, &lastgood)) return -1; + 8003c42: a901 add r1, sp, #4 + 8003c44: 2005 movs r0, #5 + uint32_t lastgood=0, match_count=0, counter=0; + 8003c46: e9cd 4401 strd r4, r4, [sp, #4] + 8003c4a: 9403 str r4, [sp, #12] + if(_read_slot_as_counter(KEYNUM_lastgood, &lastgood)) return -1; + 8003c4c: f7ff ffac bl 8003ba8 <_read_slot_as_counter> + 8003c50: 2800 cmp r0, #0 + 8003c52: d1e2 bne.n 8003c1a + if(_read_slot_as_counter(KEYNUM_match_count, &match_count)) return -1; + 8003c54: a902 add r1, sp, #8 + 8003c56: 2006 movs r0, #6 + 8003c58: f7ff ffa6 bl 8003ba8 <_read_slot_as_counter> + 8003c5c: 4601 mov r1, r0 + 8003c5e: 2800 cmp r0, #0 + 8003c60: d1db bne.n 8003c1a + if(ae_get_counter(&counter, 0)) return -1; + 8003c62: a803 add r0, sp, #12 + 8003c64: f7ff fa9f bl 80031a6 + 8003c68: 2800 cmp r0, #0 + 8003c6a: d1d6 bne.n 8003c1a + if(lastgood > counter) { + 8003c6c: 9a01 ldr r2, [sp, #4] + 8003c6e: 9903 ldr r1, [sp, #12] + match_count &= ~31; + 8003c70: 9b02 ldr r3, [sp, #8] + if(lastgood > counter) { + 8003c72: 428a cmp r2, r1 + match_count &= ~31; + 8003c74: f023 031f bic.w r3, r3, #31 + args->num_fails = counter - lastgood; + 8003c78: bf94 ite ls + 8003c7a: 1a8a subls r2, r1, r2 + args->num_fails = 99; + 8003c7c: 2263 movhi r2, #99 ; 0x63 + if(counter < match_count) { + 8003c7e: 4299 cmp r1, r3 + args->attempts_left = match_count - counter; + 8003c80: bf34 ite cc + 8003c82: 1a5b subcc r3, r3, r1 + args->attempts_left = 0; + 8003c84: 2300 movcs r3, #0 + 8003c86: 636a str r2, [r5, #52] ; 0x34 + 8003c88: 63ab str r3, [r5, #56] ; 0x38 + 8003c8a: e7c8 b.n 8003c1e + +08003c8c : + +// updates_for_good_login() +// + static int +updates_for_good_login(uint8_t digest[32]) +{ + 8003c8c: b5f0 push {r4, r5, r6, r7, lr} + 8003c8e: b08d sub sp, #52 ; 0x34 + // User got the main PIN right: update the attempt counters, + // to document this (lastgood) and also bump the match counter if needed + + uint32_t count; + int rv = ae_get_counter(&count, 0); + 8003c90: 2100 movs r1, #0 +{ + 8003c92: 4606 mov r6, r0 + int rv = ae_get_counter(&count, 0); + 8003c94: a802 add r0, sp, #8 + 8003c96: f7ff fa86 bl 80031a6 + if(rv) goto fail; + 8003c9a: 4601 mov r1, r0 + 8003c9c: 2800 cmp r0, #0 + 8003c9e: d13b bne.n 8003d18 + + // Challenge: Have to update both the counter, and the target match value because + // no other way to have exact value. + + uint32_t mc = (count + MAX_TARGET_ATTEMPTS + 32) & ~31; + 8003ca0: 9b02 ldr r3, [sp, #8] + 8003ca2: f103 042d add.w r4, r3, #45 ; 0x2d + 8003ca6: f024 041f bic.w r4, r4, #31 + ASSERT(mc >= count); + 8003caa: 42a3 cmp r3, r4 + 8003cac: d902 bls.n 8003cb4 + 8003cae: 481d ldr r0, [pc, #116] ; (8003d24 ) + 8003cb0: f7fc feca bl 8000a48 + + int bump = (mc - MAX_TARGET_ATTEMPTS) - count; + 8003cb4: 1ae3 subs r3, r4, r3 + 8003cb6: f1a3 050d sub.w r5, r3, #13 + ASSERT(bump >= 1); + 8003cba: 3b0e subs r3, #14 + 8003cbc: 2b1f cmp r3, #31 + 8003cbe: d8f6 bhi.n 8003cae + // Would rather update the counter first, so that a hostile interruption can't increase + // attempts (altho the attacker knows the pin at that point?!) .. but chip won't + // let the counter go past the match value, so that has to be first. + + // set the new "match count" + { uint32_t tmp[32/4] = {mc, mc} ; + 8003cc0: 2218 movs r2, #24 + 8003cc2: eb0d 0002 add.w r0, sp, r2 + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003cc6: 2720 movs r7, #32 + { uint32_t tmp[32/4] = {mc, mc} ; + 8003cc8: f009 fcd4 bl 800d674 + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003ccc: 2103 movs r1, #3 + 8003cce: 9700 str r7, [sp, #0] + 8003cd0: ab04 add r3, sp, #16 + 8003cd2: 4632 mov r2, r6 + 8003cd4: 2006 movs r0, #6 + { uint32_t tmp[32/4] = {mc, mc} ; + 8003cd6: e9cd 4404 strd r4, r4, [sp, #16] + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003cda: f7ff fb79 bl 80033d0 + if(rv) goto fail; + 8003cde: 4601 mov r1, r0 + 8003ce0: b9d0 cbnz r0, 8003d18 + } + + // incr the counter a bunch to get to that-13 + uint32_t new_count = 0; + 8003ce2: 9003 str r0, [sp, #12] + rv = ae_add_counter(&new_count, 0, bump); + 8003ce4: 462a mov r2, r5 + 8003ce6: a803 add r0, sp, #12 + 8003ce8: f7ff fa7c bl 80031e4 + if(rv) goto fail; + 8003cec: 4601 mov r1, r0 + 8003cee: b998 cbnz r0, 8003d18 + + ASSERT(new_count == count + bump); + 8003cf0: 9b02 ldr r3, [sp, #8] + 8003cf2: 441d add r5, r3 + 8003cf4: 9b03 ldr r3, [sp, #12] + 8003cf6: 429d cmp r5, r3 + 8003cf8: d1d9 bne.n 8003cae + ASSERT(mc > new_count); + 8003cfa: 42a5 cmp r5, r4 + 8003cfc: d2d7 bcs.n 8003cae + + // Update the "last good" counter + { uint32_t tmp[32/4] = {new_count, 0 }; + 8003cfe: 221c movs r2, #28 + 8003d00: a805 add r0, sp, #20 + 8003d02: f009 fcb7 bl 800d674 + rv = ae_encrypted_write(KEYNUM_lastgood, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003d06: 9700 str r7, [sp, #0] + 8003d08: ab04 add r3, sp, #16 + 8003d0a: 4632 mov r2, r6 + 8003d0c: 2103 movs r1, #3 + 8003d0e: 2005 movs r0, #5 + { uint32_t tmp[32/4] = {new_count, 0 }; + 8003d10: 9504 str r5, [sp, #16] + rv = ae_encrypted_write(KEYNUM_lastgood, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003d12: f7ff fb5d bl 80033d0 + if(rv) goto fail; + 8003d16: b118 cbz r0, 8003d20 + // just be reducing attempts. + + return 0; + +fail: + ae_reset_chip(); + 8003d18: f7fe fe46 bl 80029a8 + return EPIN_AE_FAIL; + 8003d1c: f06f 0069 mvn.w r0, #105 ; 0x69 +} + 8003d20: b00d add sp, #52 ; 0x34 + 8003d22: bdf0 pop {r4, r5, r6, r7, pc} + 8003d24: 0800e3e0 .word 0x0800e3e0 + +08003d28 : +{ + 8003d28: b5f0 push {r4, r5, r6, r7, lr} + 8003d2a: 4615 mov r5, r2 + 8003d2c: b089 sub sp, #36 ; 0x24 + if(pin_len == 0) { + 8003d2e: 460c mov r4, r1 + 8003d30: b931 cbnz r1, 8003d40 + memset(result, 0, 32); + 8003d32: 2220 movs r2, #32 + 8003d34: 4628 mov r0, r5 + 8003d36: f009 fc9d bl 800d674 +} + 8003d3a: 4620 mov r0, r4 + 8003d3c: b009 add sp, #36 ; 0x24 + 8003d3e: bdf0 pop {r4, r5, r6, r7, pc} + pin_hash(pin, pin_len, tmp, PIN_PURPOSE_NORMAL); + 8003d40: 4b0f ldr r3, [pc, #60] ; (8003d80 ) + 8003d42: 466a mov r2, sp + 8003d44: f7ff fe7a bl 8003a3c + int rv = ae_stretch_iter(tmp, result, KDF_ITER_PIN); + 8003d48: 2208 movs r2, #8 + 8003d4a: 4629 mov r1, r5 + 8003d4c: 4668 mov r0, sp + 8003d4e: f7ff fd57 bl 8003800 + if(rv) return EPIN_AE_FAIL; + 8003d52: 4604 mov r4, r0 + 8003d54: b988 cbnz r0, 8003d7a + memcpy(tmp, result, 32); + 8003d56: 462b mov r3, r5 + 8003d58: 466e mov r6, sp + 8003d5a: f105 0720 add.w r7, r5, #32 + 8003d5e: 6818 ldr r0, [r3, #0] + 8003d60: 6859 ldr r1, [r3, #4] + 8003d62: 4632 mov r2, r6 + 8003d64: c203 stmia r2!, {r0, r1} + 8003d66: 3308 adds r3, #8 + 8003d68: 42bb cmp r3, r7 + 8003d6a: 4616 mov r6, r2 + 8003d6c: d1f7 bne.n 8003d5e + ae_mixin_key(KEYNUM_pin_attempt, tmp, result); + 8003d6e: 462a mov r2, r5 + 8003d70: 4669 mov r1, sp + 8003d72: 2004 movs r0, #4 + 8003d74: f7ff fd6c bl 8003850 + return 0; + 8003d78: e7df b.n 8003d3a + if(rv) return EPIN_AE_FAIL; + 8003d7a: f06f 0469 mvn.w r4, #105 ; 0x69 + 8003d7e: e7dc b.n 8003d3a + 8003d80: 334d1858 .word 0x334d1858 + +08003d84 : +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8003d84: b5f0 push {r4, r5, r6, r7, lr} + args->delay_achieved = slot->tc_arg; + 8003d86: 88cb ldrh r3, [r1, #6] + 8003d88: 62c3 str r3, [r0, #44] ; 0x2c +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8003d8a: f5ad 7d0d sub.w sp, sp, #564 ; 0x234 + memcpy(key, &args->private_state, sizeof(args->private_state)); + 8003d8e: 6c03 ldr r3, [r0, #64] ; 0x40 + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8003d90: 4d0f ldr r5, [pc, #60] ; (8003dd0 ) + memcpy(key, &args->private_state, sizeof(args->private_state)); + 8003d92: 9303 str r3, [sp, #12] +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8003d94: 4606 mov r6, r0 + 8003d96: 460f mov r7, r1 + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8003d98: cd0f ldmia r5!, {r0, r1, r2, r3} + 8003d9a: ac04 add r4, sp, #16 + 8003d9c: c40f stmia r4!, {r0, r1, r2, r3} + 8003d9e: e895 0007 ldmia.w r5, {r0, r1, r2} + 8003da2: e884 0007 stmia.w r4, {r0, r1, r2} + aes_init(&ctx); + 8003da6: a80b add r0, sp, #44 ; 0x2c + 8003da8: f004 fb5a bl 8008460 + aes_add(&ctx, (uint8_t *)slot, 32); + 8003dac: 4639 mov r1, r7 + 8003dae: a80b add r0, sp, #44 ; 0x2c + 8003db0: 2220 movs r2, #32 + 8003db2: f004 fb5b bl 800846c + aes_done(&ctx, args->cached_main_pin, 32, key, NULL); + 8003db6: 2300 movs r3, #0 + 8003db8: 9300 str r3, [sp, #0] + 8003dba: 2220 movs r2, #32 + 8003dbc: ab03 add r3, sp, #12 + 8003dbe: f106 01f8 add.w r1, r6, #248 ; 0xf8 + 8003dc2: a80b add r0, sp, #44 ; 0x2c + 8003dc4: f004 fb68 bl 8008498 +} + 8003dc8: f50d 7d0d add.w sp, sp, #564 ; 0x234 + 8003dcc: bdf0 pop {r4, r5, r6, r7, pc} + 8003dce: bf00 nop + 8003dd0: 0801c074 .word 0x0801c074 + +08003dd4 : + __HAL_RCC_CRC_CLK_ENABLE(); + 8003dd4: 4b09 ldr r3, [pc, #36] ; (8003dfc ) + 8003dd6: 6c9a ldr r2, [r3, #72] ; 0x48 +{ + 8003dd8: b513 push {r0, r1, r4, lr} + __HAL_RCC_CRC_CLK_ENABLE(); + 8003dda: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8003dde: 649a str r2, [r3, #72] ; 0x48 + 8003de0: 6c9b ldr r3, [r3, #72] ; 0x48 + CRC->INIT = rng_sample(); + 8003de2: 4c07 ldr r4, [pc, #28] ; (8003e00 ) + __HAL_RCC_CRC_CLK_ENABLE(); + 8003de4: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 8003de8: 9301 str r3, [sp, #4] + 8003dea: 9b01 ldr r3, [sp, #4] + CRC->INIT = rng_sample(); + 8003dec: f7fe fc72 bl 80026d4 + 8003df0: 6120 str r0, [r4, #16] + CRC->POL = rng_sample(); + 8003df2: f7fe fc6f bl 80026d4 + 8003df6: 6160 str r0, [r4, #20] +} + 8003df8: b002 add sp, #8 + 8003dfa: bd10 pop {r4, pc} + 8003dfc: 40021000 .word 0x40021000 + 8003e00: 40023000 .word 0x40023000 + +08003e04 : +{ + 8003e04: b510 push {r4, lr} + 8003e06: b094 sub sp, #80 ; 0x50 + 8003e08: 4604 mov r4, r0 + sha256_init(&ctx); + 8003e0a: a801 add r0, sp, #4 + 8003e0c: f001 fb3e bl 800548c + reboot_nonce(&ctx); + 8003e10: a801 add r0, sp, #4 + 8003e12: f7ff fdfd bl 8003a10 + sha256_update(&ctx, rom_secrets->hash_cache_secret, 32); + 8003e16: 2220 movs r2, #32 + 8003e18: a801 add r0, sp, #4 + 8003e1a: 4904 ldr r1, [pc, #16] ; (8003e2c ) + 8003e1c: f001 fb44 bl 80054a8 + sha256_final(&ctx, key); + 8003e20: 4621 mov r1, r4 + 8003e22: a801 add r0, sp, #4 + 8003e24: f001 fb86 bl 8005534 +} + 8003e28: b014 add sp, #80 ; 0x50 + 8003e2a: bd10 pop {r4, pc} + 8003e2c: 0801c070 .word 0x0801c070 + +08003e30 : +{ + 8003e30: b530 push {r4, r5, lr} + 8003e32: 460d mov r5, r1 + 8003e34: b089 sub sp, #36 ; 0x24 + 8003e36: 4604 mov r4, r0 + if(!check_all_zeros(digest, 32)) { + 8003e38: 2120 movs r1, #32 + 8003e3a: 4628 mov r0, r5 + 8003e3c: f7fe fc2a bl 8002694 + 8003e40: b9a0 cbnz r0, 8003e6c + pin_cache_get_key(value); + 8003e42: 4668 mov r0, sp + 8003e44: f7ff ffde bl 8003e04 + 8003e48: 466b mov r3, sp + 8003e4a: f105 0120 add.w r1, r5, #32 + *(acc) ^= *(more); + 8003e4e: 781a ldrb r2, [r3, #0] + 8003e50: f815 0b01 ldrb.w r0, [r5], #1 + 8003e54: 4042 eors r2, r0 + for(; len; len--, more++, acc++) { + 8003e56: 428d cmp r5, r1 + *(acc) ^= *(more); + 8003e58: f803 2b01 strb.w r2, [r3], #1 + for(; len; len--, more++, acc++) { + 8003e5c: d1f7 bne.n 8003e4e + ASSERT(args->magic_value == PA_MAGIC_V2); + 8003e5e: 6822 ldr r2, [r4, #0] + 8003e60: 4b0d ldr r3, [pc, #52] ; (8003e98 ) + 8003e62: 429a cmp r2, r3 + 8003e64: d008 beq.n 8003e78 + 8003e66: 480d ldr r0, [pc, #52] ; (8003e9c ) + 8003e68: f7fc fdee bl 8000a48 + memset(value, 0, 32); + 8003e6c: 2220 movs r2, #32 + 8003e6e: 2100 movs r1, #0 + 8003e70: 4668 mov r0, sp + 8003e72: f009 fbff bl 800d674 + 8003e76: e7f2 b.n 8003e5e + memcpy(args->cached_main_pin, value, 32); + 8003e78: 466b mov r3, sp + 8003e7a: f104 02f8 add.w r2, r4, #248 ; 0xf8 + 8003e7e: ad08 add r5, sp, #32 + 8003e80: 461c mov r4, r3 + 8003e82: cc03 ldmia r4!, {r0, r1} + 8003e84: 42ac cmp r4, r5 + 8003e86: 6010 str r0, [r2, #0] + 8003e88: 6051 str r1, [r2, #4] + 8003e8a: 4623 mov r3, r4 + 8003e8c: f102 0208 add.w r2, r2, #8 + 8003e90: d1f6 bne.n 8003e80 +} + 8003e92: b009 add sp, #36 ; 0x24 + 8003e94: bd30 pop {r4, r5, pc} + 8003e96: bf00 nop + 8003e98: 2eaf6312 .word 0x2eaf6312 + 8003e9c: 0800e3e0 .word 0x0800e3e0 + +08003ea0 : +{ + 8003ea0: b510 push {r4, lr} + ASSERT(args->magic_value == PA_MAGIC_V2); + 8003ea2: 6802 ldr r2, [r0, #0] + 8003ea4: 4b14 ldr r3, [pc, #80] ; (8003ef8 ) + 8003ea6: 429a cmp r2, r3 +{ + 8003ea8: b088 sub sp, #32 + 8003eaa: 460c mov r4, r1 + ASSERT(args->magic_value == PA_MAGIC_V2); + 8003eac: d002 beq.n 8003eb4 + 8003eae: 4813 ldr r0, [pc, #76] ; (8003efc ) + 8003eb0: f7fc fdca bl 8000a48 + memcpy(digest, args->cached_main_pin, 32); + 8003eb4: f100 03f8 add.w r3, r0, #248 ; 0xf8 + 8003eb8: 460a mov r2, r1 + 8003eba: f500 708c add.w r0, r0, #280 ; 0x118 + 8003ebe: f853 1b04 ldr.w r1, [r3], #4 + 8003ec2: f842 1b04 str.w r1, [r2], #4 + 8003ec6: 4283 cmp r3, r0 + 8003ec8: d1f9 bne.n 8003ebe + if(!check_all_zeros(digest, 32)) { + 8003eca: 2120 movs r1, #32 + 8003ecc: 4620 mov r0, r4 + 8003ece: f7fe fbe1 bl 8002694 + 8003ed2: b970 cbnz r0, 8003ef2 + pin_cache_get_key(key); + 8003ed4: 4668 mov r0, sp + 8003ed6: f7ff ff95 bl 8003e04 + 8003eda: 1e62 subs r2, r4, #1 + 8003edc: 466b mov r3, sp + 8003ede: 341f adds r4, #31 + *(acc) ^= *(more); + 8003ee0: f812 1f01 ldrb.w r1, [r2, #1]! + 8003ee4: f813 0b01 ldrb.w r0, [r3], #1 + for(; len; len--, more++, acc++) { + 8003ee8: 42a2 cmp r2, r4 + *(acc) ^= *(more); + 8003eea: ea81 0100 eor.w r1, r1, r0 + 8003eee: 7011 strb r1, [r2, #0] + for(; len; len--, more++, acc++) { + 8003ef0: d1f6 bne.n 8003ee0 +} + 8003ef2: b008 add sp, #32 + 8003ef4: bd10 pop {r4, pc} + 8003ef6: bf00 nop + 8003ef8: 2eaf6312 .word 0x2eaf6312 + 8003efc: 0800e3e0 .word 0x0800e3e0 + +08003f00 : +{ + 8003f00: b530 push {r4, r5, lr} + 8003f02: b091 sub sp, #68 ; 0x44 + pin_hash(pin_prefix, prefix_len, tmp, PIN_PURPOSE_WORDS); + 8003f04: 4b0b ldr r3, [pc, #44] ; (8003f34 ) +{ + 8003f06: 4615 mov r5, r2 + pin_hash(pin_prefix, prefix_len, tmp, PIN_PURPOSE_WORDS); + 8003f08: 466a mov r2, sp + 8003f0a: f7ff fd97 bl 8003a3c + ae_setup(); + 8003f0e: f7fe fd59 bl 80029c4 + int rv = ae_stretch_iter(tmp, digest, KDF_ITER_WORDS); + 8003f12: 2206 movs r2, #6 + 8003f14: a908 add r1, sp, #32 + 8003f16: 4668 mov r0, sp + 8003f18: f7ff fc72 bl 8003800 + 8003f1c: 4604 mov r4, r0 + ae_reset_chip(); + 8003f1e: f7fe fd43 bl 80029a8 + if(rv) return -1; + 8003f22: b924 cbnz r4, 8003f2e + memcpy(result, digest, 4); + 8003f24: 9b08 ldr r3, [sp, #32] + 8003f26: 602b str r3, [r5, #0] +} + 8003f28: 4620 mov r0, r4 + 8003f2a: b011 add sp, #68 ; 0x44 + 8003f2c: bd30 pop {r4, r5, pc} + if(rv) return -1; + 8003f2e: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 8003f32: e7f9 b.n 8003f28 + 8003f34: 2e6d6773 .word 0x2e6d6773 + +08003f38 : +} + 8003f38: 2000 movs r0, #0 + 8003f3a: 4770 bx lr + +08003f3c : +{ + 8003f3c: b5f0 push {r4, r5, r6, r7, lr} + int rv = _validate_attempt(args, true); + 8003f3e: 2101 movs r1, #1 +{ + 8003f40: b091 sub sp, #68 ; 0x44 + 8003f42: 4605 mov r5, r0 + int rv = _validate_attempt(args, true); + 8003f44: f7ff fde6 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 8003f48: 4604 mov r4, r0 + 8003f4a: bb28 cbnz r0, 8003f98 + if(args->is_secondary) { + 8003f4c: 686b ldr r3, [r5, #4] + 8003f4e: 2b00 cmp r3, #0 + 8003f50: d158 bne.n 8004004 + int pin_len = args->pin_len; + 8003f52: 6aaf ldr r7, [r5, #40] ; 0x28 + memcpy(pin_copy, args->pin, pin_len); + 8003f54: f105 0608 add.w r6, r5, #8 + 8003f58: 463a mov r2, r7 + 8003f5a: 4631 mov r1, r6 + 8003f5c: 4668 mov r0, sp + 8003f5e: f009 fb61 bl 800d624 + memset(args, 0, PIN_ATTEMPT_SIZE_V2); + 8003f62: f44f 728c mov.w r2, #280 ; 0x118 + 8003f66: 4621 mov r1, r4 + 8003f68: 4628 mov r0, r5 + 8003f6a: f009 fb83 bl 800d674 + args->magic_value = PA_MAGIC_V2; + 8003f6e: 4b28 ldr r3, [pc, #160] ; (8004010 ) + 8003f70: 602b str r3, [r5, #0] + memcpy(args->pin, pin_copy, pin_len); + 8003f72: 463a mov r2, r7 + 8003f74: 4669 mov r1, sp + args->pin_len = pin_len; + 8003f76: 62af str r7, [r5, #40] ; 0x28 + memcpy(args->pin, pin_copy, pin_len); + 8003f78: 4630 mov r0, r6 + 8003f7a: f009 fb53 bl 800d624 + if(warmup_ae()) { + 8003f7e: f7ff fdff bl 8003b80 + 8003f82: 2800 cmp r0, #0 + 8003f84: d141 bne.n 800400a + if(get_last_success(args)) { + 8003f86: 4628 mov r0, r5 + 8003f88: f7ff fe37 bl 8003bfa + 8003f8c: 4604 mov r4, r0 + 8003f8e: b130 cbz r0, 8003f9e + ae_reset_chip(); + 8003f90: f7fe fd0a bl 80029a8 + return EPIN_AE_FAIL; + 8003f94: f06f 0469 mvn.w r4, #105 ; 0x69 +} + 8003f98: 4620 mov r0, r4 + 8003f9a: b011 add sp, #68 ; 0x44 + 8003f9c: bdf0 pop {r4, r5, r6, r7, pc} + uint8_t blank[32] = {0}; + 8003f9e: 4601 mov r1, r0 + 8003fa0: 221c movs r2, #28 + args->delay_achieved = 0; + 8003fa2: e9c5 000b strd r0, r0, [r5, #44] ; 0x2c + uint8_t blank[32] = {0}; + 8003fa6: 9008 str r0, [sp, #32] + 8003fa8: a809 add r0, sp, #36 ; 0x24 + 8003faa: f009 fb63 bl 800d674 + ae_reset_chip(); + 8003fae: f7fe fcfb bl 80029a8 + ae_pair_unlock(); + 8003fb2: f7fe fefd bl 8002db0 + int is_blank = (ae_checkmac_hard(keynum, blank) == 0); + 8003fb6: a908 add r1, sp, #32 + 8003fb8: 2003 movs r0, #3 + 8003fba: f7ff f887 bl 80030cc + 8003fbe: 4606 mov r6, r0 + ae_reset_chip(); + 8003fc0: f7fe fcf2 bl 80029a8 + if(pin_is_blank(KEYNUM_main_pin)) { + 8003fc4: b9c6 cbnz r6, 8003ff8 + args->state_flags |= PA_SUCCESSFUL | PA_IS_BLANK; + 8003fc6: 6beb ldr r3, [r5, #60] ; 0x3c + const uint8_t zeros[32] = {0}; + 8003fc8: 9408 str r4, [sp, #32] + args->state_flags |= PA_SUCCESSFUL | PA_IS_BLANK; + 8003fca: f043 0303 orr.w r3, r3, #3 + 8003fce: 63eb str r3, [r5, #60] ; 0x3c + const uint8_t zeros[32] = {0}; + 8003fd0: 221c movs r2, #28 + 8003fd2: 4621 mov r1, r4 + 8003fd4: a809 add r0, sp, #36 ; 0x24 + 8003fd6: f009 fb4d bl 800d674 + pin_cache_save(args, zeros); + 8003fda: a908 add r1, sp, #32 + 8003fdc: 4628 mov r0, r5 + 8003fde: f7ff ff27 bl 8003e30 + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8003fe2: f7fe fb77 bl 80026d4 + 8003fe6: 4b0b ldr r3, [pc, #44] ; (8004014 ) + 8003fe8: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8003fec: f020 0001 bic.w r0, r0, #1 + args->delay_achieved = 0; + 8003ff0: e9c5 440b strd r4, r4, [r5, #44] ; 0x2c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8003ff4: 4058 eors r0, r3 + 8003ff6: 6428 str r0, [r5, #64] ; 0x40 + _hmac_attempt(args, args->hmac); + 8003ff8: f105 0144 add.w r1, r5, #68 ; 0x44 + 8003ffc: 4628 mov r0, r5 + 8003ffe: f7ff fd5b bl 8003ab8 <_hmac_attempt> +} + 8004002: e7c9 b.n 8003f98 + return EPIN_PRIMARY_ONLY; + 8004004: f06f 0471 mvn.w r4, #113 ; 0x71 + 8004008: e7c6 b.n 8003f98 + return EPIN_I_AM_BRICK; + 800400a: f06f 0468 mvn.w r4, #104 ; 0x68 + 800400e: e7c3 b.n 8003f98 + 8004010: 2eaf6312 .word 0x2eaf6312 + 8004014: 0801c000 .word 0x0801c000 + +08004018 : +} + 8004018: 2000 movs r0, #0 + 800401a: 4770 bx lr + +0800401c : +// +// Do the PIN check, and return a value. Or fail. +// + int +pin_login_attempt(pinAttempt_t *args) +{ + 800401c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + bool deltamode = false; + char tmp_pin[32]; + + int rv = _validate_attempt(args, false); + 8004020: 2100 movs r1, #0 +{ + 8004022: b0c7 sub sp, #284 ; 0x11c + 8004024: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 8004026: f7ff fd75 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 800402a: 4605 mov r5, r0 + 800402c: 2800 cmp r0, #0 + 800402e: d179 bne.n 8004124 + + if(args->state_flags & PA_SUCCESSFUL) { + 8004030: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004032: 07d9 lsls r1, r3, #31 + 8004034: f100 80c5 bmi.w 80041c2 + } + + // Mk4: Check SE2 first to see if this is a "trick" pin. + // - this call may have side-effects, like wiping keys, bricking, etc. + trick_slot_t slot; + bool is_trick = se2_test_trick_pin(args->pin, args->pin_len, &slot, false); + 8004038: f104 0808 add.w r8, r4, #8 + 800403c: 4603 mov r3, r0 + 800403e: 6aa1 ldr r1, [r4, #40] ; 0x28 + 8004040: aa26 add r2, sp, #152 ; 0x98 + 8004042: 4640 mov r0, r8 + 8004044: f003 fee8 bl 8007e18 + + if(is_trick) { + 8004048: 4606 mov r6, r0 + 800404a: 2800 cmp r0, #0 + 800404c: d04b beq.n 80040e6 + // Mark as success + args->state_flags = PA_SUCCESSFUL; + args->num_fails = 0; + args->attempts_left = MAX_TARGET_ATTEMPTS; + + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 800404e: f9bd 209c ldrsh.w r2, [sp, #156] ; 0x9c + args->num_fails = 0; + 8004052: 6365 str r5, [r4, #52] ; 0x34 + args->state_flags = PA_SUCCESSFUL; + 8004054: 2301 movs r3, #1 + 8004056: 63e3 str r3, [r4, #60] ; 0x3c + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 8004058: 2a00 cmp r2, #0 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 800405a: f04f 030d mov.w r3, #13 + 800405e: 63a3 str r3, [r4, #56] ; 0x38 + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 8004060: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + 8004064: da4f bge.n 8004106 + 8004066: f413 5fc0 tst.w r3, #6144 ; 0x1800 + 800406a: bf0c ite eq + 800406c: 2701 moveq r7, #1 + 800406e: 2700 movne r7, #0 + if(check_all_zeros(slot.xdata, 32) || wipe) { + 8004070: 2120 movs r1, #32 + 8004072: a828 add r0, sp, #160 ; 0xa0 + 8004074: f7fe fb0e bl 8002694 + 8004078: b900 cbnz r0, 800407c + 800407a: b11f cbz r7, 8004084 + args->state_flags |= PA_ZERO_SECRET; + 800407c: 6be3 ldr r3, [r4, #60] ; 0x3c + 800407e: f043 0310 orr.w r3, r3, #16 + 8004082: 63e3 str r3, [r4, #60] ; 0x3c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8004084: f7fe fb26 bl 80026d4 + 8004088: 4b51 ldr r3, [pc, #324] ; (80041d0 ) + 800408a: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 800408e: f040 0001 orr.w r0, r0, #1 + 8004092: 4058 eors r0, r3 + args->delay_required = (slot->tc_flags & ~TC_HIDDEN_MASK); + 8004094: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8004098: 6420 str r0, [r4, #64] ; 0x40 + args->delay_required = (slot->tc_flags & ~TC_HIDDEN_MASK); + 800409a: f423 4278 bic.w r2, r3, #63488 ; 0xf800 + 800409e: 6322 str r2, [r4, #48] ; 0x30 + if(slot->tc_flags & TC_DELTA_MODE) { + 80040a0: 055a lsls r2, r3, #21 + 80040a2: d532 bpl.n 800410a + args->delay_achieved = 0; + 80040a4: 2300 movs r3, #0 + 80040a6: 62e3 str r3, [r4, #44] ; 0x2c + memcpy(tmp_pin, pin, pin_len); + 80040a8: 6aa7 ldr r7, [r4, #40] ; 0x28 + // Thug gave wrong PIN, but we are going to let them + // past (by calculating correct PIN, up to 4 digits different), + // and the mpy firmware can do tricky stuff to protect funds + // even though the private key is known at that point. + deltamode = true; + apply_pin_delta(args->pin, args->pin_len, slot.tc_arg, tmp_pin); + 80040aa: f8bd 909e ldrh.w r9, [sp, #158] ; 0x9e + memcpy(tmp_pin, pin, pin_len); + 80040ae: ab04 add r3, sp, #16 + 80040b0: 463a mov r2, r7 + 80040b2: 4641 mov r1, r8 + 80040b4: 4618 mov r0, r3 + 80040b6: f009 fab5 bl 800d624 + tmp_pin[pin_len] = 0; + 80040ba: 2200 movs r2, #0 + 80040bc: 55c2 strb r2, [r0, r7] + char *p = &tmp_pin[pin_len-1]; + 80040be: 1e7a subs r2, r7, #1 + 80040c0: 4402 add r2, r0 + 80040c2: 2104 movs r1, #4 + if(*p == '-') p--; + 80040c4: 7813 ldrb r3, [r2, #0] + 80040c6: 2b2d cmp r3, #45 ; 0x2d + 80040c8: f009 030f and.w r3, r9, #15 + 80040cc: bf08 it eq + 80040ce: f102 32ff addeq.w r2, r2, #4294967295 ; 0xffffffff + if((here >= 0) && (here <= 9)) { + 80040d2: 2b09 cmp r3, #9 + *p = '0' + here; + 80040d4: bf9c itt ls + 80040d6: 3330 addls r3, #48 ; 0x30 + 80040d8: 7013 strbls r3, [r2, #0] + for(int i=0; i<4; i++, p--) { + 80040da: 3901 subs r1, #1 + replacement >>= 4; + 80040dc: ea4f 1919 mov.w r9, r9, lsr #4 + for(int i=0; i<4; i++, p--) { + 80040e0: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 80040e4: d1ee bne.n 80040c4 + return 0; + } + +real_login: + // unlock the AE chip + if(warmup_ae()) return EPIN_I_AM_BRICK; + 80040e6: f7ff fd4b bl 8003b80 + 80040ea: 2800 cmp r0, #0 + 80040ec: d16c bne.n 80041c8 + + // hash up the pin now, assuming we'll use it on main PIN + uint8_t digest[32]; + rv = pin_hash_attempt(deltamode ? tmp_pin : args->pin, args->pin_len, digest); + 80040ee: b10e cbz r6, 80040f4 + 80040f0: f10d 0810 add.w r8, sp, #16 + 80040f4: 6aa1 ldr r1, [r4, #40] ; 0x28 + 80040f6: aa0c add r2, sp, #48 ; 0x30 + 80040f8: 4640 mov r0, r8 + 80040fa: f7ff fe15 bl 8003d28 + if(rv) return EPIN_AE_FAIL; + 80040fe: b1a8 cbz r0, 800412c + + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + if(rv) { + ae_reset_chip(); + + return EPIN_AE_FAIL; + 8004100: f06f 0569 mvn.w r5, #105 ; 0x69 + 8004104: e00e b.n 8004124 + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 8004106: 462f mov r7, r5 + 8004108: e7b2 b.n 8004070 + 800410a: a926 add r1, sp, #152 ; 0x98 + 800410c: 4620 mov r0, r4 + 800410e: f7ff fe39 bl 8003d84 + if(slot.tc_flags & TC_DELTA_MODE) { + 8004112: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + 8004116: 055b lsls r3, r3, #21 + 8004118: d4c6 bmi.n 80040a8 + _hmac_attempt(args, args->hmac); + 800411a: f104 0144 add.w r1, r4, #68 ; 0x44 + 800411e: 4620 mov r0, r4 + 8004120: f7ff fcca bl 8003ab8 <_hmac_attempt> + } + + _sign_attempt(args); + + return 0; +} + 8004124: 4628 mov r0, r5 + 8004126: b047 add sp, #284 ; 0x11c + 8004128: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + ae_reset_chip(); + 800412c: f7fe fc3c bl 80029a8 + ae_pair_unlock(); + 8004130: f7fe fe3e bl 8002db0 + return (ae_checkmac_hard(KEYNUM_main_pin, digest) == 0); + 8004134: a90c add r1, sp, #48 ; 0x30 + 8004136: 2003 movs r0, #3 + 8004138: f7fe ffc8 bl 80030cc + if(!is_main_pin(digest)) { + 800413c: b130 cbz r0, 800414c + se2_handle_bad_pin(args->num_fails + 1); + 800413e: 6b60 ldr r0, [r4, #52] ; 0x34 + 8004140: 3001 adds r0, #1 + 8004142: f003 ff45 bl 8007fd0 + return EPIN_AUTH_FAIL; + 8004146: f06f 056f mvn.w r5, #111 ; 0x6f + 800414a: e7eb b.n 8004124 + rv = updates_for_good_login(digest); + 800414c: a80c add r0, sp, #48 ; 0x30 + 800414e: f7ff fd9d bl 8003c8c + if(rv) return EPIN_AE_FAIL; + 8004152: 4607 mov r7, r0 + 8004154: 2800 cmp r0, #0 + 8004156: d1d3 bne.n 8004100 + pin_cache_save(args, digest); + 8004158: a90c add r1, sp, #48 ; 0x30 + 800415a: 4620 mov r0, r4 + 800415c: f7ff fe68 bl 8003e30 + args->state_flags = PA_SUCCESSFUL; + 8004160: 2301 movs r3, #1 + 8004162: 63e3 str r3, [r4, #60] ; 0x3c + args->num_fails = 0; + 8004164: 6367 str r7, [r4, #52] ; 0x34 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 8004166: 230d movs r3, #13 + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + 8004168: 2748 movs r7, #72 ; 0x48 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 800416a: 63a3 str r3, [r4, #56] ; 0x38 + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + 800416c: 9700 str r7, [sp, #0] + 800416e: ab14 add r3, sp, #80 ; 0x50 + 8004170: aa0c add r2, sp, #48 ; 0x30 + 8004172: 2103 movs r1, #3 + 8004174: 2009 movs r0, #9 + 8004176: f7ff f88b bl 8003290 + if(rv) { + 800417a: b110 cbz r0, 8004182 + ae_reset_chip(); + 800417c: f7fe fc14 bl 80029a8 + 8004180: e7be b.n 8004100 + ae_reset_chip(); + 8004182: f7fe fc11 bl 80029a8 + mcu_key_get(&mcu_key_valid); + 8004186: f10d 000f add.w r0, sp, #15 + 800418a: f7fe f945 bl 8002418 + if(check_all_zeros(ts, AE_SECRET_LEN) || !mcu_key_valid) { + 800418e: 4639 mov r1, r7 + 8004190: a814 add r0, sp, #80 ; 0x50 + 8004192: f7fe fa7f bl 8002694 + 8004196: b910 cbnz r0, 800419e + 8004198: f89d 300f ldrb.w r3, [sp, #15] + 800419c: b91b cbnz r3, 80041a6 + args->state_flags |= PA_ZERO_SECRET; + 800419e: 6be3 ldr r3, [r4, #60] ; 0x3c + 80041a0: f043 0310 orr.w r3, r3, #16 + 80041a4: 63e3 str r3, [r4, #60] ; 0x3c + if(!deltamode) { + 80041a6: 2e00 cmp r6, #0 + 80041a8: d1b7 bne.n 800411a + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 80041aa: f7fe fa93 bl 80026d4 + 80041ae: 4b08 ldr r3, [pc, #32] ; (80041d0 ) + 80041b0: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80041b4: f020 0001 bic.w r0, r0, #1 + 80041b8: 4058 eors r0, r3 + args->delay_achieved = 0; + 80041ba: e9c4 660b strd r6, r6, [r4, #44] ; 0x2c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 80041be: 6420 str r0, [r4, #64] ; 0x40 + return; + 80041c0: e7ab b.n 800411a + return EPIN_WRONG_SUCCESS; + 80041c2: f06f 056c mvn.w r5, #108 ; 0x6c + 80041c6: e7ad b.n 8004124 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 80041c8: f06f 0568 mvn.w r5, #104 ; 0x68 + 80041cc: e7aa b.n 8004124 + 80041ce: bf00 nop + 80041d0: 0801c000 .word 0x0801c000 + +080041d4 : +// +// Verify we know the main PIN, but don't do anything with it. +// + int +pin_check_logged_in(const pinAttempt_t *args, bool *is_trick) +{ + 80041d4: b570 push {r4, r5, r6, lr} + 80041d6: 460e mov r6, r1 + 80041d8: b088 sub sp, #32 + int rv = _validate_attempt(args, false); + 80041da: 2100 movs r1, #0 +{ + 80041dc: 4605 mov r5, r0 + int rv = _validate_attempt(args, false); + 80041de: f7ff fc99 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 80041e2: 4604 mov r4, r0 + 80041e4: b980 cbnz r0, 8004208 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80041e6: 6beb ldr r3, [r5, #60] ; 0x3c + 80041e8: 07da lsls r2, r3, #31 + 80041ea: d520 bpl.n 800422e + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 80041ec: 4b11 ldr r3, [pc, #68] ; (8004234 ) + 80041ee: 6c2a ldr r2, [r5, #64] ; 0x40 + 80041f0: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80041f4: 4053 eors r3, r2 + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(get_is_trick(args, NULL)) { + 80041f6: 07db lsls r3, r3, #31 + 80041f8: d509 bpl.n 800420e + // they used a trick pin to get this far. Amuse them more. + *is_trick = true; + 80041fa: 2301 movs r3, #1 + 80041fc: 7033 strb r3, [r6, #0] + + // should calibrate this, but smart money will just look at the bus + delay_ms(10); + 80041fe: 200a movs r0, #10 + 8004200: f7ff fb7a bl 80038f8 + rng_delay(); + 8004204: f7fe faba bl 800277c + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + if(rv) return EPIN_AUTH_FAIL; + } + + return 0; +} + 8004208: 4620 mov r0, r4 + 800420a: b008 add sp, #32 + 800420c: bd70 pop {r4, r5, r6, pc} + pin_cache_restore(args, auth_digest); + 800420e: 4669 mov r1, sp + *is_trick = false; + 8004210: 7030 strb r0, [r6, #0] + pin_cache_restore(args, auth_digest); + 8004212: 4628 mov r0, r5 + 8004214: f7ff fe44 bl 8003ea0 + ae_pair_unlock(); + 8004218: f7fe fdca bl 8002db0 + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + 800421c: 4669 mov r1, sp + 800421e: 2003 movs r0, #3 + 8004220: f7fe fd44 bl 8002cac + if(rv) return EPIN_AUTH_FAIL; + 8004224: 1e04 subs r4, r0, #0 + 8004226: bf18 it ne + 8004228: f06f 046f mvnne.w r4, #111 ; 0x6f + 800422c: e7ec b.n 8004208 + return EPIN_WRONG_SUCCESS; + 800422e: f06f 046c mvn.w r4, #108 ; 0x6c + 8004232: e7e9 b.n 8004208 + 8004234: 0801c000 .word 0x0801c000 + +08004238 : +// +// Change the PIN and/or the secret. (Must also know the previous value, or it must be blank) +// + int +pin_change(pinAttempt_t *args) +{ + 8004238: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 800423c: 2100 movs r1, #0 +{ + 800423e: b0a4 sub sp, #144 ; 0x90 + 8004240: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 8004242: f7ff fc67 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 8004246: 4605 mov r5, r0 + 8004248: 2800 cmp r0, #0 + 800424a: f040 8094 bne.w 8004376 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 800424e: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004250: 07d9 lsls r1, r3, #31 + 8004252: f140 809c bpl.w 800438e + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(args->state_flags & PA_IS_BLANK) { + 8004256: 079a lsls r2, r3, #30 + 8004258: d502 bpl.n 8004260 + // if blank, must provide blank value + if(args->pin_len) return EPIN_RANGE_ERR; + 800425a: 6aa3 ldr r3, [r4, #40] ; 0x28 + 800425c: 2b00 cmp r3, #0 + 800425e: d158 bne.n 8004312 + } + + // Look at change flags. + const uint32_t cf = args->change_flags; + + ASSERT(!args->is_secondary); + 8004260: 6863 ldr r3, [r4, #4] + const uint32_t cf = args->change_flags; + 8004262: f8d4 9064 ldr.w r9, [r4, #100] ; 0x64 + ASSERT(!args->is_secondary); + 8004266: b113 cbz r3, 800426e + 8004268: 484c ldr r0, [pc, #304] ; (800439c ) + 800426a: f7fc fbed bl 8000a48 + if(cf & CHANGE_SECONDARY_WALLET_PIN) { + // obsolete secondary support, can't support. + return EPIN_BAD_REQUEST; + } + if(cf & (CHANGE_DURESS_PIN | CHANGE_DURESS_SECRET | CHANGE_BRICKME_PIN)) { + 800426e: f019 0f36 tst.w r9, #54 ; 0x36 + 8004272: d10b bne.n 800428c + // we need some new API for trick PIN lookup/changes. + return EPIN_BAD_REQUEST; + } + if(!(cf & (CHANGE_WALLET_PIN | CHANGE_SECRET))) { + 8004274: f019 0f09 tst.w r9, #9 + 8004278: d04b beq.n 8004312 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 800427a: 4b49 ldr r3, [pc, #292] ; (80043a0 ) + 800427c: 6c22 ldr r2, [r4, #64] ; 0x40 + 800427e: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8004282: 4053 eors r3, r2 + // If they authorized w/ a trick PIN, new policy is to wipe ourselves if + // they try to change PIN code or the secret. + // - it's hard to fake them out here, and they may be onto us. + // - this protects the seed, but does end the game somewhat + // - all trick PINs will still be in effect, and looks like random reset + if(get_is_trick(args, NULL)) { + 8004284: 07db lsls r3, r3, #31 + 8004286: d504 bpl.n 8004292 + // User is a thug.. kill secret and reboot w/o any notice + fast_wipe(); + 8004288: f7fe f9d8 bl 800263c + return EPIN_BAD_REQUEST; + 800428c: f06f 0567 mvn.w r5, #103 ; 0x67 + 8004290: e071 b.n 8004376 + // NOT-REACHED + return EPIN_BAD_REQUEST; + } + + // unlock the AE chip + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004292: f7ff fc75 bl 8003b80 + 8004296: 4605 mov r5, r0 + 8004298: 2800 cmp r0, #0 + 800429a: d17b bne.n 8004394 + // If they tricked us to get to this point, doesn't matter as + // below SE1 validates it all again. + + // Restore cached version of PIN digest: fast + uint8_t required_digest[32]; + pin_cache_restore(args, required_digest); + 800429c: f10d 0808 add.w r8, sp, #8 + 80042a0: 4641 mov r1, r8 + 80042a2: 4620 mov r0, r4 + 80042a4: f7ff fdfc bl 8003ea0 + + // Calculate new PIN hashed value: will be slow to do + if(cf & CHANGE_WALLET_PIN) { + 80042a8: f019 0f01 tst.w r9, #1 + 80042ac: d021 beq.n 80042f2 + uint8_t new_digest[32]; + rv = pin_hash_attempt(args->new_pin, args->new_pin_len, new_digest); + 80042ae: f8d4 10ac ldr.w r1, [r4, #172] ; 0xac + 80042b2: aa12 add r2, sp, #72 ; 0x48 + 80042b4: f104 008c add.w r0, r4, #140 ; 0x8c + 80042b8: f7ff fd36 bl 8003d28 + if(rv) goto ae_fail; + 80042bc: 2800 cmp r0, #0 + 80042be: d161 bne.n 8004384 + + if(ae_encrypted_write(KEYNUM_main_pin, KEYNUM_main_pin, required_digest, new_digest, 32)) { + 80042c0: 2320 movs r3, #32 + 80042c2: 2103 movs r1, #3 + 80042c4: 9300 str r3, [sp, #0] + 80042c6: 4642 mov r2, r8 + 80042c8: ab12 add r3, sp, #72 ; 0x48 + 80042ca: 4608 mov r0, r1 + 80042cc: f7ff f880 bl 80033d0 + 80042d0: 2800 cmp r0, #0 + 80042d2: d157 bne.n 8004384 + goto ae_fail; + } + + memcpy(required_digest, new_digest, 32); + 80042d4: af12 add r7, sp, #72 ; 0x48 + 80042d6: cf0f ldmia r7!, {r0, r1, r2, r3} + 80042d8: 4646 mov r6, r8 + 80042da: c60f stmia r6!, {r0, r1, r2, r3} + 80042dc: e897 000f ldmia.w r7, {r0, r1, r2, r3} + 80042e0: e886 000f stmia.w r6, {r0, r1, r2, r3} + + // main pin is changing; reset counter to zero (good login) and our cache + pin_cache_save(args, new_digest); + 80042e4: 4620 mov r0, r4 + 80042e6: a912 add r1, sp, #72 ; 0x48 + 80042e8: f7ff fda2 bl 8003e30 + + updates_for_good_login(new_digest); + 80042ec: a812 add r0, sp, #72 ; 0x48 + 80042ee: f7ff fccd bl 8003c8c + } + + // Recording new secret. + // Note the required_digest might have just changed above. + if(cf & CHANGE_SECRET) { + 80042f2: f019 0f08 tst.w r9, #8 + 80042f6: d037 beq.n 8004368 + int which = (args->change_flags >> 8) & 0xf; + 80042f8: 6e63 ldr r3, [r4, #100] ; 0x64 + 80042fa: 121b asrs r3, r3, #8 + switch(which) { + 80042fc: f013 020c ands.w r2, r3, #12 + 8004300: d107 bne.n 8004312 + 8004302: 4928 ldr r1, [pc, #160] ; (80043a4 ) + int which = (args->change_flags >> 8) & 0xf; + 8004304: f003 030f and.w r3, r3, #15 + 8004308: f911 a003 ldrsb.w sl, [r1, r3] + uint8_t tmp[AE_SECRET_LEN]; + uint8_t check[32]; + + // what slot (key number) are updating? (probably: KEYNUM_secret) + int target_slot = keynum_for_secret(args); + if(target_slot < 0) return EPIN_RANGE_ERR; + 800430c: f1ba 0f00 cmp.w sl, #0 + 8004310: da02 bge.n 8004318 + if(args->pin_len) return EPIN_RANGE_ERR; + 8004312: f06f 0566 mvn.w r5, #102 ; 0x66 + 8004316: e02e b.n 8004376 + + se2_encrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, required_digest); + 8004318: f104 07b0 add.w r7, r4, #176 ; 0xb0 + 800431c: ae0a add r6, sp, #40 ; 0x28 + 800431e: ab12 add r3, sp, #72 ; 0x48 + 8004320: 2148 movs r1, #72 ; 0x48 + + // write into two slots + if(ae_encrypted_write(target_slot, KEYNUM_main_pin, + 8004322: f04f 0948 mov.w r9, #72 ; 0x48 + se2_encrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, required_digest); + 8004326: f8cd 8004 str.w r8, [sp, #4] + 800432a: 9600 str r6, [sp, #0] + 800432c: 4638 mov r0, r7 + 800432e: f003 ff33 bl 8008198 + if(ae_encrypted_write(target_slot, KEYNUM_main_pin, + 8004332: 2103 movs r1, #3 + 8004334: f8cd 9000 str.w r9, [sp] + 8004338: eb0d 0309 add.w r3, sp, r9 + 800433c: 4642 mov r2, r8 + 800433e: 4650 mov r0, sl + 8004340: f7ff f846 bl 80033d0 + 8004344: 4601 mov r1, r0 + 8004346: b9e8 cbnz r0, 8004384 + required_digest, tmp, AE_SECRET_LEN)){ + goto ae_fail; + } + if(ae_encrypted_write32(KEYNUM_check_secret, 0, KEYNUM_main_pin, required_digest, check)){ + 8004348: 9600 str r6, [sp, #0] + 800434a: 4643 mov r3, r8 + 800434c: 2203 movs r2, #3 + 800434e: 200a movs r0, #10 + 8004350: f7fe ffd8 bl 8003304 + 8004354: b9b0 cbnz r0, 8004384 + goto ae_fail; + } + + // update the zero-secret flag to be correct. + if(cf & CHANGE_SECRET) { + if(check_all_zeros(args->secret, AE_SECRET_LEN)) { + 8004356: 4649 mov r1, r9 + 8004358: 4638 mov r0, r7 + 800435a: f7fe f99b bl 8002694 + 800435e: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004360: b168 cbz r0, 800437e + args->state_flags |= PA_ZERO_SECRET; + 8004362: f043 0310 orr.w r3, r3, #16 + 8004366: 63e3 str r3, [r4, #60] ; 0x3c + args->state_flags &= ~PA_ZERO_SECRET; + } + } + } + + ae_reset_chip(); + 8004368: f7fe fb1e bl 80029a8 + _hmac_attempt(args, args->hmac); + 800436c: f104 0144 add.w r1, r4, #68 ; 0x44 + 8004370: 4620 mov r0, r4 + 8004372: f7ff fba1 bl 8003ab8 <_hmac_attempt> + +ae_fail: + ae_reset_chip(); + + return EPIN_AE_FAIL; +} + 8004376: 4628 mov r0, r5 + 8004378: b024 add sp, #144 ; 0x90 + 800437a: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + args->state_flags &= ~PA_ZERO_SECRET; + 800437e: f023 0310 bic.w r3, r3, #16 + 8004382: e7f0 b.n 8004366 + ae_reset_chip(); + 8004384: f7fe fb10 bl 80029a8 + return EPIN_AE_FAIL; + 8004388: f06f 0569 mvn.w r5, #105 ; 0x69 + 800438c: e7f3 b.n 8004376 + return EPIN_WRONG_SUCCESS; + 800438e: f06f 056c mvn.w r5, #108 ; 0x6c + 8004392: e7f0 b.n 8004376 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004394: f06f 0568 mvn.w r5, #104 ; 0x68 + 8004398: e7ed b.n 8004376 + 800439a: bf00 nop + 800439c: 0800e3e0 .word 0x0800e3e0 + 80043a0: 0801c000 .word 0x0801c000 + 80043a4: 0800e71c .word 0x0800e71c + +080043a8 : +// To encourage not keeping the secret in memory, a way to fetch it after you've already +// proven you know the PIN. +// + int +pin_fetch_secret(pinAttempt_t *args) +{ + 80043a8: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 80043ac: 2100 movs r1, #0 +{ + 80043ae: f5ad 7d38 sub.w sp, sp, #736 ; 0x2e0 + 80043b2: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 80043b4: f7ff fbae bl 8003b14 <_validate_attempt> + if(rv) return rv; + 80043b8: 4605 mov r5, r0 + 80043ba: 2800 cmp r0, #0 + 80043bc: d144 bne.n 8004448 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80043be: 6be3 ldr r3, [r4, #60] ; 0x3c + 80043c0: 07db lsls r3, r3, #31 + 80043c2: f140 80e3 bpl.w 800458c + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + if(args->change_flags & CHANGE_DURESS_SECRET) { + 80043c6: 6e65 ldr r5, [r4, #100] ; 0x64 + 80043c8: f015 0510 ands.w r5, r5, #16 + 80043cc: f040 80e1 bne.w 8004592 + + // fetch the already-hashed pin + // - no real need to re-prove PIN knowledge. + // - if they tricked us, doesn't matter as below the SE validates it all again + uint8_t digest[32]; + pin_cache_restore(args, digest); + 80043d0: f10d 081c add.w r8, sp, #28 + 80043d4: 4641 mov r1, r8 + 80043d6: 4620 mov r0, r4 + 80043d8: f7ff fd62 bl 8003ea0 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 80043dc: 4b70 ldr r3, [pc, #448] ; (80045a0 ) + 80043de: 6c26 ldr r6, [r4, #64] ; 0x40 + 80043e0: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80043e4: 4073 eors r3, r6 + if(!slot || !is_trick) return is_trick; + 80043e6: 07df lsls r7, r3, #31 + 80043e8: d577 bpl.n 80044da + memset(slot, 0, sizeof(trick_slot_t)); + 80043ea: 2280 movs r2, #128 ; 0x80 + 80043ec: 4629 mov r1, r5 + 80043ee: a817 add r0, sp, #92 ; 0x5c + 80043f0: f009 f940 bl 800d674 + if(args->delay_required & TC_DELTA_MODE) { + 80043f4: 6b23 ldr r3, [r4, #48] ; 0x30 + 80043f6: 0558 lsls r0, r3, #21 + 80043f8: d52b bpl.n 8004452 + slot->tc_flags = args->delay_required; + 80043fa: f8ad 3060 strh.w r3, [sp, #96] ; 0x60 + slot->slot_num = -1; // unknown + 80043fe: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004402: 9317 str r3, [sp, #92] ; 0x5c + + // determine if we should proceed under duress + trick_slot_t slot; + bool is_trick = get_is_trick(args, &slot); + + if(is_trick && !(slot.tc_flags & TC_DELTA_MODE)) { + 8004404: f8bd 6060 ldrh.w r6, [sp, #96] ; 0x60 + 8004408: f416 6180 ands.w r1, r6, #1024 ; 0x400 + 800440c: d165 bne.n 80044da + // emulate a 24-word wallet, or xprv based wallet + // see stash.py for encoding details + memset(args->secret, 0, AE_SECRET_LEN); + 800440e: 2248 movs r2, #72 ; 0x48 + 8004410: f104 00b0 add.w r0, r4, #176 ; 0xb0 + 8004414: f009 f92e bl 800d674 + + if(slot.tc_flags & TC_WORD_WALLET) { + 8004418: 04f1 lsls r1, r6, #19 + 800441a: d54c bpl.n 80044b6 + if(check_all_zeros(&slot.xdata[16], 16)) { + 800441c: ae1d add r6, sp, #116 ; 0x74 + 800441e: 2110 movs r1, #16 + 8004420: 4630 mov r0, r6 + 8004422: f7fe f937 bl 8002694 + // 2nd half is zeros, must be 12-word wallet + args->secret[0] = 0x80; // 12 word phrase + memcpy(&args->secret[1], slot.xdata, 16); + 8004426: f104 03b1 add.w r3, r4, #177 ; 0xb1 + if(check_all_zeros(&slot.xdata[16], 16)) { + 800442a: 2800 cmp r0, #0 + 800442c: d034 beq.n 8004498 + args->secret[0] = 0x80; // 12 word phrase + 800442e: 2280 movs r2, #128 ; 0x80 + 8004430: f884 20b0 strb.w r2, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 16); + 8004434: ac19 add r4, sp, #100 ; 0x64 + 8004436: 4622 mov r2, r4 + 8004438: ca03 ldmia r2!, {r0, r1} + 800443a: 42b2 cmp r2, r6 + 800443c: 6018 str r0, [r3, #0] + 800443e: 6059 str r1, [r3, #4] + 8004440: 4614 mov r4, r2 + 8004442: f103 0308 add.w r3, r3, #8 + 8004446: d1f6 bne.n 8004436 + ae_reset_chip(); + + if(rv) return EPIN_AE_FAIL; + + return 0; +} + 8004448: 4628 mov r0, r5 + 800444a: f50d 7d38 add.w sp, sp, #736 ; 0x2e0 + 800444e: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8004452: 4f54 ldr r7, [pc, #336] ; (80045a4 ) + memcpy(key, &args->private_state, sizeof(args->private_state)); + 8004454: 960f str r6, [sp, #60] ; 0x3c + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8004456: cf0f ldmia r7!, {r0, r1, r2, r3} + 8004458: ae10 add r6, sp, #64 ; 0x40 + 800445a: c60f stmia r6!, {r0, r1, r2, r3} + 800445c: e897 0007 ldmia.w r7, {r0, r1, r2} + 8004460: e886 0007 stmia.w r6, {r0, r1, r2} + aes_init(&ctx); + 8004464: a837 add r0, sp, #220 ; 0xdc + 8004466: f003 fffb bl 8008460 + aes_add(&ctx, args->cached_main_pin, 32); + 800446a: 2220 movs r2, #32 + 800446c: f104 01f8 add.w r1, r4, #248 ; 0xf8 + 8004470: a837 add r0, sp, #220 ; 0xdc + 8004472: f003 fffb bl 800846c + aes_done(&ctx, (uint8_t *)slot, 32, key, NULL); + 8004476: a917 add r1, sp, #92 ; 0x5c + 8004478: 9500 str r5, [sp, #0] + 800447a: ab0f add r3, sp, #60 ; 0x3c + 800447c: 2220 movs r2, #32 + 800447e: a837 add r0, sp, #220 ; 0xdc + 8004480: f004 f80a bl 8008498 + if(slot->tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)) { + 8004484: f8bd 1060 ldrh.w r1, [sp, #96] ; 0x60 + 8004488: f411 5fc0 tst.w r1, #6144 ; 0x1800 + 800448c: d0ba beq.n 8004404 + se2_read_trick_data(slot->slot_num, slot->tc_flags, slot->xdata); + 800448e: 9817 ldr r0, [sp, #92] ; 0x5c + 8004490: aa19 add r2, sp, #100 ; 0x64 + 8004492: f003 fc87 bl 8007da4 + if(is_trick && !(slot.tc_flags & TC_DELTA_MODE)) { + 8004496: e7b5 b.n 8004404 + args->secret[0] = 0x82; // 24 word phrase + 8004498: 2282 movs r2, #130 ; 0x82 + 800449a: f884 20b0 strb.w r2, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 32); + 800449e: ae21 add r6, sp, #132 ; 0x84 + 80044a0: aa19 add r2, sp, #100 ; 0x64 + 80044a2: 4614 mov r4, r2 + 80044a4: cc03 ldmia r4!, {r0, r1} + 80044a6: 42b4 cmp r4, r6 + 80044a8: 6018 str r0, [r3, #0] + 80044aa: 6059 str r1, [r3, #4] + 80044ac: 4622 mov r2, r4 + 80044ae: f103 0308 add.w r3, r3, #8 + 80044b2: d1f6 bne.n 80044a2 + 80044b4: e7c8 b.n 8004448 + } else if(slot.tc_flags & TC_XPRV_WALLET) { + 80044b6: 0532 lsls r2, r6, #20 + 80044b8: d5c6 bpl.n 8004448 + args->secret[0] = 0x01; // XPRV mode + 80044ba: 2301 movs r3, #1 + 80044bc: f884 30b0 strb.w r3, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 64); + 80044c0: aa19 add r2, sp, #100 ; 0x64 + 80044c2: 34b1 adds r4, #177 ; 0xb1 + 80044c4: ae29 add r6, sp, #164 ; 0xa4 + 80044c6: 4613 mov r3, r2 + 80044c8: cb03 ldmia r3!, {r0, r1} + 80044ca: 42b3 cmp r3, r6 + 80044cc: 6020 str r0, [r4, #0] + 80044ce: 6061 str r1, [r4, #4] + 80044d0: 461a mov r2, r3 + 80044d2: f104 0408 add.w r4, r4, #8 + 80044d6: d1f6 bne.n 80044c6 + 80044d8: e7b6 b.n 8004448 + int which = (args->change_flags >> 8) & 0xf; + 80044da: 6e63 ldr r3, [r4, #100] ; 0x64 + 80044dc: 121b asrs r3, r3, #8 + switch(which) { + 80044de: f013 0f0c tst.w r3, #12 + 80044e2: d159 bne.n 8004598 + 80044e4: 4a30 ldr r2, [pc, #192] ; (80045a8 ) + int which = (args->change_flags >> 8) & 0xf; + 80044e6: f003 030f and.w r3, r3, #15 + 80044ea: f912 9003 ldrsb.w r9, [r2, r3] + if(kn < 0) return EPIN_RANGE_ERR; + 80044ee: f1b9 0f00 cmp.w r9, #0 + 80044f2: db51 blt.n 8004598 + 80044f4: 2703 movs r7, #3 + rv = ae_encrypted_read(kn, KEYNUM_main_pin, digest, tmp, AE_SECRET_LEN); + 80044f6: f04f 0a48 mov.w sl, #72 ; 0x48 + 80044fa: 2103 movs r1, #3 + 80044fc: f8cd a000 str.w sl, [sp] + 8004500: ab37 add r3, sp, #220 ; 0xdc + 8004502: 4642 mov r2, r8 + 8004504: 4648 mov r0, r9 + 8004506: f7fe fec3 bl 8003290 + if(rv) continue; + 800450a: 4601 mov r1, r0 + 800450c: b130 cbz r0, 800451c + for(int retry=0; retry<3; retry++) { + 800450e: 3f01 subs r7, #1 + 8004510: d1f3 bne.n 80044fa + ae_reset_chip(); + 8004512: f7fe fa49 bl 80029a8 + if(rv) return EPIN_AE_FAIL; + 8004516: f06f 0569 mvn.w r5, #105 ; 0x69 + 800451a: e795 b.n 8004448 + rv = ae_encrypted_read32(KEYNUM_check_secret, 0, KEYNUM_main_pin, digest, check); + 800451c: ae0f add r6, sp, #60 ; 0x3c + 800451e: 9600 str r6, [sp, #0] + 8004520: 4643 mov r3, r8 + 8004522: 2203 movs r2, #3 + 8004524: 200a movs r0, #10 + 8004526: f7fe fe88 bl 800323a + if(rv) continue; + 800452a: 4605 mov r5, r0 + 800452c: 2800 cmp r0, #0 + 800452e: d1ee bne.n 800450e + se2_decrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, digest, &is_valid); + 8004530: f10d 071b add.w r7, sp, #27 + 8004534: f104 00b0 add.w r0, r4, #176 ; 0xb0 + 8004538: ab37 add r3, sp, #220 ; 0xdc + 800453a: e9cd 8701 strd r8, r7, [sp, #4] + 800453e: 9600 str r6, [sp, #0] + 8004540: 462a mov r2, r5 + 8004542: 2148 movs r1, #72 ; 0x48 + 8004544: 9005 str r0, [sp, #20] + 8004546: f003 fe7d bl 8008244 + if(!is_valid) { + 800454a: f89d 301b ldrb.w r3, [sp, #27] + 800454e: 9805 ldr r0, [sp, #20] + 8004550: b993 cbnz r3, 8004578 + memset(args->secret, 0, AE_SECRET_LEN); + 8004552: 2248 movs r2, #72 ; 0x48 + 8004554: 4629 mov r1, r5 + 8004556: f009 f88d bl 800d674 + if(!(args->state_flags & PA_ZERO_SECRET)) { + 800455a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800455c: 06db lsls r3, r3, #27 + 800455e: d408 bmi.n 8004572 + args->state_flags |= PA_ZERO_SECRET; + 8004560: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004562: f043 0310 orr.w r3, r3, #16 + 8004566: 63e3 str r3, [r4, #60] ; 0x3c + _hmac_attempt(args, args->hmac); + 8004568: f104 0144 add.w r1, r4, #68 ; 0x44 + 800456c: 4620 mov r0, r4 + 800456e: f7ff faa3 bl 8003ab8 <_hmac_attempt> + ae_reset_chip(); + 8004572: f7fe fa19 bl 80029a8 + if(rv) return EPIN_AE_FAIL; + 8004576: e767 b.n 8004448 + if(!args->secret[0] && check_all_zeros(args->secret, AE_SECRET_LEN)) { + 8004578: f894 30b0 ldrb.w r3, [r4, #176] ; 0xb0 + 800457c: 2b00 cmp r3, #0 + 800457e: d1f8 bne.n 8004572 + 8004580: 2148 movs r1, #72 ; 0x48 + 8004582: f7fe f887 bl 8002694 + 8004586: 2800 cmp r0, #0 + 8004588: d0f3 beq.n 8004572 + 800458a: e7e9 b.n 8004560 + return EPIN_WRONG_SUCCESS; + 800458c: f06f 056c mvn.w r5, #108 ; 0x6c + 8004590: e75a b.n 8004448 + return EPIN_BAD_REQUEST; + 8004592: f06f 0567 mvn.w r5, #103 ; 0x67 + 8004596: e757 b.n 8004448 + if(kn < 0) return EPIN_RANGE_ERR; + 8004598: f06f 0566 mvn.w r5, #102 ; 0x66 + 800459c: e754 b.n 8004448 + 800459e: bf00 nop + 80045a0: 0801c000 .word 0x0801c000 + 80045a4: 0801c074 .word 0x0801c074 + 80045a8: 0800e71c .word 0x0800e71c + +080045ac : +// - new API so whole thing provided in one shot? encryption issues: provide +// "dest" and all 416 bytes end up there (read case only). +// + int +pin_long_secret(pinAttempt_t *args, uint8_t *dest) +{ + 80045ac: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 80045b0: 460f mov r7, r1 + 80045b2: b099 sub sp, #100 ; 0x64 + // Validate args and signature + int rv = _validate_attempt(args, false); + 80045b4: 2100 movs r1, #0 +{ + 80045b6: 4606 mov r6, r0 + int rv = _validate_attempt(args, false); + 80045b8: f7ff faac bl 8003b14 <_validate_attempt> + if(rv) return rv; + 80045bc: 4604 mov r4, r0 + 80045be: b9b8 cbnz r0, 80045f0 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80045c0: 6bf3 ldr r3, [r6, #60] ; 0x3c + 80045c2: 07da lsls r2, r3, #31 + 80045c4: f140 80a5 bpl.w 8004712 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 80045c8: 4b55 ldr r3, [pc, #340] ; (8004720 ) + 80045ca: 6c32 ldr r2, [r6, #64] ; 0x40 + 80045cc: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80045d0: 4053 eors r3, r2 + } + + // determine if we should proceed under duress/in some trick way + bool is_trick = get_is_trick(args, NULL); + + if(is_trick) { + 80045d2: 07db lsls r3, r3, #31 + 80045d4: d510 bpl.n 80045f8 + // Not supported in trick mode. Pretend it's all zeros. Accept all writes. + memset(args->secret, 0, 32); + 80045d6: 4601 mov r1, r0 + 80045d8: 2220 movs r2, #32 + 80045da: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 80045de: f009 f849 bl 800d674 + if(dest) memset(dest, 0, AE_LONG_SECRET_LEN); + 80045e2: b12f cbz r7, 80045f0 + 80045e4: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 80045e8: 4621 mov r1, r4 + 80045ea: 4638 mov r0, r7 + 80045ec: f009 f842 bl 800d674 + +se2_fail: + ae_reset_chip(); + + return EPIN_SE2_FAIL; +} + 80045f0: 4620 mov r0, r4 + 80045f2: b019 add sp, #100 ; 0x64 + 80045f4: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + int blk = (args->change_flags >> 8) & 0xf; + 80045f8: 6e73 ldr r3, [r6, #100] ; 0x64 + 80045fa: f3c3 2803 ubfx r8, r3, #8, #4 + if(blk > 13) return EPIN_RANGE_ERR; + 80045fe: f1b8 0f0d cmp.w r8, #13 + 8004602: f300 8089 bgt.w 8004718 + pin_cache_restore(args, digest); + 8004606: a908 add r1, sp, #32 + 8004608: 4630 mov r0, r6 + 800460a: f7ff fc49 bl 8003ea0 + if(!(args->change_flags & CHANGE_SECRET)) { + 800460e: 6e71 ldr r1, [r6, #100] ; 0x64 + 8004610: f011 0908 ands.w r9, r1, #8 + 8004614: d156 bne.n 80046c4 + if(!dest) { + 8004616: bb27 cbnz r7, 8004662 + rv = ae_encrypted_read32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, tmp); + 8004618: af10 add r7, sp, #64 ; 0x40 + 800461a: 9700 str r7, [sp, #0] + 800461c: ab08 add r3, sp, #32 + 800461e: 2203 movs r2, #3 + 8004620: 4641 mov r1, r8 + 8004622: 2008 movs r0, #8 + 8004624: f7fe fe09 bl 800323a + if(rv) goto fail; + 8004628: 4605 mov r5, r0 + 800462a: 2800 cmp r0, #0 + 800462c: d16a bne.n 8004704 + se2_decrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest, &is_valid); + 800462e: f10d 031f add.w r3, sp, #31 + 8004632: 9302 str r3, [sp, #8] + 8004634: ab08 add r3, sp, #32 + 8004636: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 800463a: e9cd 4300 strd r4, r3, [sp] + 800463e: ea4f 1248 mov.w r2, r8, lsl #5 + 8004642: 463b mov r3, r7 + 8004644: 2120 movs r1, #32 + 8004646: 9005 str r0, [sp, #20] + 8004648: f003 fdfc bl 8008244 + if(!is_valid) { + 800464c: f89d 301f ldrb.w r3, [sp, #31] + 8004650: 9805 ldr r0, [sp, #20] + 8004652: b91b cbnz r3, 800465c + memset(args->secret, 0, 32); + 8004654: 2220 movs r2, #32 + 8004656: 4621 mov r1, r4 + memset(dest, 0, AE_LONG_SECRET_LEN); + 8004658: f009 f80c bl 800d674 + ae_reset_chip(); + 800465c: f7fe f9a4 bl 80029a8 + if(rv) return EPIN_AE_FAIL; + 8004660: e7c6 b.n 80045f0 + 8004662: 463e mov r6, r7 + rv = ae_encrypted_read32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, p); + 8004664: 9600 str r6, [sp, #0] + 8004666: ab08 add r3, sp, #32 + 8004668: 2203 movs r2, #3 + 800466a: 4649 mov r1, r9 + 800466c: 2008 movs r0, #8 + 800466e: f7fe fde4 bl 800323a + if(rv) goto fail; + 8004672: 4605 mov r5, r0 + 8004674: 2800 cmp r0, #0 + 8004676: d145 bne.n 8004704 + for(blk=0; blk<13; blk++, p += 32) { + 8004678: f109 0901 add.w r9, r9, #1 + 800467c: f1b9 0f0d cmp.w r9, #13 + 8004680: f106 0620 add.w r6, r6, #32 + 8004684: d1ee bne.n 8004664 + ASSERT(p == dest+AE_LONG_SECRET_LEN); + 8004686: f507 73d0 add.w r3, r7, #416 ; 0x1a0 + 800468a: 429e cmp r6, r3 + 800468c: d002 beq.n 8004694 + 800468e: 4825 ldr r0, [pc, #148] ; (8004724 ) + 8004690: f7fc f9da bl 8000a48 + se2_decrypt_secret(dest, AE_LONG_SECRET_LEN, 0, dest, NULL, digest, &is_valid); + 8004694: ab10 add r3, sp, #64 ; 0x40 + 8004696: 9302 str r3, [sp, #8] + 8004698: ab08 add r3, sp, #32 + 800469a: e9cd 0300 strd r0, r3, [sp] + 800469e: 4602 mov r2, r0 + 80046a0: 463b mov r3, r7 + 80046a2: f44f 71d0 mov.w r1, #416 ; 0x1a0 + 80046a6: 4638 mov r0, r7 + 80046a8: f003 fdcc bl 8008244 + if(!is_valid) { + 80046ac: f89d 4040 ldrb.w r4, [sp, #64] ; 0x40 + 80046b0: b924 cbnz r4, 80046bc + memset(dest, 0, AE_LONG_SECRET_LEN); + 80046b2: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 80046b6: 4621 mov r1, r4 + 80046b8: 4638 mov r0, r7 + 80046ba: e7cd b.n 8004658 + ae_reset_chip(); + 80046bc: f7fe f974 bl 80029a8 + return 0; + 80046c0: 462c mov r4, r5 + 80046c2: e795 b.n 80045f0 + uint8_t tmp[32] = {0}; + 80046c4: 221c movs r2, #28 + 80046c6: 4621 mov r1, r4 + 80046c8: a811 add r0, sp, #68 ; 0x44 + 80046ca: 9410 str r4, [sp, #64] ; 0x40 + if(se2_encrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest)) { + 80046cc: ad10 add r5, sp, #64 ; 0x40 + uint8_t tmp[32] = {0}; + 80046ce: f008 ffd1 bl 800d674 + if(se2_encrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest)) { + 80046d2: ab08 add r3, sp, #32 + 80046d4: e9cd 4300 strd r4, r3, [sp] + 80046d8: ea4f 1248 mov.w r2, r8, lsl #5 + 80046dc: 462b mov r3, r5 + 80046de: 2120 movs r1, #32 + 80046e0: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 80046e4: f003 fd58 bl 8008198 + 80046e8: b120 cbz r0, 80046f4 + ae_reset_chip(); + 80046ea: f7fe f95d bl 80029a8 + return EPIN_SE2_FAIL; + 80046ee: f06f 0472 mvn.w r4, #114 ; 0x72 + 80046f2: e77d b.n 80045f0 + rv = ae_encrypted_write32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, tmp); + 80046f4: 9500 str r5, [sp, #0] + 80046f6: ab08 add r3, sp, #32 + 80046f8: 2203 movs r2, #3 + 80046fa: 4641 mov r1, r8 + 80046fc: 2008 movs r0, #8 + 80046fe: f7fe fe01 bl 8003304 + 8004702: 4605 mov r5, r0 + ae_reset_chip(); + 8004704: f7fe f950 bl 80029a8 + if(rv) return EPIN_AE_FAIL; + 8004708: 2d00 cmp r5, #0 + 800470a: bf18 it ne + 800470c: f06f 0469 mvnne.w r4, #105 ; 0x69 + 8004710: e76e b.n 80045f0 + return EPIN_WRONG_SUCCESS; + 8004712: f06f 046c mvn.w r4, #108 ; 0x6c + 8004716: e76b b.n 80045f0 + if(blk > 13) return EPIN_RANGE_ERR; + 8004718: f06f 0466 mvn.w r4, #102 ; 0x66 + 800471c: e768 b.n 80045f0 + 800471e: bf00 nop + 8004720: 0801c000 .word 0x0801c000 + 8004724: 0800e3e0 .word 0x0800e3e0 + +08004728 : +// +// Record current flash checksum and make green light go on. +// + int +pin_firmware_greenlight(pinAttempt_t *args) +{ + 8004728: b530 push {r4, r5, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 800472a: 2100 movs r1, #0 +{ + 800472c: b09b sub sp, #108 ; 0x6c + 800472e: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 8004730: f7ff f9f0 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 8004734: bb20 cbnz r0, 8004780 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 8004736: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004738: 07da lsls r2, r3, #31 + 800473a: d529 bpl.n 8004790 + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(args->is_secondary) { + 800473c: 6865 ldr r5, [r4, #4] + 800473e: bb55 cbnz r5, 8004796 + return EPIN_PRIMARY_ONLY; + } + + // load existing PIN's hash + uint8_t digest[32]; + pin_cache_restore(args, digest); + 8004740: a902 add r1, sp, #8 + 8004742: 4620 mov r0, r4 + 8004744: f7ff fbac bl 8003ea0 + + // step 1: calc the value to use + uint8_t fw_check[32], world_check[32]; + checksum_flash(fw_check, world_check, 0); + 8004748: 462a mov r2, r5 + 800474a: a912 add r1, sp, #72 ; 0x48 + 800474c: a80a add r0, sp, #40 ; 0x28 + 800474e: f7fd f973 bl 8001a38 + + // step 2: write it out to chip. + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004752: f7ff fa15 bl 8003b80 + 8004756: bb08 cbnz r0, 800479c + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004758: 4b12 ldr r3, [pc, #72] ; (80047a4 ) + 800475a: 6c22 ldr r2, [r4, #64] ; 0x40 + 800475c: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8004760: 4053 eors r3, r2 + + // under duress, we can't fake this, but we go through the motions anyway + if(!get_is_trick(args, NULL)) { + 8004762: 07db lsls r3, r3, #31 + 8004764: d40e bmi.n 8004784 + rv = ae_encrypted_write(KEYNUM_firmware, KEYNUM_main_pin, digest, world_check, 32); + 8004766: 2320 movs r3, #32 + 8004768: 9300 str r3, [sp, #0] + 800476a: aa02 add r2, sp, #8 + 800476c: ab12 add r3, sp, #72 ; 0x48 + 800476e: 2103 movs r1, #3 + 8004770: 200e movs r0, #14 + 8004772: f7fe fe2d bl 80033d0 + + if(rv) { + 8004776: b128 cbz r0, 8004784 + ae_reset_chip(); + 8004778: f7fe f916 bl 80029a8 + + return EPIN_AE_FAIL; + 800477c: f06f 0069 mvn.w r0, #105 ; 0x69 + + return EPIN_AE_FAIL; + } + + return 0; +} + 8004780: b01b add sp, #108 ; 0x6c + 8004782: bd30 pop {r4, r5, pc} + rv = ae_set_gpio_secure(world_check); + 8004784: a812 add r0, sp, #72 ; 0x48 + 8004786: f7fe feb5 bl 80034f4 + if(rv) { + 800478a: 2800 cmp r0, #0 + 800478c: d0f8 beq.n 8004780 + 800478e: e7f3 b.n 8004778 + return EPIN_WRONG_SUCCESS; + 8004790: f06f 006c mvn.w r0, #108 ; 0x6c + 8004794: e7f4 b.n 8004780 + return EPIN_PRIMARY_ONLY; + 8004796: f06f 0071 mvn.w r0, #113 ; 0x71 + 800479a: e7f1 b.n 8004780 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 800479c: f06f 0068 mvn.w r0, #104 ; 0x68 + 80047a0: e7ee b.n 8004780 + 80047a2: bf00 nop + 80047a4: 0801c000 .word 0x0801c000 + +080047a8 : +// Update the system firmware via file in PSRAM. Arrange for +// light to stay green through out process. +// + int +pin_firmware_upgrade(pinAttempt_t *args) +{ + 80047a8: b570 push {r4, r5, r6, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 80047aa: 2100 movs r1, #0 +{ + 80047ac: b092 sub sp, #72 ; 0x48 + 80047ae: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 80047b0: f7ff f9b0 bl 8003b14 <_validate_attempt> + if(rv) return rv; + 80047b4: 2800 cmp r0, #0 + 80047b6: d14e bne.n 8004856 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80047b8: 6be3 ldr r3, [r4, #60] ; 0x3c + 80047ba: 07da lsls r2, r3, #31 + 80047bc: d54d bpl.n 800485a + // must come here with a successful PIN login + return EPIN_WRONG_SUCCESS; + } + + if(args->change_flags != CHANGE_FIRMWARE) { + 80047be: 6e63 ldr r3, [r4, #100] ; 0x64 + 80047c0: 2b40 cmp r3, #64 ; 0x40 + 80047c2: d11c bne.n 80047fe + } + + // expecting start/length relative to psram start + uint32_t *about = (uint32_t *)args->secret; + uint32_t start = about[0]; + uint32_t len = about[1]; + 80047c4: e9d4 562c ldrd r5, r6, [r4, #176] ; 0xb0 + + if(len < 32768) return EPIN_RANGE_ERR; + 80047c8: f5a6 4300 sub.w r3, r6, #32768 ; 0x8000 + 80047cc: f5b3 1ffc cmp.w r3, #2064384 ; 0x1f8000 + 80047d0: d846 bhi.n 8004860 + if(len > 2<<20) return EPIN_RANGE_ERR; + if(start+len > PSRAM_SIZE) return EPIN_RANGE_ERR; + 80047d2: 19ab adds r3, r5, r6 + 80047d4: f5b3 0f00 cmp.w r3, #8388608 ; 0x800000 + 80047d8: d842 bhi.n 8004860 + + const uint8_t *data = (const uint8_t *)PSRAM_BASE+start; + 80047da: f105 4510 add.w r5, r5, #2415919104 ; 0x90000000 + + // verify a firmware image that's in RAM, and calc its digest + // - also applies watermark policy, etc + uint8_t world_check[32]; + bool ok = verify_firmware_in_ram(data, len, world_check); + 80047de: aa02 add r2, sp, #8 + 80047e0: 4631 mov r1, r6 + 80047e2: 4628 mov r0, r5 + 80047e4: f7fd fa36 bl 8001c54 + if(!ok) { + 80047e8: 2800 cmp r0, #0 + 80047ea: d03c beq.n 8004866 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 80047ec: 4b21 ldr r3, [pc, #132] ; (8004874 ) + 80047ee: 6c22 ldr r2, [r4, #64] ; 0x40 + 80047f0: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80047f4: 4053 eors r3, r2 + return EPIN_AUTH_FAIL; + } + + // under duress, we can't fake this, so kill ourselves. + if(get_is_trick(args, NULL)) { + 80047f6: 07db lsls r3, r3, #31 + 80047f8: d504 bpl.n 8004804 + // User is a thug.. kill secret and reboot w/o any notice + fast_wipe(); + 80047fa: f7fd ff1f bl 800263c + return EPIN_BAD_REQUEST; + 80047fe: f06f 0067 mvn.w r0, #103 ; 0x67 + 8004802: e028 b.n 8004856 + return EPIN_BAD_REQUEST; + } + + // load existing PIN's hash + uint8_t digest[32]; + pin_cache_restore(args, digest); + 8004804: a90a add r1, sp, #40 ; 0x28 + 8004806: 4620 mov r0, r4 + 8004808: f7ff fb4a bl 8003ea0 + + // step 1: calc the value to use, see above + if(warmup_ae()) return EPIN_I_AM_BRICK; + 800480c: f7ff f9b8 bl 8003b80 + 8004810: bb60 cbnz r0, 800486c + + // step 2: write it out to chip. + rv = ae_encrypted_write(KEYNUM_firmware, KEYNUM_main_pin, digest, world_check, 32); + 8004812: 2320 movs r3, #32 + 8004814: 9300 str r3, [sp, #0] + 8004816: aa0a add r2, sp, #40 ; 0x28 + 8004818: ab02 add r3, sp, #8 + 800481a: 2103 movs r1, #3 + 800481c: 200e movs r0, #14 + 800481e: f7fe fdd7 bl 80033d0 + if(rv) goto fail; + 8004822: b9a0 cbnz r0, 800484e + + // this turns on green light + rv = ae_set_gpio_secure(world_check); + 8004824: a802 add r0, sp, #8 + 8004826: f7fe fe65 bl 80034f4 + if(rv) goto fail; + 800482a: b980 cbnz r0, 800484e + + // -- point of no return -- + + // burn it, shows progress + psram_do_upgrade(data, len); + 800482c: 4631 mov r1, r6 + 800482e: 4628 mov r0, r5 + 8004830: f000 fbf4 bl 800501c + 8004834: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8004838: 490f ldr r1, [pc, #60] ; (8004878 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800483a: 4b10 ldr r3, [pc, #64] ; (800487c ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 800483c: 68ca ldr r2, [r1, #12] + 800483e: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8004842: 4313 orrs r3, r2 + 8004844: 60cb str r3, [r1, #12] + 8004846: f3bf 8f4f dsb sy + __NOP(); + 800484a: bf00 nop + for(;;) /* wait until reset */ + 800484c: e7fd b.n 800484a + NVIC_SystemReset(); + + return 0; + +fail: + ae_reset_chip(); + 800484e: f7fe f8ab bl 80029a8 + + return EPIN_AE_FAIL; + 8004852: f06f 0069 mvn.w r0, #105 ; 0x69 +} + 8004856: b012 add sp, #72 ; 0x48 + 8004858: bd70 pop {r4, r5, r6, pc} + return EPIN_WRONG_SUCCESS; + 800485a: f06f 006c mvn.w r0, #108 ; 0x6c + 800485e: e7fa b.n 8004856 + if(len < 32768) return EPIN_RANGE_ERR; + 8004860: f06f 0066 mvn.w r0, #102 ; 0x66 + 8004864: e7f7 b.n 8004856 + return EPIN_AUTH_FAIL; + 8004866: f06f 006f mvn.w r0, #111 ; 0x6f + 800486a: e7f4 b.n 8004856 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 800486c: f06f 0068 mvn.w r0, #104 ; 0x68 + 8004870: e7f1 b.n 8004856 + 8004872: bf00 nop + 8004874: 0801c000 .word 0x0801c000 + 8004878: e000ed00 .word 0xe000ed00 + 800487c: 05fa0004 .word 0x05fa0004 + +08004880 : + +// strcat_hex() +// + void +strcat_hex(char *msg, const void *d, int len) +{ + 8004880: b570 push {r4, r5, r6, lr} + 8004882: 4616 mov r6, r2 + 8004884: 4604 mov r4, r0 + 8004886: 460d mov r5, r1 + char *p = msg+strlen(msg); + 8004888: f008 ff27 bl 800d6da + const uint8_t *h = (const uint8_t *)d; + + for(; len; len--, h++) { + *(p++) = hexmap[(*h>>4) & 0xf]; + 800488c: 4a0b ldr r2, [pc, #44] ; (80048bc ) + char *p = msg+strlen(msg); + 800488e: 4420 add r0, r4 + for(; len; len--, h++) { + 8004890: 1e69 subs r1, r5, #1 + 8004892: eb00 0646 add.w r6, r0, r6, lsl #1 + 8004896: 42b0 cmp r0, r6 + 8004898: d102 bne.n 80048a0 + *(p++) = hexmap[(*h>>0) & 0xf]; + } + + *(p++) = 0; + 800489a: 2300 movs r3, #0 + 800489c: 7003 strb r3, [r0, #0] +} + 800489e: bd70 pop {r4, r5, r6, pc} + *(p++) = hexmap[(*h>>4) & 0xf]; + 80048a0: f811 3f01 ldrb.w r3, [r1, #1]! + 80048a4: 091b lsrs r3, r3, #4 + 80048a6: 5cd3 ldrb r3, [r2, r3] + 80048a8: f800 3b02 strb.w r3, [r0], #2 + *(p++) = hexmap[(*h>>0) & 0xf]; + 80048ac: 780b ldrb r3, [r1, #0] + 80048ae: f003 030f and.w r3, r3, #15 + 80048b2: 5cd3 ldrb r3, [r2, r3] + 80048b4: f800 3c01 strb.w r3, [r0, #-1] + for(; len; len--, h++) { + 80048b8: e7ed b.n 8004896 + 80048ba: bf00 nop + 80048bc: 0800e752 .word 0x0800e752 + +080048c0 : + * parameters in the USART_InitTypeDef and initialize the associated handle. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) +{ + 80048c0: b5f8 push {r3, r4, r5, r6, r7, lr} + /* Check the USART handle allocation */ + if (husart == NULL) + 80048c2: 4604 mov r4, r0 + 80048c4: b910 cbnz r0, 80048cc + { + return HAL_ERROR; + 80048c6: 2501 movs r5, #1 + /* Enable the Peripheral */ + __HAL_USART_ENABLE(husart); + + /* TEACK and/or REACK to check before moving husart->State to Ready */ + return (USART_CheckIdleState(husart)); +} + 80048c8: 4628 mov r0, r5 + 80048ca: bdf8 pop {r3, r4, r5, r6, r7, pc} + if (husart->State == HAL_USART_STATE_RESET) + 80048cc: f890 3059 ldrb.w r3, [r0, #89] ; 0x59 + 80048d0: f003 02ff and.w r2, r3, #255 ; 0xff + 80048d4: b90b cbnz r3, 80048da + husart->Lock = HAL_UNLOCKED; + 80048d6: f880 2058 strb.w r2, [r0, #88] ; 0x58 + __HAL_USART_DISABLE(husart); + 80048da: 6823 ldr r3, [r4, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 80048dc: 6921 ldr r1, [r4, #16] + husart->State = HAL_USART_STATE_BUSY; + 80048de: 2502 movs r5, #2 + 80048e0: f884 5059 strb.w r5, [r4, #89] ; 0x59 + __HAL_USART_DISABLE(husart); + 80048e4: 681a ldr r2, [r3, #0] + 80048e6: f022 0201 bic.w r2, r2, #1 + 80048ea: 601a str r2, [r3, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 80048ec: 68a2 ldr r2, [r4, #8] + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 80048ee: 6818 ldr r0, [r3, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 80048f0: 430a orrs r2, r1 + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 80048f2: 49a9 ldr r1, [pc, #676] ; (8004b98 ) + 80048f4: 4001 ands r1, r0 + 80048f6: 430a orrs r2, r1 + 80048f8: 6961 ldr r1, [r4, #20] + MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); + 80048fa: 69a0 ldr r0, [r4, #24] + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 80048fc: 430a orrs r2, r1 + 80048fe: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 8004902: 601a str r2, [r3, #0] + MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); + 8004904: 6859 ldr r1, [r3, #4] + 8004906: 6a22 ldr r2, [r4, #32] + 8004908: f421 517c bic.w r1, r1, #16128 ; 0x3f00 + 800490c: f021 0109 bic.w r1, r1, #9 + 8004910: 4302 orrs r2, r0 + 8004912: 430a orrs r2, r1 + 8004914: 69e1 ldr r1, [r4, #28] + 8004916: 430a orrs r2, r1 + 8004918: 68e1 ldr r1, [r4, #12] + 800491a: 430a orrs r2, r1 + 800491c: f442 6200 orr.w r2, r2, #2048 ; 0x800 + 8004920: 605a str r2, [r3, #4] + MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler); + 8004922: 6ad9 ldr r1, [r3, #44] ; 0x2c + 8004924: 6a62 ldr r2, [r4, #36] ; 0x24 + 8004926: f021 010f bic.w r1, r1, #15 + 800492a: 4311 orrs r1, r2 + 800492c: 62d9 str r1, [r3, #44] ; 0x2c + USART_GETCLOCKSOURCE(husart, clocksource); + 800492e: 499b ldr r1, [pc, #620] ; (8004b9c ) + 8004930: 428b cmp r3, r1 + 8004932: d10e bne.n 8004952 + 8004934: 4b9a ldr r3, [pc, #616] ; (8004ba0 ) + 8004936: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 800493a: f003 0303 and.w r3, r3, #3 + 800493e: 42ab cmp r3, r5 + 8004940: f000 80cd beq.w 8004ade + 8004944: 2b03 cmp r3, #3 + 8004946: d01a beq.n 800497e + 8004948: 2b01 cmp r3, #1 + 800494a: d153 bne.n 80049f4 + pclk = HAL_RCC_GetSysClockFreq(); + 800494c: f003 ff3e bl 80087cc + 8004950: e052 b.n 80049f8 + USART_GETCLOCKSOURCE(husart, clocksource); + 8004952: 4994 ldr r1, [pc, #592] ; (8004ba4 ) + 8004954: 428b cmp r3, r1 + 8004956: d13c bne.n 80049d2 + 8004958: 4b91 ldr r3, [pc, #580] ; (8004ba0 ) + 800495a: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 800495e: f003 030c and.w r3, r3, #12 + 8004962: 2b08 cmp r3, #8 + 8004964: f000 80bb beq.w 8004ade + 8004968: d807 bhi.n 800497a + 800496a: 2b00 cmp r3, #0 + 800496c: f000 80b4 beq.w 8004ad8 + 8004970: 2b04 cmp r3, #4 + 8004972: d0eb beq.n 800494c + uint32_t usartdiv = 0x00000000; + 8004974: 2300 movs r3, #0 + ret = HAL_ERROR; + 8004976: 2501 movs r5, #1 + 8004978: e06e b.n 8004a58 + USART_GETCLOCKSOURCE(husart, clocksource); + 800497a: 2b0c cmp r3, #12 + 800497c: d1fa bne.n 8004974 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 800497e: 2a00 cmp r2, #0 + 8004980: f000 80fb beq.w 8004b7a + 8004984: 2a01 cmp r2, #1 + 8004986: f000 80fa beq.w 8004b7e + 800498a: 2a02 cmp r2, #2 + 800498c: f000 80f9 beq.w 8004b82 + 8004990: 2a03 cmp r2, #3 + 8004992: f000 80f8 beq.w 8004b86 + 8004996: 2a04 cmp r2, #4 + 8004998: f000 80f7 beq.w 8004b8a + 800499c: 2a05 cmp r2, #5 + 800499e: f000 80f6 beq.w 8004b8e + 80049a2: 2a06 cmp r2, #6 + 80049a4: f000 80f5 beq.w 8004b92 + 80049a8: 2a07 cmp r2, #7 + 80049aa: f000 8101 beq.w 8004bb0 + 80049ae: 2a08 cmp r2, #8 + 80049b0: f000 8100 beq.w 8004bb4 + 80049b4: 2a09 cmp r2, #9 + 80049b6: f000 80ff beq.w 8004bb8 + 80049ba: 2a0a cmp r2, #10 + 80049bc: f000 80fe beq.w 8004bbc + 80049c0: 2a0b cmp r2, #11 + 80049c2: bf14 ite ne + 80049c4: 2201 movne r2, #1 + 80049c6: f44f 7280 moveq.w r2, #256 ; 0x100 + 80049ca: 6861 ldr r1, [r4, #4] + 80049cc: f44f 4300 mov.w r3, #32768 ; 0x8000 + 80049d0: e0a1 b.n 8004b16 + USART_GETCLOCKSOURCE(husart, clocksource); + 80049d2: 4975 ldr r1, [pc, #468] ; (8004ba8 ) + 80049d4: 428b cmp r3, r1 + 80049d6: d1cd bne.n 8004974 + 80049d8: 4b71 ldr r3, [pc, #452] ; (8004ba0 ) + 80049da: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 80049de: f003 0330 and.w r3, r3, #48 ; 0x30 + 80049e2: 2b20 cmp r3, #32 + 80049e4: d07b beq.n 8004ade + 80049e6: d803 bhi.n 80049f0 + 80049e8: 2b00 cmp r3, #0 + 80049ea: d075 beq.n 8004ad8 + 80049ec: 2b10 cmp r3, #16 + 80049ee: e7c0 b.n 8004972 + 80049f0: 2b30 cmp r3, #48 ; 0x30 + 80049f2: e7c3 b.n 800497c + pclk = HAL_RCC_GetPCLK2Freq(); + 80049f4: f004 faf8 bl 8008fe8 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 80049f8: 6a62 ldr r2, [r4, #36] ; 0x24 + 80049fa: 2a00 cmp r2, #0 + 80049fc: f000 80a7 beq.w 8004b4e + 8004a00: 2a01 cmp r2, #1 + 8004a02: f000 80a6 beq.w 8004b52 + 8004a06: 2a02 cmp r2, #2 + 8004a08: f000 80a5 beq.w 8004b56 + 8004a0c: 2a03 cmp r2, #3 + 8004a0e: f000 80a4 beq.w 8004b5a + 8004a12: 2a04 cmp r2, #4 + 8004a14: f000 80a3 beq.w 8004b5e + 8004a18: 2a05 cmp r2, #5 + 8004a1a: f000 80a2 beq.w 8004b62 + 8004a1e: 2a06 cmp r2, #6 + 8004a20: f000 80a1 beq.w 8004b66 + 8004a24: 2a07 cmp r2, #7 + 8004a26: f000 80a0 beq.w 8004b6a + 8004a2a: 2a08 cmp r2, #8 + 8004a2c: f000 809f beq.w 8004b6e + 8004a30: 2a09 cmp r2, #9 + 8004a32: f000 809e beq.w 8004b72 + 8004a36: 2a0a cmp r2, #10 + 8004a38: f000 809d beq.w 8004b76 + 8004a3c: 2a0b cmp r2, #11 + 8004a3e: bf14 ite ne + 8004a40: 2201 movne r2, #1 + 8004a42: f44f 7280 moveq.w r2, #256 ; 0x100 + 8004a46: 6861 ldr r1, [r4, #4] + 8004a48: fbb0 f0f2 udiv r0, r0, r2 + 8004a4c: 084b lsrs r3, r1, #1 + 8004a4e: eb03 0340 add.w r3, r3, r0, lsl #1 + HAL_StatusTypeDef ret = HAL_OK; + 8004a52: 2500 movs r5, #0 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004a54: fbb3 f3f1 udiv r3, r3, r1 + if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX)) + 8004a58: f1a3 0110 sub.w r1, r3, #16 + 8004a5c: f64f 72ef movw r2, #65519 ; 0xffef + 8004a60: 4291 cmp r1, r2 + brrtemp = (uint16_t)(usartdiv & 0xFFF0U); + 8004a62: bf9f itttt ls + 8004a64: f023 020f bicls.w r2, r3, #15 + 8004a68: b292 uxthls r2, r2 + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + 8004a6a: f3c3 0342 ubfxls r3, r3, #1, #3 + husart->Instance->BRR = brrtemp; + 8004a6e: 6821 ldrls r1, [r4, #0] + 8004a70: bf9a itte ls + 8004a72: 4313 orrls r3, r2 + 8004a74: 60cb strls r3, [r1, #12] + ret = HAL_ERROR; + 8004a76: 2501 movhi r5, #1 + husart->NbTxDataToProcess = 1U; + 8004a78: 2301 movs r3, #1 + husart->RxISR = NULL; + 8004a7a: 2200 movs r2, #0 + if (USART_SetConfig(husart) == HAL_ERROR) + 8004a7c: 429d cmp r5, r3 + husart->TxISR = NULL; + 8004a7e: e9c4 2212 strd r2, r2, [r4, #72] ; 0x48 + husart->NbTxDataToProcess = 1U; + 8004a82: 87a3 strh r3, [r4, #60] ; 0x3c + husart->NbRxDataToProcess = 1U; + 8004a84: 8763 strh r3, [r4, #58] ; 0x3a + if (USART_SetConfig(husart) == HAL_ERROR) + 8004a86: f43f af1e beq.w 80048c6 + husart->Instance->CR2 &= ~USART_CR2_LINEN; + 8004a8a: 6823 ldr r3, [r4, #0] + 8004a8c: 6859 ldr r1, [r3, #4] + 8004a8e: f421 4180 bic.w r1, r1, #16384 ; 0x4000 + 8004a92: 6059 str r1, [r3, #4] + husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + 8004a94: 6899 ldr r1, [r3, #8] + 8004a96: f021 012a bic.w r1, r1, #42 ; 0x2a + 8004a9a: 6099 str r1, [r3, #8] + __HAL_USART_ENABLE(husart); + 8004a9c: 6819 ldr r1, [r3, #0] + 8004a9e: f041 0101 orr.w r1, r1, #1 + 8004aa2: 6019 str r1, [r3, #0] + husart->ErrorCode = HAL_USART_ERROR_NONE; + 8004aa4: 65e2 str r2, [r4, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8004aa6: f002 fb21 bl 80070ec + if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + 8004aaa: 6823 ldr r3, [r4, #0] + 8004aac: 681b ldr r3, [r3, #0] + 8004aae: 071a lsls r2, r3, #28 + tickstart = HAL_GetTick(); + 8004ab0: 4607 mov r7, r0 + if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + 8004ab2: f100 8085 bmi.w 8004bc0 + if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + 8004ab6: 6823 ldr r3, [r4, #0] + 8004ab8: 681b ldr r3, [r3, #0] + 8004aba: 075b lsls r3, r3, #29 + 8004abc: d505 bpl.n 8004aca + while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + 8004abe: 6823 ldr r3, [r4, #0] + 8004ac0: 69de ldr r6, [r3, #28] + 8004ac2: f416 0680 ands.w r6, r6, #4194304 ; 0x400000 + 8004ac6: f000 808e beq.w 8004be6 + husart->State = HAL_USART_STATE_READY; + 8004aca: 2301 movs r3, #1 + 8004acc: f884 3059 strb.w r3, [r4, #89] ; 0x59 + __HAL_UNLOCK(husart); + 8004ad0: 2300 movs r3, #0 + 8004ad2: f884 3058 strb.w r3, [r4, #88] ; 0x58 + return HAL_OK; + 8004ad6: e6f7 b.n 80048c8 + pclk = HAL_RCC_GetPCLK1Freq(); + 8004ad8: f004 fa74 bl 8008fc4 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004adc: e78c b.n 80049f8 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004ade: b302 cbz r2, 8004b22 + 8004ae0: 2a01 cmp r2, #1 + 8004ae2: d020 beq.n 8004b26 + 8004ae4: 2a02 cmp r2, #2 + 8004ae6: d020 beq.n 8004b2a + 8004ae8: 2a03 cmp r2, #3 + 8004aea: d020 beq.n 8004b2e + 8004aec: 2a04 cmp r2, #4 + 8004aee: d020 beq.n 8004b32 + 8004af0: 2a05 cmp r2, #5 + 8004af2: d020 beq.n 8004b36 + 8004af4: 2a06 cmp r2, #6 + 8004af6: d020 beq.n 8004b3a + 8004af8: 2a07 cmp r2, #7 + 8004afa: d020 beq.n 8004b3e + 8004afc: 2a08 cmp r2, #8 + 8004afe: d020 beq.n 8004b42 + 8004b00: 2a09 cmp r2, #9 + 8004b02: d020 beq.n 8004b46 + 8004b04: 2a0a cmp r2, #10 + 8004b06: d020 beq.n 8004b4a + 8004b08: 2a0b cmp r2, #11 + 8004b0a: bf14 ite ne + 8004b0c: 2201 movne r2, #1 + 8004b0e: f44f 7280 moveq.w r2, #256 ; 0x100 + 8004b12: 6861 ldr r1, [r4, #4] + 8004b14: 4b25 ldr r3, [pc, #148] ; (8004bac ) + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004b16: fbb3 f2f2 udiv r2, r3, r2 + 8004b1a: 084b lsrs r3, r1, #1 + 8004b1c: eb03 0342 add.w r3, r3, r2, lsl #1 + 8004b20: e797 b.n 8004a52 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004b22: 2201 movs r2, #1 + 8004b24: e7f5 b.n 8004b12 + 8004b26: 2202 movs r2, #2 + 8004b28: e7f3 b.n 8004b12 + 8004b2a: 2204 movs r2, #4 + 8004b2c: e7f1 b.n 8004b12 + 8004b2e: 2206 movs r2, #6 + 8004b30: e7ef b.n 8004b12 + 8004b32: 2208 movs r2, #8 + 8004b34: e7ed b.n 8004b12 + 8004b36: 220a movs r2, #10 + 8004b38: e7eb b.n 8004b12 + 8004b3a: 220c movs r2, #12 + 8004b3c: e7e9 b.n 8004b12 + 8004b3e: 2210 movs r2, #16 + 8004b40: e7e7 b.n 8004b12 + 8004b42: 2220 movs r2, #32 + 8004b44: e7e5 b.n 8004b12 + 8004b46: 2240 movs r2, #64 ; 0x40 + 8004b48: e7e3 b.n 8004b12 + 8004b4a: 2280 movs r2, #128 ; 0x80 + 8004b4c: e7e1 b.n 8004b12 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004b4e: 2201 movs r2, #1 + 8004b50: e779 b.n 8004a46 + 8004b52: 2202 movs r2, #2 + 8004b54: e777 b.n 8004a46 + 8004b56: 2204 movs r2, #4 + 8004b58: e775 b.n 8004a46 + 8004b5a: 2206 movs r2, #6 + 8004b5c: e773 b.n 8004a46 + 8004b5e: 2208 movs r2, #8 + 8004b60: e771 b.n 8004a46 + 8004b62: 220a movs r2, #10 + 8004b64: e76f b.n 8004a46 + 8004b66: 220c movs r2, #12 + 8004b68: e76d b.n 8004a46 + 8004b6a: 2210 movs r2, #16 + 8004b6c: e76b b.n 8004a46 + 8004b6e: 2220 movs r2, #32 + 8004b70: e769 b.n 8004a46 + 8004b72: 2240 movs r2, #64 ; 0x40 + 8004b74: e767 b.n 8004a46 + 8004b76: 2280 movs r2, #128 ; 0x80 + 8004b78: e765 b.n 8004a46 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004b7a: 2201 movs r2, #1 + 8004b7c: e725 b.n 80049ca + 8004b7e: 2202 movs r2, #2 + 8004b80: e723 b.n 80049ca + 8004b82: 2204 movs r2, #4 + 8004b84: e721 b.n 80049ca + 8004b86: 2206 movs r2, #6 + 8004b88: e71f b.n 80049ca + 8004b8a: 2208 movs r2, #8 + 8004b8c: e71d b.n 80049ca + 8004b8e: 220a movs r2, #10 + 8004b90: e71b b.n 80049ca + 8004b92: 220c movs r2, #12 + 8004b94: e719 b.n 80049ca + 8004b96: bf00 nop + 8004b98: cfff69f3 .word 0xcfff69f3 + 8004b9c: 40013800 .word 0x40013800 + 8004ba0: 40021000 .word 0x40021000 + 8004ba4: 40004400 .word 0x40004400 + 8004ba8: 40004800 .word 0x40004800 + 8004bac: 00f42400 .word 0x00f42400 + 8004bb0: 2210 movs r2, #16 + 8004bb2: e70a b.n 80049ca + 8004bb4: 2220 movs r2, #32 + 8004bb6: e708 b.n 80049ca + 8004bb8: 2240 movs r2, #64 ; 0x40 + 8004bba: e706 b.n 80049ca + 8004bbc: 2280 movs r2, #128 ; 0x80 + 8004bbe: e704 b.n 80049ca + while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + 8004bc0: 6823 ldr r3, [r4, #0] + 8004bc2: 69de ldr r6, [r3, #28] + 8004bc4: f416 1600 ands.w r6, r6, #2097152 ; 0x200000 + 8004bc8: f47f af75 bne.w 8004ab6 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 8004bcc: f002 fa8e bl 80070ec + 8004bd0: 1bc0 subs r0, r0, r7 + 8004bd2: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8 + 8004bd6: d9f3 bls.n 8004bc0 + husart->State = HAL_USART_STATE_READY; + 8004bd8: 2301 movs r3, #1 + 8004bda: f884 3059 strb.w r3, [r4, #89] ; 0x59 + __HAL_UNLOCK(husart); + 8004bde: f884 6058 strb.w r6, [r4, #88] ; 0x58 + return HAL_TIMEOUT; + 8004be2: 2503 movs r5, #3 + 8004be4: e670 b.n 80048c8 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 8004be6: f002 fa81 bl 80070ec + 8004bea: 1bc0 subs r0, r0, r7 + 8004bec: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8 + 8004bf0: f67f af65 bls.w 8004abe + 8004bf4: e7f0 b.n 8004bd8 + 8004bf6: bf00 nop + +08004bf8 : + __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); + 8004bf8: 4b14 ldr r3, [pc, #80] ; (8004c4c ) + 8004bfa: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8004bfe: f022 0203 bic.w r2, r2, #3 + 8004c02: f042 0201 orr.w r2, r2, #1 +{ + 8004c06: b513 push {r0, r1, r4, lr} + __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); + 8004c08: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + __HAL_RCC_USART1_CLK_ENABLE(); + 8004c0c: 6e1a ldr r2, [r3, #96] ; 0x60 + memset(&con, 0, sizeof(con)); + 8004c0e: 4c10 ldr r4, [pc, #64] ; (8004c50 ) + __HAL_RCC_USART1_CLK_ENABLE(); + 8004c10: f442 4280 orr.w r2, r2, #16384 ; 0x4000 + 8004c14: 661a str r2, [r3, #96] ; 0x60 + 8004c16: 6e1b ldr r3, [r3, #96] ; 0x60 + 8004c18: f403 4380 and.w r3, r3, #16384 ; 0x4000 + 8004c1c: 9301 str r3, [sp, #4] + memset(&con, 0, sizeof(con)); + 8004c1e: 2258 movs r2, #88 ; 0x58 + 8004c20: 2100 movs r1, #0 + 8004c22: f104 0008 add.w r0, r4, #8 + __HAL_RCC_USART1_CLK_ENABLE(); + 8004c26: 9b01 ldr r3, [sp, #4] + memset(&con, 0, sizeof(con)); + 8004c28: f008 fd24 bl 800d674 + con.Init.BaudRate = 115200; + 8004c2c: 4a09 ldr r2, [pc, #36] ; (8004c54 ) + 8004c2e: f44f 33e1 mov.w r3, #115200 ; 0x1c200 + 8004c32: e9c4 2300 strd r2, r3, [r4] + HAL_StatusTypeDef rv = HAL_USART_Init(&con); + 8004c36: 4620 mov r0, r4 + con.Init.Mode = USART_MODE_TX_RX; + 8004c38: 230c movs r3, #12 + 8004c3a: 6163 str r3, [r4, #20] + HAL_StatusTypeDef rv = HAL_USART_Init(&con); + 8004c3c: f7ff fe40 bl 80048c0 + ASSERT(rv == HAL_OK); + 8004c40: b110 cbz r0, 8004c48 + 8004c42: 4805 ldr r0, [pc, #20] ; (8004c58 ) + 8004c44: f7fb ff00 bl 8000a48 +} + 8004c48: b002 add sp, #8 + 8004c4a: bd10 pop {r4, pc} + 8004c4c: 40021000 .word 0x40021000 + 8004c50: 2009e1c0 .word 0x2009e1c0 + 8004c54: 40013800 .word 0x40013800 + 8004c58: 0800e3e0 .word 0x0800e3e0 + +08004c5c : + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) +{ + while(Size > 0U) { + 8004c5c: 4b0b ldr r3, [pc, #44] ; (8004c8c ) + 8004c5e: 440a add r2, r1 + 8004c60: 4291 cmp r1, r2 + 8004c62: d10b bne.n 8004c7c + MY_UART->TDR = *pTxData; + pTxData++; + Size --; + } + + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 8004c64: 69da ldr r2, [r3, #28] + 8004c66: 0652 lsls r2, r2, #25 + 8004c68: d5fc bpl.n 8004c64 + // wait for final byte to be sent + } + + // Clear Transmission Complete Flag + MY_UART->ICR = USART_CLEAR_TCF; + 8004c6a: 2240 movs r2, #64 ; 0x40 + 8004c6c: 621a str r2, [r3, #32] + + // Clear overrun flag and discard the received data + MY_UART->ICR = USART_CLEAR_OREF; + 8004c6e: 2208 movs r2, #8 + 8004c70: 621a str r2, [r3, #32] + MY_UART->RQR = USART_RXDATA_FLUSH_REQUEST; + 8004c72: 831a strh r2, [r3, #24] + MY_UART->RQR = USART_TXDATA_FLUSH_REQUEST; + 8004c74: 2210 movs r2, #16 + 8004c76: 831a strh r2, [r3, #24] + + return HAL_OK; +} + 8004c78: 2000 movs r0, #0 + 8004c7a: 4770 bx lr + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 8004c7c: 69d8 ldr r0, [r3, #28] + 8004c7e: 0600 lsls r0, r0, #24 + 8004c80: d5fc bpl.n 8004c7c + MY_UART->TDR = *pTxData; + 8004c82: f811 0b01 ldrb.w r0, [r1], #1 + 8004c86: 8518 strh r0, [r3, #40] ; 0x28 + Size --; + 8004c88: e7ea b.n 8004c60 + 8004c8a: bf00 nop + 8004c8c: 40013800 .word 0x40013800 + +08004c90 : +{ + 8004c90: b510 push {r4, lr} + 8004c92: 4604 mov r4, r0 + rng_delay(); + 8004c94: f7fd fd72 bl 800277c + HAL_USART_Transmit(&con, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY); + 8004c98: 4620 mov r0, r4 + 8004c9a: f008 fd1e bl 800d6da + 8004c9e: 4621 mov r1, r4 + 8004ca0: b282 uxth r2, r0 + 8004ca2: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004ca6: 4803 ldr r0, [pc, #12] ; (8004cb4 ) + 8004ca8: f7ff ffd8 bl 8004c5c +} + 8004cac: e8bd 4010 ldmia.w sp!, {r4, lr} + rng_delay(); + 8004cb0: f7fd bd64 b.w 800277c + 8004cb4: 2009e1c0 .word 0x2009e1c0 + +08004cb8 : +{ + 8004cb8: b513 push {r0, r1, r4, lr} + 8004cba: 4604 mov r4, r0 + uint8_t cb = c; + 8004cbc: f88d 0007 strb.w r0, [sp, #7] + rng_delay(); + 8004cc0: f7fd fd5c bl 800277c + if(cb != '\n') { + 8004cc4: f89d 3007 ldrb.w r3, [sp, #7] + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004cc8: 4808 ldr r0, [pc, #32] ; (8004cec ) + if(cb != '\n') { + 8004cca: 2b0a cmp r3, #10 + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004ccc: bf08 it eq + 8004cce: 4908 ldreq r1, [pc, #32] ; (8004cf0 ) + HAL_USART_Transmit(&con, &cb, 1, HAL_MAX_DELAY); + 8004cd0: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004cd4: bf1a itte ne + 8004cd6: 2201 movne r2, #1 + 8004cd8: f10d 0107 addne.w r1, sp, #7 + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004cdc: 2202 moveq r2, #2 + 8004cde: f7ff ffbd bl 8004c5c + rng_delay(); + 8004ce2: f7fd fd4b bl 800277c +} + 8004ce6: 4620 mov r0, r4 + 8004ce8: b002 add sp, #8 + 8004cea: bd10 pop {r4, pc} + 8004cec: 2009e1c0 .word 0x2009e1c0 + 8004cf0: 0800e74f .word 0x0800e74f + +08004cf4 : +{ + 8004cf4: b538 push {r3, r4, r5, lr} + putchar(hexmap[(b>>4) & 0xf]); + 8004cf6: 4d06 ldr r5, [pc, #24] ; (8004d10 ) + 8004cf8: 0903 lsrs r3, r0, #4 +{ + 8004cfa: 4604 mov r4, r0 + putchar(hexmap[(b>>0) & 0xf]); + 8004cfc: f004 040f and.w r4, r4, #15 + putchar(hexmap[(b>>4) & 0xf]); + 8004d00: 5ce8 ldrb r0, [r5, r3] + 8004d02: f7ff ffd9 bl 8004cb8 + putchar(hexmap[(b>>0) & 0xf]); + 8004d06: 5d28 ldrb r0, [r5, r4] +} + 8004d08: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + putchar(hexmap[(b>>0) & 0xf]); + 8004d0c: f7ff bfd4 b.w 8004cb8 + 8004d10: 0800e752 .word 0x0800e752 + +08004d14 : +{ + 8004d14: b538 push {r3, r4, r5, lr} + putchar(hexmap[(w>>12) & 0xf]); + 8004d16: 4d0b ldr r5, [pc, #44] ; (8004d44 ) + 8004d18: 0b03 lsrs r3, r0, #12 +{ + 8004d1a: 4604 mov r4, r0 + putchar(hexmap[(w>>12) & 0xf]); + 8004d1c: 5ce8 ldrb r0, [r5, r3] + 8004d1e: f7ff ffcb bl 8004cb8 + putchar(hexmap[(w>>8) & 0xf]); + 8004d22: f3c4 2303 ubfx r3, r4, #8, #4 + 8004d26: 5ce8 ldrb r0, [r5, r3] + 8004d28: f7ff ffc6 bl 8004cb8 + putchar(hexmap[(w>>4) & 0xf]); + 8004d2c: f3c4 1303 ubfx r3, r4, #4, #4 + putchar(hexmap[(w>>0) & 0xf]); + 8004d30: f004 040f and.w r4, r4, #15 + putchar(hexmap[(w>>4) & 0xf]); + 8004d34: 5ce8 ldrb r0, [r5, r3] + 8004d36: f7ff ffbf bl 8004cb8 + putchar(hexmap[(w>>0) & 0xf]); + 8004d3a: 5d28 ldrb r0, [r5, r4] +} + 8004d3c: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + putchar(hexmap[(w>>0) & 0xf]); + 8004d40: f7ff bfba b.w 8004cb8 + 8004d44: 0800e752 .word 0x0800e752 + +08004d48 : +{ + 8004d48: b510 push {r4, lr} + 8004d4a: 4604 mov r4, r0 + puthex4(w >> 16); + 8004d4c: 0c00 lsrs r0, r0, #16 + 8004d4e: f7ff ffe1 bl 8004d14 + puthex4(w & 0xffff); + 8004d52: b2a0 uxth r0, r4 +} + 8004d54: e8bd 4010 ldmia.w sp!, {r4, lr} + puthex4(w & 0xffff); + 8004d58: f7ff bfdc b.w 8004d14 + +08004d5c : +{ + 8004d5c: b5f8 push {r3, r4, r5, r6, r7, lr} + 8004d5e: 4605 mov r5, r0 + 8004d60: 2604 movs r6, #4 + for(int m=1000; m; m /= 10) { + 8004d62: f44f 747a mov.w r4, #1000 ; 0x3e8 + char n = '0' + ((w / m) % 10); + 8004d66: 270a movs r7, #10 + if(w >= m) { + 8004d68: 42a5 cmp r5, r4 + 8004d6a: db09 blt.n 8004d80 + char n = '0' + ((w / m) % 10); + 8004d6c: fb95 f3f4 sdiv r3, r5, r4 + 8004d70: fb93 f0f7 sdiv r0, r3, r7 + 8004d74: fb07 3310 mls r3, r7, r0, r3 + 8004d78: 3330 adds r3, #48 ; 0x30 + putchar(n); + 8004d7a: b2d8 uxtb r0, r3 + 8004d7c: f7ff ff9c bl 8004cb8 + for(int m=1000; m; m /= 10) { + 8004d80: fb94 f4f7 sdiv r4, r4, r7 + 8004d84: 3e01 subs r6, #1 + 8004d86: d1ef bne.n 8004d68 +} + 8004d88: bdf8 pop {r3, r4, r5, r6, r7, pc} + +08004d8a : +{ + 8004d8a: b570 push {r4, r5, r6, lr} + 8004d8c: 4606 mov r6, r0 + 8004d8e: 460d mov r5, r1 + for(int i=0; i +} + 8004d96: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + putchar('\n'); + 8004d9a: 200a movs r0, #10 + 8004d9c: f7ff bf8c b.w 8004cb8 + puthex2(data[i]); + 8004da0: 5d30 ldrb r0, [r6, r4] + 8004da2: f7ff ffa7 bl 8004cf4 + for(int i=0; i + ... + +08004dac : +{ + 8004dac: b513 push {r0, r1, r4, lr} + 8004dae: 9001 str r0, [sp, #4] + int ln = strlen(msg); + 8004db0: f008 fc93 bl 800d6da + 8004db4: 4604 mov r4, r0 + rng_delay(); + 8004db6: f7fd fce1 bl 800277c + if(ln) HAL_USART_Transmit(&con, (uint8_t *)msg, ln, HAL_MAX_DELAY); + 8004dba: 9901 ldr r1, [sp, #4] + 8004dbc: b12c cbz r4, 8004dca + 8004dbe: 4809 ldr r0, [pc, #36] ; (8004de4 ) + 8004dc0: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004dc4: b2a2 uxth r2, r4 + 8004dc6: f7ff ff49 bl 8004c5c + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004dca: 4907 ldr r1, [pc, #28] ; (8004de8 ) + 8004dcc: 4805 ldr r0, [pc, #20] ; (8004de4 ) + 8004dce: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004dd2: 2202 movs r2, #2 + 8004dd4: f7ff ff42 bl 8004c5c + rng_delay(); + 8004dd8: f7fd fcd0 bl 800277c +} + 8004ddc: 2001 movs r0, #1 + 8004dde: b002 add sp, #8 + 8004de0: bd10 pop {r4, pc} + 8004de2: bf00 nop + 8004de4: 2009e1c0 .word 0x2009e1c0 + 8004de8: 0800e74f .word 0x0800e74f + +08004dec : + +// psram_send_byte() +// + void +psram_send_byte(OSPI_HandleTypeDef *qh, uint8_t cmd_byte, bool is_quad) +{ + 8004dec: b570 push {r4, r5, r6, lr} + 8004dee: b094 sub sp, #80 ; 0x50 + 8004df0: 4604 mov r4, r0 + 8004df2: 460e mov r6, r1 + 8004df4: 4615 mov r5, r2 + // Send single-byte commands to the PSRAM chip. Quad mode or normal SPI. + + OSPI_RegularCmdTypeDef cmd = { + 8004df6: 2100 movs r1, #0 + 8004df8: 2250 movs r2, #80 ; 0x50 + 8004dfa: 4668 mov r0, sp + 8004dfc: f008 fc3a bl 800d674 + .OperationType = HAL_OSPI_OPTYPE_COMMON_CFG, + .Instruction = cmd_byte, // Exit Quad Mode + .InstructionMode = is_quad ? HAL_OSPI_INSTRUCTION_4_LINES : HAL_OSPI_INSTRUCTION_1_LINE, + 8004e00: 2d00 cmp r5, #0 + 8004e02: bf14 ite ne + 8004e04: 2303 movne r3, #3 + 8004e06: 2301 moveq r3, #1 + .DataMode = HAL_OSPI_DATA_NONE, + .NbData = 0, // how much to read in bytes + }; + + // Start and finish a "Indirection functional mode" request + HAL_OSPI_Command(qh, &cmd, HAL_MAX_DELAY); + 8004e08: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 8004e0c: 4669 mov r1, sp + 8004e0e: 4620 mov r0, r4 + OSPI_RegularCmdTypeDef cmd = { + 8004e10: 9602 str r6, [sp, #8] + 8004e12: 9303 str r3, [sp, #12] + HAL_OSPI_Command(qh, &cmd, HAL_MAX_DELAY); + 8004e14: f006 f884 bl 800af20 +} + 8004e18: b014 add sp, #80 ; 0x50 + 8004e1a: bd70 pop {r4, r5, r6, pc} + +08004e1c : + +// psram_setup() +// + void +psram_setup(void) +{ + 8004e1c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8004e20: b0c6 sub sp, #280 ; 0x118 + // Using OSPI1 block + OSPI_HandleTypeDef qh = { 0 }; + 8004e22: 2250 movs r2, #80 ; 0x50 + 8004e24: 2100 movs r1, #0 + 8004e26: a80a add r0, sp, #40 ; 0x28 + 8004e28: f008 fc24 bl 800d674 + + // enable clocks + __HAL_RCC_OSPI1_CLK_ENABLE(); + 8004e2c: 4b6a ldr r3, [pc, #424] ; (8004fd8 ) + // reset module + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + + // configure pins: Port E PE10-PE15 + GPIO_InitTypeDef setup = { + 8004e2e: 4c6b ldr r4, [pc, #428] ; (8004fdc ) + __HAL_RCC_OSPI1_CLK_ENABLE(); + 8004e30: 6d1a ldr r2, [r3, #80] ; 0x50 + 8004e32: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8004e36: 651a str r2, [r3, #80] ; 0x50 + 8004e38: 6d1a ldr r2, [r3, #80] ; 0x50 + 8004e3a: f402 7280 and.w r2, r2, #256 ; 0x100 + 8004e3e: 9201 str r2, [sp, #4] + 8004e40: 9a01 ldr r2, [sp, #4] + __HAL_RCC_GPIOE_CLK_ENABLE(); + 8004e42: 6cda ldr r2, [r3, #76] ; 0x4c + 8004e44: f042 0210 orr.w r2, r2, #16 + 8004e48: 64da str r2, [r3, #76] ; 0x4c + 8004e4a: 6cda ldr r2, [r3, #76] ; 0x4c + 8004e4c: f002 0210 and.w r2, r2, #16 + 8004e50: 9202 str r2, [sp, #8] + 8004e52: 9a02 ldr r2, [sp, #8] + __HAL_RCC_OSPI1_FORCE_RESET(); + 8004e54: 6b1a ldr r2, [r3, #48] ; 0x30 + 8004e56: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8004e5a: 631a str r2, [r3, #48] ; 0x30 + __HAL_RCC_OSPI1_RELEASE_RESET(); + 8004e5c: 6b1a ldr r2, [r3, #48] ; 0x30 + 8004e5e: f422 7280 bic.w r2, r2, #256 ; 0x100 + 8004e62: 631a str r2, [r3, #48] ; 0x30 + GPIO_InitTypeDef setup = { + 8004e64: cc0f ldmia r4!, {r0, r1, r2, r3} + 8004e66: ad05 add r5, sp, #20 + 8004e68: c50f stmia r5!, {r0, r1, r2, r3} + 8004e6a: 6823 ldr r3, [r4, #0] + .Mode = GPIO_MODE_AF_PP, // not sure + .Pull = GPIO_NOPULL, // not sure + .Speed = GPIO_SPEED_FREQ_VERY_HIGH, + .Alternate = GPIO_AF10_OCTOSPIM_P1, + }; + HAL_GPIO_Init(GPIOE, &setup); + 8004e6c: 485c ldr r0, [pc, #368] ; (8004fe0 ) + GPIO_InitTypeDef setup = { + 8004e6e: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOE, &setup); + 8004e70: a905 add r1, sp, #20 + 8004e72: f7fc f8cd bl 8001010 + + + // Config operational values + qh.Instance = OCTOSPI1; + qh.Init.FifoThreshold = 1; // ?? unused + 8004e76: 4b5b ldr r3, [pc, #364] ; (8004fe4 ) + 8004e78: 2701 movs r7, #1 + qh.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + qh.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; // want standard mode (but octo only?) + qh.Init.DeviceSize = 24; // assume max size, actual is 8Mbyte + 8004e7a: 2218 movs r2, #24 + qh.Init.FifoThreshold = 1; // ?? unused + 8004e7c: e9cd 370a strd r3, r7, [sp, #40] ; 0x28 + qh.Init.ChipSelectHighTime = 1; // 1, maxed out, seems to work + 8004e80: e9cd 270e strd r2, r7, [sp, #56] ; 0x38 + qh.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + 8004e84: 2300 movs r3, #0 + qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe? + 8004e86: f04f 5280 mov.w r2, #268435456 ; 0x10000000 + qh.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; // required! + qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata) +#if HCLK_FREQUENCY == 80000000 + qh.Init.ClockPrescaler = 1; // prescaler (1=>80Mhz, 2=>40Mhz, etc) +#elif HCLK_FREQUENCY == 120000000 + qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc) + 8004e8a: f04f 0802 mov.w r8, #2 +#else +# error "testing needed" +#endif + qh.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED; // dont need it? + 8004e8e: f04f 0908 mov.w r9, #8 + // - (during reads) 3 => 400ns 4 => 660ns 5+ => 1us + // - LATER: Errata 2.8.1 => says shall not use + qh.Init.ChipSelectBoundary = 0; + + // module init + HAL_StatusTypeDef rv = HAL_OSPI_Init(&qh); + 8004e92: a80a add r0, sp, #40 ; 0x28 + qh.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; // want standard mode (but octo only?) + 8004e94: e9cd 330c strd r3, r3, [sp, #48] ; 0x30 + qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata) + 8004e98: e9cd 3310 strd r3, r3, [sp, #64] ; 0x40 + qh.Init.ChipSelectBoundary = 0; + 8004e9c: e9cd 3915 strd r3, r9, [sp, #84] ; 0x54 + qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe? + 8004ea0: 9214 str r2, [sp, #80] ; 0x50 + qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc) + 8004ea2: f8cd 8048 str.w r8, [sp, #72] ; 0x48 + HAL_StatusTypeDef rv = HAL_OSPI_Init(&qh); + 8004ea6: f005 ffd1 bl 800ae4c + ASSERT(rv == HAL_OK); + 8004eaa: 4606 mov r6, r0 + 8004eac: b110 cbz r0, 8004eb4 + 8004eae: 484e ldr r0, [pc, #312] ; (8004fe8 ) + 8004eb0: f7fb fdca bl 8000a48 + + // do some SPI commands first + + // Exit Quad mode, to get to a known state, after first power-up + psram_send_byte(&qh, 0xf5, true); + 8004eb4: 463a mov r2, r7 + 8004eb6: 21f5 movs r1, #245 ; 0xf5 + 8004eb8: a80a add r0, sp, #40 ; 0x28 + 8004eba: f7ff ff97 bl 8004dec + + // Chip Reset sequence + psram_send_byte(&qh, 0x66, false); // reset enable + 8004ebe: 4632 mov r2, r6 + 8004ec0: 2166 movs r1, #102 ; 0x66 + 8004ec2: a80a add r0, sp, #40 ; 0x28 + 8004ec4: f7ff ff92 bl 8004dec + + // Read Electronic ID + // - length not clear from datasheet, but repeats after 8 bytes + uint8_t psram_chip_eid[8]; + + { OSPI_RegularCmdTypeDef cmd = { + 8004ec8: ad32 add r5, sp, #200 ; 0xc8 + psram_send_byte(&qh, 0x99, false); // reset + 8004eca: 4632 mov r2, r6 + 8004ecc: 2199 movs r1, #153 ; 0x99 + 8004ece: a80a add r0, sp, #40 ; 0x28 + 8004ed0: f7ff ff8c bl 8004dec + { OSPI_RegularCmdTypeDef cmd = { + 8004ed4: 2250 movs r2, #80 ; 0x50 + 8004ed6: 4631 mov r1, r6 + 8004ed8: 4628 mov r0, r5 + 8004eda: f008 fbcb bl 800d674 + 8004ede: 239f movs r3, #159 ; 0x9f + 8004ee0: e9cd 3734 strd r3, r7, [sp, #208] ; 0xd0 + 8004ee4: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 8004ee8: f44f 7380 mov.w r3, #256 ; 0x100 + 8004eec: e9cd 3a39 strd r3, sl, [sp, #228] ; 0xe4 + .DataMode = HAL_OSPI_DATA_1_LINE, + .NbData = sizeof(psram_chip_eid), // how much to read in bytes + }; + + // Start a "Indirection functional mode" request + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004ef0: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + { OSPI_RegularCmdTypeDef cmd = { + 8004ef4: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004ef8: 4629 mov r1, r5 + 8004efa: a80a add r0, sp, #40 ; 0x28 + { OSPI_RegularCmdTypeDef cmd = { + 8004efc: e9cd 3940 strd r3, r9, [sp, #256] ; 0x100 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004f00: f006 f80e bl 800af20 + if(rv != HAL_OK) goto fail; + 8004f04: 2800 cmp r0, #0 + 8004f06: d15d bne.n 8004fc4 + + rv = HAL_OSPI_Receive(&qh, psram_chip_eid, HAL_MAX_DELAY); + 8004f08: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 8004f0c: a903 add r1, sp, #12 + 8004f0e: a80a add r0, sp, #40 ; 0x28 + 8004f10: f006 f938 bl 800b184 + if(rv != HAL_OK) goto fail; + 8004f14: 4606 mov r6, r0 + 8004f16: 2800 cmp r0, #0 + 8004f18: d154 bne.n 8004fc4 + } + + //puts2("PSRAM EID: "); + //hex_dump(psram_chip_eid, sizeof(psram_chip_eid)); + ASSERT(psram_chip_eid[0] == 0x0d); + 8004f1a: f89d 300c ldrb.w r3, [sp, #12] + 8004f1e: 2b0d cmp r3, #13 + 8004f20: d1c5 bne.n 8004eae + ASSERT(psram_chip_eid[1] == 0x5d); + 8004f22: f89d 300d ldrb.w r3, [sp, #13] + 8004f26: 2b5d cmp r3, #93 ; 0x5d + 8004f28: d1c1 bne.n 8004eae + // .. other bits seem pretty similar between devices, they don't claim they are UUID + + // Put into Quad mode + psram_send_byte(&qh, 0x35, false); // 0x35 = Enter Quad Mode + 8004f2a: 4602 mov r2, r0 + 8004f2c: 2135 movs r1, #53 ; 0x35 + 8004f2e: a80a add r0, sp, #40 ; 0x28 + 8004f30: f7ff ff5c bl 8004dec + + // Configure read/write cycles for mem-mapped mode + { OSPI_RegularCmdTypeDef cmd = { + 8004f34: 4631 mov r1, r6 + 8004f36: 224c movs r2, #76 ; 0x4c + 8004f38: a81f add r0, sp, #124 ; 0x7c + 8004f3a: f008 fb9b bl 800d674 + 8004f3e: f04f 0903 mov.w r9, #3 + 8004f42: f8cd 8078 str.w r8, [sp, #120] ; 0x78 + 8004f46: f8cd 8080 str.w r8, [sp, #128] ; 0x80 + .DataMode = HAL_OSPI_DATA_4_LINES, + .NbData = 0, // don't care / TBD? + }; + + // Config for write + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004f4a: a91e add r1, sp, #120 ; 0x78 + { OSPI_RegularCmdTypeDef cmd = { + 8004f4c: f44f 7840 mov.w r8, #768 ; 0x300 + 8004f50: f04f 7640 mov.w r6, #50331648 ; 0x3000000 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004f54: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 8004f58: a80a add r0, sp, #40 ; 0x28 + { OSPI_RegularCmdTypeDef cmd = { + 8004f5a: e9cd 8a25 strd r8, sl, [sp, #148] ; 0x94 + 8004f5e: f8cd 9084 str.w r9, [sp, #132] ; 0x84 + 8004f62: 962c str r6, [sp, #176] ; 0xb0 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8004f64: f005 ffdc bl 800af20 + if(rv != HAL_OK) goto fail; + 8004f68: 4601 mov r1, r0 + 8004f6a: bb58 cbnz r0, 8004fc4 + + // .. for read + OSPI_RegularCmdTypeDef cmd2 = { + 8004f6c: 224c movs r2, #76 ; 0x4c + 8004f6e: a833 add r0, sp, #204 ; 0xcc + 8004f70: f008 fb80 bl 800d674 + 8004f74: 23eb movs r3, #235 ; 0xeb + 8004f76: e9cd 3934 strd r3, r9, [sp, #208] ; 0xd0 + .DataMode = HAL_OSPI_DATA_4_LINES, + .NbData = 0, // don't care / TBD? + }; + + // Config for read + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 8004f7a: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + OSPI_RegularCmdTypeDef cmd2 = { + 8004f7e: 2306 movs r3, #6 + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 8004f80: 4629 mov r1, r5 + 8004f82: a80a add r0, sp, #40 ; 0x28 + OSPI_RegularCmdTypeDef cmd2 = { + 8004f84: e9cd 8a39 strd r8, sl, [sp, #228] ; 0xe4 + 8004f88: 9732 str r7, [sp, #200] ; 0xc8 + 8004f8a: 9640 str r6, [sp, #256] ; 0x100 + 8004f8c: 9343 str r3, [sp, #268] ; 0x10c + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 8004f8e: f005 ffc7 bl 800af20 + if(rv != HAL_OK) goto fail; + 8004f92: b9b8 cbnz r0, 8004fc4 + } + + // config for memmap + { OSPI_MemoryMappedTypeDef mmap = { + 8004f94: e9d4 0101 ldrd r0, r1, [r4, #4] + 8004f98: e885 0003 stmia.w r5, {r0, r1} + // Need this so that CS lines returns to inactive sometimes. + .TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE, + .TimeOutPeriod = 16, // no idea, max value 0xffff + }; + + rv = HAL_OSPI_MemoryMapped(&qh, &mmap); + 8004f9c: 4629 mov r1, r5 + 8004f9e: a80a add r0, sp, #40 ; 0x28 + 8004fa0: f006 f9d6 bl 800b350 + if(rv != HAL_OK) goto fail; + 8004fa4: b970 cbnz r0, 8004fc4 +#else + // Only a quick operational check only here. Non-destructive. + { __IO uint32_t *ptr = (uint32_t *)(PSRAM_BASE+PSRAM_SIZE-4); + uint32_t tmp; + + tmp = *ptr; + 8004fa6: 4b11 ldr r3, [pc, #68] ; (8004fec ) + *ptr = 0x55aa1234; + 8004fa8: 4a11 ldr r2, [pc, #68] ; (8004ff0 ) + tmp = *ptr; + 8004faa: f8d3 1ffc ldr.w r1, [r3, #4092] ; 0xffc + *ptr = 0x55aa1234; + 8004fae: f8c3 2ffc str.w r2, [r3, #4092] ; 0xffc + if(*ptr != 0x55aa1234) goto fail; + 8004fb2: f8d3 0ffc ldr.w r0, [r3, #4092] ; 0xffc + 8004fb6: 4290 cmp r0, r2 + 8004fb8: d104 bne.n 8004fc4 + *ptr = tmp; + 8004fba: f8c3 1ffc str.w r1, [r3, #4092] ; 0xffc + + oled_setup(); + oled_show(screen_fatal); + + LOCKUP_FOREVER(); +} + 8004fbe: b046 add sp, #280 ; 0x118 + 8004fc0: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + puts("PSRAM fail"); + 8004fc4: 480b ldr r0, [pc, #44] ; (8004ff4 ) + 8004fc6: f7ff fef1 bl 8004dac + oled_setup(); + 8004fca: f7fb feab bl 8000d24 + oled_show(screen_fatal); + 8004fce: 480a ldr r0, [pc, #40] ; (8004ff8 ) + 8004fd0: f7fb ff38 bl 8000e44 + LOCKUP_FOREVER(); + 8004fd4: bf30 wfi + 8004fd6: e7fd b.n 8004fd4 + 8004fd8: 40021000 .word 0x40021000 + 8004fdc: 0800e790 .word 0x0800e790 + 8004fe0: 48001000 .word 0x48001000 + 8004fe4: a0001000 .word 0xa0001000 + 8004fe8: 0800e3e0 .word 0x0800e3e0 + 8004fec: 907ff000 .word 0x907ff000 + 8004ff0: 55aa1234 .word 0x55aa1234 + 8004ff4: 0800e762 .word 0x0800e762 + 8004ff8: 0800db52 .word 0x0800db52 + +08004ffc : + +// psram_wipe() +// + void +psram_wipe(void) +{ + 8004ffc: b508 push {r3, lr} + if(OCTOSPI1->CR == 0) return; // PSRAM not enabled (yet?) + 8004ffe: 4b06 ldr r3, [pc, #24] ; (8005018 ) + 8005000: 681b ldr r3, [r3, #0] + 8005002: b143 cbz r3, 8005016 + + // Fast! But real; maybe 150ms + //puts2("PSRAM Wipe: "); + memset4((uint32_t *)PSRAM_BASE, rng_sample(), PSRAM_SIZE); + 8005004: f7fd fb66 bl 80026d4 + 8005008: f04f 4310 mov.w r3, #2415919104 ; 0x90000000 + *dest = value; + 800500c: f843 0b04 str.w r0, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8005010: f113 4fdf cmn.w r3, #1870659584 ; 0x6f800000 + 8005014: d1fa bne.n 800500c + //puts("done"); +} + 8005016: bd08 pop {r3, pc} + 8005018: a0001000 .word 0xa0001000 + +0800501c : +// NOTE: Incoming start address is typically not aligned. +// + void +psram_do_upgrade(const uint8_t *start, uint32_t size) +{ + ASSERT(size >= FW_MIN_LENGTH); + 800501c: f5b1 2f80 cmp.w r1, #262144 ; 0x40000 +{ + 8005020: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + 8005024: 4606 mov r6, r0 + 8005026: 460d mov r5, r1 + ASSERT(size >= FW_MIN_LENGTH); + 8005028: d202 bcs.n 8005030 + 800502a: 481e ldr r0, [pc, #120] ; (80050a4 ) + 800502c: f7fb fd0c bl 8000a48 + + // In case of reset/crash, we can recover, so save + // what we need for that -- yes, we will re-verify signatures + volatile recovery_header_t *h = RECHDR_POS; + h->start = start; + 8005030: 4b1d ldr r3, [pc, #116] ; (80050a8 ) + h->size = size; + h->magic1 = RECHDR_MAGIC1; + 8005032: 4a1e ldr r2, [pc, #120] ; (80050ac ) + h->start = start; + 8005034: 6058 str r0, [r3, #4] + h->size = size; + 8005036: 6099 str r1, [r3, #8] + h->magic1 = RECHDR_MAGIC1; + 8005038: 601a str r2, [r3, #0] + h->magic2 = RECHDR_MAGIC2; + 800503a: 4a1d ldr r2, [pc, #116] ; (80050b0 ) + 800503c: 60da str r2, [r3, #12] + + flash_setup0(); + 800503e: f7fc ffc3 bl 8001fc8 + flash_unlock(); + 8005042: f7fc ffe5 bl 8002010 + for(uint32_t pos=0; pos < size; pos += 8) { + uint32_t dest = FIRMWARE_START+pos; + + if(dest % (4*FLASH_ERASE_SIZE) == 0) { + // show some progress + oled_show_progress(screen_upgrading, pos*100/size); + 8005046: f8df 906c ldr.w r9, [pc, #108] ; 80050b4 + for(uint32_t pos=0; pos < size; pos += 8) { + 800504a: 2400 movs r4, #0 + oled_show_progress(screen_upgrading, pos*100/size); + 800504c: f04f 0864 mov.w r8, #100 ; 0x64 + uint32_t dest = FIRMWARE_START+pos; + 8005050: f104 6700 add.w r7, r4, #134217728 ; 0x8000000 + if(dest % (4*FLASH_ERASE_SIZE) == 0) { + 8005054: f3c4 030d ubfx r3, r4, #0, #14 + 8005058: f507 3700 add.w r7, r7, #131072 ; 0x20000 + 800505c: b933 cbnz r3, 800506c + oled_show_progress(screen_upgrading, pos*100/size); + 800505e: fb08 f104 mul.w r1, r8, r4 + 8005062: 4648 mov r0, r9 + 8005064: fbb1 f1f5 udiv r1, r1, r5 + 8005068: f7fb ff2e bl 8000ec8 + } + + if(dest % FLASH_ERASE_SIZE == 0) { + 800506c: f3c7 030b ubfx r3, r7, #0, #12 + 8005070: b923 cbnz r3, 800507c + // page erase as we go + rv = flash_page_erase(dest); + 8005072: 4638 mov r0, r7 + 8005074: f008 fb40 bl 800d6f8 <__flash_page_erase_veneer> + puts2("erase rv="); + puthex2(rv); + putchar('\n'); + } +#endif + ASSERT(rv == 0); + 8005078: 2800 cmp r0, #0 + 800507a: d1d6 bne.n 800502a + } + + memcpy(&tmp, start+pos, 8); + 800507c: 1932 adds r2, r6, r4 + 800507e: 5930 ldr r0, [r6, r4] + 8005080: 6851 ldr r1, [r2, #4] + 8005082: 466b mov r3, sp + 8005084: c303 stmia r3!, {r0, r1} + rv = flash_burn(dest, tmp); + 8005086: 4638 mov r0, r7 + 8005088: e9dd 2300 ldrd r2, r3, [sp] + 800508c: f008 fb30 bl 800d6f0 <__flash_burn_veneer> + puts2(" addr="); + puthex8(dest); + putchar('\n'); + } +#endif + ASSERT(rv == 0); + 8005090: 2800 cmp r0, #0 + 8005092: d1ca bne.n 800502a + for(uint32_t pos=0; pos < size; pos += 8) { + 8005094: 3408 adds r4, #8 + 8005096: 42a5 cmp r5, r4 + 8005098: d8da bhi.n 8005050 + } + + flash_lock(); +} + 800509a: b003 add sp, #12 + 800509c: e8bd 43f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, lr} + flash_lock(); + 80050a0: f7fc bfae b.w 8002000 + 80050a4: 0800e3e0 .word 0x0800e3e0 + 80050a8: 907ff800 .word 0x907ff800 + 80050ac: dbcc8350 .word 0xdbcc8350 + 80050b0: bafcfba3 .word 0xbafcfba3 + 80050b4: 0800e18b .word 0x0800e18b + +080050b8 : +{ + 80050b8: b510 push {r4, lr} + if( (h->magic1 != RECHDR_MAGIC1) + 80050ba: 4c1f ldr r4, [pc, #124] ; (8005138 ) + 80050bc: 4b1f ldr r3, [pc, #124] ; (800513c ) + 80050be: 6822 ldr r2, [r4, #0] + 80050c0: 429a cmp r2, r3 +{ + 80050c2: b088 sub sp, #32 + if( (h->magic1 != RECHDR_MAGIC1) + 80050c4: d113 bne.n 80050ee + || (h->magic2 != RECHDR_MAGIC2) + 80050c6: 68e2 ldr r2, [r4, #12] + 80050c8: 4b1d ldr r3, [pc, #116] ; (8005140 ) + 80050ca: 429a cmp r2, r3 + 80050cc: d10f bne.n 80050ee + || ((uint32_t)h->start < PSRAM_BASE) + 80050ce: 6863 ldr r3, [r4, #4] + 80050d0: f1b3 4f10 cmp.w r3, #2415919104 ; 0x90000000 + 80050d4: d30b bcc.n 80050ee + || ((uint32_t)h->start >= PSRAM_BASE+(PSRAM_SIZE/2)) + 80050d6: 6862 ldr r2, [r4, #4] + 80050d8: 4b1a ldr r3, [pc, #104] ; (8005144 ) + 80050da: 429a cmp r2, r3 + 80050dc: d807 bhi.n 80050ee + || (h->size > FW_MAX_LENGTH_MK4) + 80050de: 68a3 ldr r3, [r4, #8] + 80050e0: f5b3 1ff0 cmp.w r3, #1966080 ; 0x1e0000 + 80050e4: d803 bhi.n 80050ee + || (h->size < FW_MIN_LENGTH) + 80050e6: 68a3 ldr r3, [r4, #8] + 80050e8: f5b3 2f80 cmp.w r3, #262144 ; 0x40000 + 80050ec: d205 bcs.n 80050fa + puts("PSR: nada"); + 80050ee: 4816 ldr r0, [pc, #88] ; (8005148 ) + puts("PSR: version"); + 80050f0: f7ff fe5c bl 8004dac +} + 80050f4: 2000 movs r0, #0 + 80050f6: b008 add sp, #32 + 80050f8: bd10 pop {r4, pc} + bool ok = verify_firmware_in_ram(h->start, h->size, world_check); + 80050fa: 6860 ldr r0, [r4, #4] + 80050fc: 68a1 ldr r1, [r4, #8] + 80050fe: 466a mov r2, sp + 8005100: f7fc fda8 bl 8001c54 + if(!ok) { + 8005104: b908 cbnz r0, 800510a + puts("PSR: !check"); + 8005106: 4811 ldr r0, [pc, #68] ; (800514c ) + 8005108: e7f2 b.n 80050f0 + if(!verify_world_checksum(world_check)) { + 800510a: 4668 mov r0, sp + 800510c: f7fc fdf6 bl 8001cfc + 8005110: b908 cbnz r0, 8005116 + puts("PSR: version"); + 8005112: 480f ldr r0, [pc, #60] ; (8005150 ) + 8005114: e7ec b.n 80050f0 + psram_do_upgrade(h->start, h->size); + 8005116: 6860 ldr r0, [r4, #4] + 8005118: 68a1 ldr r1, [r4, #8] + 800511a: f7ff ff7f bl 800501c + 800511e: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8005122: 490c ldr r1, [pc, #48] ; (8005154 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8005124: 4b0c ldr r3, [pc, #48] ; (8005158 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8005126: 68ca ldr r2, [r1, #12] + 8005128: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800512c: 4313 orrs r3, r2 + 800512e: 60cb str r3, [r1, #12] + 8005130: f3bf 8f4f dsb sy + __NOP(); + 8005134: bf00 nop + for(;;) /* wait until reset */ + 8005136: e7fd b.n 8005134 + 8005138: 907ff800 .word 0x907ff800 + 800513c: dbcc8350 .word 0xdbcc8350 + 8005140: bafcfba3 .word 0xbafcfba3 + 8005144: 903fffff .word 0x903fffff + 8005148: 0800e76d .word 0x0800e76d + 800514c: 0800e777 .word 0x0800e777 + 8005150: 0800e783 .word 0x0800e783 + 8005154: e000ed00 .word 0xe000ed00 + 8005158: 05fa0004 .word 0x05fa0004 + +0800515c : + +// sdcard_light() +// + void inline +sdcard_light(bool on) +{ + 800515c: 4602 mov r2, r0 + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, !!on); // turn LED off + 800515e: 2180 movs r1, #128 ; 0x80 + 8005160: 4801 ldr r0, [pc, #4] ; (8005168 ) + 8005162: f7fc b8cf b.w 8001304 + 8005166: bf00 nop + 8005168: 48000800 .word 0x48000800 + +0800516c : + +// sdcard_is_inserted() +// + bool +sdcard_is_inserted(void) +{ + 800516c: b508 push {r3, lr} +#ifdef FOR_Q1_ONLY + return !HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_3); // PD3 - inserted when low (Q) +#else + return !!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13); // PC13 - inserted when high (Mk4) + 800516e: f44f 5100 mov.w r1, #8192 ; 0x2000 + 8005172: 4803 ldr r0, [pc, #12] ; (8005180 ) + 8005174: f7fc f8c0 bl 80012f8 +#endif +} + 8005178: 3800 subs r0, #0 + 800517a: bf18 it ne + 800517c: 2001 movne r0, #1 + 800517e: bd08 pop {r3, pc} + 8005180: 48000800 .word 0x48000800 + +08005184 : + +// sdcard_try_file() +// + void +sdcard_try_file(uint32_t blk_pos) +{ + 8005184: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8005188: 4606 mov r6, r0 + 800518a: f5ad 7d0a sub.w sp, sp, #552 ; 0x228 + oled_show(screen_verify); + 800518e: 4832 ldr r0, [pc, #200] ; (8005258 ) + uint8_t *ps = (uint8_t *)PSRAM_BASE; + //uint8_t buf[512*8]; // half of all our SRAM 0x00002000 + uint8_t buf[512]; // slower, but works. + + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + int rv = HAL_SD_ReadBlocks(&hsd, buf, blk_pos+(off/512), sizeof(buf)/512, 60000); + 8005190: f8df 80e4 ldr.w r8, [pc, #228] ; 8005278 + oled_show(screen_verify); + 8005194: f7fb fe56 bl 8000e44 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 8005198: 2500 movs r5, #0 + int rv = HAL_SD_ReadBlocks(&hsd, buf, blk_pos+(off/512), sizeof(buf)/512, 60000); + 800519a: f64e 2760 movw r7, #60000 ; 0xea60 + 800519e: 9700 str r7, [sp, #0] + 80051a0: 2301 movs r3, #1 + 80051a2: eb06 2255 add.w r2, r6, r5, lsr #9 + 80051a6: a90a add r1, sp, #40 ; 0x28 + 80051a8: 4640 mov r0, r8 + 80051aa: f006 fe4d bl 800be48 + if(rv != HAL_OK) { + 80051ae: 4604 mov r4, r0 + 80051b0: b130 cbz r0, 80051c0 + puts("long read fail"); + 80051b2: 482a ldr r0, [pc, #168] ; (800525c ) + + // Check we have the **right** firmware, based on the world check sum + // but don't set the light at this point. + // - this includes check over bootrom (ourselves) + if(!verify_world_checksum(world_check)) { + puts("wrong world"); + 80051b4: f7ff fdfa bl 8004dac + // Do the upgrade, using PSRAM data. + psram_do_upgrade(start, len); + + // done + NVIC_SystemReset(); +} + 80051b8: f50d 7d0a add.w sp, sp, #552 ; 0x228 + 80051bc: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + memcpy(ps + off, buf, sizeof(buf)); + 80051c0: f105 4010 add.w r0, r5, #2415919104 ; 0x90000000 + 80051c4: f44f 7200 mov.w r2, #512 ; 0x200 + 80051c8: a90a add r1, sp, #40 ; 0x28 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 80051ca: f505 7500 add.w r5, r5, #512 ; 0x200 + memcpy(ps + off, buf, sizeof(buf)); + 80051ce: f008 fa29 bl 800d624 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 80051d2: f5b5 1ff0 cmp.w r5, #1966080 ; 0x1e0000 + 80051d6: d1e2 bne.n 800519e + for(int idx=0; idxtargets; idx++) { + 80051d8: f04f 4310 mov.w r3, #2415919104 ; 0x90000000 + if(elem->addr == FIRMWARE_START) { + 80051dc: 4d20 ldr r5, [pc, #128] ; (8005260 ) + for(int idx=0; idxtargets; idx++) { + 80051de: 7a99 ldrb r1, [r3, #10] + 80051e0: 4620 mov r0, r4 + ptr += sizeof(DFUFile_t); + 80051e2: 330b adds r3, #11 + for(int idx=0; idxtargets; idx++) { + 80051e4: 4288 cmp r0, r1 + 80051e6: db01 blt.n 80051ec + puts("DFU parse fail"); + 80051e8: 481e ldr r0, [pc, #120] ; (8005264 ) + 80051ea: e7e3 b.n 80051b4 + for(int ei=0; eielements; ei++) { + 80051ec: f8d3 610e ldr.w r6, [r3, #270] ; 0x10e + 80051f0: 2200 movs r2, #0 + ptr += sizeof(DFUTarget_t); + 80051f2: f503 7389 add.w r3, r3, #274 ; 0x112 + for(int ei=0; eielements; ei++) { + 80051f6: 42b2 cmp r2, r6 + 80051f8: d101 bne.n 80051fe + for(int idx=0; idxtargets; idx++) { + 80051fa: 3001 adds r0, #1 + 80051fc: e7f2 b.n 80051e4 + ptr += sizeof(DFUElement_t); + 80051fe: 461c mov r4, r3 + if(elem->addr == FIRMWARE_START) { + 8005200: f854 7b08 ldr.w r7, [r4], #8 + 8005204: 42af cmp r7, r5 + 8005206: d110 bne.n 800522a + *target_size = elem->size; + 8005208: 685d ldr r5, [r3, #4] + bool ok = verify_firmware_in_ram(start, len, world_check); + 800520a: aa02 add r2, sp, #8 + 800520c: 4629 mov r1, r5 + 800520e: 4620 mov r0, r4 + 8005210: f7fc fd20 bl 8001c54 + if(!ok) return; + 8005214: 2800 cmp r0, #0 + 8005216: d0cf beq.n 80051b8 + puts("good firmware"); + 8005218: 4813 ldr r0, [pc, #76] ; (8005268 ) + 800521a: f7ff fdc7 bl 8004dac + if(!verify_world_checksum(world_check)) { + 800521e: a802 add r0, sp, #8 + 8005220: f7fc fd6c bl 8001cfc + 8005224: b920 cbnz r0, 8005230 + puts("wrong world"); + 8005226: 4811 ldr r0, [pc, #68] ; (800526c ) + 8005228: e7c4 b.n 80051b4 + for(int ei=0; eielements; ei++) { + 800522a: 3201 adds r2, #1 + ptr += sizeof(DFUElement_t); + 800522c: 4623 mov r3, r4 + 800522e: e7e2 b.n 80051f6 + sdcard_light(false); + 8005230: 2000 movs r0, #0 + 8005232: f7ff ff93 bl 800515c + psram_do_upgrade(start, len); + 8005236: 4629 mov r1, r5 + 8005238: 4620 mov r0, r4 + 800523a: f7ff feef bl 800501c + 800523e: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8005242: 490b ldr r1, [pc, #44] ; (8005270 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8005244: 4b0b ldr r3, [pc, #44] ; (8005274 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8005246: 68ca ldr r2, [r1, #12] + 8005248: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800524c: 4313 orrs r3, r2 + 800524e: 60cb str r3, [r1, #12] + 8005250: f3bf 8f4f dsb sy + __NOP(); + 8005254: bf00 nop + for(;;) /* wait until reset */ + 8005256: e7fd b.n 8005254 + 8005258: 0800e242 .word 0x0800e242 + 800525c: 0800e7ac .word 0x0800e7ac + 8005260: 08020000 .word 0x08020000 + 8005264: 0800e7bb .word 0x0800e7bb + 8005268: 0800e7ca .word 0x0800e7ca + 800526c: 0800e7d8 .word 0x0800e7d8 + 8005270: e000ed00 .word 0xe000ed00 + 8005274: 05fa0004 .word 0x05fa0004 + 8005278: 2009e220 .word 0x2009e220 + +0800527c : + +// sdcard_search() +// + void +sdcard_search(void) +{ + 800527c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + oled_show(screen_search); + 8005280: 4854 ldr r0, [pc, #336] ; (80053d4 ) +{ + 8005282: f5ad 7d04 sub.w sp, sp, #528 ; 0x210 + oled_show(screen_search); + 8005286: f7fb fddd bl 8000e44 + + if(!sdcard_is_inserted()) return; + 800528a: f7ff ff6f bl 800516c + 800528e: 2800 cmp r0, #0 + 8005290: d07a beq.n 8005388 + __HAL_RCC_SDMMC1_CLK_ENABLE(); + 8005292: 4f51 ldr r7, [pc, #324] ; (80053d8 ) + + uint32_t num_blocks; + + // open card (power it) and get details, do setup + puts2("sdcard_search: "); + 8005294: 4851 ldr r0, [pc, #324] ; (80053dc ) + { GPIO_InitTypeDef setup = { + 8005296: 4c52 ldr r4, [pc, #328] ; (80053e0 ) + puts2("sdcard_search: "); + 8005298: f7ff fcfa bl 8004c90 + __HAL_RCC_SDMMC1_CLK_ENABLE(); + 800529c: 6cfb ldr r3, [r7, #76] ; 0x4c + 800529e: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 80052a2: 64fb str r3, [r7, #76] ; 0x4c + 80052a4: 6cfb ldr r3, [r7, #76] ; 0x4c + 80052a6: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 80052aa: 9303 str r3, [sp, #12] + 80052ac: 9b03 ldr r3, [sp, #12] + { GPIO_InitTypeDef setup = { + 80052ae: cc0f ldmia r4!, {r0, r1, r2, r3} + 80052b0: ad04 add r5, sp, #16 + 80052b2: c50f stmia r5!, {r0, r1, r2, r3} + 80052b4: f854 3b04 ldr.w r3, [r4], #4 + 80052b8: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOC, &setup); + 80052ba: 484a ldr r0, [pc, #296] ; (80053e4 ) + 80052bc: a904 add r1, sp, #16 + 80052be: f7fb fea7 bl 8001010 + { GPIO_InitTypeDef setup = { + 80052c2: cc0f ldmia r4!, {r0, r1, r2, r3} + 80052c4: ae04 add r6, sp, #16 + 80052c6: c60f stmia r6!, {r0, r1, r2, r3} + 80052c8: 6823 ldr r3, [r4, #0] + 80052ca: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOD, &setup); + 80052cc: a904 add r1, sp, #16 + 80052ce: 4846 ldr r0, [pc, #280] ; (80053e8 ) + memset(&hsd, 0, sizeof(SD_HandleTypeDef)); + 80052d0: 4d46 ldr r5, [pc, #280] ; (80053ec ) + HAL_GPIO_Init(GPIOD, &setup); + 80052d2: f7fb fe9d bl 8001010 + __HAL_RCC_SDMMC1_FORCE_RESET(); + 80052d6: 6afb ldr r3, [r7, #44] ; 0x2c + 80052d8: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 80052dc: 62fb str r3, [r7, #44] ; 0x2c + __HAL_RCC_SDMMC1_RELEASE_RESET(); + 80052de: 6afb ldr r3, [r7, #44] ; 0x2c + 80052e0: f423 0380 bic.w r3, r3, #4194304 ; 0x400000 + 80052e4: 62fb str r3, [r7, #44] ; 0x2c + sdcard_setup(); + delay_ms(100); + 80052e6: 2064 movs r0, #100 ; 0x64 + 80052e8: f7fe fb06 bl 80038f8 + memset(&hsd, 0, sizeof(SD_HandleTypeDef)); + 80052ec: 2280 movs r2, #128 ; 0x80 + 80052ee: 2100 movs r1, #0 + 80052f0: 4628 mov r0, r5 + 80052f2: f008 f9bf bl 800d674 + puts2("sdcard_probe: "); + 80052f6: 483e ldr r0, [pc, #248] ; (80053f0 ) + 80052f8: f7ff fcca bl 8004c90 + hsd.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + 80052fc: 4a3d ldr r2, [pc, #244] ; (80053f4 ) + 80052fe: 2300 movs r3, #0 + 8005300: e9c5 2300 strd r2, r3, [r5] + hsd.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_ENABLE; + 8005304: f44f 5280 mov.w r2, #4096 ; 0x1000 + hsd.Init.BusWide = SDMMC_BUS_WIDE_1B; + 8005308: e9c5 2302 strd r2, r3, [r5, #8] + hsd.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + 800530c: 612b str r3, [r5, #16] + int rv = HAL_SD_Init(&hsd); + 800530e: 4628 mov r0, r5 + hsd.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV; + 8005310: 2303 movs r3, #3 + 8005312: 616b str r3, [r5, #20] + int rv = HAL_SD_Init(&hsd); + 8005314: f007 fb12 bl 800c93c + if(rv != HAL_OK) { + 8005318: 4604 mov r4, r0 + 800531a: b130 cbz r0, 800532a + puts("init fail"); + 800531c: 4836 ldr r0, [pc, #216] ; (80053f8 ) + oled_show_progress(screen_search, pos*100 / num_blocks); + sdcard_light(true); + } + } + +} + 800531e: f50d 7d04 add.w sp, sp, #528 ; 0x210 + 8005322: e8bd 41f0 ldmia.w sp!, {r4, r5, r6, r7, r8, lr} + puts("bsize?"); + 8005326: f7ff bd41 b.w 8004dac + sdcard_light(true); + 800532a: 2001 movs r0, #1 + 800532c: f7ff ff16 bl 800515c + rv = HAL_SD_ConfigSpeedBusOperation(&hsd, SDMMC_SPEED_MODE_AUTO); + 8005330: 4621 mov r1, r4 + 8005332: 4628 mov r0, r5 + 8005334: f007 fbda bl 800caec + if(rv != HAL_OK) { + 8005338: b108 cbz r0, 800533e + puts("speed"); + 800533a: 4830 ldr r0, [pc, #192] ; (80053fc ) + 800533c: e7ef b.n 800531e + rv = HAL_SD_ConfigWideBusOperation(&hsd, SDMMC_BUS_WIDE_4B); + 800533e: f44f 4180 mov.w r1, #16384 ; 0x4000 + 8005342: 4628 mov r0, r5 + 8005344: f007 fa24 bl 800c790 + if(rv != HAL_OK) { + 8005348: 4604 mov r4, r0 + 800534a: b108 cbz r0, 8005350 + puts("wide"); + 800534c: 482c ldr r0, [pc, #176] ; (8005400 ) + 800534e: e7e6 b.n 800531e + if(hsd.SdCard.BlockSize != 512) { + 8005350: 6d2b ldr r3, [r5, #80] ; 0x50 + 8005352: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 8005356: d001 beq.n 800535c + puts("bsize?"); + 8005358: 482a ldr r0, [pc, #168] ; (8005404 ) + 800535a: e7e0 b.n 800531e + puts("ok"); + 800535c: 482a ldr r0, [pc, #168] ; (8005408 ) + *num_blocks = hsd.SdCard.BlockNbr; + 800535e: 6cee ldr r6, [r5, #76] ; 0x4c + if(memcmp(blk, "DfuSe", 5) == 0) { + 8005360: 4f2a ldr r7, [pc, #168] ; (800540c ) + oled_show_progress(screen_search, pos*100 / num_blocks); + 8005362: f8df 8070 ldr.w r8, [pc, #112] ; 80053d4 + puts("ok"); + 8005366: f7ff fd21 bl 8004dac + for(int pos=0; pos + int rv = HAL_SD_ReadBlocks(&hsd, blk, pos, 1, 60000); + 800536e: f64e 2360 movw r3, #60000 ; 0xea60 + 8005372: 9300 str r3, [sp, #0] + 8005374: 4622 mov r2, r4 + 8005376: 2301 movs r3, #1 + 8005378: a904 add r1, sp, #16 + 800537a: 4628 mov r0, r5 + 800537c: f006 fd64 bl 800be48 + if(rv != HAL_OK) { + 8005380: b130 cbz r0, 8005390 + puts("fail read"); + 8005382: 4823 ldr r0, [pc, #140] ; (8005410 ) + 8005384: f7ff fd12 bl 8004dac +} + 8005388: f50d 7d04 add.w sp, sp, #528 ; 0x210 + 800538c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if(memcmp(blk, "DfuSe", 5) == 0) { + 8005390: 2205 movs r2, #5 + 8005392: 4639 mov r1, r7 + 8005394: a804 add r0, sp, #16 + 8005396: f008 f935 bl 800d604 + 800539a: b9b0 cbnz r0, 80053ca + puts2("found @ "); + 800539c: 481d ldr r0, [pc, #116] ; (8005414 ) + 800539e: f7ff fc77 bl 8004c90 + puthex8(pos); + 80053a2: 4620 mov r0, r4 + 80053a4: f7ff fcd0 bl 8004d48 + putchar('\n'); + 80053a8: 200a movs r0, #10 + 80053aa: f7ff fc85 bl 8004cb8 + sdcard_try_file(pos); + 80053ae: 4620 mov r0, r4 + 80053b0: f7ff fee8 bl 8005184 + oled_show_progress(screen_search, pos*100 / num_blocks); + 80053b4: 2164 movs r1, #100 ; 0x64 + 80053b6: 4640 mov r0, r8 + 80053b8: 4361 muls r1, r4 + 80053ba: fbb1 f1f6 udiv r1, r1, r6 + 80053be: f7fb fd83 bl 8000ec8 + sdcard_light(true); + 80053c2: 2001 movs r0, #1 + 80053c4: f7ff feca bl 800515c + 80053c8: e001 b.n 80053ce + if(pos % 128 == 0) { + 80053ca: 0663 lsls r3, r4, #25 + 80053cc: d0f2 beq.n 80053b4 + for(int pos=0; pos + 80053d2: bf00 nop + 80053d4: 0800e079 .word 0x0800e079 + 80053d8: 40021000 .word 0x40021000 + 80053dc: 0800e7e4 .word 0x0800e7e4 + 80053e0: 0800e84c .word 0x0800e84c + 80053e4: 48000800 .word 0x48000800 + 80053e8: 48000c00 .word 0x48000c00 + 80053ec: 2009e220 .word 0x2009e220 + 80053f0: 0800e7f4 .word 0x0800e7f4 + 80053f4: 50062400 .word 0x50062400 + 80053f8: 0800e803 .word 0x0800e803 + 80053fc: 0800e80d .word 0x0800e80d + 8005400: 0800e813 .word 0x0800e813 + 8005404: 0800e818 .word 0x0800e818 + 8005408: 0800e81f .word 0x0800e81f + 800540c: 0800e82c .word 0x0800e82c + 8005410: 0800e822 .word 0x0800e822 + 8005414: 0800e832 .word 0x0800e832 + +08005418 : + +// sdcard_recovery() +// + void +sdcard_recovery(void) +{ + 8005418: b508 push {r3, lr} + // Use SDCard to recover. Must be precise version they tried to + // install before, and will be slow AF. + + puts("Recovery mode."); + 800541a: 480b ldr r0, [pc, #44] ; (8005448 ) + while(1) { + // .. need them to insert a card + + sdcard_light(false); + while(!sdcard_is_inserted()) { + oled_show(screen_recovery); + 800541c: 4c0b ldr r4, [pc, #44] ; (800544c ) + puts("Recovery mode."); + 800541e: f7ff fcc5 bl 8004dac + sdcard_light(false); + 8005422: 2000 movs r0, #0 + 8005424: f7ff fe9a bl 800515c + while(!sdcard_is_inserted()) { + 8005428: f7ff fea0 bl 800516c + 800542c: b128 cbz r0, 800543a + delay_ms(200); + } + + // look for binary, will reset system if successful + sdcard_light(true); + 800542e: 2001 movs r0, #1 + 8005430: f7ff fe94 bl 800515c + sdcard_search(); + 8005434: f7ff ff22 bl 800527c + sdcard_light(false); + 8005438: e7f3 b.n 8005422 + oled_show(screen_recovery); + 800543a: 4620 mov r0, r4 + 800543c: f7fb fd02 bl 8000e44 + delay_ms(200); + 8005440: 20c8 movs r0, #200 ; 0xc8 + 8005442: f7fe fa59 bl 80038f8 + 8005446: e7ef b.n 8005428 + 8005448: 0800e83b .word 0x0800e83b + 800544c: 0800dc78 .word 0x0800dc78 + +08005450 : +#include + +// so we don't need stm32l4xx_hal_hash_ex.c +HAL_StatusTypeDef HAL_HASHEx_SHA256_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA256); + 8005450: 4b01 ldr r3, [pc, #4] ; (8005458 ) + 8005452: f005 ba41 b.w 800a8d8 + 8005456: bf00 nop + 8005458: 00040080 .word 0x00040080 + +0800545c : +} + +HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 800545c: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA256); + 800545e: 4c04 ldr r4, [pc, #16] ; (8005470 ) + 8005460: 9401 str r4, [sp, #4] + 8005462: 9c04 ldr r4, [sp, #16] + 8005464: 9400 str r4, [sp, #0] + 8005466: f005 f993 bl 800a790 +} + 800546a: b002 add sp, #8 + 800546c: bd10 pop {r4, pc} + 800546e: bf00 nop + 8005470: 00040080 .word 0x00040080 + +08005474 : + +HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 8005474: b513 push {r0, r1, r4, lr} + return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA256); + 8005476: 4c04 ldr r4, [pc, #16] ; (8005488 ) + 8005478: 9401 str r4, [sp, #4] + 800547a: 9c04 ldr r4, [sp, #16] + 800547c: 9400 str r4, [sp, #0] + 800547e: f005 fbc9 bl 800ac14 +} + 8005482: b002 add sp, #8 + 8005484: bd10 pop {r4, pc} + 8005486: bf00 nop + 8005488: 00040080 .word 0x00040080 + +0800548c : + +void sha256_init(SHA256_CTX *ctx) +{ + 800548c: b510 push {r4, lr} + memset(ctx, 0, sizeof(SHA256_CTX)); + 800548e: 2248 movs r2, #72 ; 0x48 +{ + 8005490: 4604 mov r4, r0 + memset(ctx, 0, sizeof(SHA256_CTX)); + 8005492: 2100 movs r1, #0 + 8005494: 3004 adds r0, #4 + 8005496: f008 f8ed bl 800d674 + +#if 1 + ctx->num_pending = 0; + ctx->hh.Init.DataType = HASH_DATATYPE_8B; + 800549a: 2320 movs r3, #32 + 800549c: 6023 str r3, [r4, #0] + HAL_HASH_Init(&ctx->hh); + 800549e: 4620 mov r0, r4 + __HAL_HASH_RESET_MDMAT(); + + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, + HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT); +#endif +} + 80054a0: e8bd 4010 ldmia.w sp!, {r4, lr} + HAL_HASH_Init(&ctx->hh); + 80054a4: f005 b802 b.w 800a4ac + +080054a8 : + +void sha256_update(SHA256_CTX *ctx, const uint8_t data[], uint32_t len) +{ + 80054a8: b5f8 push {r3, r4, r5, r6, r7, lr} + HAL_StatusTypeDef rv; + + // clear out any pending bytes + if(ctx->num_pending + len >= 4) { + 80054aa: f890 3048 ldrb.w r3, [r0, #72] ; 0x48 + 80054ae: 4413 add r3, r2 + 80054b0: 2b03 cmp r3, #3 +{ + 80054b2: 4605 mov r5, r0 + 80054b4: 460e mov r6, r1 + 80054b6: 4614 mov r4, r2 + if(ctx->num_pending + len >= 4) { + 80054b8: d818 bhi.n 80054ec + } + } + + // write full blocks + uint32_t blocks = len / 4; + if(blocks) { + 80054ba: 2c03 cmp r4, #3 + 80054bc: d926 bls.n 800550c +#if 1 + rv = HAL_HASHEx_SHA256_Accumulate(&ctx->hh, (uint8_t *)data, blocks*4); + 80054be: f024 0703 bic.w r7, r4, #3 + 80054c2: 463a mov r2, r7 + 80054c4: 4631 mov r1, r6 + 80054c6: 4628 mov r0, r5 + 80054c8: f7ff ffc2 bl 8005450 + ASSERT(rv == HAL_OK); + 80054cc: b9c8 cbnz r0, 8005502 + uint32_t tmp; + memcpy(&tmp, data, 4); + HASH->DIN = tmp; + } +#endif + len -= blocks*4; + 80054ce: f004 0403 and.w r4, r4, #3 + data += blocks*4; + 80054d2: 443e add r6, r7 + 80054d4: e01a b.n 800550c + ctx->pending[ctx->num_pending++] = *data; + 80054d6: 1c5a adds r2, r3, #1 + 80054d8: b2d2 uxtb r2, r2 + 80054da: f885 2048 strb.w r2, [r5, #72] ; 0x48 + 80054de: 442b add r3, r5 + 80054e0: f816 1b01 ldrb.w r1, [r6], #1 + 80054e4: f883 1044 strb.w r1, [r3, #68] ; 0x44 + if(!len) break; + 80054e8: 3c01 subs r4, #1 + 80054ea: d00d beq.n 8005508 + while(ctx->num_pending != 4) { + 80054ec: f895 3048 ldrb.w r3, [r5, #72] ; 0x48 + 80054f0: 2b04 cmp r3, #4 + 80054f2: d1f0 bne.n 80054d6 + rv = HAL_HASHEx_SHA256_Accumulate(&ctx->hh, ctx->pending, 4); + 80054f4: 2204 movs r2, #4 + 80054f6: f105 0144 add.w r1, r5, #68 ; 0x44 + 80054fa: 4628 mov r0, r5 + 80054fc: f7ff ffa8 bl 8005450 + ASSERT(rv == HAL_OK); + 8005500: b140 cbz r0, 8005514 + 8005502: 480b ldr r0, [pc, #44] ; (8005530 ) + 8005504: f7fb faa0 bl 8000a48 + if(ctx->num_pending == 4) { + 8005508: 2a04 cmp r2, #4 + 800550a: d0f3 beq.n 80054f4 + 800550c: 4434 add r4, r6 + } + + // save runt for later + ASSERT(len <= 3); + while(len) { + 800550e: 42b4 cmp r4, r6 + 8005510: d103 bne.n 800551a + ctx->pending[ctx->num_pending++] = *data; + data++; + len--; + } +} + 8005512: bdf8 pop {r3, r4, r5, r6, r7, pc} + ctx->num_pending = 0; + 8005514: f885 0048 strb.w r0, [r5, #72] ; 0x48 + 8005518: e7cf b.n 80054ba + ctx->pending[ctx->num_pending++] = *data; + 800551a: f895 3048 ldrb.w r3, [r5, #72] ; 0x48 + 800551e: 1c5a adds r2, r3, #1 + 8005520: f885 2048 strb.w r2, [r5, #72] ; 0x48 + 8005524: 442b add r3, r5 + 8005526: f816 2b01 ldrb.w r2, [r6], #1 + 800552a: f883 2044 strb.w r2, [r3, #68] ; 0x44 + len--; + 800552e: e7ee b.n 800550e + 8005530: 0800e3e0 .word 0x0800e3e0 + +08005534 : + +void sha256_final(SHA256_CTX *ctx, uint8_t digest[32]) +{ + 8005534: b513 push {r0, r1, r4, lr} + // Do final 0-3 bytes, pad and return digest. +#if 1 + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&ctx->hh, + 8005536: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800553a: 9200 str r2, [sp, #0] +{ + 800553c: 460b mov r3, r1 + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&ctx->hh, + 800553e: f890 2048 ldrb.w r2, [r0, #72] ; 0x48 + 8005542: f100 0144 add.w r1, r0, #68 ; 0x44 + 8005546: f7ff ff89 bl 800545c + ctx->pending, ctx->num_pending, digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 800554a: b110 cbz r0, 8005552 + 800554c: 4802 ldr r0, [pc, #8] ; (8005558 ) + 800554e: f7fb fa7b bl 8000a48 + tmp = __REV(HASH_DIGEST->HR[6]); + memcpy(out, &tmp, 4); out += 4; + tmp = __REV(HASH_DIGEST->HR[7]); + memcpy(out, &tmp, 4); +#endif +} + 8005552: b002 add sp, #8 + 8005554: bd10 pop {r4, pc} + 8005556: bf00 nop + 8005558: 0800e3e0 .word 0x0800e3e0 + +0800555c : +// +// single-shot version (best) +// + void +sha256_single(const uint8_t data[], uint32_t len, uint8_t digest[32]) +{ + 800555c: b530 push {r4, r5, lr} + 800555e: b097 sub sp, #92 ; 0x5c + 8005560: 4604 mov r4, r0 + 8005562: 460d mov r5, r1 + 8005564: 9203 str r2, [sp, #12] + HASH_HandleTypeDef hh = {0}; + 8005566: 2100 movs r1, #0 + 8005568: 2240 movs r2, #64 ; 0x40 + 800556a: a806 add r0, sp, #24 + 800556c: f008 f882 bl 800d674 + + hh.Init.DataType = HASH_DATATYPE_8B; + 8005570: 2220 movs r2, #32 + + HAL_HASH_Init(&hh); + 8005572: a805 add r0, sp, #20 + hh.Init.DataType = HASH_DATATYPE_8B; + 8005574: 9205 str r2, [sp, #20] + HAL_HASH_Init(&hh); + 8005576: f004 ff99 bl 800a4ac + + // It's called "Start" but it handles the runt packet, so really can only + // be used once at end of message, or for whole message. + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&hh, (uint8_t *)data, len, + 800557a: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800557e: 9200 str r2, [sp, #0] + 8005580: 9b03 ldr r3, [sp, #12] + 8005582: 462a mov r2, r5 + 8005584: 4621 mov r1, r4 + 8005586: a805 add r0, sp, #20 + 8005588: f7ff ff68 bl 800545c + digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 800558c: b110 cbz r0, 8005594 + 800558e: 4802 ldr r0, [pc, #8] ; (8005598 ) + 8005590: f7fb fa5a bl 8000a48 +} + 8005594: b017 add sp, #92 ; 0x5c + 8005596: bd30 pop {r4, r5, pc} + 8005598: 0800e3e0 .word 0x0800e3e0 + +0800559c : +// hmac_sha256_init() +// + void +hmac_sha256_init(HMAC_CTX *ctx) +{ + memset(ctx, 0, sizeof(HMAC_CTX)); + 800559c: f44f 7282 mov.w r2, #260 ; 0x104 + 80055a0: 2100 movs r1, #0 + 80055a2: f008 b867 b.w 800d674 + ... + +080055a8 : + +// hmac_sha256_update() +// + void +hmac_sha256_update(HMAC_CTX *ctx, const uint8_t data[], uint32_t len) +{ + 80055a8: b538 push {r3, r4, r5, lr} + 80055aa: 4604 mov r4, r0 + // simple append + ASSERT(ctx->num_pending + len < sizeof(ctx->pending)); + 80055ac: f8d0 0100 ldr.w r0, [r0, #256] ; 0x100 + 80055b0: 1883 adds r3, r0, r2 + 80055b2: 2bff cmp r3, #255 ; 0xff +{ + 80055b4: 4615 mov r5, r2 + ASSERT(ctx->num_pending + len < sizeof(ctx->pending)); + 80055b6: d902 bls.n 80055be + 80055b8: 4805 ldr r0, [pc, #20] ; (80055d0 ) + 80055ba: f7fb fa45 bl 8000a48 + + memcpy(ctx->pending+ctx->num_pending, data, len); + 80055be: 4420 add r0, r4 + 80055c0: f008 f830 bl 800d624 + + ctx->num_pending += len; + 80055c4: f8d4 2100 ldr.w r2, [r4, #256] ; 0x100 + 80055c8: 442a add r2, r5 + 80055ca: f8c4 2100 str.w r2, [r4, #256] ; 0x100 +} + 80055ce: bd38 pop {r3, r4, r5, pc} + 80055d0: 0800e3e0 .word 0x0800e3e0 + +080055d4 : + +// hmac_sha256_final() +// + void +hmac_sha256_final(HMAC_CTX *ctx, const uint8_t key[32], uint8_t digest[32]) +{ + 80055d4: b530 push {r4, r5, lr} + 80055d6: b097 sub sp, #92 ; 0x5c + 80055d8: 4604 mov r4, r0 + 80055da: 460d mov r5, r1 + 80055dc: 9203 str r2, [sp, #12] + HASH_HandleTypeDef hh = {0}; + 80055de: 2100 movs r1, #0 + 80055e0: 2238 movs r2, #56 ; 0x38 + 80055e2: a808 add r0, sp, #32 + 80055e4: f008 f846 bl 800d674 + + hh.Init.DataType = HASH_DATATYPE_8B; + 80055e8: 2220 movs r2, #32 + hh.Init.pKey = (uint8_t *)key; // const viol due to API dumbness + hh.Init.KeySize = 32; + + HAL_HASH_Init(&hh); + 80055ea: a805 add r0, sp, #20 + hh.Init.KeySize = 32; + 80055ec: e9cd 2506 strd r2, r5, [sp, #24] + hh.Init.DataType = HASH_DATATYPE_8B; + 80055f0: 9205 str r2, [sp, #20] + HAL_HASH_Init(&hh); + 80055f2: f004 ff5b bl 800a4ac + + HAL_StatusTypeDef rv = HAL_HMACEx_SHA256_Start(&hh, + 80055f6: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 80055fa: 9200 str r2, [sp, #0] + 80055fc: 9b03 ldr r3, [sp, #12] + 80055fe: f8d4 2100 ldr.w r2, [r4, #256] ; 0x100 + 8005602: 4621 mov r1, r4 + 8005604: a805 add r0, sp, #20 + 8005606: f7ff ff35 bl 8005474 + ctx->pending, ctx->num_pending, digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 800560a: b110 cbz r0, 8005612 + 800560c: 4802 ldr r0, [pc, #8] ; (8005618 ) + 800560e: f7fb fa1b bl 8000a48 +} + 8005612: b017 add sp, #92 ; 0x5c + 8005614: bd30 pop {r4, r5, pc} + 8005616: bf00 nop + 8005618: 0800e3e0 .word 0x0800e3e0 + +0800561c : + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + 800561c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + ); + +#else /* Thumb-1 */ + uint32_t r4, r5, r6, r7; + + __asm__ volatile ( + 8005620: 3b01 subs r3, #1 + 8005622: 009b lsls r3, r3, #2 + 8005624: 4698 mov r8, r3 + 8005626: 005b lsls r3, r3, #1 + 8005628: 4699 mov r9, r3 + 800562a: 2300 movs r3, #0 + 800562c: 2400 movs r4, #0 + 800562e: 2500 movs r5, #0 + 8005630: 2600 movs r6, #0 + 8005632: b401 push {r0} + 8005634: 2700 movs r7, #0 + 8005636: e002 b.n 800563e + 8005638: 0037 movs r7, r6 + 800563a: 4640 mov r0, r8 + 800563c: 1a3f subs r7, r7, r0 + 800563e: b478 push {r3, r4, r5, r6} + 8005640: 1bf0 subs r0, r6, r7 + 8005642: 5814 ldr r4, [r2, r0] + 8005644: 59c8 ldr r0, [r1, r7] + 8005646: 0c03 lsrs r3, r0, #16 + 8005648: b280 uxth r0, r0 + 800564a: 0c25 lsrs r5, r4, #16 + 800564c: b2a4 uxth r4, r4 + 800564e: 001e movs r6, r3 + 8005650: 436e muls r6, r5 + 8005652: 4363 muls r3, r4 + 8005654: 4345 muls r5, r0 + 8005656: 4360 muls r0, r4 + 8005658: 2400 movs r4, #0 + 800565a: 195b adds r3, r3, r5 + 800565c: 4164 adcs r4, r4 + 800565e: 0424 lsls r4, r4, #16 + 8005660: 1936 adds r6, r6, r4 + 8005662: 041c lsls r4, r3, #16 + 8005664: 0c1b lsrs r3, r3, #16 + 8005666: 1900 adds r0, r0, r4 + 8005668: 415e adcs r6, r3 + 800566a: bc38 pop {r3, r4, r5} + 800566c: 181b adds r3, r3, r0 + 800566e: 4174 adcs r4, r6 + 8005670: 2000 movs r0, #0 + 8005672: 4145 adcs r5, r0 + 8005674: bc40 pop {r6} + 8005676: 3704 adds r7, #4 + 8005678: 4547 cmp r7, r8 + 800567a: dc01 bgt.n 8005680 + 800567c: 42b7 cmp r7, r6 + 800567e: ddde ble.n 800563e + 8005680: 9800 ldr r0, [sp, #0] + 8005682: 5183 str r3, [r0, r6] + 8005684: 4623 mov r3, r4 + 8005686: 462c mov r4, r5 + 8005688: 2500 movs r5, #0 + 800568a: 3604 adds r6, #4 + 800568c: 4546 cmp r6, r8 + 800568e: ddd1 ble.n 8005634 + 8005690: 454e cmp r6, r9 + 8005692: ddd1 ble.n 8005638 + 8005694: 5183 str r3, [r0, r6] + 8005696: bc01 pop {r0} + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left), [r2] "l" (right) + : "r8", "r9", "cc", "memory" + ); +#endif +} + 8005698: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + +0800569c : + +#if !asm_clear +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + vli[i] = 0; + 800569c: ea21 71e1 bic.w r1, r1, r1, asr #31 + 80056a0: 008a lsls r2, r1, #2 + 80056a2: 2100 movs r1, #0 + 80056a4: f007 bfe6 b.w 800d674 + +080056a8 : +} +#endif /* !asm_clear */ + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { + 80056a8: b510 push {r4, lr} + uECC_word_t bits = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + 80056aa: 2300 movs r3, #0 + uECC_word_t bits = 0; + 80056ac: 461a mov r2, r3 + for (i = 0; i < num_words; ++i) { + 80056ae: b25c sxtb r4, r3 + 80056b0: 42a1 cmp r1, r4 + 80056b2: dc03 bgt.n 80056bc + bits |= vli[i]; + } + return (bits == 0); +} + 80056b4: fab2 f082 clz r0, r2 + 80056b8: 0940 lsrs r0, r0, #5 + 80056ba: bd10 pop {r4, pc} + bits |= vli[i]; + 80056bc: f850 4023 ldr.w r4, [r0, r3, lsl #2] + 80056c0: 3301 adds r3, #1 + 80056c2: 4322 orrs r2, r4 + for (i = 0; i < num_words; ++i) { + 80056c4: e7f3 b.n 80056ae + +080056c6 : + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) { + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 80056c6: 114a asrs r2, r1, #5 + 80056c8: 2301 movs r3, #1 + 80056ca: f850 0022 ldr.w r0, [r0, r2, lsl #2] + 80056ce: f001 011f and.w r1, r1, #31 + 80056d2: fa03 f101 lsl.w r1, r3, r1 +} + 80056d6: 4008 ands r0, r1 + 80056d8: 4770 bx lr + +080056da : +/* Counts the number of words in vli. */ +static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_words) { + wordcount_t i; + /* Search from the end until we find a non-zero digit. + We do it in reverse because we expect that most digits will be nonzero. */ + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + 80056da: 3901 subs r1, #1 + + return (i + 1); +} + +/* Counts the number of bits required to represent vli. */ +uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { + 80056dc: b510 push {r4, lr} + 80056de: b249 sxtb r1, r1 + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + 80056e0: 1d04 adds r4, r0, #4 + 80056e2: 060a lsls r2, r1, #24 + 80056e4: b2cb uxtb r3, r1 + 80056e6: d404 bmi.n 80056f2 + 80056e8: 3901 subs r1, #1 + 80056ea: f854 2021 ldr.w r2, [r4, r1, lsl #2] + 80056ee: 2a00 cmp r2, #0 + 80056f0: d0f7 beq.n 80056e2 + return (i + 1); + 80056f2: 3301 adds r3, #1 + 80056f4: b25b sxtb r3, r3 + uECC_word_t i; + uECC_word_t digit; + + wordcount_t num_digits = vli_numDigits(vli, max_words); + if (num_digits == 0) { + 80056f6: b173 cbz r3, 8005716 + return 0; + } + + digit = vli[num_digits - 1]; + 80056f8: f103 4280 add.w r2, r3, #1073741824 ; 0x40000000 + 80056fc: 3a01 subs r2, #1 + 80056fe: f850 2022 ldr.w r2, [r0, r2, lsl #2] + for (i = 0; digit; ++i) { + 8005702: 2000 movs r0, #0 + 8005704: b922 cbnz r2, 8005710 + digit >>= 1; + } + + return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i); + 8005706: 3b01 subs r3, #1 + 8005708: eb00 1343 add.w r3, r0, r3, lsl #5 + 800570c: b218 sxth r0, r3 +} + 800570e: bd10 pop {r4, pc} + digit >>= 1; + 8005710: 0852 lsrs r2, r2, #1 + for (i = 0; digit; ++i) { + 8005712: 3001 adds r0, #1 + 8005714: e7f6 b.n 8005704 + return 0; + 8005716: 4618 mov r0, r3 + 8005718: e7f9 b.n 800570e + +0800571a : + +/* Sets dest = src. */ +#if !asm_set +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + 800571a: b510 push {r4, lr} + wordcount_t i; + for (i = 0; i < num_words; ++i) { + 800571c: 2300 movs r3, #0 + 800571e: b25c sxtb r4, r3 + 8005720: 42a2 cmp r2, r4 + 8005722: dc00 bgt.n 8005726 + dest[i] = src[i]; + } +} + 8005724: bd10 pop {r4, pc} + dest[i] = src[i]; + 8005726: f851 4023 ldr.w r4, [r1, r3, lsl #2] + 800572a: f840 4023 str.w r4, [r0, r3, lsl #2] + for (i = 0; i < num_words; ++i) { + 800572e: 3301 adds r3, #1 + 8005730: e7f5 b.n 800571e + +08005732 : +#endif /* !asm_set */ + +/* Returns sign of left - right. */ +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + 8005732: b510 push {r4, lr} + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + 8005734: 3a01 subs r2, #1 + 8005736: b252 sxtb r2, r2 + 8005738: 0613 lsls r3, r2, #24 + 800573a: d501 bpl.n 8005740 + return 1; + } else if (left[i] < right[i]) { + return -1; + } + } + return 0; + 800573c: 2000 movs r0, #0 +} + 800573e: bd10 pop {r4, pc} + if (left[i] > right[i]) { + 8005740: f850 4022 ldr.w r4, [r0, r2, lsl #2] + 8005744: f851 3022 ldr.w r3, [r1, r2, lsl #2] + 8005748: 429c cmp r4, r3 + 800574a: d805 bhi.n 8005758 + } else if (left[i] < right[i]) { + 800574c: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 8005750: d2f2 bcs.n 8005738 + return -1; + 8005752: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8005756: e7f2 b.n 800573e + return 1; + 8005758: 2001 movs r0, #1 + 800575a: e7f0 b.n 800573e + +0800575c : +#if !asm_rshift1 +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t *end = vli; + uECC_word_t carry = 0; + + vli += num_words; + 800575c: eb00 0181 add.w r1, r0, r1, lsl #2 + uECC_word_t carry = 0; + 8005760: 2300 movs r3, #0 + while (vli-- > end) { + 8005762: 4288 cmp r0, r1 + 8005764: d300 bcc.n 8005768 + uECC_word_t temp = *vli; + *vli = (temp >> 1) | carry; + carry = temp << (uECC_WORD_BITS - 1); + } +} + 8005766: 4770 bx lr + uECC_word_t temp = *vli; + 8005768: f851 2d04 ldr.w r2, [r1, #-4]! + *vli = (temp >> 1) | carry; + 800576c: ea43 0352 orr.w r3, r3, r2, lsr #1 + 8005770: 600b str r3, [r1, #0] + carry = temp << (uECC_WORD_BITS - 1); + 8005772: 07d3 lsls r3, r2, #31 + 8005774: e7f5 b.n 8005762 + +08005776 : +/* Computes result = (left * right) % mod. */ +uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + 8005776: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800577a: b0b5 sub sp, #212 ; 0xd4 + 800577c: 461f mov r7, r3 + 800577e: f99d 50f8 ldrsb.w r5, [sp, #248] ; 0xf8 + 8005782: 4680 mov r8, r0 + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, num_words); + 8005784: 462b mov r3, r5 + 8005786: a804 add r0, sp, #16 + 8005788: f7ff ff48 bl 800561c + uECC_word_t *v[2] = {tmp, product}; + 800578c: ab24 add r3, sp, #144 ; 0x90 + 800578e: e9cd 3002 strd r3, r0, [sp, #8] + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words); + 8005792: 4629 mov r1, r5 + 8005794: 4638 mov r0, r7 + 8005796: f7ff ffa0 bl 80056da + 800579a: ebc0 1085 rsb r0, r0, r5, lsl #6 + 800579e: b204 sxth r4, r0 + wordcount_t word_shift = shift / uECC_WORD_BITS; + 80057a0: 2c00 cmp r4, #0 + 80057a2: 4626 mov r6, r4 + 80057a4: bfb8 it lt + 80057a6: f104 061f addlt.w r6, r4, #31 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 80057aa: 4263 negs r3, r4 + wordcount_t word_shift = shift / uECC_WORD_BITS; + 80057ac: f346 1647 sbfx r6, r6, #5, #8 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 80057b0: f003 031f and.w r3, r3, #31 + 80057b4: f004 091f and.w r9, r4, #31 + uECC_vli_clear(mod_multiple, word_shift); + 80057b8: 4631 mov r1, r6 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 80057ba: bf58 it pl + 80057bc: f1c3 0900 rsbpl r9, r3, #0 + uECC_vli_clear(mod_multiple, word_shift); + 80057c0: a814 add r0, sp, #80 ; 0x50 + 80057c2: f7ff ff6b bl 800569c + if (bit_shift > 0) { + 80057c6: f1b9 0f00 cmp.w r9, #0 + 80057ca: b236 sxth r6, r6 + 80057cc: dd2b ble.n 8005826 + 80057ce: ab14 add r3, sp, #80 ; 0x50 + uECC_word_t carry = 0; + 80057d0: 2200 movs r2, #0 + 80057d2: eb03 0686 add.w r6, r3, r6, lsl #2 + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + 80057d6: f1c9 0c20 rsb ip, r9, #32 + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 80057da: 4613 mov r3, r2 + 80057dc: 42ab cmp r3, r5 + 80057de: d317 bcc.n 8005810 + for (i = 0; i < num_words * 2; ++i) { + 80057e0: 006b lsls r3, r5, #1 + 80057e2: 9301 str r3, [sp, #4] + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 80057e4: ab14 add r3, sp, #80 ; 0x50 + 80057e6: eb03 0985 add.w r9, r3, r5, lsl #2 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 80057ea: 1e6f subs r7, r5, #1 + 80057ec: ab34 add r3, sp, #208 ; 0xd0 + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 80057ee: 2601 movs r6, #1 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 80057f0: eb03 0787 add.w r7, r3, r7, lsl #2 + for (index = 1; shift >= 0; --shift) { + 80057f4: 2c00 cmp r4, #0 + 80057f6: da54 bge.n 80058a2 + uECC_vli_set(result, v[index], num_words); + 80057f8: ab34 add r3, sp, #208 ; 0xd0 + 80057fa: eb03 0686 add.w r6, r3, r6, lsl #2 + 80057fe: 462a mov r2, r5 + 8005800: f856 1cc8 ldr.w r1, [r6, #-200] + 8005804: 4640 mov r0, r8 + 8005806: f7ff ff88 bl 800571a + uECC_vli_mmod(result, product, mod, num_words); +} + 800580a: b035 add sp, #212 ; 0xd4 + 800580c: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; + 8005810: f857 0023 ldr.w r0, [r7, r3, lsl #2] + 8005814: fa00 f109 lsl.w r1, r0, r9 + 8005818: 430a orrs r2, r1 + 800581a: f846 2b04 str.w r2, [r6], #4 + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 800581e: 3301 adds r3, #1 + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + 8005820: fa20 f20c lsr.w r2, r0, ip + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 8005824: e7da b.n 80057dc + uECC_vli_set(mod_multiple + word_shift, mod, num_words); + 8005826: ab14 add r3, sp, #80 ; 0x50 + 8005828: 462a mov r2, r5 + 800582a: 4639 mov r1, r7 + 800582c: eb03 0086 add.w r0, r3, r6, lsl #2 + 8005830: f7ff ff73 bl 800571a + 8005834: e7d4 b.n 80057e0 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 8005836: fa0f fe82 sxth.w lr, r2 + 800583a: f85a 3cc8 ldr.w r3, [sl, #-200] + 800583e: f853 b02e ldr.w fp, [r3, lr, lsl #2] + 8005842: ab34 add r3, sp, #208 ; 0xd0 + 8005844: eb03 0282 add.w r2, r3, r2, lsl #2 + 8005848: 3001 adds r0, #1 + 800584a: f852 3c80 ldr.w r3, [r2, #-128] + 800584e: 440b add r3, r1 + 8005850: ebbb 0303 subs.w r3, fp, r3 + 8005854: bf34 ite cc + 8005856: 2201 movcc r2, #1 + 8005858: 2200 movcs r2, #0 + if (diff != v[index][i]) { + 800585a: 459b cmp fp, r3 + borrow = (diff > v[index][i]); + 800585c: bf18 it ne + 800585e: 4611 movne r1, r2 + v[1 - index][i] = diff; + 8005860: f85c 2cc8 ldr.w r2, [ip, #-200] + 8005864: f842 302e str.w r3, [r2, lr, lsl #2] + for (i = 0; i < num_words * 2; ++i) { + 8005868: 9b01 ldr r3, [sp, #4] + 800586a: b242 sxtb r2, r0 + 800586c: 429a cmp r2, r3 + 800586e: dbe2 blt.n 8005836 + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + 8005870: 1a73 subs r3, r6, r1 + 8005872: 425e negs r6, r3 + uECC_vli_rshift1(mod_multiple, num_words); + 8005874: 4629 mov r1, r5 + 8005876: a814 add r0, sp, #80 ; 0x50 + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + 8005878: 415e adcs r6, r3 + uECC_vli_rshift1(mod_multiple, num_words); + 800587a: f7ff ff6f bl 800575c + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 800587e: ab34 add r3, sp, #208 ; 0xd0 + 8005880: eb03 0385 add.w r3, r3, r5, lsl #2 + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005884: 4629 mov r1, r5 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 8005886: f853 2c80 ldr.w r2, [r3, #-128] + 800588a: f857 3c80 ldr.w r3, [r7, #-128] + 800588e: ea43 73c2 orr.w r3, r3, r2, lsl #31 + 8005892: f847 3c80 str.w r3, [r7, #-128] + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005896: 4648 mov r0, r9 + 8005898: 3c01 subs r4, #1 + 800589a: f7ff ff5f bl 800575c + for (index = 1; shift >= 0; --shift) { + 800589e: b224 sxth r4, r4 + 80058a0: e7a8 b.n 80057f4 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 80058a2: ab34 add r3, sp, #208 ; 0xd0 + 80058a4: 2000 movs r0, #0 + v[1 - index][i] = diff; + 80058a6: f1c6 0c01 rsb ip, r6, #1 + uECC_word_t borrow = 0; + 80058aa: 4601 mov r1, r0 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 80058ac: eb03 0a86 add.w sl, r3, r6, lsl #2 + v[1 - index][i] = diff; + 80058b0: eb03 0c8c add.w ip, r3, ip, lsl #2 + 80058b4: e7d8 b.n 8005868 + +080058b6 : + +uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve) { + 80058b6: b530 push {r4, r5, lr} + 80058b8: 461c mov r4, r3 + 80058ba: b091 sub sp, #68 ; 0x44 + 80058bc: 4605 mov r5, r0 + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); + 80058be: f993 3000 ldrsb.w r3, [r3] + 80058c2: 4668 mov r0, sp + 80058c4: f7ff feaa bl 800561c +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); + 80058c8: 4601 mov r1, r0 + 80058ca: f8d4 30b0 ldr.w r3, [r4, #176] ; 0xb0 + 80058ce: 4628 mov r0, r5 + 80058d0: 4798 blx r3 +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + 80058d2: b011 add sp, #68 ; 0x44 + 80058d4: bd30 pop {r4, r5, pc} + +080058d6 : +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + 80058d6: 4613 mov r3, r2 + uECC_vli_modMult_fast(result, left, left, curve); + 80058d8: 460a mov r2, r1 + 80058da: f7ff bfec b.w 80058b6 + +080058de : + +/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ +static void apply_z(uECC_word_t * X1, + uECC_word_t * Y1, + const uECC_word_t * const Z, + uECC_Curve curve) { + 80058de: b570 push {r4, r5, r6, lr} + 80058e0: 4614 mov r4, r2 + 80058e2: b08a sub sp, #40 ; 0x28 + 80058e4: 4606 mov r6, r0 + 80058e6: 460d mov r5, r1 + uECC_word_t t1[uECC_MAX_WORDS]; + + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + 80058e8: 461a mov r2, r3 + 80058ea: 4621 mov r1, r4 + 80058ec: a802 add r0, sp, #8 + 80058ee: 9301 str r3, [sp, #4] + 80058f0: f7ff fff1 bl 80058d6 + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + 80058f4: 9b01 ldr r3, [sp, #4] + 80058f6: aa02 add r2, sp, #8 + 80058f8: 4631 mov r1, r6 + 80058fa: 4630 mov r0, r6 + 80058fc: f7ff ffdb bl 80058b6 + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + 8005900: a902 add r1, sp, #8 + 8005902: 9b01 ldr r3, [sp, #4] + 8005904: 4622 mov r2, r4 + 8005906: 4608 mov r0, r1 + 8005908: f7ff ffd5 bl 80058b6 + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ + 800590c: 9b01 ldr r3, [sp, #4] + 800590e: aa02 add r2, sp, #8 + 8005910: 4629 mov r1, r5 + 8005912: 4628 mov r0, r5 + 8005914: f7ff ffcf bl 80058b6 +} + 8005918: b00a add sp, #40 ; 0x28 + 800591a: bd70 pop {r4, r5, r6, pc} + +0800591c : + +#else + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uECC_word_t *native) { + 800591c: b5f0 push {r4, r5, r6, r7, lr} + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + 800591e: 2500 movs r5, #0 + unsigned b = num_bytes - 1 - i; + 8005920: 1e4f subs r7, r1, #1 + 8005922: b26c sxtb r4, r5 + for (i = 0; i < num_bytes; ++i) { + 8005924: 428c cmp r4, r1 + 8005926: f105 0501 add.w r5, r5, #1 + 800592a: db00 blt.n 800592e + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + } +} + 800592c: bdf0 pop {r4, r5, r6, r7, pc} + unsigned b = num_bytes - 1 - i; + 800592e: 1b3b subs r3, r7, r4 + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + 8005930: f023 0603 bic.w r6, r3, #3 + 8005934: f003 0303 and.w r3, r3, #3 + 8005938: 5996 ldr r6, [r2, r6] + 800593a: 00db lsls r3, r3, #3 + 800593c: fa26 f303 lsr.w r3, r6, r3 + 8005940: 5503 strb r3, [r0, r4] + for (i = 0; i < num_bytes; ++i) { + 8005942: e7ee b.n 8005922 + +08005944 : + +uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native, + const uint8_t *bytes, + int num_bytes) { + 8005944: b5f8 push {r3, r4, r5, r6, r7, lr} + 8005946: 460e mov r6, r1 + wordcount_t i; + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005948: 1cd1 adds r1, r2, #3 + 800594a: bf48 it mi + 800594c: 1d91 addmi r1, r2, #6 + int num_bytes) { + 800594e: 4614 mov r4, r2 + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005950: f341 0187 sbfx r1, r1, #2, #8 + int num_bytes) { + 8005954: 4605 mov r5, r0 + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + 8005956: 1e67 subs r7, r4, #1 + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005958: f7ff fea0 bl 800569c + for (i = 0; i < num_bytes; ++i) { + 800595c: 2000 movs r0, #0 + 800595e: b242 sxtb r2, r0 + 8005960: 42a2 cmp r2, r4 + 8005962: f100 0001 add.w r0, r0, #1 + 8005966: db00 blt.n 800596a + native[b / uECC_WORD_SIZE] |= + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + } +} + 8005968: bdf8 pop {r3, r4, r5, r6, r7, pc} + unsigned b = num_bytes - 1 - i; + 800596a: 1abb subs r3, r7, r2 + native[b / uECC_WORD_SIZE] |= + 800596c: f023 0103 bic.w r1, r3, #3 + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + 8005970: 5cb2 ldrb r2, [r6, r2] + 8005972: f003 0303 and.w r3, r3, #3 + 8005976: 00db lsls r3, r3, #3 + 8005978: fa02 f303 lsl.w r3, r2, r3 + native[b / uECC_WORD_SIZE] |= + 800597c: 586a ldr r2, [r5, r1] + 800597e: 431a orrs r2, r3 + 8005980: 506a str r2, [r5, r1] + for (i = 0; i < num_bytes; ++i) { + 8005982: e7ec b.n 800595e + +08005984 : + return 0; +} + +/* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always + the same size as the hash result size. */ +static void HMAC_init(uECC_HashContext *hash_context, const uint8_t *K) { + 8005984: b570 push {r4, r5, r6, lr} + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 8005986: e9d0 3504 ldrd r3, r5, [r0, #16] +static void HMAC_init(uECC_HashContext *hash_context, const uint8_t *K) { + 800598a: 4604 mov r4, r0 + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 800598c: eb05 0543 add.w r5, r5, r3, lsl #1 + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + 8005990: 2300 movs r3, #0 + 8005992: 6922 ldr r2, [r4, #16] + 8005994: 429a cmp r2, r3 + 8005996: d80d bhi.n 80059b4 + pad[i] = K[i] ^ 0x36; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x36; + 8005998: 2136 movs r1, #54 ; 0x36 + for (; i < hash_context->block_size; ++i) + 800599a: 68e2 ldr r2, [r4, #12] + 800599c: 429a cmp r2, r3 + 800599e: d80f bhi.n 80059c0 + + hash_context->init_hash(hash_context); + 80059a0: 6823 ldr r3, [r4, #0] + 80059a2: 4620 mov r0, r4 + 80059a4: 4798 blx r3 + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 80059a6: 6863 ldr r3, [r4, #4] + 80059a8: 68e2 ldr r2, [r4, #12] + 80059aa: 4629 mov r1, r5 + 80059ac: 4620 mov r0, r4 +} + 80059ae: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 80059b2: 4718 bx r3 + pad[i] = K[i] ^ 0x36; + 80059b4: 5cca ldrb r2, [r1, r3] + 80059b6: f082 0236 eor.w r2, r2, #54 ; 0x36 + 80059ba: 54ea strb r2, [r5, r3] + for (i = 0; i < hash_context->result_size; ++i) + 80059bc: 3301 adds r3, #1 + 80059be: e7e8 b.n 8005992 + pad[i] = 0x36; + 80059c0: 54e9 strb r1, [r5, r3] + for (; i < hash_context->block_size; ++i) + 80059c2: 3301 adds r3, #1 + 80059c4: e7e9 b.n 800599a + +080059c6 : + +static void HMAC_update(uECC_HashContext *hash_context, + const uint8_t *message, + unsigned message_size) { + hash_context->update_hash(hash_context, message, message_size); + 80059c6: 6843 ldr r3, [r0, #4] + 80059c8: 4718 bx r3 + +080059ca : +} + +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 80059ca: b570 push {r4, r5, r6, lr} + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 80059cc: e9d0 3604 ldrd r3, r6, [r0, #16] +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 80059d0: 4604 mov r4, r0 + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 80059d2: eb06 0643 add.w r6, r6, r3, lsl #1 +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 80059d6: 4615 mov r5, r2 + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + 80059d8: 2300 movs r3, #0 + 80059da: 6922 ldr r2, [r4, #16] + 80059dc: 429a cmp r2, r3 + 80059de: d81a bhi.n 8005a16 + pad[i] = K[i] ^ 0x5c; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x5c; + 80059e0: 215c movs r1, #92 ; 0x5c + for (; i < hash_context->block_size; ++i) + 80059e2: 68e2 ldr r2, [r4, #12] + 80059e4: 429a cmp r2, r3 + 80059e6: d81c bhi.n 8005a22 + + hash_context->finish_hash(hash_context, result); + 80059e8: 4629 mov r1, r5 + 80059ea: 68a3 ldr r3, [r4, #8] + 80059ec: 4620 mov r0, r4 + 80059ee: 4798 blx r3 + + hash_context->init_hash(hash_context); + 80059f0: 6823 ldr r3, [r4, #0] + 80059f2: 4620 mov r0, r4 + 80059f4: 4798 blx r3 + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 80059f6: 6863 ldr r3, [r4, #4] + 80059f8: 68e2 ldr r2, [r4, #12] + 80059fa: 4631 mov r1, r6 + 80059fc: 4620 mov r0, r4 + 80059fe: 4798 blx r3 + hash_context->update_hash(hash_context, result, hash_context->result_size); + 8005a00: 6863 ldr r3, [r4, #4] + 8005a02: 6922 ldr r2, [r4, #16] + 8005a04: 4629 mov r1, r5 + 8005a06: 4620 mov r0, r4 + 8005a08: 4798 blx r3 + hash_context->finish_hash(hash_context, result); + 8005a0a: 68a3 ldr r3, [r4, #8] + 8005a0c: 4629 mov r1, r5 + 8005a0e: 4620 mov r0, r4 +} + 8005a10: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + hash_context->finish_hash(hash_context, result); + 8005a14: 4718 bx r3 + pad[i] = K[i] ^ 0x5c; + 8005a16: 5cca ldrb r2, [r1, r3] + 8005a18: f082 025c eor.w r2, r2, #92 ; 0x5c + 8005a1c: 54f2 strb r2, [r6, r3] + for (i = 0; i < hash_context->result_size; ++i) + 8005a1e: 3301 adds r3, #1 + 8005a20: e7db b.n 80059da + pad[i] = 0x5c; + 8005a22: 54f1 strb r1, [r6, r3] + for (; i < hash_context->block_size; ++i) + 8005a24: 3301 adds r3, #1 + 8005a26: e7dc b.n 80059e2 + +08005a28 : + +/* V = HMAC_K(V) */ +static void update_V(uECC_HashContext *hash_context, uint8_t *K, uint8_t *V) { + 8005a28: b570 push {r4, r5, r6, lr} + 8005a2a: 4604 mov r4, r0 + 8005a2c: 4615 mov r5, r2 + 8005a2e: 460e mov r6, r1 + HMAC_init(hash_context, K); + 8005a30: f7ff ffa8 bl 8005984 + HMAC_update(hash_context, V, hash_context->result_size); + 8005a34: 6922 ldr r2, [r4, #16] + 8005a36: 4629 mov r1, r5 + 8005a38: 4620 mov r0, r4 + 8005a3a: f7ff ffc4 bl 80059c6 + HMAC_finish(hash_context, K, V); + 8005a3e: 462a mov r2, r5 + 8005a40: 4631 mov r1, r6 + 8005a42: 4620 mov r0, r4 +} + 8005a44: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + HMAC_finish(hash_context, K, V); + 8005a48: f7ff bfbf b.w 80059ca + +08005a4c : +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + 8005a4c: b530 push {r4, r5, lr} + __asm__ volatile ( + 8005a4e: 2300 movs r3, #0 + 8005a50: c910 ldmia r1!, {r4} + 8005a52: ca20 ldmia r2!, {r5} + 8005a54: 1b64 subs r4, r4, r5 + 8005a56: c010 stmia r0!, {r4} + 8005a58: c910 ldmia r1!, {r4} + 8005a5a: ca20 ldmia r2!, {r5} + 8005a5c: 41ac sbcs r4, r5 + 8005a5e: c010 stmia r0!, {r4} + 8005a60: c910 ldmia r1!, {r4} + 8005a62: ca20 ldmia r2!, {r5} + 8005a64: 41ac sbcs r4, r5 + 8005a66: c010 stmia r0!, {r4} + 8005a68: c910 ldmia r1!, {r4} + 8005a6a: ca20 ldmia r2!, {r5} + 8005a6c: 41ac sbcs r4, r5 + 8005a6e: c010 stmia r0!, {r4} + 8005a70: c910 ldmia r1!, {r4} + 8005a72: ca20 ldmia r2!, {r5} + 8005a74: 41ac sbcs r4, r5 + 8005a76: c010 stmia r0!, {r4} + 8005a78: c910 ldmia r1!, {r4} + 8005a7a: ca20 ldmia r2!, {r5} + 8005a7c: 41ac sbcs r4, r5 + 8005a7e: c010 stmia r0!, {r4} + 8005a80: c910 ldmia r1!, {r4} + 8005a82: ca20 ldmia r2!, {r5} + 8005a84: 41ac sbcs r4, r5 + 8005a86: c010 stmia r0!, {r4} + 8005a88: c910 ldmia r1!, {r4} + 8005a8a: ca20 ldmia r2!, {r5} + 8005a8c: 41ac sbcs r4, r5 + 8005a8e: c010 stmia r0!, {r4} + 8005a90: 415b adcs r3, r3 +} + 8005a92: fab3 f083 clz r0, r3 + 8005a96: 0940 lsrs r0, r0, #5 + 8005a98: bd30 pop {r4, r5, pc} + +08005a9a : + uECC_Curve curve) { + 8005a9a: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 8005a9e: 4698 mov r8, r3 + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005aa0: f9b3 3002 ldrsh.w r3, [r3, #2] + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005aa4: f113 041f adds.w r4, r3, #31 + 8005aa8: bf48 it mi + 8005aaa: f103 043e addmi.w r4, r3, #62 ; 0x3e + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005aae: 1ddd adds r5, r3, #7 + 8005ab0: bf48 it mi + 8005ab2: f103 050e addmi.w r5, r3, #14 + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005ab6: 1166 asrs r6, r4, #5 + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005ab8: 10ec asrs r4, r5, #3 + 8005aba: 4294 cmp r4, r2 + uECC_vli_clear(native, num_n_words); + 8005abc: b275 sxtb r5, r6 + 8005abe: bf28 it cs + 8005ac0: 4614 movcs r4, r2 + uECC_Curve curve) { + 8005ac2: 4607 mov r7, r0 + 8005ac4: 4689 mov r9, r1 + uECC_vli_clear(native, num_n_words); + 8005ac6: 4629 mov r1, r5 + 8005ac8: f7ff fde8 bl 800569c + uECC_vli_bytesToNative(native, bits, bits_size); + 8005acc: 4622 mov r2, r4 + 8005ace: 4649 mov r1, r9 + 8005ad0: 4638 mov r0, r7 + 8005ad2: f7ff ff37 bl 8005944 + if (bits_size * 8 <= (unsigned)curve->num_n_bits) { + 8005ad6: f9b8 2002 ldrsh.w r2, [r8, #2] + 8005ada: ebb2 0fc4 cmp.w r2, r4, lsl #3 + 8005ade: ea4f 03c4 mov.w r3, r4, lsl #3 + 8005ae2: d21f bcs.n 8005b24 + int shift = bits_size * 8 - curve->num_n_bits; + 8005ae4: 1a9b subs r3, r3, r2 + uECC_word_t *ptr = native + num_n_words; + 8005ae6: eb07 0486 add.w r4, r7, r6, lsl #2 + uECC_word_t carry = 0; + 8005aea: 2100 movs r1, #0 + carry = temp << (uECC_WORD_BITS - shift); + 8005aec: f1c3 0620 rsb r6, r3, #32 + while (ptr-- > native) { + 8005af0: 42a7 cmp r7, r4 + 8005af2: d30e bcc.n 8005b12 + if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) { + 8005af4: f108 0824 add.w r8, r8, #36 ; 0x24 + 8005af8: 462a mov r2, r5 + 8005afa: 4639 mov r1, r7 + 8005afc: 4640 mov r0, r8 + 8005afe: f7ff fe18 bl 8005732 + 8005b02: 2801 cmp r0, #1 + 8005b04: d00e beq.n 8005b24 + uECC_vli_sub(native, native, curve->n, num_n_words); + 8005b06: 4642 mov r2, r8 + 8005b08: 4638 mov r0, r7 +} + 8005b0a: e8bd 43f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + uECC_vli_sub(native, native, curve->n, num_n_words); + 8005b0e: f7ff bf9d b.w 8005a4c + uECC_word_t temp = *ptr; + 8005b12: f854 0d04 ldr.w r0, [r4, #-4]! + *ptr = (temp >> shift) | carry; + 8005b16: fa20 f203 lsr.w r2, r0, r3 + 8005b1a: 430a orrs r2, r1 + 8005b1c: 6022 str r2, [r4, #0] + carry = temp << (uECC_WORD_BITS - shift); + 8005b1e: fa00 f106 lsl.w r1, r0, r6 + 8005b22: e7e5 b.n 8005af0 +} + 8005b24: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + +08005b28 : + wordcount_t num_words) { + 8005b28: b530 push {r4, r5, lr} + 8005b2a: b089 sub sp, #36 ; 0x24 + 8005b2c: 4615 mov r5, r2 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005b2e: 460a mov r2, r1 + 8005b30: 4601 mov r1, r0 + 8005b32: 4668 mov r0, sp + 8005b34: f7ff ff8a bl 8005a4c + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + 8005b38: 4629 mov r1, r5 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005b3a: 4604 mov r4, r0 + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + 8005b3c: 4668 mov r0, sp + 8005b3e: f7ff fdb3 bl 80056a8 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005b42: 3c00 subs r4, #0 + 8005b44: bf18 it ne + 8005b46: 2401 movne r4, #1 + return (!equal - 2 * neg); + 8005b48: 0064 lsls r4, r4, #1 +} + 8005b4a: 2800 cmp r0, #0 + 8005b4c: bf14 ite ne + 8005b4e: 4260 negne r0, r4 + 8005b50: f1c4 0001 rsbeq r0, r4, #1 + 8005b54: b009 add sp, #36 ; 0x24 + 8005b56: bd30 pop {r4, r5, pc} + +08005b58 : + wordcount_t num_words) { + 8005b58: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8005b5c: 460f mov r7, r1 + if (!g_rng_function) { + 8005b5e: f8df a06c ldr.w sl, [pc, #108] ; 8005bcc + wordcount_t num_words) { + 8005b62: 4606 mov r6, r0 + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + 8005b64: 4611 mov r1, r2 + 8005b66: 4638 mov r0, r7 + wordcount_t num_words) { + 8005b68: 4614 mov r4, r2 + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + 8005b6a: f7ff fdb6 bl 80056da + if (!g_rng_function) { + 8005b6e: f8da 3000 ldr.w r3, [sl] + 8005b72: b303 cbz r3, 8005bb6 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005b74: 2504 movs r5, #4 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005b76: ebc0 1044 rsb r0, r0, r4, lsl #5 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005b7a: fb14 fb05 smulbb fp, r4, r5 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005b7e: b200 sxth r0, r0 + 8005b80: fb05 6504 mla r5, r5, r4, r6 + 8005b84: f04f 38ff mov.w r8, #4294967295 ; 0xffffffff + 8005b88: 3d04 subs r5, #4 + 8005b8a: fa28 f800 lsr.w r8, r8, r0 + 8005b8e: f04f 0940 mov.w r9, #64 ; 0x40 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005b92: f8da 3000 ldr.w r3, [sl] + 8005b96: 4659 mov r1, fp + 8005b98: 4630 mov r0, r6 + 8005b9a: 4798 blx r3 + 8005b9c: b158 cbz r0, 8005bb6 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005b9e: 682b ldr r3, [r5, #0] + 8005ba0: ea03 0308 and.w r3, r3, r8 + 8005ba4: 602b str r3, [r5, #0] + if (!uECC_vli_isZero(random, num_words) && + 8005ba6: 4621 mov r1, r4 + 8005ba8: 4630 mov r0, r6 + 8005baa: f7ff fd7d bl 80056a8 + 8005bae: b120 cbz r0, 8005bba + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8005bb0: f1b9 0901 subs.w r9, r9, #1 + 8005bb4: d1ed bne.n 8005b92 + return 0; + 8005bb6: 2000 movs r0, #0 + 8005bb8: e006 b.n 8005bc8 + uECC_vli_cmp(top, random, num_words) == 1) { + 8005bba: 4622 mov r2, r4 + 8005bbc: 4631 mov r1, r6 + 8005bbe: 4638 mov r0, r7 + 8005bc0: f7ff ffb2 bl 8005b28 + if (!uECC_vli_isZero(random, num_words) && + 8005bc4: 2801 cmp r0, #1 + 8005bc6: d1f3 bne.n 8005bb0 +} + 8005bc8: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} + 8005bcc: 2009e2a0 .word 0x2009e2a0 + +08005bd0 : +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + 8005bd0: b530 push {r4, r5, lr} + __asm__ volatile ( + 8005bd2: 4603 mov r3, r0 + 8005bd4: 2000 movs r0, #0 + 8005bd6: c910 ldmia r1!, {r4} + 8005bd8: ca20 ldmia r2!, {r5} + 8005bda: 1964 adds r4, r4, r5 + 8005bdc: c310 stmia r3!, {r4} + 8005bde: c910 ldmia r1!, {r4} + 8005be0: ca20 ldmia r2!, {r5} + 8005be2: 416c adcs r4, r5 + 8005be4: c310 stmia r3!, {r4} + 8005be6: c910 ldmia r1!, {r4} + 8005be8: ca20 ldmia r2!, {r5} + 8005bea: 416c adcs r4, r5 + 8005bec: c310 stmia r3!, {r4} + 8005bee: c910 ldmia r1!, {r4} + 8005bf0: ca20 ldmia r2!, {r5} + 8005bf2: 416c adcs r4, r5 + 8005bf4: c310 stmia r3!, {r4} + 8005bf6: c910 ldmia r1!, {r4} + 8005bf8: ca20 ldmia r2!, {r5} + 8005bfa: 416c adcs r4, r5 + 8005bfc: c310 stmia r3!, {r4} + 8005bfe: c910 ldmia r1!, {r4} + 8005c00: ca20 ldmia r2!, {r5} + 8005c02: 416c adcs r4, r5 + 8005c04: c310 stmia r3!, {r4} + 8005c06: c910 ldmia r1!, {r4} + 8005c08: ca20 ldmia r2!, {r5} + 8005c0a: 416c adcs r4, r5 + 8005c0c: c310 stmia r3!, {r4} + 8005c0e: c910 ldmia r1!, {r4} + 8005c10: ca20 ldmia r2!, {r5} + 8005c12: 416c adcs r4, r5 + 8005c14: c310 stmia r3!, {r4} + 8005c16: 4140 adcs r0, r0 +} + 8005c18: bd30 pop {r4, r5, pc} + +08005c1a : + uECC_Curve curve) { + 8005c1a: b573 push {r0, r1, r4, r5, r6, lr} + 8005c1c: 460d mov r5, r1 + 8005c1e: 4616 mov r6, r2 + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005c20: 4601 mov r1, r0 + 8005c22: f103 0224 add.w r2, r3, #36 ; 0x24 + 8005c26: 4628 mov r0, r5 + 8005c28: 9201 str r2, [sp, #4] + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005c2a: f9b3 4002 ldrsh.w r4, [r3, #2] + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005c2e: f7ff ffcf bl 8005bd0 + 8005c32: 9a01 ldr r2, [sp, #4] + 8005c34: b9c8 cbnz r0, 8005c6a + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005c36: f114 031f adds.w r3, r4, #31 + 8005c3a: bf48 it mi + 8005c3c: f104 033e addmi.w r3, r4, #62 ; 0x3e + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + 8005c40: f343 1347 sbfx r3, r3, #5, #8 + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005c44: ebb4 1f43 cmp.w r4, r3, lsl #5 + 8005c48: da11 bge.n 8005c6e + uECC_vli_testBit(k0, num_n_bits)); + 8005c4a: 4621 mov r1, r4 + 8005c4c: 4628 mov r0, r5 + 8005c4e: 9201 str r2, [sp, #4] + 8005c50: f7ff fd39 bl 80056c6 + 8005c54: 9a01 ldr r2, [sp, #4] + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + 8005c56: 1e04 subs r4, r0, #0 + 8005c58: bf18 it ne + 8005c5a: 2401 movne r4, #1 + uECC_vli_add(k1, k0, curve->n, num_n_words); + 8005c5c: 4629 mov r1, r5 + 8005c5e: 4630 mov r0, r6 + 8005c60: f7ff ffb6 bl 8005bd0 +} + 8005c64: 4620 mov r0, r4 + 8005c66: b002 add sp, #8 + 8005c68: bd70 pop {r4, r5, r6, pc} + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005c6a: 2401 movs r4, #1 + 8005c6c: e7f6 b.n 8005c5c + 8005c6e: 2400 movs r4, #0 + 8005c70: e7f4 b.n 8005c5c + +08005c72 : + /* add the 2^32 multiple */ + result[4 + num_words_secp256k1] = + uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + 8005c72: b5f8 push {r3, r4, r5, r6, r7, lr} + 8005c74: 460a mov r2, r1 + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uint32_t carry = 0; + 8005c76: 2300 movs r3, #0 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + 8005c78: 4604 mov r4, r0 + 8005c7a: 3904 subs r1, #4 + 8005c7c: 3804 subs r0, #4 + 8005c7e: f102 071c add.w r7, r2, #28 + wordcount_t k; + + for (k = 0; k < num_words_secp256k1; ++k) { + uint64_t p = (uint64_t)0x3D1 * right[k] + carry; + 8005c82: 469e mov lr, r3 + 8005c84: f240 35d1 movw r5, #977 ; 0x3d1 + 8005c88: f851 6f04 ldr.w r6, [r1, #4]! + 8005c8c: 46f4 mov ip, lr + 8005c8e: fbe6 3c05 umlal r3, ip, r6, r5 + for (k = 0; k < num_words_secp256k1; ++k) { + 8005c92: 428f cmp r7, r1 + result[k] = p; + 8005c94: f840 3f04 str.w r3, [r0, #4]! + carry = p >> 32; + 8005c98: 4663 mov r3, ip + for (k = 0; k < num_words_secp256k1; ++k) { + 8005c9a: d1f5 bne.n 8005c88 + } + result[num_words_secp256k1] = carry; + /* add the 2^32 multiple */ + result[1 + num_words_secp256k1] = + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); + 8005c9c: 1d21 adds r1, r4, #4 + result[num_words_secp256k1] = carry; + 8005c9e: f8c4 c020 str.w ip, [r4, #32] + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); + 8005ca2: 4608 mov r0, r1 + 8005ca4: f7ff ff94 bl 8005bd0 + result[1 + num_words_secp256k1] = + 8005ca8: 6260 str r0, [r4, #36] ; 0x24 +} + 8005caa: bdf8 pop {r3, r4, r5, r6, r7, pc} + +08005cac : +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + 8005cac: b570 push {r4, r5, r6, lr} + 8005cae: b090 sub sp, #64 ; 0x40 + 8005cb0: 460e mov r6, r1 + 8005cb2: 4604 mov r4, r0 + uECC_vli_clear(tmp, num_words_secp256k1); + 8005cb4: 2108 movs r1, #8 + 8005cb6: 4668 mov r0, sp + 8005cb8: f7ff fcf0 bl 800569c + uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); + 8005cbc: 2108 movs r1, #8 + 8005cbe: a808 add r0, sp, #32 + 8005cc0: f7ff fcec bl 800569c + omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ + 8005cc4: f106 0120 add.w r1, r6, #32 + 8005cc8: 4668 mov r0, sp + 8005cca: f7ff ffd2 bl 8005c72 + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + 8005cce: 466a mov r2, sp + 8005cd0: 4631 mov r1, r6 + 8005cd2: 4620 mov r0, r4 + 8005cd4: f7ff ff7c bl 8005bd0 + uECC_vli_clear(product, num_words_secp256k1); + 8005cd8: 2108 movs r1, #8 + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + 8005cda: 4605 mov r5, r0 + uECC_vli_clear(product, num_words_secp256k1); + 8005cdc: 4630 mov r0, r6 + 8005cde: f7ff fcdd bl 800569c + omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ + 8005ce2: 4630 mov r0, r6 + 8005ce4: a908 add r1, sp, #32 + 8005ce6: f7ff ffc4 bl 8005c72 + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + 8005cea: 4632 mov r2, r6 + 8005cec: 4621 mov r1, r4 + 8005cee: 4620 mov r0, r4 + 8005cf0: f7ff ff6e bl 8005bd0 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005cf4: 4e0b ldr r6, [pc, #44] ; (8005d24 ) + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + 8005cf6: 4405 add r5, r0 + while (carry > 0) { + 8005cf8: b96d cbnz r5, 8005d16 + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) > 0) { + 8005cfa: 490a ldr r1, [pc, #40] ; (8005d24 ) + 8005cfc: 2208 movs r2, #8 + 8005cfe: 4620 mov r0, r4 + 8005d00: f7ff fd17 bl 8005732 + 8005d04: 2800 cmp r0, #0 + 8005d06: dd04 ble.n 8005d12 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005d08: 460a mov r2, r1 + 8005d0a: 4620 mov r0, r4 + 8005d0c: 4621 mov r1, r4 + 8005d0e: f7ff fe9d bl 8005a4c +} + 8005d12: b010 add sp, #64 ; 0x40 + 8005d14: bd70 pop {r4, r5, r6, pc} + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005d16: 4632 mov r2, r6 + 8005d18: 4621 mov r1, r4 + 8005d1a: 4620 mov r0, r4 + --carry; + 8005d1c: 3d01 subs r5, #1 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005d1e: f7ff fe95 bl 8005a4c + 8005d22: e7e9 b.n 8005cf8 + 8005d24: 0800e878 .word 0x0800e878 + +08005d28 : +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 8005d28: e92d 44f0 stmdb sp!, {r4, r5, r6, r7, sl, lr} + uECC_vli_set(result, product, num_words_secp256r1); + 8005d2c: 2208 movs r2, #8 +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 8005d2e: b088 sub sp, #32 + uECC_vli_set(result, product, num_words_secp256r1); + 8005d30: f7ff fcf3 bl 800571a + tmp[3] = product[11]; + 8005d34: 6acb ldr r3, [r1, #44] ; 0x2c + 8005d36: 9303 str r3, [sp, #12] + tmp[4] = product[12]; + 8005d38: 6b0b ldr r3, [r1, #48] ; 0x30 + 8005d3a: 9304 str r3, [sp, #16] + tmp[5] = product[13]; + 8005d3c: 6b4b ldr r3, [r1, #52] ; 0x34 + 8005d3e: 9305 str r3, [sp, #20] + tmp[6] = product[14]; + 8005d40: 6b8b ldr r3, [r1, #56] ; 0x38 + 8005d42: 9306 str r3, [sp, #24] +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 8005d44: 460c mov r4, r1 + 8005d46: 4682 mov sl, r0 + tmp[0] = tmp[1] = tmp[2] = 0; + 8005d48: 2700 movs r7, #0 + tmp[7] = product[15]; + 8005d4a: 6bcb ldr r3, [r1, #60] ; 0x3c + 8005d4c: 9307 str r3, [sp, #28] + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d4e: 466a mov r2, sp + 8005d50: 4669 mov r1, sp + 8005d52: 4668 mov r0, sp + tmp[0] = tmp[1] = tmp[2] = 0; + 8005d54: e9cd 7701 strd r7, r7, [sp, #4] + 8005d58: 9700 str r7, [sp, #0] + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d5a: f7ff ff39 bl 8005bd0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005d5e: 466a mov r2, sp + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d60: 4605 mov r5, r0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005d62: 4651 mov r1, sl + 8005d64: 4650 mov r0, sl + 8005d66: f7ff ff33 bl 8005bd0 + tmp[3] = product[12]; + 8005d6a: 6b23 ldr r3, [r4, #48] ; 0x30 + 8005d6c: 9303 str r3, [sp, #12] + tmp[4] = product[13]; + 8005d6e: 6b63 ldr r3, [r4, #52] ; 0x34 + 8005d70: 9304 str r3, [sp, #16] + tmp[5] = product[14]; + 8005d72: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8005d74: 9305 str r3, [sp, #20] + tmp[6] = product[15]; + 8005d76: 6be3 ldr r3, [r4, #60] ; 0x3c + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005d78: 4405 add r5, r0 + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d7a: 466a mov r2, sp + 8005d7c: 4669 mov r1, sp + 8005d7e: 4668 mov r0, sp + tmp[7] = 0; + 8005d80: e9cd 3706 strd r3, r7, [sp, #24] + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d84: f7ff ff24 bl 8005bd0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005d88: 466a mov r2, sp + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8005d8a: 4405 add r5, r0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005d8c: 4651 mov r1, sl + 8005d8e: 4650 mov r0, sl + 8005d90: f7ff ff1e bl 8005bd0 + tmp[0] = product[8]; + 8005d94: 6a23 ldr r3, [r4, #32] + 8005d96: 9300 str r3, [sp, #0] + tmp[1] = product[9]; + 8005d98: 6a63 ldr r3, [r4, #36] ; 0x24 + 8005d9a: 9301 str r3, [sp, #4] + tmp[2] = product[10]; + 8005d9c: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8005d9e: 9302 str r3, [sp, #8] + tmp[6] = product[14]; + 8005da0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8005da2: 9306 str r3, [sp, #24] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005da4: 4405 add r5, r0 + tmp[7] = product[15]; + 8005da6: 6be3 ldr r3, [r4, #60] ; 0x3c + 8005da8: 9307 str r3, [sp, #28] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005daa: 466a mov r2, sp + 8005dac: 4651 mov r1, sl + 8005dae: 4650 mov r0, sl + tmp[3] = tmp[4] = tmp[5] = 0; + 8005db0: e9cd 7704 strd r7, r7, [sp, #16] + 8005db4: 9703 str r7, [sp, #12] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005db6: f7ff ff0b bl 8005bd0 + tmp[0] = product[9]; + 8005dba: 6a63 ldr r3, [r4, #36] ; 0x24 + 8005dbc: 9300 str r3, [sp, #0] + tmp[1] = product[10]; + 8005dbe: 6aa3 ldr r3, [r4, #40] ; 0x28 + tmp[4] = product[14]; + 8005dc0: 6ba2 ldr r2, [r4, #56] ; 0x38 + tmp[1] = product[10]; + 8005dc2: 9301 str r3, [sp, #4] + tmp[2] = product[11]; + 8005dc4: 6ae3 ldr r3, [r4, #44] ; 0x2c + 8005dc6: 9302 str r3, [sp, #8] + tmp[4] = product[14]; + 8005dc8: 9204 str r2, [sp, #16] + tmp[3] = product[13]; + 8005dca: 6b63 ldr r3, [r4, #52] ; 0x34 + tmp[5] = product[15]; + 8005dcc: 6be2 ldr r2, [r4, #60] ; 0x3c + tmp[3] = product[13]; + 8005dce: 9303 str r3, [sp, #12] + tmp[6] = product[13]; + 8005dd0: e9cd 2305 strd r2, r3, [sp, #20] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005dd4: 182e adds r6, r5, r0 + tmp[7] = product[8]; + 8005dd6: 6a23 ldr r3, [r4, #32] + 8005dd8: 9307 str r3, [sp, #28] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005dda: 466a mov r2, sp + 8005ddc: 4651 mov r1, sl + 8005dde: 4650 mov r0, sl + 8005de0: f7ff fef6 bl 8005bd0 + tmp[0] = product[11]; + 8005de4: 6ae3 ldr r3, [r4, #44] ; 0x2c + 8005de6: 9300 str r3, [sp, #0] + tmp[1] = product[12]; + 8005de8: 6b23 ldr r3, [r4, #48] ; 0x30 + 8005dea: 9301 str r3, [sp, #4] + tmp[2] = product[13]; + 8005dec: 6b63 ldr r3, [r4, #52] ; 0x34 + 8005dee: 9302 str r3, [sp, #8] + tmp[6] = product[8]; + 8005df0: 6a23 ldr r3, [r4, #32] + 8005df2: 9306 str r3, [sp, #24] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8005df4: 1835 adds r5, r6, r0 + tmp[7] = product[10]; + 8005df6: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8005df8: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005dfa: 466a mov r2, sp + 8005dfc: 4651 mov r1, sl + 8005dfe: 4650 mov r0, sl + tmp[3] = tmp[4] = tmp[5] = 0; + 8005e00: e9cd 7704 strd r7, r7, [sp, #16] + 8005e04: 9703 str r7, [sp, #12] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e06: f7ff fe21 bl 8005a4c + tmp[0] = product[12]; + 8005e0a: 6b23 ldr r3, [r4, #48] ; 0x30 + 8005e0c: 9300 str r3, [sp, #0] + tmp[1] = product[13]; + 8005e0e: 6b63 ldr r3, [r4, #52] ; 0x34 + 8005e10: 9301 str r3, [sp, #4] + tmp[2] = product[14]; + 8005e12: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8005e14: 9302 str r3, [sp, #8] + tmp[3] = product[15]; + 8005e16: 6be3 ldr r3, [r4, #60] ; 0x3c + 8005e18: 9303 str r3, [sp, #12] + tmp[6] = product[9]; + 8005e1a: 6a63 ldr r3, [r4, #36] ; 0x24 + 8005e1c: 9306 str r3, [sp, #24] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e1e: 1a2e subs r6, r5, r0 + tmp[7] = product[11]; + 8005e20: 6ae3 ldr r3, [r4, #44] ; 0x2c + 8005e22: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e24: 466a mov r2, sp + 8005e26: 4651 mov r1, sl + 8005e28: 4650 mov r0, sl + tmp[4] = tmp[5] = 0; + 8005e2a: e9cd 7704 strd r7, r7, [sp, #16] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e2e: f7ff fe0d bl 8005a4c + tmp[0] = product[13]; + 8005e32: 6b63 ldr r3, [r4, #52] ; 0x34 + 8005e34: 9300 str r3, [sp, #0] + tmp[1] = product[14]; + 8005e36: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8005e38: 9301 str r3, [sp, #4] + tmp[2] = product[15]; + 8005e3a: 6be3 ldr r3, [r4, #60] ; 0x3c + 8005e3c: 9302 str r3, [sp, #8] + tmp[3] = product[8]; + 8005e3e: 6a23 ldr r3, [r4, #32] + 8005e40: 9303 str r3, [sp, #12] + tmp[4] = product[9]; + 8005e42: 6a63 ldr r3, [r4, #36] ; 0x24 + 8005e44: 9304 str r3, [sp, #16] + tmp[5] = product[10]; + 8005e46: 6aa3 ldr r3, [r4, #40] ; 0x28 + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e48: 1a36 subs r6, r6, r0 + tmp[6] = 0; + 8005e4a: e9cd 3705 strd r3, r7, [sp, #20] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e4e: 466a mov r2, sp + tmp[7] = product[12]; + 8005e50: 6b23 ldr r3, [r4, #48] ; 0x30 + 8005e52: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e54: 4651 mov r1, sl + 8005e56: 4650 mov r0, sl + 8005e58: f7ff fdf8 bl 8005a4c + tmp[0] = product[14]; + 8005e5c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8005e5e: 9300 str r3, [sp, #0] + tmp[1] = product[15]; + 8005e60: 6be3 ldr r3, [r4, #60] ; 0x3c + tmp[2] = 0; + 8005e62: e9cd 3701 strd r3, r7, [sp, #4] + tmp[3] = product[9]; + 8005e66: 6a63 ldr r3, [r4, #36] ; 0x24 + 8005e68: 9303 str r3, [sp, #12] + tmp[4] = product[10]; + 8005e6a: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8005e6c: 9304 str r3, [sp, #16] + tmp[5] = product[11]; + 8005e6e: 6ae3 ldr r3, [r4, #44] ; 0x2c + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e70: 1a36 subs r6, r6, r0 + tmp[6] = 0; + 8005e72: e9cd 3705 strd r3, r7, [sp, #20] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e76: 466a mov r2, sp + tmp[7] = product[13]; + 8005e78: 6b63 ldr r3, [r4, #52] ; 0x34 + 8005e7a: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8005e7c: 4651 mov r1, sl + 8005e7e: 4650 mov r0, sl + 8005e80: f7ff fde4 bl 8005a4c + if (carry < 0) { + 8005e84: 1a36 subs r6, r6, r0 + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + 8005e86: 4c0d ldr r4, [pc, #52] ; (8005ebc ) + if (carry < 0) { + 8005e88: d40e bmi.n 8005ea8 + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + 8005e8a: b936 cbnz r6, 8005e9a + 8005e8c: 2208 movs r2, #8 + 8005e8e: 4651 mov r1, sl + 8005e90: 4620 mov r0, r4 + 8005e92: f7ff fc4e bl 8005732 + 8005e96: 2801 cmp r0, #1 + 8005e98: d00d beq.n 8005eb6 + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + 8005e9a: 4622 mov r2, r4 + 8005e9c: 4651 mov r1, sl + 8005e9e: 4650 mov r0, sl + 8005ea0: f7ff fdd4 bl 8005a4c + 8005ea4: 1a36 subs r6, r6, r0 + 8005ea6: e7f0 b.n 8005e8a + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + 8005ea8: 4622 mov r2, r4 + 8005eaa: 4651 mov r1, sl + 8005eac: 4650 mov r0, sl + 8005eae: f7ff fe8f bl 8005bd0 + } while (carry < 0); + 8005eb2: 1836 adds r6, r6, r0 + 8005eb4: d4f8 bmi.n 8005ea8 +} + 8005eb6: b008 add sp, #32 + 8005eb8: e8bd 84f0 ldmia.w sp!, {r4, r5, r6, r7, sl, pc} + 8005ebc: 0800e92c .word 0x0800e92c + +08005ec0 : +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + 8005ec0: b5f0 push {r4, r5, r6, r7, lr} + 8005ec2: b091 sub sp, #68 ; 0x44 + 8005ec4: 460d mov r5, r1 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 8005ec6: 221c movs r2, #28 + 8005ec8: 2100 movs r1, #0 +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + 8005eca: 4606 mov r6, r0 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 8005ecc: a801 add r0, sp, #4 + 8005ece: f007 fbd1 bl 800d674 + 8005ed2: 2401 movs r4, #1 + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 8005ed4: 221c movs r2, #28 + 8005ed6: 2100 movs r1, #0 + 8005ed8: a809 add r0, sp, #36 ; 0x24 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 8005eda: 9400 str r4, [sp, #0] + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 8005edc: f007 fbca bl 800d674 + wordcount_t num_words = curve->num_words; + 8005ee0: 4629 mov r1, r5 + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + 8005ee2: 466a mov r2, sp + wordcount_t num_words = curve->num_words; + 8005ee4: f911 7b04 ldrsb.w r7, [r1], #4 + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 8005ee8: 9408 str r4, [sp, #32] + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + 8005eea: 4668 mov r0, sp + 8005eec: f7ff fe70 bl 8005bd0 + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + 8005ef0: 4639 mov r1, r7 + 8005ef2: 4668 mov r0, sp + 8005ef4: f7ff fbf1 bl 80056da + 8005ef8: 1e44 subs r4, r0, #1 + 8005efa: b224 sxth r4, r4 + 8005efc: 2c01 cmp r4, #1 + 8005efe: dc06 bgt.n 8005f0e + uECC_vli_set(a, l_result, num_words); + 8005f00: 463a mov r2, r7 + 8005f02: a908 add r1, sp, #32 + 8005f04: 4630 mov r0, r6 + 8005f06: f7ff fc08 bl 800571a +} + 8005f0a: b011 add sp, #68 ; 0x44 + 8005f0c: bdf0 pop {r4, r5, r6, r7, pc} + uECC_vli_modSquare_fast(l_result, l_result, curve); + 8005f0e: a908 add r1, sp, #32 + 8005f10: 4608 mov r0, r1 + 8005f12: 462a mov r2, r5 + 8005f14: f7ff fcdf bl 80058d6 + if (uECC_vli_testBit(p1, i)) { + 8005f18: 4621 mov r1, r4 + 8005f1a: 4668 mov r0, sp + 8005f1c: f7ff fbd3 bl 80056c6 + 8005f20: b128 cbz r0, 8005f2e + uECC_vli_modMult_fast(l_result, l_result, a, curve); + 8005f22: a908 add r1, sp, #32 + 8005f24: 462b mov r3, r5 + 8005f26: 4632 mov r2, r6 + 8005f28: 4608 mov r0, r1 + 8005f2a: f7ff fcc4 bl 80058b6 + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + 8005f2e: 3c01 subs r4, #1 + 8005f30: e7e3 b.n 8005efa + +08005f32 : + if (!EVEN(uv)) { + 8005f32: 6803 ldr r3, [r0, #0] + wordcount_t num_words) { + 8005f34: b570 push {r4, r5, r6, lr} + if (!EVEN(uv)) { + 8005f36: f013 0601 ands.w r6, r3, #1 + wordcount_t num_words) { + 8005f3a: 4605 mov r5, r0 + 8005f3c: 4614 mov r4, r2 + if (!EVEN(uv)) { + 8005f3e: d004 beq.n 8005f4a + carry = uECC_vli_add(uv, uv, mod, num_words); + 8005f40: 460a mov r2, r1 + 8005f42: 4601 mov r1, r0 + 8005f44: f7ff fe44 bl 8005bd0 + 8005f48: 4606 mov r6, r0 + uECC_vli_rshift1(uv, num_words); + 8005f4a: 4621 mov r1, r4 + 8005f4c: 4628 mov r0, r5 + 8005f4e: f7ff fc05 bl 800575c + if (carry) { + 8005f52: b146 cbz r6, 8005f66 + uv[num_words - 1] |= HIGH_BIT_SET; + 8005f54: f104 4280 add.w r2, r4, #1073741824 ; 0x40000000 + 8005f58: 3a01 subs r2, #1 + 8005f5a: f855 3022 ldr.w r3, [r5, r2, lsl #2] + 8005f5e: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 8005f62: f845 3022 str.w r3, [r5, r2, lsl #2] +} + 8005f66: bd70 pop {r4, r5, r6, pc} + +08005f68 : + wordcount_t num_words) { + 8005f68: b5f0 push {r4, r5, r6, r7, lr} + 8005f6a: 460f mov r7, r1 + 8005f6c: b0a1 sub sp, #132 ; 0x84 + 8005f6e: 4606 mov r6, r0 + if (uECC_vli_isZero(input, num_words)) { + 8005f70: 4619 mov r1, r3 + 8005f72: 4638 mov r0, r7 + wordcount_t num_words) { + 8005f74: 4615 mov r5, r2 + 8005f76: 461c mov r4, r3 + if (uECC_vli_isZero(input, num_words)) { + 8005f78: f7ff fb96 bl 80056a8 + 8005f7c: b128 cbz r0, 8005f8a + uECC_vli_clear(result, num_words); + 8005f7e: 4630 mov r0, r6 +} + 8005f80: b021 add sp, #132 ; 0x84 + 8005f82: e8bd 40f0 ldmia.w sp!, {r4, r5, r6, r7, lr} + uECC_vli_clear(result, num_words); + 8005f86: f7ff bb89 b.w 800569c + uECC_vli_set(a, input, num_words); + 8005f8a: 4622 mov r2, r4 + 8005f8c: 4639 mov r1, r7 + 8005f8e: 4668 mov r0, sp + 8005f90: f7ff fbc3 bl 800571a + uECC_vli_set(b, mod, num_words); + 8005f94: 4629 mov r1, r5 + 8005f96: a808 add r0, sp, #32 + 8005f98: f7ff fbbf bl 800571a + uECC_vli_clear(u, num_words); + 8005f9c: 4621 mov r1, r4 + 8005f9e: a810 add r0, sp, #64 ; 0x40 + 8005fa0: f7ff fb7c bl 800569c + u[0] = 1; + 8005fa4: 2301 movs r3, #1 + uECC_vli_clear(v, num_words); + 8005fa6: 4621 mov r1, r4 + 8005fa8: a818 add r0, sp, #96 ; 0x60 + u[0] = 1; + 8005faa: 9310 str r3, [sp, #64] ; 0x40 + uECC_vli_clear(v, num_words); + 8005fac: f7ff fb76 bl 800569c + while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) { + 8005fb0: 4622 mov r2, r4 + 8005fb2: a908 add r1, sp, #32 + 8005fb4: 4668 mov r0, sp + 8005fb6: f7ff fbbc bl 8005732 + 8005fba: b930 cbnz r0, 8005fca + uECC_vli_set(result, u, num_words); + 8005fbc: 4622 mov r2, r4 + 8005fbe: a910 add r1, sp, #64 ; 0x40 + 8005fc0: 4630 mov r0, r6 + 8005fc2: f7ff fbaa bl 800571a +} + 8005fc6: b021 add sp, #132 ; 0x84 + 8005fc8: bdf0 pop {r4, r5, r6, r7, pc} + if (EVEN(a)) { + 8005fca: 9b00 ldr r3, [sp, #0] + 8005fcc: 07da lsls r2, r3, #31 + 8005fce: d409 bmi.n 8005fe4 + uECC_vli_rshift1(a, num_words); + 8005fd0: 4621 mov r1, r4 + 8005fd2: 4668 mov r0, sp + 8005fd4: f7ff fbc2 bl 800575c + vli_modInv_update(u, mod, num_words); + 8005fd8: 4622 mov r2, r4 + 8005fda: 4629 mov r1, r5 + 8005fdc: a810 add r0, sp, #64 ; 0x40 + vli_modInv_update(v, mod, num_words); + 8005fde: f7ff ffa8 bl 8005f32 + 8005fe2: e7e5 b.n 8005fb0 + } else if (EVEN(b)) { + 8005fe4: 9b08 ldr r3, [sp, #32] + 8005fe6: 07db lsls r3, r3, #31 + 8005fe8: d407 bmi.n 8005ffa + uECC_vli_rshift1(b, num_words); + 8005fea: 4621 mov r1, r4 + 8005fec: a808 add r0, sp, #32 + 8005fee: f7ff fbb5 bl 800575c + vli_modInv_update(v, mod, num_words); + 8005ff2: 4622 mov r2, r4 + 8005ff4: 4629 mov r1, r5 + 8005ff6: a818 add r0, sp, #96 ; 0x60 + 8005ff8: e7f1 b.n 8005fde + } else if (cmpResult > 0) { + 8005ffa: 2800 cmp r0, #0 + 8005ffc: dd1a ble.n 8006034 + uECC_vli_sub(a, a, b, num_words); + 8005ffe: aa08 add r2, sp, #32 + 8006000: 4669 mov r1, sp + 8006002: 4668 mov r0, sp + 8006004: f7ff fd22 bl 8005a4c + uECC_vli_rshift1(a, num_words); + 8006008: 4621 mov r1, r4 + 800600a: 4668 mov r0, sp + 800600c: f7ff fba6 bl 800575c + if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) { + 8006010: 4622 mov r2, r4 + 8006012: a918 add r1, sp, #96 ; 0x60 + 8006014: a810 add r0, sp, #64 ; 0x40 + 8006016: f7ff fb8c bl 8005732 + 800601a: 2800 cmp r0, #0 + 800601c: da04 bge.n 8006028 + uECC_vli_add(u, u, mod, num_words); + 800601e: a910 add r1, sp, #64 ; 0x40 + 8006020: 462a mov r2, r5 + 8006022: 4608 mov r0, r1 + 8006024: f7ff fdd4 bl 8005bd0 + uECC_vli_sub(u, u, v, num_words); + 8006028: a910 add r1, sp, #64 ; 0x40 + 800602a: aa18 add r2, sp, #96 ; 0x60 + 800602c: 4608 mov r0, r1 + 800602e: f7ff fd0d bl 8005a4c + 8006032: e7d1 b.n 8005fd8 + uECC_vli_sub(b, b, a, num_words); + 8006034: 466a mov r2, sp + 8006036: a808 add r0, sp, #32 + 8006038: f7ff fd08 bl 8005a4c + uECC_vli_rshift1(b, num_words); + 800603c: 4621 mov r1, r4 + 800603e: a808 add r0, sp, #32 + 8006040: f7ff fb8c bl 800575c + if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) { + 8006044: 4622 mov r2, r4 + 8006046: a910 add r1, sp, #64 ; 0x40 + 8006048: a818 add r0, sp, #96 ; 0x60 + 800604a: f7ff fb72 bl 8005732 + 800604e: 2800 cmp r0, #0 + 8006050: da04 bge.n 800605c + uECC_vli_add(v, v, mod, num_words); + 8006052: a918 add r1, sp, #96 ; 0x60 + 8006054: 462a mov r2, r5 + 8006056: 4608 mov r0, r1 + 8006058: f7ff fdba bl 8005bd0 + uECC_vli_sub(v, v, u, num_words); + 800605c: a918 add r1, sp, #96 ; 0x60 + 800605e: aa10 add r2, sp, #64 ; 0x40 + 8006060: 4608 mov r0, r1 + 8006062: f7ff fcf3 bl 8005a4c + 8006066: e7c4 b.n 8005ff2 + +08006068 : + wordcount_t num_words) { + 8006068: b570 push {r4, r5, r6, lr} + 800606a: 4604 mov r4, r0 + 800606c: f99d 6010 ldrsb.w r6, [sp, #16] + 8006070: 461d mov r5, r3 + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + 8006072: f7ff fdad bl 8005bd0 + if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) { + 8006076: b930 cbnz r0, 8006086 + 8006078: 4632 mov r2, r6 + 800607a: 4621 mov r1, r4 + 800607c: 4628 mov r0, r5 + 800607e: f7ff fb58 bl 8005732 + 8006082: 2801 cmp r0, #1 + 8006084: d006 beq.n 8006094 + uECC_vli_sub(result, result, mod, num_words); + 8006086: 462a mov r2, r5 + 8006088: 4621 mov r1, r4 + 800608a: 4620 mov r0, r4 +} + 800608c: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + uECC_vli_sub(result, result, mod, num_words); + 8006090: f7ff bcdc b.w 8005a4c +} + 8006094: bd70 pop {r4, r5, r6, pc} + +08006096 : +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + 8006096: b573 push {r0, r1, r4, r5, r6, lr} + 8006098: 4604 mov r4, r0 + 800609a: 4615 mov r5, r2 + 800609c: 460e mov r6, r1 + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 800609e: f7ff fc1a bl 80058d6 + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ + 80060a2: 462b mov r3, r5 + 80060a4: 4632 mov r2, r6 + 80060a6: 4621 mov r1, r4 + 80060a8: 4620 mov r0, r4 + 80060aa: f7ff fc04 bl 80058b6 + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ + 80060ae: 2308 movs r3, #8 + 80060b0: 9300 str r3, [sp, #0] + 80060b2: f105 0284 add.w r2, r5, #132 ; 0x84 + 80060b6: 1d2b adds r3, r5, #4 + 80060b8: 4621 mov r1, r4 + 80060ba: 4620 mov r0, r4 + 80060bc: f7ff ffd4 bl 8006068 +} + 80060c0: b002 add sp, #8 + 80060c2: bd70 pop {r4, r5, r6, pc} + +080060c4 : +uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result, + 80060c4: b538 push {r3, r4, r5, lr} + 80060c6: 4604 mov r4, r0 + 80060c8: 461d mov r5, r3 + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); + 80060ca: f7ff fcbf bl 8005a4c + if (l_borrow) { + 80060ce: b130 cbz r0, 80060de + uECC_vli_add(result, result, mod, num_words); + 80060d0: 462a mov r2, r5 + 80060d2: 4621 mov r1, r4 + 80060d4: 4620 mov r0, r4 +} + 80060d6: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + uECC_vli_add(result, result, mod, num_words); + 80060da: f7ff bd79 b.w 8005bd0 +} + 80060de: bd38 pop {r3, r4, r5, pc} + +080060e0 : + uECC_Curve curve) { + 80060e0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80060e4: b09a sub sp, #104 ; 0x68 + 80060e6: 4615 mov r5, r2 + 80060e8: 9f22 ldr r7, [sp, #136] ; 0x88 + wordcount_t num_words = curve->num_words; + 80060ea: 463c mov r4, r7 + uECC_Curve curve) { + 80060ec: 4698 mov r8, r3 + wordcount_t num_words = curve->num_words; + 80060ee: f914 ab04 ldrsb.w sl, [r4], #4 + uECC_Curve curve) { + 80060f2: 4606 mov r6, r0 + 80060f4: 4689 mov r9, r1 + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + 80060f6: 4623 mov r3, r4 + 80060f8: 4602 mov r2, r0 + 80060fa: 4629 mov r1, r5 + 80060fc: a802 add r0, sp, #8 + 80060fe: f7ff ffe1 bl 80060c4 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + 8006102: a902 add r1, sp, #8 + 8006104: 463a mov r2, r7 + 8006106: 4608 mov r0, r1 + 8006108: f7ff fbe5 bl 80058d6 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + 800610c: 463b mov r3, r7 + 800610e: aa02 add r2, sp, #8 + 8006110: 4631 mov r1, r6 + 8006112: 4630 mov r0, r6 + 8006114: f7ff fbcf bl 80058b6 + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + 8006118: 463b mov r3, r7 + 800611a: aa02 add r2, sp, #8 + 800611c: 4629 mov r1, r5 + 800611e: 4628 mov r0, r5 + 8006120: f7ff fbc9 bl 80058b6 + uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */ + 8006124: 4623 mov r3, r4 + 8006126: 464a mov r2, r9 + 8006128: 4641 mov r1, r8 + 800612a: a802 add r0, sp, #8 + 800612c: f8cd a000 str.w sl, [sp] + 8006130: f7ff ff9a bl 8006068 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + 8006134: 4623 mov r3, r4 + 8006136: 464a mov r2, r9 + 8006138: 4641 mov r1, r8 + 800613a: 4640 mov r0, r8 + 800613c: f7ff ffc2 bl 80060c4 + uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */ + 8006140: 4623 mov r3, r4 + 8006142: 4632 mov r2, r6 + 8006144: 4629 mov r1, r5 + 8006146: a80a add r0, sp, #40 ; 0x28 + 8006148: f7ff ffbc bl 80060c4 + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + 800614c: 463b mov r3, r7 + 800614e: aa0a add r2, sp, #40 ; 0x28 + 8006150: 4649 mov r1, r9 + 8006152: 4648 mov r0, r9 + 8006154: f7ff fbaf bl 80058b6 + uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */ + 8006158: 4623 mov r3, r4 + 800615a: 462a mov r2, r5 + 800615c: 4631 mov r1, r6 + 800615e: a80a add r0, sp, #40 ; 0x28 + 8006160: f8cd a000 str.w sl, [sp] + 8006164: f7ff ff80 bl 8006068 + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + 8006168: 463a mov r2, r7 + 800616a: 4641 mov r1, r8 + 800616c: 4628 mov r0, r5 + 800616e: f7ff fbb2 bl 80058d6 + uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */ + 8006172: 4623 mov r3, r4 + 8006174: aa0a add r2, sp, #40 ; 0x28 + 8006176: 4629 mov r1, r5 + 8006178: 4628 mov r0, r5 + 800617a: f7ff ffa3 bl 80060c4 + uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */ + 800617e: 4623 mov r3, r4 + 8006180: 462a mov r2, r5 + 8006182: 4631 mov r1, r6 + 8006184: a812 add r0, sp, #72 ; 0x48 + 8006186: f7ff ff9d bl 80060c4 + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + 800618a: 463b mov r3, r7 + 800618c: aa12 add r2, sp, #72 ; 0x48 + 800618e: 4641 mov r1, r8 + 8006190: 4640 mov r0, r8 + 8006192: f7ff fb90 bl 80058b6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ + 8006196: 4623 mov r3, r4 + 8006198: 464a mov r2, r9 + 800619a: 4641 mov r1, r8 + 800619c: 4640 mov r0, r8 + 800619e: f7ff ff91 bl 80060c4 + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + 80061a2: 463a mov r2, r7 + 80061a4: a902 add r1, sp, #8 + 80061a6: a812 add r0, sp, #72 ; 0x48 + 80061a8: f7ff fb95 bl 80058d6 + uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */ + 80061ac: a912 add r1, sp, #72 ; 0x48 + 80061ae: 4623 mov r3, r4 + 80061b0: aa0a add r2, sp, #40 ; 0x28 + 80061b2: 4608 mov r0, r1 + 80061b4: f7ff ff86 bl 80060c4 + uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */ + 80061b8: 4623 mov r3, r4 + 80061ba: 4632 mov r2, r6 + 80061bc: a912 add r1, sp, #72 ; 0x48 + 80061be: a80a add r0, sp, #40 ; 0x28 + 80061c0: f7ff ff80 bl 80060c4 + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + 80061c4: a90a add r1, sp, #40 ; 0x28 + 80061c6: 463b mov r3, r7 + 80061c8: aa02 add r2, sp, #8 + 80061ca: 4608 mov r0, r1 + 80061cc: f7ff fb73 bl 80058b6 + uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */ + 80061d0: 4623 mov r3, r4 + 80061d2: 464a mov r2, r9 + 80061d4: a90a add r1, sp, #40 ; 0x28 + 80061d6: 4648 mov r0, r9 + 80061d8: f7ff ff74 bl 80060c4 + uECC_vli_set(X1, t7, num_words); + 80061dc: 4652 mov r2, sl + 80061de: a912 add r1, sp, #72 ; 0x48 + 80061e0: 4630 mov r0, r6 + 80061e2: f7ff fa9a bl 800571a +} + 80061e6: b01a add sp, #104 ; 0x68 + 80061e8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + +080061ec : + uECC_Curve curve) { + 80061ec: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80061f0: b088 sub sp, #32 + 80061f2: 4614 mov r4, r2 + 80061f4: f8dd 8040 ldr.w r8, [sp, #64] ; 0x40 + wordcount_t num_words = curve->num_words; + 80061f8: 4645 mov r5, r8 + uECC_Curve curve) { + 80061fa: 461e mov r6, r3 + wordcount_t num_words = curve->num_words; + 80061fc: f915 ab04 ldrsb.w sl, [r5], #4 + uECC_Curve curve) { + 8006200: 4607 mov r7, r0 + 8006202: 4689 mov r9, r1 + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + 8006204: 462b mov r3, r5 + 8006206: 4602 mov r2, r0 + 8006208: 4621 mov r1, r4 + 800620a: 4668 mov r0, sp + 800620c: f7ff ff5a bl 80060c4 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + 8006210: 4642 mov r2, r8 + 8006212: 4669 mov r1, sp + 8006214: 4668 mov r0, sp + 8006216: f7ff fb5e bl 80058d6 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + 800621a: 4643 mov r3, r8 + 800621c: 466a mov r2, sp + 800621e: 4639 mov r1, r7 + 8006220: 4638 mov r0, r7 + 8006222: f7ff fb48 bl 80058b6 + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + 8006226: 4643 mov r3, r8 + 8006228: 466a mov r2, sp + 800622a: 4621 mov r1, r4 + 800622c: 4620 mov r0, r4 + 800622e: f7ff fb42 bl 80058b6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + 8006232: 462b mov r3, r5 + 8006234: 464a mov r2, r9 + 8006236: 4631 mov r1, r6 + 8006238: 4630 mov r0, r6 + 800623a: f7ff ff43 bl 80060c4 + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + 800623e: 4642 mov r2, r8 + 8006240: 4631 mov r1, r6 + 8006242: 4668 mov r0, sp + 8006244: f7ff fb47 bl 80058d6 + uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */ + 8006248: 462b mov r3, r5 + 800624a: 463a mov r2, r7 + 800624c: 4669 mov r1, sp + 800624e: 4668 mov r0, sp + 8006250: f7ff ff38 bl 80060c4 + uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */ + 8006254: 462b mov r3, r5 + 8006256: 4622 mov r2, r4 + 8006258: 4669 mov r1, sp + 800625a: 4668 mov r0, sp + 800625c: f7ff ff32 bl 80060c4 + uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */ + 8006260: 462b mov r3, r5 + 8006262: 463a mov r2, r7 + 8006264: 4621 mov r1, r4 + 8006266: 4620 mov r0, r4 + 8006268: f7ff ff2c bl 80060c4 + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + 800626c: 4643 mov r3, r8 + 800626e: 4622 mov r2, r4 + 8006270: 4649 mov r1, r9 + 8006272: 4648 mov r0, r9 + 8006274: f7ff fb1f bl 80058b6 + uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */ + 8006278: 462b mov r3, r5 + 800627a: 466a mov r2, sp + 800627c: 4639 mov r1, r7 + 800627e: 4620 mov r0, r4 + 8006280: f7ff ff20 bl 80060c4 + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + 8006284: 4643 mov r3, r8 + 8006286: 4622 mov r2, r4 + 8006288: 4631 mov r1, r6 + 800628a: 4630 mov r0, r6 + 800628c: f7ff fb13 bl 80058b6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */ + 8006290: 462b mov r3, r5 + 8006292: 464a mov r2, r9 + 8006294: 4631 mov r1, r6 + 8006296: 4630 mov r0, r6 + 8006298: f7ff ff14 bl 80060c4 + uECC_vli_set(X2, t5, num_words); + 800629c: 4652 mov r2, sl + 800629e: 4669 mov r1, sp + 80062a0: 4620 mov r0, r4 + 80062a2: f7ff fa3a bl 800571a +} + 80062a6: b008 add sp, #32 + 80062a8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + +080062ac : + uECC_Curve curve) { + 80062ac: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 80062b0: b0b1 sub sp, #196 ; 0xc4 + 80062b2: e9cd 0102 strd r0, r1, [sp, #8] + 80062b6: 9c3b ldr r4, [sp, #236] ; 0xec + 80062b8: 9204 str r2, [sp, #16] + wordcount_t num_words = curve->num_words; + 80062ba: f994 9000 ldrsb.w r9, [r4] + uECC_vli_set(Rx[1], point, num_words); + 80062be: a818 add r0, sp, #96 ; 0x60 + 80062c0: 464a mov r2, r9 + uECC_Curve curve) { + 80062c2: 461d mov r5, r3 + uECC_vli_set(Rx[1], point, num_words); + 80062c4: f7ff fa29 bl 800571a + uECC_vli_set(Ry[1], point + num_words, num_words); + 80062c8: ea4f 0389 mov.w r3, r9, lsl #2 + 80062cc: 9305 str r3, [sp, #20] + 80062ce: 9b03 ldr r3, [sp, #12] + 80062d0: eb03 0a89 add.w sl, r3, r9, lsl #2 + 80062d4: 4651 mov r1, sl + 80062d6: a828 add r0, sp, #160 ; 0xa0 + 80062d8: f7ff fa1f bl 800571a + wordcount_t num_words = curve->num_words; + 80062dc: f994 2000 ldrsb.w r2, [r4] + if (initial_Z) { + 80062e0: 2d00 cmp r5, #0 + 80062e2: f000 8082 beq.w 80063ea + uECC_vli_set(z, initial_Z, num_words); + 80062e6: 4629 mov r1, r5 + 80062e8: a808 add r0, sp, #32 + 80062ea: f7ff fa16 bl 800571a + uECC_vli_set(X2, X1, num_words); + 80062ee: af10 add r7, sp, #64 ; 0x40 + 80062f0: a918 add r1, sp, #96 ; 0x60 + 80062f2: 4638 mov r0, r7 + uECC_vli_set(Y2, Y1, num_words); + 80062f4: f10d 0880 add.w r8, sp, #128 ; 0x80 + uECC_vli_set(X2, X1, num_words); + 80062f8: f7ff fa0f bl 800571a + uECC_vli_set(Y2, Y1, num_words); + 80062fc: a928 add r1, sp, #160 ; 0xa0 + 80062fe: 4640 mov r0, r8 + 8006300: f7ff fa0b bl 800571a + apply_z(X1, Y1, z, curve); + 8006304: 4623 mov r3, r4 + 8006306: aa08 add r2, sp, #32 + 8006308: a818 add r0, sp, #96 ; 0x60 + 800630a: f7ff fae8 bl 80058de + curve->double_jacobian(X1, Y1, z, curve); + 800630e: f8d4 50a4 ldr.w r5, [r4, #164] ; 0xa4 + 8006312: 4623 mov r3, r4 + 8006314: aa08 add r2, sp, #32 + 8006316: a928 add r1, sp, #160 ; 0xa0 + 8006318: a818 add r0, sp, #96 ; 0x60 + 800631a: 47a8 blx r5 + apply_z(X2, Y2, z, curve); + 800631c: 4623 mov r3, r4 + 800631e: aa08 add r2, sp, #32 + 8006320: 4641 mov r1, r8 + 8006322: 4638 mov r0, r7 + 8006324: f7ff fadb bl 80058de + for (i = num_bits - 2; i > 0; --i) { + 8006328: f9bd 50e8 ldrsh.w r5, [sp, #232] ; 0xe8 + 800632c: 3d02 subs r5, #2 + 800632e: b22d sxth r5, r5 + 8006330: 2d00 cmp r5, #0 + 8006332: dc63 bgt.n 80063fc + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 8006334: 9b04 ldr r3, [sp, #16] + 8006336: 681d ldr r5, [r3, #0] + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 8006338: 9400 str r4, [sp, #0] + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 800633a: f005 0601 and.w r6, r5, #1 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 800633e: ab10 add r3, sp, #64 ; 0x40 + 8006340: eb03 1746 add.w r7, r3, r6, lsl #5 + 8006344: 43ed mvns r5, r5 + 8006346: ab20 add r3, sp, #128 ; 0x80 + 8006348: eb03 1646 add.w r6, r3, r6, lsl #5 + 800634c: f005 0501 and.w r5, r5, #1 + 8006350: ab10 add r3, sp, #64 ; 0x40 + 8006352: eb03 1845 add.w r8, r3, r5, lsl #5 + 8006356: ab20 add r3, sp, #128 ; 0x80 + 8006358: eb03 1545 add.w r5, r3, r5, lsl #5 + 800635c: 462b mov r3, r5 + 800635e: 4642 mov r2, r8 + 8006360: 4631 mov r1, r6 + 8006362: 4638 mov r0, r7 + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + 8006364: f104 0b04 add.w fp, r4, #4 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 8006368: f7ff feba bl 80060e0 + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + 800636c: 465b mov r3, fp + 800636e: aa10 add r2, sp, #64 ; 0x40 + 8006370: a918 add r1, sp, #96 ; 0x60 + 8006372: a808 add r0, sp, #32 + 8006374: f7ff fea6 bl 80060c4 + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + 8006378: a908 add r1, sp, #32 + 800637a: 4623 mov r3, r4 + 800637c: 4632 mov r2, r6 + 800637e: 4608 mov r0, r1 + 8006380: f7ff fa99 bl 80058b6 + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + 8006384: a908 add r1, sp, #32 + 8006386: 9a03 ldr r2, [sp, #12] + 8006388: 4623 mov r3, r4 + 800638a: 4608 mov r0, r1 + 800638c: f7ff fa93 bl 80058b6 + uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */ + 8006390: a908 add r1, sp, #32 + 8006392: 464b mov r3, r9 + 8006394: 465a mov r2, fp + 8006396: 4608 mov r0, r1 + 8006398: f7ff fde6 bl 8005f68 + uECC_vli_modMult_fast(z, z, point + num_words, curve); + 800639c: a908 add r1, sp, #32 + 800639e: 4623 mov r3, r4 + 80063a0: 4652 mov r2, sl + 80063a2: 4608 mov r0, r1 + 80063a4: f7ff fa87 bl 80058b6 + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + 80063a8: a908 add r1, sp, #32 + 80063aa: 4623 mov r3, r4 + 80063ac: 463a mov r2, r7 + 80063ae: 4608 mov r0, r1 + 80063b0: f7ff fa81 bl 80058b6 + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + 80063b4: 4633 mov r3, r6 + 80063b6: 463a mov r2, r7 + 80063b8: 4629 mov r1, r5 + 80063ba: 4640 mov r0, r8 + 80063bc: 9400 str r4, [sp, #0] + 80063be: f7ff ff15 bl 80061ec + apply_z(Rx[0], Ry[0], z, curve); + 80063c2: 4623 mov r3, r4 + 80063c4: aa08 add r2, sp, #32 + 80063c6: a920 add r1, sp, #128 ; 0x80 + 80063c8: a810 add r0, sp, #64 ; 0x40 + 80063ca: f7ff fa88 bl 80058de + uECC_vli_set(result, Rx[0], num_words); + 80063ce: 9802 ldr r0, [sp, #8] + 80063d0: 464a mov r2, r9 + 80063d2: a910 add r1, sp, #64 ; 0x40 + 80063d4: f7ff f9a1 bl 800571a + uECC_vli_set(result + num_words, Ry[0], num_words); + 80063d8: 9802 ldr r0, [sp, #8] + 80063da: 9b05 ldr r3, [sp, #20] + 80063dc: a920 add r1, sp, #128 ; 0x80 + 80063de: 4418 add r0, r3 + 80063e0: f7ff f99b bl 800571a +} + 80063e4: b031 add sp, #196 ; 0xc4 + 80063e6: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + uECC_vli_clear(z, num_words); + 80063ea: 4611 mov r1, r2 + 80063ec: a808 add r0, sp, #32 + 80063ee: 9206 str r2, [sp, #24] + 80063f0: f7ff f954 bl 800569c + z[0] = 1; + 80063f4: 2301 movs r3, #1 + 80063f6: 9a06 ldr r2, [sp, #24] + 80063f8: 9308 str r3, [sp, #32] + 80063fa: e778 b.n 80062ee + nb = !uECC_vli_testBit(scalar, i); + 80063fc: 4629 mov r1, r5 + 80063fe: 9804 ldr r0, [sp, #16] + 8006400: f7ff f961 bl 80056c6 + 8006404: fab0 f680 clz r6, r0 + 8006408: 0976 lsrs r6, r6, #5 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 800640a: f1c6 0101 rsb r1, r6, #1 + 800640e: eb07 1b46 add.w fp, r7, r6, lsl #5 + 8006412: eb08 1646 add.w r6, r8, r6, lsl #5 + 8006416: eb07 1041 add.w r0, r7, r1, lsl #5 + 800641a: 4633 mov r3, r6 + 800641c: eb08 1141 add.w r1, r8, r1, lsl #5 + 8006420: 465a mov r2, fp + 8006422: 9400 str r4, [sp, #0] + 8006424: e9cd 0106 strd r0, r1, [sp, #24] + 8006428: f7ff fe5a bl 80060e0 + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + 800642c: 9907 ldr r1, [sp, #28] + 800642e: 9806 ldr r0, [sp, #24] + 8006430: 9400 str r4, [sp, #0] + 8006432: 460b mov r3, r1 + 8006434: 4602 mov r2, r0 + 8006436: 4631 mov r1, r6 + 8006438: 4658 mov r0, fp + 800643a: f7ff fed7 bl 80061ec + for (i = num_bits - 2; i > 0; --i) { + 800643e: 3d01 subs r5, #1 + 8006440: e775 b.n 800632e + +08006442 : + uECC_Curve curve) { + 8006442: b530 push {r4, r5, lr} + 8006444: 4614 mov r4, r2 + 8006446: b095 sub sp, #84 ; 0x54 + 8006448: 4605 mov r5, r0 + uECC_word_t *p2[2] = {tmp1, tmp2}; + 800644a: aa0c add r2, sp, #48 ; 0x30 + carry = regularize_k(private, tmp1, tmp2, curve); + 800644c: 4623 mov r3, r4 + uECC_Curve curve) { + 800644e: 4608 mov r0, r1 + uECC_word_t *p2[2] = {tmp1, tmp2}; + 8006450: a904 add r1, sp, #16 + 8006452: 9102 str r1, [sp, #8] + 8006454: 9203 str r2, [sp, #12] + carry = regularize_k(private, tmp1, tmp2, curve); + 8006456: f7ff fbe0 bl 8005c1a + EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve); + 800645a: fab0 f380 clz r3, r0 + 800645e: 095b lsrs r3, r3, #5 + 8006460: aa14 add r2, sp, #80 ; 0x50 + 8006462: eb02 0283 add.w r2, r2, r3, lsl #2 + 8006466: 8863 ldrh r3, [r4, #2] + 8006468: 9401 str r4, [sp, #4] + 800646a: 3301 adds r3, #1 + 800646c: b21b sxth r3, r3 + 800646e: 9300 str r3, [sp, #0] + 8006470: f852 2c48 ldr.w r2, [r2, #-72] + 8006474: 2300 movs r3, #0 + 8006476: f104 0144 add.w r1, r4, #68 ; 0x44 + 800647a: 4628 mov r0, r5 + 800647c: f7ff ff16 bl 80062ac + if (EccPoint_isZero(result, curve)) { + 8006480: 7821 ldrb r1, [r4, #0] + 8006482: 0049 lsls r1, r1, #1 + 8006484: b249 sxtb r1, r1 + 8006486: 4628 mov r0, r5 + 8006488: f7ff f90e bl 80056a8 +} + 800648c: fab0 f080 clz r0, r0 + 8006490: 0940 lsrs r0, r0, #5 + 8006492: b015 add sp, #84 ; 0x54 + 8006494: bd30 pop {r4, r5, pc} + ... + +08006498 : + uECC_Curve curve) { + 8006498: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800649c: ed2d 8b02 vpush {d8} + 80064a0: b0a7 sub sp, #156 ; 0x9c + 80064a2: 461e mov r6, r3 + 80064a4: 9d33 ldr r5, [sp, #204] ; 0xcc + wordcount_t num_words = curve->num_words; + 80064a6: f995 a000 ldrsb.w sl, [r5] + uECC_Curve curve) { + 80064aa: ee08 1a10 vmov s16, r1 + 80064ae: 4683 mov fp, r0 + uECC_word_t *k2[2] = {tmp, s}; + 80064b0: f10d 0918 add.w r9, sp, #24 + 80064b4: ab0e add r3, sp, #56 ; 0x38 + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80064b6: 4651 mov r1, sl + 80064b8: 4630 mov r0, r6 + uECC_Curve curve) { + 80064ba: ee08 2a90 vmov s17, r2 + uECC_word_t *k2[2] = {tmp, s}; + 80064be: f8cd 9010 str.w r9, [sp, #16] + 80064c2: 9305 str r3, [sp, #20] + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80064c4: f7ff f8f0 bl 80056a8 + 80064c8: b128 cbz r0, 80064d6 + return 0; + 80064ca: 2000 movs r0, #0 +} + 80064cc: b027 add sp, #156 ; 0x9c + 80064ce: ecbd 8b02 vpop {d8} + 80064d2: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 80064d6: f9b5 8002 ldrsh.w r8, [r5, #2] + 80064da: f118 041f adds.w r4, r8, #31 + 80064de: bf48 it mi + 80064e0: f108 043e addmi.w r4, r8, #62 ; 0x3e + 80064e4: f344 1447 sbfx r4, r4, #5, #8 + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80064e8: f105 0724 add.w r7, r5, #36 ; 0x24 + 80064ec: 4622 mov r2, r4 + 80064ee: 4631 mov r1, r6 + 80064f0: 4638 mov r0, r7 + 80064f2: f7ff fb19 bl 8005b28 + 80064f6: 2801 cmp r0, #1 + 80064f8: 9003 str r0, [sp, #12] + 80064fa: d1e6 bne.n 80064ca + carry = regularize_k(k, tmp, s, curve); + 80064fc: 462b mov r3, r5 + 80064fe: aa0e add r2, sp, #56 ; 0x38 + 8006500: 4649 mov r1, r9 + 8006502: 4630 mov r0, r6 + 8006504: f7ff fb89 bl 8005c1a + EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve); + 8006508: fab0 f080 clz r0, r0 + 800650c: ab26 add r3, sp, #152 ; 0x98 + 800650e: 0940 lsrs r0, r0, #5 + 8006510: f108 0801 add.w r8, r8, #1 + 8006514: eb03 0080 add.w r0, r3, r0, lsl #2 + 8006518: fa0f f388 sxth.w r3, r8 + 800651c: 9300 str r3, [sp, #0] + 800651e: 9501 str r5, [sp, #4] + 8006520: f850 2c88 ldr.w r2, [r0, #-136] + 8006524: f105 0144 add.w r1, r5, #68 ; 0x44 + 8006528: a816 add r0, sp, #88 ; 0x58 + 800652a: 2300 movs r3, #0 + 800652c: f7ff febe bl 80062ac + if (uECC_vli_isZero(p, num_words)) { + 8006530: 4651 mov r1, sl + 8006532: a816 add r0, sp, #88 ; 0x58 + 8006534: f7ff f8b8 bl 80056a8 + 8006538: 2800 cmp r0, #0 + 800653a: d1c6 bne.n 80064ca + uECC_recid = (p[curve->num_words] & 0x01); + 800653c: f995 3000 ldrsb.w r3, [r5] + 8006540: aa26 add r2, sp, #152 ; 0x98 + 8006542: eb02 0383 add.w r3, r2, r3, lsl #2 + 8006546: 4a3b ldr r2, [pc, #236] ; (8006634 ) + 8006548: f853 3c40 ldr.w r3, [r3, #-64] + 800654c: f003 0301 and.w r3, r3, #1 + 8006550: 7013 strb r3, [r2, #0] + if (!g_rng_function) { + 8006552: 4b39 ldr r3, [pc, #228] ; (8006638 ) + 8006554: 681b ldr r3, [r3, #0] + 8006556: 2b00 cmp r3, #0 + 8006558: d163 bne.n 8006622 + uECC_vli_clear(tmp, num_n_words); + 800655a: 4621 mov r1, r4 + 800655c: 4648 mov r0, r9 + 800655e: f7ff f89d bl 800569c + tmp[0] = 1; + 8006562: 9b03 ldr r3, [sp, #12] + 8006564: 9306 str r3, [sp, #24] + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */ + 8006566: 463b mov r3, r7 + 8006568: aa06 add r2, sp, #24 + 800656a: 4631 mov r1, r6 + 800656c: 4630 mov r0, r6 + 800656e: 9400 str r4, [sp, #0] + 8006570: f7ff f901 bl 8005776 + uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */ + 8006574: 4623 mov r3, r4 + 8006576: 463a mov r2, r7 + 8006578: 4631 mov r1, r6 + 800657a: 4630 mov r0, r6 + 800657c: f7ff fcf4 bl 8005f68 + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */ + 8006580: 463b mov r3, r7 + 8006582: aa06 add r2, sp, #24 + 8006584: 4631 mov r1, r6 + 8006586: 4630 mov r0, r6 + 8006588: 9400 str r4, [sp, #0] + 800658a: f7ff f8f4 bl 8005776 + uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */ + 800658e: f995 1001 ldrsb.w r1, [r5, #1] + 8006592: 9832 ldr r0, [sp, #200] ; 0xc8 + 8006594: aa16 add r2, sp, #88 ; 0x58 + 8006596: f7ff f9c1 bl 800591c + uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */ + 800659a: f9b5 3002 ldrsh.w r3, [r5, #2] + 800659e: 1dda adds r2, r3, #7 + 80065a0: bf48 it mi + 80065a2: f103 020e addmi.w r2, r3, #14 + 80065a6: 10d2 asrs r2, r2, #3 + 80065a8: 4659 mov r1, fp + 80065aa: a806 add r0, sp, #24 + 80065ac: f7ff f9ca bl 8005944 + s[num_n_words - 1] = 0; + 80065b0: aa26 add r2, sp, #152 ; 0x98 + 80065b2: 1e63 subs r3, r4, #1 + 80065b4: eb02 0383 add.w r3, r2, r3, lsl #2 + 80065b8: 2200 movs r2, #0 + uECC_vli_set(s, p, num_words); + 80065ba: a80e add r0, sp, #56 ; 0x38 + s[num_n_words - 1] = 0; + 80065bc: f843 2c60 str.w r2, [r3, #-96] + uECC_vli_set(s, p, num_words); + 80065c0: a916 add r1, sp, #88 ; 0x58 + 80065c2: 4652 mov r2, sl + 80065c4: f7ff f8a9 bl 800571a + uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */ + 80065c8: 4602 mov r2, r0 + 80065ca: 463b mov r3, r7 + 80065cc: a906 add r1, sp, #24 + 80065ce: 9400 str r4, [sp, #0] + 80065d0: f7ff f8d1 bl 8005776 + bits2int(tmp, message_hash, hash_size, curve); + 80065d4: ee18 2a90 vmov r2, s17 + 80065d8: ee18 1a10 vmov r1, s16 + 80065dc: 462b mov r3, r5 + 80065de: a806 add r0, sp, #24 + 80065e0: f7ff fa5b bl 8005a9a + uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */ + 80065e4: aa0e add r2, sp, #56 ; 0x38 + 80065e6: 4610 mov r0, r2 + 80065e8: 463b mov r3, r7 + 80065ea: a906 add r1, sp, #24 + 80065ec: 9400 str r4, [sp, #0] + 80065ee: f7ff fd3b bl 8006068 + uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */ + 80065f2: a90e add r1, sp, #56 ; 0x38 + 80065f4: 4608 mov r0, r1 + 80065f6: 463b mov r3, r7 + 80065f8: 4632 mov r2, r6 + 80065fa: 9400 str r4, [sp, #0] + 80065fc: f7ff f8bb bl 8005776 + if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) { + 8006600: 4621 mov r1, r4 + 8006602: a80e add r0, sp, #56 ; 0x38 + 8006604: f7ff f869 bl 80056da + 8006608: f995 1001 ldrsb.w r1, [r5, #1] + 800660c: ebb0 0fc1 cmp.w r0, r1, lsl #3 + 8006610: f73f af5b bgt.w 80064ca + uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s); + 8006614: 9b32 ldr r3, [sp, #200] ; 0xc8 + 8006616: aa0e add r2, sp, #56 ; 0x38 + 8006618: 1858 adds r0, r3, r1 + 800661a: f7ff f97f bl 800591c + return 1; + 800661e: 2001 movs r0, #1 + 8006620: e754 b.n 80064cc + } else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) { + 8006622: 4622 mov r2, r4 + 8006624: 4639 mov r1, r7 + 8006626: 4648 mov r0, r9 + 8006628: f7ff fa96 bl 8005b58 + 800662c: 2800 cmp r0, #0 + 800662e: d19a bne.n 8006566 + 8006630: e74b b.n 80064ca + 8006632: bf00 nop + 8006634: 2009e2a4 .word 0x2009e2a4 + 8006638: 2009e2a0 .word 0x2009e2a0 + +0800663c : + uECC_Curve curve) { + 800663c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8006640: 4605 mov r5, r0 + 8006642: b093 sub sp, #76 ; 0x4c + 8006644: 460c mov r4, r1 + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + 8006646: 4610 mov r0, r2 + 8006648: 2108 movs r1, #8 + uECC_Curve curve) { + 800664a: 4617 mov r7, r2 + 800664c: 461e mov r6, r3 + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + 800664e: f7ff f82b bl 80056a8 + 8006652: 2800 cmp r0, #0 + 8006654: d161 bne.n 800671a + uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ + 8006656: 4632 mov r2, r6 + 8006658: 4621 mov r1, r4 + 800665a: a80a add r0, sp, #40 ; 0x28 + 800665c: f7ff f93b bl 80058d6 + uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ + 8006660: 4633 mov r3, r6 + 8006662: aa0a add r2, sp, #40 ; 0x28 + 8006664: 4629 mov r1, r5 + 8006666: a802 add r0, sp, #8 + 8006668: f7ff f925 bl 80058b6 + uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ + 800666c: 4632 mov r2, r6 + 800666e: 4629 mov r1, r5 + 8006670: 4628 mov r0, r5 + 8006672: f7ff f930 bl 80058d6 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ + 8006676: a90a add r1, sp, #40 ; 0x28 + 8006678: 4608 mov r0, r1 + 800667a: 4632 mov r2, r6 + 800667c: f7ff f92b bl 80058d6 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 8006680: f04f 0808 mov.w r8, #8 + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + 8006684: 463a mov r2, r7 + 8006686: 4638 mov r0, r7 + 8006688: 4633 mov r3, r6 + 800668a: 4621 mov r1, r4 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 800668c: 1d37 adds r7, r6, #4 + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + 800668e: f7ff f912 bl 80058b6 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 8006692: 463b mov r3, r7 + 8006694: 462a mov r2, r5 + 8006696: 4629 mov r1, r5 + 8006698: 4620 mov r0, r4 + 800669a: f8cd 8000 str.w r8, [sp] + 800669e: f7ff fce3 bl 8006068 + uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ + 80066a2: 463b mov r3, r7 + 80066a4: f8cd 8000 str.w r8, [sp] + 80066a8: 462a mov r2, r5 + 80066aa: 4621 mov r1, r4 + 80066ac: 4620 mov r0, r4 + 80066ae: f7ff fcdb bl 8006068 + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 80066b2: 6823 ldr r3, [r4, #0] + if (uECC_vli_testBit(Y1, 0)) { + 80066b4: 07db lsls r3, r3, #31 + 80066b6: d533 bpl.n 8006720 + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + 80066b8: 463a mov r2, r7 + 80066ba: 4621 mov r1, r4 + 80066bc: 4620 mov r0, r4 + 80066be: f7ff fa87 bl 8005bd0 + uECC_vli_rshift1(Y1, num_words_secp256k1); + 80066c2: 4641 mov r1, r8 + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + 80066c4: 4681 mov r9, r0 + uECC_vli_rshift1(Y1, num_words_secp256k1); + 80066c6: 4620 mov r0, r4 + 80066c8: f7ff f848 bl 800575c + Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); + 80066cc: 69e3 ldr r3, [r4, #28] + 80066ce: ea43 73c9 orr.w r3, r3, r9, lsl #31 + 80066d2: 61e3 str r3, [r4, #28] + uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ + 80066d4: 4632 mov r2, r6 + 80066d6: 4621 mov r1, r4 + 80066d8: 4628 mov r0, r5 + 80066da: f7ff f8fc bl 80058d6 + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ + 80066de: 463b mov r3, r7 + 80066e0: aa02 add r2, sp, #8 + 80066e2: 4629 mov r1, r5 + 80066e4: 4628 mov r0, r5 + 80066e6: f7ff fced bl 80060c4 + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ + 80066ea: 463b mov r3, r7 + 80066ec: aa02 add r2, sp, #8 + 80066ee: 4629 mov r1, r5 + 80066f0: 4628 mov r0, r5 + 80066f2: f7ff fce7 bl 80060c4 + uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ + 80066f6: a902 add r1, sp, #8 + 80066f8: 4608 mov r0, r1 + 80066fa: 463b mov r3, r7 + 80066fc: 462a mov r2, r5 + 80066fe: f7ff fce1 bl 80060c4 + uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ + 8006702: 4633 mov r3, r6 + 8006704: aa02 add r2, sp, #8 + 8006706: 4621 mov r1, r4 + 8006708: 4620 mov r0, r4 + 800670a: f7ff f8d4 bl 80058b6 + uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ + 800670e: 463b mov r3, r7 + 8006710: aa0a add r2, sp, #40 ; 0x28 + 8006712: 4621 mov r1, r4 + 8006714: 4620 mov r0, r4 + 8006716: f7ff fcd5 bl 80060c4 +} + 800671a: b013 add sp, #76 ; 0x4c + 800671c: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + uECC_vli_rshift1(Y1, num_words_secp256k1); + 8006720: 4641 mov r1, r8 + 8006722: 4620 mov r0, r4 + 8006724: f7ff f81a bl 800575c + 8006728: e7d4 b.n 80066d4 + +0800672a : +static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + 800672a: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800672e: b08a sub sp, #40 ; 0x28 + 8006730: 4604 mov r4, r0 + 8006732: 4615 mov r5, r2 + 8006734: 460e mov r6, r1 + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 8006736: 221c movs r2, #28 + 8006738: 2100 movs r1, #0 + 800673a: a803 add r0, sp, #12 + 800673c: f006 ff9a bl 800d674 + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + 8006740: 1d2f adds r7, r5, #4 + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 8006742: 2303 movs r3, #3 + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 8006744: 462a mov r2, r5 + 8006746: 4631 mov r1, r6 + 8006748: 4620 mov r0, r4 + wordcount_t num_words = curve->num_words; + 800674a: f995 8000 ldrsb.w r8, [r5] + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 800674e: 9302 str r3, [sp, #8] + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 8006750: f7ff f8c1 bl 80058d6 + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + 8006754: 463b mov r3, r7 + 8006756: aa02 add r2, sp, #8 + 8006758: 4621 mov r1, r4 + 800675a: 4620 mov r0, r4 + 800675c: f7ff fcb2 bl 80060c4 + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + 8006760: 462b mov r3, r5 + 8006762: 4632 mov r2, r6 + 8006764: 4621 mov r1, r4 + 8006766: 4620 mov r0, r4 + 8006768: f7ff f8a5 bl 80058b6 + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */ + 800676c: f8cd 8000 str.w r8, [sp] + 8006770: 463b mov r3, r7 + 8006772: f105 0284 add.w r2, r5, #132 ; 0x84 + 8006776: 4621 mov r1, r4 + 8006778: 4620 mov r0, r4 + 800677a: f7ff fc75 bl 8006068 +} + 800677e: b00a add sp, #40 ; 0x28 + 8006780: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +08006784 : + uECC_Curve curve) { + 8006784: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + wordcount_t num_words = curve->num_words; + 8006788: f993 8000 ldrsb.w r8, [r3] + uECC_Curve curve) { + 800678c: b092 sub sp, #72 ; 0x48 + 800678e: 4604 mov r4, r0 + 8006790: 4689 mov r9, r1 + if (uECC_vli_isZero(Z1, num_words)) { + 8006792: 4610 mov r0, r2 + 8006794: 4641 mov r1, r8 + uECC_Curve curve) { + 8006796: 4615 mov r5, r2 + 8006798: 461e mov r6, r3 + if (uECC_vli_isZero(Z1, num_words)) { + 800679a: f7fe ff85 bl 80056a8 + 800679e: 2800 cmp r0, #0 + 80067a0: f040 808e bne.w 80068c0 + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + 80067a4: 4632 mov r2, r6 + 80067a6: 4649 mov r1, r9 + 80067a8: a802 add r0, sp, #8 + 80067aa: f7ff f894 bl 80058d6 + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + 80067ae: 4633 mov r3, r6 + 80067b0: aa02 add r2, sp, #8 + 80067b2: 4621 mov r1, r4 + 80067b4: a80a add r0, sp, #40 ; 0x28 + 80067b6: f7ff f87e bl 80058b6 + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + 80067ba: a902 add r1, sp, #8 + 80067bc: 4608 mov r0, r1 + 80067be: 4632 mov r2, r6 + 80067c0: f7ff f889 bl 80058d6 + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + 80067c4: 4633 mov r3, r6 + 80067c6: 462a mov r2, r5 + 80067c8: 4649 mov r1, r9 + 80067ca: 4648 mov r0, r9 + 80067cc: f7ff f873 bl 80058b6 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + 80067d0: 1d37 adds r7, r6, #4 + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + 80067d2: 4632 mov r2, r6 + 80067d4: 4629 mov r1, r5 + 80067d6: 4628 mov r0, r5 + 80067d8: f7ff f87d bl 80058d6 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + 80067dc: 463b mov r3, r7 + 80067de: 462a mov r2, r5 + 80067e0: 4621 mov r1, r4 + 80067e2: 4620 mov r0, r4 + 80067e4: f8cd 8000 str.w r8, [sp] + 80067e8: f7ff fc3e bl 8006068 + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ + 80067ec: 463b mov r3, r7 + 80067ee: 462a mov r2, r5 + 80067f0: 4629 mov r1, r5 + 80067f2: 4628 mov r0, r5 + 80067f4: f8cd 8000 str.w r8, [sp] + 80067f8: f7ff fc36 bl 8006068 + uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ + 80067fc: 463b mov r3, r7 + 80067fe: 462a mov r2, r5 + 8006800: 4621 mov r1, r4 + 8006802: 4628 mov r0, r5 + 8006804: f7ff fc5e bl 80060c4 + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + 8006808: 4633 mov r3, r6 + 800680a: 462a mov r2, r5 + 800680c: 4621 mov r1, r4 + 800680e: 4620 mov r0, r4 + 8006810: f7ff f851 bl 80058b6 + uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ + 8006814: 463b mov r3, r7 + 8006816: 4622 mov r2, r4 + 8006818: 4621 mov r1, r4 + 800681a: 4628 mov r0, r5 + 800681c: f8cd 8000 str.w r8, [sp] + 8006820: f7ff fc22 bl 8006068 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ + 8006824: 463b mov r3, r7 + 8006826: f8cd 8000 str.w r8, [sp] + 800682a: 462a mov r2, r5 + 800682c: 4621 mov r1, r4 + 800682e: 4620 mov r0, r4 + 8006830: f7ff fc1a bl 8006068 + 8006834: 6823 ldr r3, [r4, #0] + if (uECC_vli_testBit(X1, 0)) { + 8006836: 07db lsls r3, r3, #31 + 8006838: d545 bpl.n 80068c6 + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + 800683a: 463a mov r2, r7 + 800683c: 4621 mov r1, r4 + 800683e: 4620 mov r0, r4 + 8006840: f7ff f9c6 bl 8005bd0 + uECC_vli_rshift1(X1, num_words); + 8006844: 4641 mov r1, r8 + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + 8006846: 4682 mov sl, r0 + uECC_vli_rshift1(X1, num_words); + 8006848: 4620 mov r0, r4 + 800684a: f7fe ff87 bl 800575c + X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + 800684e: f108 4380 add.w r3, r8, #1073741824 ; 0x40000000 + 8006852: 3b01 subs r3, #1 + 8006854: f854 2023 ldr.w r2, [r4, r3, lsl #2] + 8006858: ea42 72ca orr.w r2, r2, sl, lsl #31 + 800685c: f844 2023 str.w r2, [r4, r3, lsl #2] + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + 8006860: 4632 mov r2, r6 + 8006862: 4621 mov r1, r4 + 8006864: 4628 mov r0, r5 + 8006866: f7ff f836 bl 80058d6 + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ + 800686a: 463b mov r3, r7 + 800686c: aa0a add r2, sp, #40 ; 0x28 + 800686e: 4629 mov r1, r5 + 8006870: 4628 mov r0, r5 + 8006872: f7ff fc27 bl 80060c4 + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ + 8006876: 463b mov r3, r7 + 8006878: aa0a add r2, sp, #40 ; 0x28 + 800687a: 4629 mov r1, r5 + 800687c: 4628 mov r0, r5 + 800687e: f7ff fc21 bl 80060c4 + uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ + 8006882: a90a add r1, sp, #40 ; 0x28 + 8006884: 4608 mov r0, r1 + 8006886: 463b mov r3, r7 + 8006888: 462a mov r2, r5 + 800688a: f7ff fc1b bl 80060c4 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + 800688e: 4633 mov r3, r6 + 8006890: aa0a add r2, sp, #40 ; 0x28 + 8006892: 4621 mov r1, r4 + 8006894: 4620 mov r0, r4 + 8006896: f7ff f80e bl 80058b6 + uECC_vli_modSub(t4, X1, t4, curve->p, num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ + 800689a: aa02 add r2, sp, #8 + 800689c: 463b mov r3, r7 + 800689e: 4610 mov r0, r2 + 80068a0: 4621 mov r1, r4 + 80068a2: f7ff fc0f bl 80060c4 + uECC_vli_set(X1, Z1, num_words); + 80068a6: 4642 mov r2, r8 + 80068a8: 4629 mov r1, r5 + 80068aa: 4620 mov r0, r4 + 80068ac: f7fe ff35 bl 800571a + uECC_vli_set(Z1, Y1, num_words); + 80068b0: 4649 mov r1, r9 + 80068b2: 4628 mov r0, r5 + 80068b4: f7fe ff31 bl 800571a + uECC_vli_set(Y1, t4, num_words); + 80068b8: a902 add r1, sp, #8 + 80068ba: 4648 mov r0, r9 + 80068bc: f7fe ff2d bl 800571a +} + 80068c0: b012 add sp, #72 ; 0x48 + 80068c2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + uECC_vli_rshift1(X1, num_words); + 80068c6: 4641 mov r1, r8 + 80068c8: 4620 mov r0, r4 + 80068ca: f7fe ff47 bl 800575c + 80068ce: e7c7 b.n 8006860 + +080068d0 : + g_rng_function = rng_function; + 80068d0: 4b01 ldr r3, [pc, #4] ; (80068d8 ) + 80068d2: 6018 str r0, [r3, #0] +} + 80068d4: 4770 bx lr + 80068d6: bf00 nop + 80068d8: 2009e2a0 .word 0x2009e2a0 + +080068dc : +uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } + 80068dc: 4800 ldr r0, [pc, #0] ; (80068e0 ) + 80068de: 4770 bx lr + 80068e0: 0800e928 .word 0x0800e928 + +080068e4 : +uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } + 80068e4: 4800 ldr r0, [pc, #0] ; (80068e8 ) + 80068e6: 4770 bx lr + 80068e8: 0800e874 .word 0x0800e874 + +080068ec : + uECC_Curve curve) { + 80068ec: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 80068f0: 4605 mov r5, r0 + 80068f2: b098 sub sp, #96 ; 0x60 + 80068f4: 460f mov r7, r1 + 80068f6: 4614 mov r4, r2 + 80068f8: 2640 movs r6, #64 ; 0x40 + if (!uECC_generate_random_int(private, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + 80068fa: f102 0824 add.w r8, r2, #36 ; 0x24 + 80068fe: f9b4 3002 ldrsh.w r3, [r4, #2] + 8006902: f113 021f adds.w r2, r3, #31 + 8006906: bf48 it mi + 8006908: f103 023e addmi.w r2, r3, #62 ; 0x3e + 800690c: f342 1247 sbfx r2, r2, #5, #8 + 8006910: 4641 mov r1, r8 + 8006912: 4668 mov r0, sp + 8006914: f7ff f920 bl 8005b58 + 8006918: b330 cbz r0, 8006968 + if (EccPoint_compute_public_key(public, private, curve)) { + 800691a: 4622 mov r2, r4 + 800691c: 4669 mov r1, sp + 800691e: a808 add r0, sp, #32 + 8006920: f7ff fd8f bl 8006442 + 8006924: b1f0 cbz r0, 8006964 + uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), private); + 8006926: f9b4 3002 ldrsh.w r3, [r4, #2] + 800692a: 1dd9 adds r1, r3, #7 + 800692c: bf48 it mi + 800692e: f103 010e addmi.w r1, r3, #14 + 8006932: 466a mov r2, sp + 8006934: 10c9 asrs r1, r1, #3 + 8006936: 4638 mov r0, r7 + 8006938: f7fe fff0 bl 800591c + uECC_vli_nativeToBytes(public_key, curve->num_bytes, public); + 800693c: f994 1001 ldrsb.w r1, [r4, #1] + 8006940: aa08 add r2, sp, #32 + 8006942: 4628 mov r0, r5 + 8006944: f7fe ffea bl 800591c + public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words); + 8006948: f994 1001 ldrsb.w r1, [r4, #1] + 800694c: f994 2000 ldrsb.w r2, [r4] + uECC_vli_nativeToBytes( + 8006950: ab08 add r3, sp, #32 + 8006952: 1868 adds r0, r5, r1 + 8006954: eb03 0282 add.w r2, r3, r2, lsl #2 + 8006958: f7fe ffe0 bl 800591c + return 1; + 800695c: 2001 movs r0, #1 +} + 800695e: b018 add sp, #96 ; 0x60 + 8006960: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8006964: 3e01 subs r6, #1 + 8006966: d1ca bne.n 80068fe + return 0; + 8006968: 2000 movs r0, #0 + 800696a: e7f8 b.n 800695e + +0800696c : + uECC_Curve curve) { + 800696c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8006970: 461c mov r4, r3 + wordcount_t num_bytes = curve->num_bytes; + 8006972: f993 6001 ldrsb.w r6, [r3, #1] + wordcount_t num_words = curve->num_words; + 8006976: f993 9000 ldrsb.w r9, [r3] + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 800697a: f9b3 3002 ldrsh.w r3, [r3, #2] + uECC_Curve curve) { + 800697e: b0a6 sub sp, #152 ; 0x98 + 8006980: 4617 mov r7, r2 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006982: 1dda adds r2, r3, #7 + 8006984: bf48 it mi + 8006986: f103 020e addmi.w r2, r3, #14 + uECC_word_t *p2[2] = {private, tmp}; + 800698a: f10d 0818 add.w r8, sp, #24 + uECC_Curve curve) { + 800698e: 4605 mov r5, r0 + uECC_word_t *p2[2] = {private, tmp}; + 8006990: f10d 0a38 add.w sl, sp, #56 ; 0x38 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006994: 10d2 asrs r2, r2, #3 + 8006996: 4640 mov r0, r8 + uECC_word_t *p2[2] = {private, tmp}; + 8006998: f8cd 8010 str.w r8, [sp, #16] + 800699c: f8cd a014 str.w sl, [sp, #20] + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 80069a0: f7fe ffd0 bl 8005944 + uECC_vli_bytesToNative(public, public_key, num_bytes); + 80069a4: 4629 mov r1, r5 + 80069a6: 4632 mov r2, r6 + 80069a8: a816 add r0, sp, #88 ; 0x58 + 80069aa: f7fe ffcb bl 8005944 + uECC_vli_bytesToNative(public + num_words, public_key + num_bytes, num_bytes); + 80069ae: ab16 add r3, sp, #88 ; 0x58 + 80069b0: 19a9 adds r1, r5, r6 + 80069b2: eb03 0089 add.w r0, r3, r9, lsl #2 + 80069b6: 4632 mov r2, r6 + 80069b8: f7fe ffc4 bl 8005944 + carry = regularize_k(private, private, tmp, curve); + 80069bc: 4623 mov r3, r4 + 80069be: 4652 mov r2, sl + 80069c0: 4641 mov r1, r8 + 80069c2: 4640 mov r0, r8 + 80069c4: f7ff f929 bl 8005c1a + if (g_rng_function) { + 80069c8: 4b19 ldr r3, [pc, #100] ; (8006a30 ) + 80069ca: 681b ldr r3, [r3, #0] + carry = regularize_k(private, private, tmp, curve); + 80069cc: 4605 mov r5, r0 + if (g_rng_function) { + 80069ce: b163 cbz r3, 80069ea + if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) { + 80069d0: ab26 add r3, sp, #152 ; 0x98 + 80069d2: eb03 0380 add.w r3, r3, r0, lsl #2 + 80069d6: 464a mov r2, r9 + 80069d8: f853 3c88 ldr.w r3, [r3, #-136] + 80069dc: 9303 str r3, [sp, #12] + 80069de: 4618 mov r0, r3 + 80069e0: 1d21 adds r1, r4, #4 + 80069e2: f7ff f8b9 bl 8005b58 + 80069e6: 9b03 ldr r3, [sp, #12] + 80069e8: b1f0 cbz r0, 8006a28 + EccPoint_mult(public, public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve); + 80069ea: fab5 f185 clz r1, r5 + 80069ee: aa26 add r2, sp, #152 ; 0x98 + 80069f0: 0949 lsrs r1, r1, #5 + 80069f2: eb02 0181 add.w r1, r2, r1, lsl #2 + 80069f6: 8862 ldrh r2, [r4, #2] + 80069f8: 9401 str r4, [sp, #4] + 80069fa: 3201 adds r2, #1 + 80069fc: b212 sxth r2, r2 + 80069fe: 9200 str r2, [sp, #0] + 8006a00: f851 2c88 ldr.w r2, [r1, #-136] + 8006a04: a916 add r1, sp, #88 ; 0x58 + 8006a06: 4608 mov r0, r1 + 8006a08: f7ff fc50 bl 80062ac + uECC_vli_nativeToBytes(secret, num_bytes, public); + 8006a0c: aa16 add r2, sp, #88 ; 0x58 + 8006a0e: 4631 mov r1, r6 + 8006a10: 4638 mov r0, r7 + 8006a12: f7fe ff83 bl 800591c + return !EccPoint_isZero(public, curve); + 8006a16: 7821 ldrb r1, [r4, #0] + 8006a18: 0049 lsls r1, r1, #1 + 8006a1a: b249 sxtb r1, r1 + 8006a1c: 4610 mov r0, r2 + 8006a1e: f7fe fe43 bl 80056a8 + 8006a22: fab0 f080 clz r0, r0 + 8006a26: 0940 lsrs r0, r0, #5 +} + 8006a28: b026 add sp, #152 ; 0x98 + 8006a2a: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 8006a2e: bf00 nop + 8006a30: 2009e2a0 .word 0x2009e2a0 + +08006a34 : +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve) { + 8006a34: b530 push {r4, r5, lr} + for (i = 0; i < curve->num_bytes; ++i) { + 8006a36: 2400 movs r4, #0 + 8006a38: f992 5001 ldrsb.w r5, [r2, #1] + 8006a3c: b263 sxtb r3, r4 + 8006a3e: 429d cmp r5, r3 + 8006a40: dc08 bgt.n 8006a54 + compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01); + 8006a42: eb00 0045 add.w r0, r0, r5, lsl #1 + 8006a46: f810 3c01 ldrb.w r3, [r0, #-1] + 8006a4a: f003 0301 and.w r3, r3, #1 + 8006a4e: 3302 adds r3, #2 + 8006a50: 700b strb r3, [r1, #0] +} + 8006a52: bd30 pop {r4, r5, pc} + compressed[i+1] = public_key[i]; + 8006a54: 5cc5 ldrb r5, [r0, r3] + 8006a56: 440b add r3, r1 + 8006a58: 3401 adds r4, #1 + 8006a5a: 705d strb r5, [r3, #1] + for (i = 0; i < curve->num_bytes; ++i) { + 8006a5c: e7ec b.n 8006a38 + +08006a5e : +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006a5e: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + uECC_word_t *y = point + curve->num_words; + 8006a62: f992 8000 ldrsb.w r8, [r2] +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006a66: b090 sub sp, #64 ; 0x40 + 8006a68: 4614 mov r4, r2 + 8006a6a: 4607 mov r7, r0 + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); + 8006a6c: f992 2001 ldrsb.w r2, [r2, #1] + uECC_word_t *y = point + curve->num_words; + 8006a70: eb0d 0588 add.w r5, sp, r8, lsl #2 +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006a74: 460e mov r6, r1 + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); + 8006a76: 1c41 adds r1, r0, #1 + 8006a78: 4668 mov r0, sp + 8006a7a: f7fe ff63 bl 8005944 + curve->x_side(y, point, curve); + 8006a7e: 4622 mov r2, r4 + 8006a80: f8d4 30ac ldr.w r3, [r4, #172] ; 0xac + 8006a84: 4669 mov r1, sp + 8006a86: 4628 mov r0, r5 + 8006a88: 4798 blx r3 + curve->mod_sqrt(y, curve); + 8006a8a: f8d4 30a8 ldr.w r3, [r4, #168] ; 0xa8 + 8006a8e: 4621 mov r1, r4 + 8006a90: 4628 mov r0, r5 + 8006a92: 4798 blx r3 + if ((y[0] & 0x01) != (compressed[0] & 0x01)) { + 8006a94: 783b ldrb r3, [r7, #0] + 8006a96: f85d 2028 ldr.w r2, [sp, r8, lsl #2] + 8006a9a: 4053 eors r3, r2 + 8006a9c: 07db lsls r3, r3, #31 + 8006a9e: d504 bpl.n 8006aaa + uECC_vli_sub(y, curve->p, y, curve->num_words); + 8006aa0: 462a mov r2, r5 + 8006aa2: 1d21 adds r1, r4, #4 + 8006aa4: 4628 mov r0, r5 + 8006aa6: f7fe ffd1 bl 8005a4c + uECC_vli_nativeToBytes(public_key, curve->num_bytes, point); + 8006aaa: f994 1001 ldrsb.w r1, [r4, #1] + 8006aae: 466a mov r2, sp + 8006ab0: 4630 mov r0, r6 + 8006ab2: f7fe ff33 bl 800591c + uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y); + 8006ab6: f994 1001 ldrsb.w r1, [r4, #1] + 8006aba: 462a mov r2, r5 + 8006abc: 1870 adds r0, r6, r1 + 8006abe: f7fe ff2d bl 800591c +} + 8006ac2: b010 add sp, #64 ; 0x40 + 8006ac4: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +08006ac8 : +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006ac8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + if (EccPoint_isZero(point, curve)) { + 8006acc: 780d ldrb r5, [r1, #0] + wordcount_t num_words = curve->num_words; + 8006ace: f991 2000 ldrsb.w r2, [r1] +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006ad2: b092 sub sp, #72 ; 0x48 + 8006ad4: 460e mov r6, r1 + if (EccPoint_isZero(point, curve)) { + 8006ad6: 0069 lsls r1, r5, #1 + 8006ad8: b249 sxtb r1, r1 +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006ada: 4607 mov r7, r0 + wordcount_t num_words = curve->num_words; + 8006adc: 9201 str r2, [sp, #4] + if (EccPoint_isZero(point, curve)) { + 8006ade: f7fe fde3 bl 80056a8 + 8006ae2: 4604 mov r4, r0 + 8006ae4: bb80 cbnz r0, 8006b48 + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + 8006ae6: f106 0804 add.w r8, r6, #4 + 8006aea: 9a01 ldr r2, [sp, #4] + 8006aec: 4639 mov r1, r7 + 8006aee: 4640 mov r0, r8 + 8006af0: f7fe fe1f bl 8005732 + 8006af4: 2801 cmp r0, #1 + 8006af6: d11a bne.n 8006b2e + uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) { + 8006af8: 9a01 ldr r2, [sp, #4] + 8006afa: 4640 mov r0, r8 + 8006afc: eb07 0182 add.w r1, r7, r2, lsl #2 + 8006b00: f7fe fe17 bl 8005732 + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + 8006b04: 2801 cmp r0, #1 + 8006b06: d112 bne.n 8006b2e + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + 8006b08: 4632 mov r2, r6 + 8006b0a: a802 add r0, sp, #8 + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + 8006b0c: f10d 0828 add.w r8, sp, #40 ; 0x28 + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + 8006b10: f7fe fee1 bl 80058d6 + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + 8006b14: f8d6 30ac ldr.w r3, [r6, #172] ; 0xac + 8006b18: 4632 mov r2, r6 + 8006b1a: 4639 mov r1, r7 + 8006b1c: 4640 mov r0, r8 + 8006b1e: 4798 blx r3 + for (i = num_words - 1; i >= 0; --i) { + 8006b20: 1e6b subs r3, r5, #1 + 8006b22: b25b sxtb r3, r3 + 8006b24: 061a lsls r2, r3, #24 + 8006b26: d506 bpl.n 8006b36 + return (diff == 0); + 8006b28: fab4 f484 clz r4, r4 + 8006b2c: 0964 lsrs r4, r4, #5 +} + 8006b2e: 4620 mov r0, r4 + 8006b30: b012 add sp, #72 ; 0x48 + 8006b32: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + diff |= (left[i] ^ right[i]); + 8006b36: aa02 add r2, sp, #8 + 8006b38: f858 1023 ldr.w r1, [r8, r3, lsl #2] + 8006b3c: f852 2023 ldr.w r2, [r2, r3, lsl #2] + 8006b40: 404a eors r2, r1 + 8006b42: 4314 orrs r4, r2 + for (i = num_words - 1; i >= 0; --i) { + 8006b44: 3b01 subs r3, #1 + 8006b46: e7ed b.n 8006b24 + return 0; + 8006b48: 2400 movs r4, #0 + 8006b4a: e7f0 b.n 8006b2e + +08006b4c : +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { + 8006b4c: b530 push {r4, r5, lr} + 8006b4e: 460c mov r4, r1 + 8006b50: b091 sub sp, #68 ; 0x44 + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8006b52: f991 2001 ldrsb.w r2, [r1, #1] +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { + 8006b56: 4605 mov r5, r0 + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8006b58: 4601 mov r1, r0 + 8006b5a: 4668 mov r0, sp + 8006b5c: f7fe fef2 bl 8005944 + public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes); + 8006b60: f994 2001 ldrsb.w r2, [r4, #1] + 8006b64: f994 0000 ldrsb.w r0, [r4] + uECC_vli_bytesToNative( + 8006b68: 18a9 adds r1, r5, r2 + 8006b6a: eb0d 0080 add.w r0, sp, r0, lsl #2 + 8006b6e: f7fe fee9 bl 8005944 + return uECC_valid_point(public, curve); + 8006b72: 4621 mov r1, r4 + 8006b74: 4668 mov r0, sp + 8006b76: f7ff ffa7 bl 8006ac8 +} + 8006b7a: b011 add sp, #68 ; 0x44 + 8006b7c: bd30 pop {r4, r5, pc} + +08006b7e : +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006b7e: b570 push {r4, r5, r6, lr} + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006b80: f9b2 3002 ldrsh.w r3, [r2, #2] +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006b84: 4614 mov r4, r2 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006b86: 1dda adds r2, r3, #7 + 8006b88: bf48 it mi + 8006b8a: f103 020e addmi.w r2, r3, #14 +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006b8e: b098 sub sp, #96 ; 0x60 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006b90: 10d2 asrs r2, r2, #3 +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006b92: 460e mov r6, r1 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006b94: 4601 mov r1, r0 + 8006b96: 4668 mov r0, sp + 8006b98: f7fe fed4 bl 8005944 + if (uECC_vli_isZero(private, BITS_TO_WORDS(curve->num_n_bits))) { + 8006b9c: f9b4 3002 ldrsh.w r3, [r4, #2] + 8006ba0: f113 021f adds.w r2, r3, #31 + 8006ba4: bf48 it mi + 8006ba6: f103 023e addmi.w r2, r3, #62 ; 0x3e + 8006baa: f342 1147 sbfx r1, r2, #5, #8 + 8006bae: 4668 mov r0, sp + 8006bb0: f7fe fd7a bl 80056a8 + 8006bb4: b110 cbz r0, 8006bbc + return 0; + 8006bb6: 2000 movs r0, #0 +} + 8006bb8: b018 add sp, #96 ; 0x60 + 8006bba: bd70 pop {r4, r5, r6, pc} + if (uECC_vli_cmp(curve->n, private, BITS_TO_WORDS(curve->num_n_bits)) != 1) { + 8006bbc: 460a mov r2, r1 + 8006bbe: f104 0024 add.w r0, r4, #36 ; 0x24 + 8006bc2: 4669 mov r1, sp + 8006bc4: f7fe ffb0 bl 8005b28 + 8006bc8: 2801 cmp r0, #1 + 8006bca: 4605 mov r5, r0 + 8006bcc: d1f3 bne.n 8006bb6 + if (!EccPoint_compute_public_key(public, private, curve)) { + 8006bce: 4622 mov r2, r4 + 8006bd0: 4669 mov r1, sp + 8006bd2: a808 add r0, sp, #32 + 8006bd4: f7ff fc35 bl 8006442 + 8006bd8: 2800 cmp r0, #0 + 8006bda: d0ec beq.n 8006bb6 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, public); + 8006bdc: f994 1001 ldrsb.w r1, [r4, #1] + 8006be0: aa08 add r2, sp, #32 + 8006be2: 4630 mov r0, r6 + 8006be4: f7fe fe9a bl 800591c + public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words); + 8006be8: f994 1001 ldrsb.w r1, [r4, #1] + 8006bec: f994 2000 ldrsb.w r2, [r4] + uECC_vli_nativeToBytes( + 8006bf0: ab08 add r3, sp, #32 + 8006bf2: 1870 adds r0, r6, r1 + 8006bf4: eb03 0282 add.w r2, r3, r2, lsl #2 + 8006bf8: f7fe fe90 bl 800591c + return 1; + 8006bfc: 4628 mov r0, r5 + 8006bfe: e7db b.n 8006bb8 + +08006c00 : + uECC_Curve curve) { + 8006c00: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8006c04: b08a sub sp, #40 ; 0x28 + 8006c06: 4605 mov r5, r0 + 8006c08: f8dd 9048 ldr.w r9, [sp, #72] ; 0x48 + 8006c0c: 460e mov r6, r1 + 8006c0e: 4617 mov r7, r2 + 8006c10: 4698 mov r8, r3 + 8006c12: 2440 movs r4, #64 ; 0x40 + if (!uECC_generate_random_int(k, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + 8006c14: f109 0a24 add.w sl, r9, #36 ; 0x24 + 8006c18: f9b9 3002 ldrsh.w r3, [r9, #2] + 8006c1c: f113 021f adds.w r2, r3, #31 + 8006c20: bf48 it mi + 8006c22: f103 023e addmi.w r2, r3, #62 ; 0x3e + 8006c26: f342 1247 sbfx r2, r2, #5, #8 + 8006c2a: 4651 mov r1, sl + 8006c2c: a802 add r0, sp, #8 + 8006c2e: f7fe ff93 bl 8005b58 + 8006c32: b150 cbz r0, 8006c4a + if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) { + 8006c34: e9cd 8900 strd r8, r9, [sp] + 8006c38: ab02 add r3, sp, #8 + 8006c3a: 463a mov r2, r7 + 8006c3c: 4631 mov r1, r6 + 8006c3e: 4628 mov r0, r5 + 8006c40: f7ff fc2a bl 8006498 + 8006c44: b928 cbnz r0, 8006c52 + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8006c46: 3c01 subs r4, #1 + 8006c48: d1e6 bne.n 8006c18 + return 0; + 8006c4a: 2000 movs r0, #0 +} + 8006c4c: b00a add sp, #40 ; 0x28 + 8006c4e: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + return 1; + 8006c52: 2001 movs r0, #1 + 8006c54: e7fa b.n 8006c4c + +08006c56 : +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve) { + 8006c56: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8006c5a: b091 sub sp, #68 ; 0x44 + 8006c5c: 4693 mov fp, r2 + uint8_t *K = hash_context->tmp; + uint8_t *V = K + hash_context->result_size; + wordcount_t num_bytes = curve->num_bytes; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006c5e: 9a1b ldr r2, [sp, #108] ; 0x6c + 8006c60: f9b2 8002 ldrsh.w r8, [r2, #2] + uint8_t *V = K + hash_context->result_size; + 8006c64: e9d3 6504 ldrd r6, r5, [r3, #16] + uECC_Curve curve) { + 8006c68: 461c mov r4, r3 + wordcount_t num_bytes = curve->num_bytes; + 8006c6a: 9b1b ldr r3, [sp, #108] ; 0x6c + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006c6c: f118 071f adds.w r7, r8, #31 + 8006c70: bf48 it mi + 8006c72: f108 073e addmi.w r7, r8, #62 ; 0x3e + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t tries; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) { + 8006c76: 2200 movs r2, #0 + wordcount_t num_bytes = curve->num_bytes; + 8006c78: f993 3001 ldrsb.w r3, [r3, #1] + uECC_Curve curve) { + 8006c7c: 4681 mov r9, r0 + 8006c7e: 468a mov sl, r1 + uint8_t *V = K + hash_context->result_size; + 8006c80: 442e add r6, r5 + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006c82: f347 1747 sbfx r7, r7, #5, #8 + V[i] = 0x01; + 8006c86: 2001 movs r0, #1 + K[i] = 0; + 8006c88: 4694 mov ip, r2 + for (i = 0; i < hash_context->result_size; ++i) { + 8006c8a: 6921 ldr r1, [r4, #16] + 8006c8c: 4291 cmp r1, r2 + 8006c8e: f200 8086 bhi.w 8006d9e + } + + /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + 8006c92: 4629 mov r1, r5 + 8006c94: 4620 mov r0, r4 + 8006c96: 9303 str r3, [sp, #12] + 8006c98: f7fe fe74 bl 8005984 + V[hash_context->result_size] = 0x00; + 8006c9c: 6922 ldr r2, [r4, #16] + 8006c9e: 2100 movs r1, #0 + 8006ca0: 54b1 strb r1, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 8006ca2: 6922 ldr r2, [r4, #16] + 8006ca4: 4631 mov r1, r6 + 8006ca6: 3201 adds r2, #1 + 8006ca8: 4620 mov r0, r4 + 8006caa: f7fe fe8c bl 80059c6 + HMAC_update(hash_context, private_key, num_bytes); + 8006cae: 9b03 ldr r3, [sp, #12] + 8006cb0: 4649 mov r1, r9 + 8006cb2: 461a mov r2, r3 + 8006cb4: 4620 mov r0, r4 + 8006cb6: f7fe fe86 bl 80059c6 + HMAC_update(hash_context, message_hash, hash_size); + 8006cba: 465a mov r2, fp + 8006cbc: 4651 mov r1, sl + 8006cbe: 4620 mov r0, r4 + 8006cc0: f7fe fe81 bl 80059c6 + HMAC_finish(hash_context, K, K); + 8006cc4: 462a mov r2, r5 + 8006cc6: 4629 mov r1, r5 + 8006cc8: 4620 mov r0, r4 + 8006cca: f7fe fe7e bl 80059ca + + update_V(hash_context, K, V); + 8006cce: 4632 mov r2, r6 + 8006cd0: 4629 mov r1, r5 + 8006cd2: 4620 mov r0, r4 + 8006cd4: f7fe fea8 bl 8005a28 + + /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + 8006cd8: 4629 mov r1, r5 + 8006cda: 4620 mov r0, r4 + 8006cdc: f7fe fe52 bl 8005984 + V[hash_context->result_size] = 0x01; + 8006ce0: 6922 ldr r2, [r4, #16] + 8006ce2: 2101 movs r1, #1 + 8006ce4: 54b1 strb r1, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 8006ce6: 6922 ldr r2, [r4, #16] + 8006ce8: 4620 mov r0, r4 + 8006cea: 440a add r2, r1 + 8006cec: 4631 mov r1, r6 + 8006cee: f7fe fe6a bl 80059c6 + HMAC_update(hash_context, private_key, num_bytes); + 8006cf2: 9b03 ldr r3, [sp, #12] + 8006cf4: 4649 mov r1, r9 + 8006cf6: 461a mov r2, r3 + 8006cf8: 4620 mov r0, r4 + 8006cfa: f7fe fe64 bl 80059c6 + HMAC_update(hash_context, message_hash, hash_size); + 8006cfe: 465a mov r2, fp + 8006d00: 4651 mov r1, sl + 8006d02: 4620 mov r0, r4 + 8006d04: f7fe fe5f bl 80059c6 + HMAC_finish(hash_context, K, K); + 8006d08: 462a mov r2, r5 + 8006d0a: 4629 mov r1, r5 + 8006d0c: 4620 mov r0, r4 + 8006d0e: f7fe fe5c bl 80059ca + + update_V(hash_context, K, V); + 8006d12: 4632 mov r2, r6 + 8006d14: 4629 mov r1, r5 + 8006d16: 4620 mov r0, r4 + 8006d18: f7fe fe86 bl 8005a28 + wordcount_t T_bytes = 0; + for (;;) { + update_V(hash_context, K, V); + for (i = 0; i < hash_context->result_size; ++i) { + T_ptr[T_bytes++] = V[i]; + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + 8006d1c: 00bb lsls r3, r7, #2 + 8006d1e: 9304 str r3, [sp, #16] + goto filled; + } + } + } + filled: + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + 8006d20: 017b lsls r3, r7, #5 + 8006d22: 9305 str r3, [sp, #20] + uECC_word_t mask = (uECC_word_t)-1; + T[num_n_words - 1] &= + mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits)); + 8006d24: ebc8 1347 rsb r3, r8, r7, lsl #5 + 8006d28: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 8006d2c: b21b sxth r3, r3 + 8006d2e: fa22 f303 lsr.w r3, r2, r3 + 8006d32: 9306 str r3, [sp, #24] + 8006d34: 2340 movs r3, #64 ; 0x40 + 8006d36: 9303 str r3, [sp, #12] + T[num_n_words - 1] &= + 8006d38: 4417 add r7, r2 + 8006d3a: 446b add r3, sp + 8006d3c: eb03 0787 add.w r7, r3, r7, lsl #2 + wordcount_t T_bytes = 0; + 8006d40: 2300 movs r3, #0 + update_V(hash_context, K, V); + 8006d42: 4632 mov r2, r6 + 8006d44: 4629 mov r1, r5 + 8006d46: 4620 mov r0, r4 + 8006d48: 9307 str r3, [sp, #28] + 8006d4a: f7fe fe6d bl 8005a28 + for (i = 0; i < hash_context->result_size; ++i) { + 8006d4e: 6920 ldr r0, [r4, #16] + 8006d50: 9b07 ldr r3, [sp, #28] + 8006d52: 4631 mov r1, r6 + 8006d54: 4430 add r0, r6 + 8006d56: 461a mov r2, r3 + T_ptr[T_bytes++] = V[i]; + 8006d58: ab08 add r3, sp, #32 + 8006d5a: eb03 0c02 add.w ip, r3, r2 + for (i = 0; i < hash_context->result_size; ++i) { + 8006d5e: 4288 cmp r0, r1 + 8006d60: 4613 mov r3, r2 + 8006d62: f102 0201 add.w r2, r2, #1 + 8006d66: b252 sxtb r2, r2 + 8006d68: d0eb beq.n 8006d42 + T_ptr[T_bytes++] = V[i]; + 8006d6a: f811 3b01 ldrb.w r3, [r1], #1 + 8006d6e: f88c 3000 strb.w r3, [ip] + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + 8006d72: 9b04 ldr r3, [sp, #16] + 8006d74: 4293 cmp r3, r2 + 8006d76: dcef bgt.n 8006d58 + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + 8006d78: 9b05 ldr r3, [sp, #20] + 8006d7a: 4598 cmp r8, r3 + 8006d7c: db14 blt.n 8006da8 + } + + if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) { + 8006d7e: 9b1b ldr r3, [sp, #108] ; 0x6c + 8006d80: 9301 str r3, [sp, #4] + 8006d82: 9b1a ldr r3, [sp, #104] ; 0x68 + 8006d84: 9300 str r3, [sp, #0] + 8006d86: 465a mov r2, fp + 8006d88: ab08 add r3, sp, #32 + 8006d8a: 4651 mov r1, sl + 8006d8c: 4648 mov r0, r9 + 8006d8e: f7ff fb83 bl 8006498 + 8006d92: b180 cbz r0, 8006db6 + return 1; + 8006d94: 2301 movs r3, #1 + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + } + return 0; +} + 8006d96: 4618 mov r0, r3 + 8006d98: b011 add sp, #68 ; 0x44 + 8006d9a: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + V[i] = 0x01; + 8006d9e: 54b0 strb r0, [r6, r2] + K[i] = 0; + 8006da0: f805 c002 strb.w ip, [r5, r2] + for (i = 0; i < hash_context->result_size; ++i) { + 8006da4: 3201 adds r2, #1 + 8006da6: e770 b.n 8006c8a + T[num_n_words - 1] &= + 8006da8: f857 3c20 ldr.w r3, [r7, #-32] + 8006dac: 9a06 ldr r2, [sp, #24] + 8006dae: 4013 ands r3, r2 + 8006db0: f847 3c20 str.w r3, [r7, #-32] + 8006db4: e7e3 b.n 8006d7e + 8006db6: 9007 str r0, [sp, #28] + HMAC_init(hash_context, K); + 8006db8: 4629 mov r1, r5 + 8006dba: 4620 mov r0, r4 + 8006dbc: f7fe fde2 bl 8005984 + V[hash_context->result_size] = 0x00; + 8006dc0: 6922 ldr r2, [r4, #16] + 8006dc2: 9b07 ldr r3, [sp, #28] + 8006dc4: 54b3 strb r3, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 8006dc6: 6922 ldr r2, [r4, #16] + 8006dc8: 4631 mov r1, r6 + 8006dca: 3201 adds r2, #1 + 8006dcc: 4620 mov r0, r4 + 8006dce: f7fe fdfa bl 80059c6 + HMAC_finish(hash_context, K, K); + 8006dd2: 462a mov r2, r5 + 8006dd4: 4629 mov r1, r5 + 8006dd6: 4620 mov r0, r4 + 8006dd8: f7fe fdf7 bl 80059ca + update_V(hash_context, K, V); + 8006ddc: 4632 mov r2, r6 + 8006dde: 4629 mov r1, r5 + 8006de0: 4620 mov r0, r4 + 8006de2: f7fe fe21 bl 8005a28 + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8006de6: 9b03 ldr r3, [sp, #12] + 8006de8: 3b01 subs r3, #1 + 8006dea: 9303 str r3, [sp, #12] + 8006dec: 9b07 ldr r3, [sp, #28] + 8006dee: d1a7 bne.n 8006d40 + 8006df0: e7d1 b.n 8006d96 + +08006df2 : + +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve) { + 8006df2: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8006df6: ed2d 8b02 vpush {d8} + 8006dfa: b0fb sub sp, #492 ; 0x1ec + 8006dfc: 461c mov r4, r3 + 8006dfe: 9d86 ldr r5, [sp, #536] ; 0x218 + const uECC_word_t *point; + bitcount_t num_bits; + bitcount_t i; + uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006e00: f9b5 3002 ldrsh.w r3, [r5, #2] + wordcount_t num_words = curve->num_words; + 8006e04: f995 8000 ldrsb.w r8, [r5] + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006e08: f113 061f adds.w r6, r3, #31 + 8006e0c: bf48 it mi + 8006e0e: f103 063e addmi.w r6, r3, #62 ; 0x3e + 8006e12: f346 1647 sbfx r6, r6, #5, #8 + + rx[num_n_words - 1] = 0; + 8006e16: f106 3aff add.w sl, r6, #4294967295 ; 0xffffffff + uECC_Curve curve) { + 8006e1a: 4691 mov r9, r2 + rx[num_n_words - 1] = 0; + 8006e1c: aa22 add r2, sp, #136 ; 0x88 + 8006e1e: 2300 movs r3, #0 + 8006e20: f842 302a str.w r3, [r2, sl, lsl #2] + r[num_n_words - 1] = 0; + 8006e24: aa7a add r2, sp, #488 ; 0x1e8 + 8006e26: eb02 028a add.w r2, r2, sl, lsl #2 + uECC_Curve curve) { + 8006e2a: 4607 mov r7, r0 + r[num_n_words - 1] = 0; + 8006e2c: f842 3cc0 str.w r3, [r2, #-192] + s[num_n_words - 1] = 0; + 8006e30: f842 3ca0 str.w r3, [r2, #-160] + uECC_Curve curve) { + 8006e34: ee08 1a90 vmov s17, r1 + + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8006e38: f995 2001 ldrsb.w r2, [r5, #1] + 8006e3c: 4601 mov r1, r0 + 8006e3e: a85a add r0, sp, #360 ; 0x168 + 8006e40: f7fe fd80 bl 8005944 + uECC_vli_bytesToNative( + public + num_words, public_key + curve->num_bytes, curve->num_bytes); + 8006e44: ea4f 0388 mov.w r3, r8, lsl #2 + 8006e48: f995 2001 ldrsb.w r2, [r5, #1] + 8006e4c: 9304 str r3, [sp, #16] + uECC_vli_bytesToNative( + 8006e4e: ab5a add r3, sp, #360 ; 0x168 + 8006e50: eb03 0388 add.w r3, r3, r8, lsl #2 + 8006e54: 4618 mov r0, r3 + 8006e56: 18b9 adds r1, r7, r2 + 8006e58: ee08 3a10 vmov s16, r3 + 8006e5c: f7fe fd72 bl 8005944 + uECC_vli_bytesToNative(r, signature, curve->num_bytes); + 8006e60: 4621 mov r1, r4 + 8006e62: f995 2001 ldrsb.w r2, [r5, #1] + 8006e66: a84a add r0, sp, #296 ; 0x128 + 8006e68: f7fe fd6c bl 8005944 + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes); + 8006e6c: f995 2001 ldrsb.w r2, [r5, #1] + 8006e70: a852 add r0, sp, #328 ; 0x148 + 8006e72: 18a1 adds r1, r4, r2 + 8006e74: f7fe fd66 bl 8005944 + + /* r, s must not be 0. */ + if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) { + 8006e78: 4641 mov r1, r8 + 8006e7a: a84a add r0, sp, #296 ; 0x128 + 8006e7c: f7fe fc14 bl 80056a8 + 8006e80: 2300 movs r3, #0 + 8006e82: 4604 mov r4, r0 + 8006e84: 2800 cmp r0, #0 + 8006e86: f040 812b bne.w 80070e0 + 8006e8a: a852 add r0, sp, #328 ; 0x148 + 8006e8c: f7fe fc0c bl 80056a8 + 8006e90: 9002 str r0, [sp, #8] + 8006e92: 2800 cmp r0, #0 + 8006e94: f040 8126 bne.w 80070e4 + return 0; + } + + /* r, s must be < n. */ + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 8006e98: f105 0b24 add.w fp, r5, #36 ; 0x24 + 8006e9c: 4632 mov r2, r6 + 8006e9e: a94a add r1, sp, #296 ; 0x128 + 8006ea0: 4658 mov r0, fp + 8006ea2: f7fe fc46 bl 8005732 + 8006ea6: 2801 cmp r0, #1 + 8006ea8: f040 811e bne.w 80070e8 + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + 8006eac: 4632 mov r2, r6 + 8006eae: a952 add r1, sp, #328 ; 0x148 + 8006eb0: 4658 mov r0, fp + 8006eb2: f7fe fc3e bl 8005732 + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 8006eb6: 2801 cmp r0, #1 + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + 8006eb8: 9005 str r0, [sp, #20] + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 8006eba: f040 8115 bne.w 80070e8 + return 0; + } + + /* Calculate u1 and u2. */ + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + 8006ebe: ac1a add r4, sp, #104 ; 0x68 + u1[num_n_words - 1] = 0; + 8006ec0: af0a add r7, sp, #40 ; 0x28 + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + 8006ec2: 4633 mov r3, r6 + 8006ec4: 465a mov r2, fp + 8006ec6: 4620 mov r0, r4 + 8006ec8: f7ff f84e bl 8005f68 + u1[num_n_words - 1] = 0; + 8006ecc: 9b02 ldr r3, [sp, #8] + 8006ece: f847 302a str.w r3, [r7, sl, lsl #2] + bits2int(u1, message_hash, hash_size, curve); + 8006ed2: 464a mov r2, r9 + 8006ed4: 4638 mov r0, r7 + 8006ed6: ee18 1a90 vmov r1, s17 + 8006eda: 462b mov r3, r5 + 8006edc: f7fe fddd bl 8005a9a + uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */ + 8006ee0: 4639 mov r1, r7 + 8006ee2: 4638 mov r0, r7 + 8006ee4: 465b mov r3, fp + 8006ee6: 4622 mov r2, r4 + 8006ee8: 9600 str r6, [sp, #0] + 8006eea: f7fe fc44 bl 8005776 + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + + /* Calculate sum = G + Q. */ + uECC_vli_set(sum, public, num_words); + 8006eee: f50d 7ad4 add.w sl, sp, #424 ; 0x1a8 + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + 8006ef2: 465b mov r3, fp + 8006ef4: 4622 mov r2, r4 + 8006ef6: a94a add r1, sp, #296 ; 0x128 + 8006ef8: a812 add r0, sp, #72 ; 0x48 + 8006efa: 9600 str r6, [sp, #0] + 8006efc: f7fe fc3b bl 8005776 + uECC_vli_set(sum, public, num_words); + 8006f00: 4642 mov r2, r8 + 8006f02: 4650 mov r0, sl + 8006f04: a95a add r1, sp, #360 ; 0x168 + 8006f06: f7fe fc08 bl 800571a + uECC_vli_set(sum + num_words, public + num_words, num_words); + 8006f0a: 9b04 ldr r3, [sp, #16] + 8006f0c: eb0a 0903 add.w r9, sl, r3 + 8006f10: ee18 1a10 vmov r1, s16 + 8006f14: 4648 mov r0, r9 + 8006f16: f7fe fc00 bl 800571a + uECC_vli_set(tx, curve->G, num_words); + 8006f1a: f105 0344 add.w r3, r5, #68 ; 0x44 + 8006f1e: 4619 mov r1, r3 + 8006f20: a832 add r0, sp, #200 ; 0xc8 + 8006f22: 9303 str r3, [sp, #12] + 8006f24: f7fe fbf9 bl 800571a + uECC_vli_set(ty, curve->G + num_words, num_words); + 8006f28: e9dd 3103 ldrd r3, r1, [sp, #12] + 8006f2c: a83a add r0, sp, #232 ; 0xe8 + 8006f2e: 1859 adds r1, r3, r1 + 8006f30: f7fe fbf3 bl 800571a + uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */ + 8006f34: 1d2b adds r3, r5, #4 + 8006f36: ee08 3a10 vmov s16, r3 + 8006f3a: 4651 mov r1, sl + 8006f3c: aa32 add r2, sp, #200 ; 0xc8 + 8006f3e: 4620 mov r0, r4 + 8006f40: f7ff f8c0 bl 80060c4 + XYcZ_add(tx, ty, sum, sum + num_words, curve); + 8006f44: 464b mov r3, r9 + 8006f46: 4652 mov r2, sl + 8006f48: a93a add r1, sp, #232 ; 0xe8 + 8006f4a: a832 add r0, sp, #200 ; 0xc8 + 8006f4c: 9500 str r5, [sp, #0] + 8006f4e: f7ff f94d bl 80061ec + uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */ + 8006f52: ee18 2a10 vmov r2, s16 + 8006f56: 4643 mov r3, r8 + 8006f58: 4621 mov r1, r4 + 8006f5a: 4620 mov r0, r4 + 8006f5c: f7ff f804 bl 8005f68 + apply_z(sum, sum + num_words, z, curve); + 8006f60: 462b mov r3, r5 + 8006f62: 4649 mov r1, r9 + 8006f64: 4650 mov r0, sl + 8006f66: 4622 mov r2, r4 + 8006f68: f7fe fcb9 bl 80058de + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + points[0] = 0; + 8006f6c: 9a02 ldr r2, [sp, #8] + 8006f6e: 9206 str r2, [sp, #24] + points[1] = curve->G; + 8006f70: 9a03 ldr r2, [sp, #12] + 8006f72: 9207 str r2, [sp, #28] + points[2] = public; + points[3] = sum; + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 8006f74: 4631 mov r1, r6 + points[2] = public; + 8006f76: aa5a add r2, sp, #360 ; 0x168 + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 8006f78: 4638 mov r0, r7 + points[3] = sum; + 8006f7a: e9cd 2a08 strd r2, sl, [sp, #32] + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 8006f7e: f7fe fbac bl 80056da + 8006f82: 4631 mov r1, r6 + 8006f84: 4682 mov sl, r0 + 8006f86: a812 add r0, sp, #72 ; 0x48 + 8006f88: f7fe fba7 bl 80056da + return (a > b ? a : b); + 8006f8c: 4550 cmp r0, sl + 8006f8e: bfb8 it lt + 8006f90: 4650 movlt r0, sl + uECC_vli_numBits(u2, num_n_words)); + + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8006f92: fa1f f980 uxth.w r9, r0 + 8006f96: f109 31ff add.w r1, r9, #4294967295 ; 0xffffffff + 8006f9a: b209 sxth r1, r1 + 8006f9c: 4638 mov r0, r7 + 8006f9e: 9103 str r1, [sp, #12] + 8006fa0: f7fe fb91 bl 80056c6 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 8006fa4: 9903 ldr r1, [sp, #12] + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8006fa6: 1e07 subs r7, r0, #0 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 8006fa8: a812 add r0, sp, #72 ; 0x48 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8006faa: bf18 it ne + 8006fac: 2701 movne r7, #1 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 8006fae: f7fe fb8a bl 80056c6 + 8006fb2: 2800 cmp r0, #0 + 8006fb4: bf14 ite ne + 8006fb6: 2002 movne r0, #2 + 8006fb8: 2000 moveq r0, #0 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8006fba: ab06 add r3, sp, #24 + 8006fbc: 4307 orrs r7, r0 + uECC_vli_set(rx, point, num_words); + 8006fbe: 4642 mov r2, r8 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8006fc0: f853 1027 ldr.w r1, [r3, r7, lsl #2] + uECC_vli_set(rx, point, num_words); + 8006fc4: a822 add r0, sp, #136 ; 0x88 + 8006fc6: f7fe fba8 bl 800571a + uECC_vli_set(ry, point + num_words, num_words); + 8006fca: 9b04 ldr r3, [sp, #16] + 8006fcc: f10d 0aa8 add.w sl, sp, #168 ; 0xa8 + 8006fd0: 4419 add r1, r3 + 8006fd2: 4650 mov r0, sl + 8006fd4: f7fe fba1 bl 800571a + uECC_vli_clear(z, num_words); + 8006fd8: 4641 mov r1, r8 + 8006fda: 4620 mov r0, r4 + 8006fdc: f7fe fb5e bl 800569c + z[0] = 1; + 8006fe0: 9b05 ldr r3, [sp, #20] + 8006fe2: 6023 str r3, [r4, #0] + + for (i = num_bits - 2; i >= 0; --i) { + 8006fe4: f1a9 0902 sub.w r9, r9, #2 + 8006fe8: ab22 add r3, sp, #136 ; 0x88 + 8006fea: fa0f f989 sxth.w r9, r9 + 8006fee: 9303 str r3, [sp, #12] + 8006ff0: f1b9 0f00 cmp.w r9, #0 + 8006ff4: da26 bge.n 8007044 + XYcZ_add(tx, ty, rx, ry, curve); + uECC_vli_modMult_fast(z, z, tz, curve); + } + } + + uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */ + 8006ff6: ee18 2a10 vmov r2, s16 + 8006ffa: 4643 mov r3, r8 + 8006ffc: 4621 mov r1, r4 + 8006ffe: 4620 mov r0, r4 + 8007000: f7fe ffb2 bl 8005f68 + apply_z(rx, ry, z, curve); + 8007004: 9803 ldr r0, [sp, #12] + 8007006: 462b mov r3, r5 + 8007008: 4622 mov r2, r4 + 800700a: 4651 mov r1, sl + 800700c: f7fe fc67 bl 80058de + + /* v = x1 (mod n) */ + if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) { + 8007010: 9903 ldr r1, [sp, #12] + 8007012: 4632 mov r2, r6 + 8007014: 4658 mov r0, fp + 8007016: f7fe fb8c bl 8005732 + 800701a: 2801 cmp r0, #1 + 800701c: d003 beq.n 8007026 + uECC_vli_sub(rx, rx, curve->n, num_n_words); + 800701e: 465a mov r2, fp + 8007020: 4608 mov r0, r1 + 8007022: f7fe fd13 bl 8005a4c + for (i = num_words - 1; i >= 0; --i) { + 8007026: f108 33ff add.w r3, r8, #4294967295 ; 0xffffffff + 800702a: b25b sxtb r3, r3 + diff |= (left[i] ^ right[i]); + 800702c: a94a add r1, sp, #296 ; 0x128 + for (i = num_words - 1; i >= 0; --i) { + 800702e: 061a lsls r2, r3, #24 + 8007030: d54b bpl.n 80070ca + return (diff == 0); + 8007032: 9b02 ldr r3, [sp, #8] + 8007034: fab3 f083 clz r0, r3 + 8007038: 0940 lsrs r0, r0, #5 + } + + /* Accept only if v == r. */ + return (int)(uECC_vli_equal(rx, r, num_words)); +} + 800703a: b07b add sp, #492 ; 0x1ec + 800703c: ecbd 8b02 vpop {d8} + 8007040: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + curve->double_jacobian(rx, ry, z, curve); + 8007044: 462b mov r3, r5 + 8007046: 4622 mov r2, r4 + 8007048: f8d5 70a4 ldr.w r7, [r5, #164] ; 0xa4 + 800704c: 9803 ldr r0, [sp, #12] + 800704e: 4651 mov r1, sl + 8007050: 47b8 blx r7 + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); + 8007052: 4649 mov r1, r9 + 8007054: a80a add r0, sp, #40 ; 0x28 + 8007056: f7fe fb36 bl 80056c6 + 800705a: 4649 mov r1, r9 + 800705c: 1e07 subs r7, r0, #0 + 800705e: a812 add r0, sp, #72 ; 0x48 + 8007060: bf18 it ne + 8007062: 2701 movne r7, #1 + 8007064: f7fe fb2f bl 80056c6 + 8007068: 2800 cmp r0, #0 + 800706a: bf14 ite ne + 800706c: 2002 movne r0, #2 + 800706e: 2000 moveq r0, #0 + 8007070: 4307 orrs r7, r0 + point = points[index]; + 8007072: ab06 add r3, sp, #24 + 8007074: f853 1027 ldr.w r1, [r3, r7, lsl #2] + if (point) { + 8007078: b311 cbz r1, 80070c0 + uECC_vli_set(tx, point, num_words); + 800707a: 4642 mov r2, r8 + 800707c: a832 add r0, sp, #200 ; 0xc8 + 800707e: f7fe fb4c bl 800571a + uECC_vli_set(ty, point + num_words, num_words); + 8007082: 9b04 ldr r3, [sp, #16] + 8007084: a83a add r0, sp, #232 ; 0xe8 + 8007086: 4419 add r1, r3 + 8007088: f7fe fb47 bl 800571a + apply_z(tx, ty, z, curve); + 800708c: 4601 mov r1, r0 + 800708e: 462b mov r3, r5 + 8007090: 4622 mov r2, r4 + 8007092: a832 add r0, sp, #200 ; 0xc8 + 8007094: f7fe fc23 bl 80058de + uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */ + 8007098: ee18 3a10 vmov r3, s16 + 800709c: 9903 ldr r1, [sp, #12] + 800709e: aa32 add r2, sp, #200 ; 0xc8 + 80070a0: a842 add r0, sp, #264 ; 0x108 + 80070a2: f7ff f80f bl 80060c4 + XYcZ_add(tx, ty, rx, ry, curve); + 80070a6: 9a03 ldr r2, [sp, #12] + 80070a8: 9500 str r5, [sp, #0] + 80070aa: 4653 mov r3, sl + 80070ac: a93a add r1, sp, #232 ; 0xe8 + 80070ae: a832 add r0, sp, #200 ; 0xc8 + 80070b0: f7ff f89c bl 80061ec + uECC_vli_modMult_fast(z, z, tz, curve); + 80070b4: 462b mov r3, r5 + 80070b6: aa42 add r2, sp, #264 ; 0x108 + 80070b8: 4621 mov r1, r4 + 80070ba: 4620 mov r0, r4 + 80070bc: f7fe fbfb bl 80058b6 + for (i = num_bits - 2; i >= 0; --i) { + 80070c0: f109 39ff add.w r9, r9, #4294967295 ; 0xffffffff + 80070c4: fa0f f989 sxth.w r9, r9 + 80070c8: e792 b.n 8006ff0 + diff |= (left[i] ^ right[i]); + 80070ca: 9a03 ldr r2, [sp, #12] + 80070cc: f851 0023 ldr.w r0, [r1, r3, lsl #2] + 80070d0: f852 2023 ldr.w r2, [r2, r3, lsl #2] + 80070d4: 4042 eors r2, r0 + 80070d6: 9802 ldr r0, [sp, #8] + 80070d8: 4310 orrs r0, r2 + 80070da: 9002 str r0, [sp, #8] + for (i = num_words - 1; i >= 0; --i) { + 80070dc: 3b01 subs r3, #1 + 80070de: e7a6 b.n 800702e + return 0; + 80070e0: 4618 mov r0, r3 + 80070e2: e7aa b.n 800703a + 80070e4: 4620 mov r0, r4 + 80070e6: e7a8 b.n 800703a + 80070e8: 9802 ldr r0, [sp, #8] + 80070ea: e7a6 b.n 800703a + +080070ec : +const uint32_t MSIRangeTable[12] = {100000, 200000, 400000, 800000, 1000000, 2000000, \ + 4000000, 8000000, 16000000, 24000000, 32000000, 48000000}; +uint32_t SystemCoreClock; + +// TODO: cleanup HAL stuff to not use this +uint32_t HAL_GetTick(void) { return 53; } + 80070ec: 2035 movs r0, #53 ; 0x35 + 80070ee: 4770 bx lr + +080070f0 : +uint32_t uwTickPrio = 0; /* (1UL << __NVIC_PRIO_BITS); * Invalid priority */ + +// unwanted junk from stm32l4xx_hal_rcc.c +HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) { return 0; } + 80070f0: 2000 movs r0, #0 + 80070f2: 4770 bx lr + +080070f4 : + * or PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when applicable) + */ +uint32_t HAL_PWREx_GetVoltageRange(void) +{ +#if defined(PWR_CR5_R1MODE) + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 80070f4: 4b07 ldr r3, [pc, #28] ; (8007114 ) + 80070f6: 6818 ldr r0, [r3, #0] + 80070f8: f400 60c0 and.w r0, r0, #1536 ; 0x600 + 80070fc: f5b0 6f80 cmp.w r0, #1024 ; 0x400 + 8007100: d006 beq.n 8007110 + { + return PWR_REGULATOR_VOLTAGE_SCALE2; + } + else if (READ_BIT(PWR->CR5, PWR_CR5_R1MODE) == PWR_CR5_R1MODE) + 8007102: f8d3 0080 ldr.w r0, [r3, #128] ; 0x80 + { + /* PWR_CR5_R1MODE bit set means that Range 1 Boost is disabled */ + return PWR_REGULATOR_VOLTAGE_SCALE1; + 8007106: f410 7080 ands.w r0, r0, #256 ; 0x100 + 800710a: bf18 it ne + 800710c: f44f 7000 movne.w r0, #512 ; 0x200 + return PWR_REGULATOR_VOLTAGE_SCALE1_BOOST; + } +#else + return (PWR->CR1 & PWR_CR1_VOS); +#endif +} + 8007110: 4770 bx lr + 8007112: bf00 nop + 8007114: 40007000 .word 0x40007000 + +08007118 : + uint32_t wait_loop_index; + + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling)); + +#if defined(PWR_CR5_R1MODE) + if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) + 8007118: 4b29 ldr r3, [pc, #164] ; (80071c0 ) + { + /* If current range is range 2 */ + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 800711a: 681a ldr r2, [r3, #0] + if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) + 800711c: bb30 cbnz r0, 800716c + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 800711e: f402 62c0 and.w r2, r2, #1536 ; 0x600 + 8007122: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + { + /* Make sure Range 1 Boost is enabled */ + CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); + 8007126: f8d3 2080 ldr.w r2, [r3, #128] ; 0x80 + 800712a: f422 7280 bic.w r2, r2, #256 ; 0x100 + 800712e: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007132: d11a bne.n 800716a + + /* Set Range 1 */ + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1); + 8007134: 681a ldr r2, [r3, #0] + 8007136: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 800713a: f442 7200 orr.w r2, r2, #512 ; 0x200 + 800713e: 601a str r2, [r3, #0] + + /* Wait until VOSF is cleared */ + wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1; + 8007140: 4a20 ldr r2, [pc, #128] ; (80071c4 ) + 8007142: 6812 ldr r2, [r2, #0] + 8007144: 2132 movs r1, #50 ; 0x32 + 8007146: 434a muls r2, r1 + 8007148: 491f ldr r1, [pc, #124] ; (80071c8 ) + 800714a: fbb2 f2f1 udiv r2, r2, r1 + 800714e: 3201 adds r2, #1 + while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U)) + 8007150: 6959 ldr r1, [r3, #20] + 8007152: 0549 lsls r1, r1, #21 + 8007154: d500 bpl.n 8007158 + 8007156: b922 cbnz r2, 8007162 + { + wait_loop_index--; + } + if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) + 8007158: 695b ldr r3, [r3, #20] + 800715a: 0558 lsls r0, r3, #21 + 800715c: d403 bmi.n 8007166 + /* No need to wait for VOSF to be cleared for this transition */ + } + } +#endif + + return HAL_OK; + 800715e: 2000 movs r0, #0 +} + 8007160: 4770 bx lr + wait_loop_index--; + 8007162: 3a01 subs r2, #1 + 8007164: e7f4 b.n 8007150 + return HAL_TIMEOUT; + 8007166: 2003 movs r0, #3 + 8007168: 4770 bx lr + CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); + 800716a: 4770 bx lr + else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1) + 800716c: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8007170: d11f bne.n 80071b2 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007172: f402 62c0 and.w r2, r2, #1536 ; 0x600 + 8007176: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + SET_BIT(PWR->CR5, PWR_CR5_R1MODE); + 800717a: f8d3 2080 ldr.w r2, [r3, #128] ; 0x80 + 800717e: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8007182: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007186: d1ea bne.n 800715e + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1); + 8007188: 681a ldr r2, [r3, #0] + 800718a: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 800718e: f442 7200 orr.w r2, r2, #512 ; 0x200 + 8007192: 601a str r2, [r3, #0] + wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1; + 8007194: 4a0b ldr r2, [pc, #44] ; (80071c4 ) + 8007196: 6812 ldr r2, [r2, #0] + 8007198: 2132 movs r1, #50 ; 0x32 + 800719a: 434a muls r2, r1 + 800719c: 490a ldr r1, [pc, #40] ; (80071c8 ) + 800719e: fbb2 f2f1 udiv r2, r2, r1 + 80071a2: 3201 adds r2, #1 + while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U)) + 80071a4: 6959 ldr r1, [r3, #20] + 80071a6: 0549 lsls r1, r1, #21 + 80071a8: d5d6 bpl.n 8007158 + 80071aa: 2a00 cmp r2, #0 + 80071ac: d0d4 beq.n 8007158 + wait_loop_index--; + 80071ae: 3a01 subs r2, #1 + 80071b0: e7f8 b.n 80071a4 + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2); + 80071b2: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 80071b6: f442 6280 orr.w r2, r2, #1024 ; 0x400 + 80071ba: 601a str r2, [r3, #0] + 80071bc: e7cf b.n 800715e + 80071be: bf00 nop + 80071c0: 40007000 .word 0x40007000 + 80071c4: 2009e2a8 .word 0x2009e2a8 + 80071c8: 000f4240 .word 0x000f4240 + +080071cc : + +__weak void HAL_SDEx_DriveTransceiver_1_8V_Callback(FlagStatus status) +{ + // unused? +} + 80071cc: 4770 bx lr + ... + +080071d0 <__NVIC_SystemReset>: + 80071d0: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80071d4: 4905 ldr r1, [pc, #20] ; (80071ec <__NVIC_SystemReset+0x1c>) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80071d6: 4b06 ldr r3, [pc, #24] ; (80071f0 <__NVIC_SystemReset+0x20>) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80071d8: 68ca ldr r2, [r1, #12] + 80071da: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80071de: 4313 orrs r3, r2 + 80071e0: 60cb str r3, [r1, #12] + 80071e2: f3bf 8f4f dsb sy + __NOP(); + 80071e6: bf00 nop + for(;;) /* wait until reset */ + 80071e8: e7fd b.n 80071e6 <__NVIC_SystemReset+0x16> + 80071ea: bf00 nop + 80071ec: e000ed00 .word 0xe000ed00 + 80071f0: 05fa0004 .word 0x05fa0004 + +080071f4 : +{ + 80071f4: b510 push {r4, lr} + 80071f6: 3801 subs r0, #1 + 80071f8: 440a add r2, r1 + *(acc) ^= *(more); + 80071fa: f811 4b01 ldrb.w r4, [r1], #1 + 80071fe: f810 3f01 ldrb.w r3, [r0, #1]! + for(; len; len--, more++, acc++) { + 8007202: 4291 cmp r1, r2 + *(acc) ^= *(more); + 8007204: ea83 0304 eor.w r3, r3, r4 + 8007208: 7003 strb r3, [r0, #0] + for(; len; len--, more++, acc++) { + 800720a: d1f6 bne.n 80071fa + } +} + 800720c: bd10 pop {r4, pc} + ... + +08007210 : + +// se2_write1() +// + static bool +se2_write1(uint8_t cmd, uint8_t arg) +{ + 8007210: b51f push {r0, r1, r2, r3, r4, lr} + uint8_t data[3] = { cmd, 1, arg }; + 8007212: 2301 movs r3, #1 + 8007214: f88d 300d strb.w r3, [sp, #13] + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 8007218: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + uint8_t data[3] = { cmd, 1, arg }; + 800721c: f88d 000c strb.w r0, [sp, #12] + 8007220: f88d 100e strb.w r1, [sp, #14] + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 8007224: 9300 str r3, [sp, #0] + 8007226: aa03 add r2, sp, #12 + 8007228: 2303 movs r3, #3 + 800722a: 2136 movs r1, #54 ; 0x36 + 800722c: 4804 ldr r0, [pc, #16] ; (8007240 ) + 800722e: f004 fb7f bl 800b930 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 8007232: 3800 subs r0, #0 + 8007234: bf18 it ne + 8007236: 2001 movne r0, #1 + 8007238: b005 add sp, #20 + 800723a: f85d fb04 ldr.w pc, [sp], #4 + 800723e: bf00 nop + 8007240: 2009e3ec .word 0x2009e3ec + +08007244 : + +// se2_write2() +// + static bool +se2_write2(uint8_t cmd, uint8_t arg1, uint8_t arg2) +{ + 8007244: b51f push {r0, r1, r2, r3, r4, lr} + uint8_t data[4] = { cmd, 2, arg1, arg2 }; + 8007246: 2302 movs r3, #2 + 8007248: f88d 300d strb.w r3, [sp, #13] + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 800724c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + uint8_t data[4] = { cmd, 2, arg1, arg2 }; + 8007250: f88d 000c strb.w r0, [sp, #12] + 8007254: f88d 100e strb.w r1, [sp, #14] + 8007258: f88d 200f strb.w r2, [sp, #15] + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 800725c: 9300 str r3, [sp, #0] + 800725e: aa03 add r2, sp, #12 + 8007260: 2304 movs r3, #4 + 8007262: 2136 movs r1, #54 ; 0x36 + 8007264: 4804 ldr r0, [pc, #16] ; (8007278 ) + 8007266: f004 fb63 bl 800b930 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 800726a: 3800 subs r0, #0 + 800726c: bf18 it ne + 800726e: 2001 movne r0, #1 + 8007270: b005 add sp, #20 + 8007272: f85d fb04 ldr.w pc, [sp], #4 + 8007276: bf00 nop + 8007278: 2009e3ec .word 0x2009e3ec + +0800727c : + +// se2_write_n() +// + static bool +se2_write_n(uint8_t cmd, uint8_t *param1, const uint8_t *data_in, uint8_t len) +{ + 800727c: b5f0 push {r4, r5, r6, r7, lr} + 800727e: 460d mov r5, r1 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007280: 2d00 cmp r5, #0 + 8007282: bf14 ite ne + 8007284: 2403 movne r4, #3 + 8007286: 2402 moveq r4, #2 + 8007288: 441c add r4, r3 +{ + 800728a: 4611 mov r1, r2 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 800728c: f104 0207 add.w r2, r4, #7 +{ + 8007290: b083 sub sp, #12 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007292: f402 727e and.w r2, r2, #1016 ; 0x3f8 +{ + 8007296: af02 add r7, sp, #8 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007298: ebad 0d02 sub.w sp, sp, r2 + 800729c: ae02 add r6, sp, #8 + + *(p++) = cmd; + *(p++) = sizeof(data) - 2; + 800729e: f1a4 0202 sub.w r2, r4, #2 + *(p++) = cmd; + 80072a2: f88d 0008 strb.w r0, [sp, #8] + *(p++) = sizeof(data) - 2; + 80072a6: 7072 strb r2, [r6, #1] + if(param1) { + *(p++) = *param1; + 80072a8: bf1b ittet ne + 80072aa: 782a ldrbne r2, [r5, #0] + 80072ac: 70b2 strbne r2, [r6, #2] + *(p++) = sizeof(data) - 2; + 80072ae: f10d 000a addeq.w r0, sp, #10 + *(p++) = *param1; + 80072b2: f10d 000b addne.w r0, sp, #11 + } + if(len) { + 80072b6: b113 cbz r3, 80072be + memcpy(p, data_in, len); + 80072b8: 461a mov r2, r3 + 80072ba: f006 f9b3 bl 800d624 + } + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 80072be: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 80072c2: 9300 str r3, [sp, #0] + 80072c4: 4632 mov r2, r6 + 80072c6: 4623 mov r3, r4 + 80072c8: 2136 movs r1, #54 ; 0x36 + 80072ca: 4804 ldr r0, [pc, #16] ; (80072dc ) + 80072cc: f004 fb30 bl 800b930 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 80072d0: 3800 subs r0, #0 + 80072d2: bf18 it ne + 80072d4: 2001 movne r0, #1 + 80072d6: 3704 adds r7, #4 + 80072d8: 46bd mov sp, r7 + 80072da: bdf0 pop {r4, r5, r6, r7, pc} + 80072dc: 2009e3ec .word 0x2009e3ec + +080072e0 : + +// rng_for_uECC() +// + static int +rng_for_uECC(uint8_t *dest, unsigned size) +{ + 80072e0: b508 push {r3, lr} + 'dest' was filled with random data, or 0 if the random data could not be generated. + The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + + typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + */ + rng_buffer(dest, size); + 80072e2: f7fb fa35 bl 8002750 + + return 1; +} + 80072e6: 2001 movs r0, #1 + 80072e8: bd08 pop {r3, pc} + ... + +080072ec : +{ + 80072ec: b508 push {r3, lr} + 80072ee: 4602 mov r2, r0 + CALL_CHECK(se2_write_n(0x87, NULL, data, len)); + 80072f0: b2cb uxtb r3, r1 + 80072f2: 2087 movs r0, #135 ; 0x87 + 80072f4: 2100 movs r1, #0 + 80072f6: f7ff ffc1 bl 800727c + 80072fa: b118 cbz r0, 8007304 + 80072fc: 4802 ldr r0, [pc, #8] ; (8007308 ) + 80072fe: 21c1 movs r1, #193 ; 0xc1 + 8007300: f006 f9c6 bl 800d690 +} + 8007304: bd08 pop {r3, pc} + 8007306: bf00 nop + 8007308: 2009e390 .word 0x2009e390 + +0800730c : +{ + 800730c: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + HAL_StatusTypeDef rv = HAL_I2C_Master_Receive(&i2c_port, I2C_ADDR, rx, len, HAL_MAX_DELAY); + 8007310: f8df 9044 ldr.w r9, [pc, #68] ; 8007358 +{ + 8007314: 4604 mov r4, r0 + 8007316: 460d mov r5, r1 + 8007318: f44f 7696 mov.w r6, #300 ; 0x12c + HAL_StatusTypeDef rv = HAL_I2C_Master_Receive(&i2c_port, I2C_ADDR, rx, len, HAL_MAX_DELAY); + 800731c: b287 uxth r7, r0 + 800731e: f04f 38ff mov.w r8, #4294967295 ; 0xffffffff + 8007322: f8cd 8000 str.w r8, [sp] + 8007326: 463b mov r3, r7 + 8007328: 462a mov r2, r5 + 800732a: 2136 movs r1, #54 ; 0x36 + 800732c: 4648 mov r0, r9 + 800732e: f004 fbb3 bl 800ba98 + if(rv == HAL_OK) { + 8007332: b938 cbnz r0, 8007344 + if(rx[0] != len-1) { + 8007334: 782b ldrb r3, [r5, #0] + 8007336: 3c01 subs r4, #1 + 8007338: 42a3 cmp r3, r4 + 800733a: d10a bne.n 8007352 + return rx[1]; + 800733c: 7868 ldrb r0, [r5, #1] +} + 800733e: b003 add sp, #12 + 8007340: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + delay_ms(1); + 8007344: 2001 movs r0, #1 + 8007346: f7fc fad7 bl 80038f8 + for(int tries=0; tries<300; tries++) { + 800734a: 3e01 subs r6, #1 + 800734c: d1e9 bne.n 8007322 + return RC_NO_ACK; + 800734e: 200f movs r0, #15 + 8007350: e7f5 b.n 800733e + return RC_WRONG_SIZE; + 8007352: 201f movs r0, #31 + 8007354: e7f3 b.n 800733e + 8007356: bf00 nop + 8007358: 2009e3ec .word 0x2009e3ec + +0800735c : +{ + 800735c: b507 push {r0, r1, r2, lr} + return se2_read_n(2, rx); + 800735e: 2002 movs r0, #2 + 8007360: a901 add r1, sp, #4 + 8007362: f7ff ffd3 bl 800730c +} + 8007366: b003 add sp, #12 + 8007368: f85d fb04 ldr.w pc, [sp], #4 + +0800736c : +{ + 800736c: b507 push {r0, r1, r2, lr} + CALL_CHECK(se2_write_n(0x96, &page_num, data, 32)); + 800736e: 2320 movs r3, #32 +{ + 8007370: 460a mov r2, r1 + 8007372: f88d 0007 strb.w r0, [sp, #7] + CALL_CHECK(se2_write_n(0x96, &page_num, data, 32)); + 8007376: f10d 0107 add.w r1, sp, #7 + 800737a: 2096 movs r0, #150 ; 0x96 + 800737c: f7ff ff7e bl 800727c + 8007380: b118 cbz r0, 800738a + 8007382: 21cb movs r1, #203 ; 0xcb + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007384: 4805 ldr r0, [pc, #20] ; (800739c ) + 8007386: f006 f983 bl 800d690 + 800738a: f7ff ffe7 bl 800735c + 800738e: 28aa cmp r0, #170 ; 0xaa + 8007390: d001 beq.n 8007396 + 8007392: 21cd movs r1, #205 ; 0xcd + 8007394: e7f6 b.n 8007384 +} + 8007396: b003 add sp, #12 + 8007398: f85d fb04 ldr.w pc, [sp], #4 + 800739c: 2009e390 .word 0x2009e390 + +080073a0 : + ASSERT(pubkey_num < 2); + 80073a0: 2801 cmp r0, #1 +{ + 80073a2: b508 push {r3, lr} + ASSERT(pubkey_num < 2); + 80073a4: d902 bls.n 80073ac + 80073a6: 480a ldr r0, [pc, #40] ; (80073d0 ) + 80073a8: f7f9 fb4e bl 8000a48 + CALL_CHECK(se2_write1(0xcb, (wpe <<6) | pubkey_num)); + 80073ac: ea40 1181 orr.w r1, r0, r1, lsl #6 + 80073b0: b2c9 uxtb r1, r1 + 80073b2: 20cb movs r0, #203 ; 0xcb + 80073b4: f7ff ff2c bl 8007210 + 80073b8: b118 cbz r0, 80073c2 + 80073ba: 21d9 movs r1, #217 ; 0xd9 + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 80073bc: 4805 ldr r0, [pc, #20] ; (80073d4 ) + 80073be: f006 f967 bl 800d690 + 80073c2: f7ff ffcb bl 800735c + 80073c6: 28aa cmp r0, #170 ; 0xaa + 80073c8: d001 beq.n 80073ce + 80073ca: 21db movs r1, #219 ; 0xdb + 80073cc: e7f6 b.n 80073bc +} + 80073ce: bd08 pop {r3, pc} + 80073d0: 0800e3e0 .word 0x0800e3e0 + 80073d4: 2009e390 .word 0x2009e390 + +080073d8 : +{ + 80073d8: b570 push {r4, r5, r6, lr} + 80073da: b0dc sub sp, #368 ; 0x170 + 80073dc: 460d mov r5, r1 + 80073de: f88d 0007 strb.w r0, [sp, #7] + rng_buffer(chal, sizeof(chal)); + 80073e2: 2120 movs r1, #32 + 80073e4: a802 add r0, sp, #8 +{ + 80073e6: 4616 mov r6, r2 + 80073e8: 461c mov r4, r3 + rng_buffer(chal, sizeof(chal)); + 80073ea: f7fb f9b1 bl 8002750 + se2_write_buffer(chal, sizeof(chal)); + 80073ee: 2120 movs r1, #32 + 80073f0: a802 add r0, sp, #8 + 80073f2: f7ff ff7b bl 80072ec + CALL_CHECK(se2_write1(0xa5, (keynum<<5) | page_num)); + 80073f6: f89d 3007 ldrb.w r3, [sp, #7] + 80073fa: ea43 1146 orr.w r1, r3, r6, lsl #5 + 80073fe: b2c9 uxtb r1, r1 + 8007400: 20a5 movs r0, #165 ; 0xa5 + 8007402: f7ff ff05 bl 8007210 + 8007406: b118 cbz r0, 8007410 + 8007408: 21eb movs r1, #235 ; 0xeb + CHECK_RIGHT(se2_read_n(sizeof(check), check) == RC_SUCCESS); + 800740a: 481e ldr r0, [pc, #120] ; (8007484 ) + 800740c: f006 f940 bl 800d690 + 8007410: a912 add r1, sp, #72 ; 0x48 + 8007412: 2022 movs r0, #34 ; 0x22 + 8007414: f7ff ff7a bl 800730c + 8007418: 28aa cmp r0, #170 ; 0xaa + 800741a: d001 beq.n 8007420 + 800741c: 21ee movs r1, #238 ; 0xee + 800741e: e7f4 b.n 800740a + hmac_sha256_init(&ctx); + 8007420: a81b add r0, sp, #108 ; 0x6c + 8007422: f7fe f8bb bl 800559c + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 8007426: 4b18 ldr r3, [pc, #96] ; (8007488 ) + 8007428: 4918 ldr r1, [pc, #96] ; (800748c ) + 800742a: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 800742e: 33b0 adds r3, #176 ; 0xb0 + 8007430: 2aff cmp r2, #255 ; 0xff + 8007432: bf18 it ne + 8007434: 4619 movne r1, r3 + 8007436: a81b add r0, sp, #108 ; 0x6c + 8007438: 2208 movs r2, #8 + 800743a: 3160 adds r1, #96 ; 0x60 + 800743c: f7fe f8b4 bl 80055a8 + hmac_sha256_update(&ctx, data, 32); + 8007440: 4629 mov r1, r5 + 8007442: a81b add r0, sp, #108 ; 0x6c + 8007444: 2220 movs r2, #32 + 8007446: f7fe f8af bl 80055a8 + hmac_sha256_update(&ctx, chal, 32); + 800744a: a902 add r1, sp, #8 + 800744c: a81b add r0, sp, #108 ; 0x6c + 800744e: 2220 movs r2, #32 + 8007450: f7fe f8aa bl 80055a8 + hmac_sha256_update(&ctx, &page_num, 1); + 8007454: f10d 0107 add.w r1, sp, #7 + 8007458: a81b add r0, sp, #108 ; 0x6c + 800745a: 2201 movs r2, #1 + 800745c: f7fe f8a4 bl 80055a8 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 8007460: a81b add r0, sp, #108 ; 0x6c + 8007462: 490b ldr r1, [pc, #44] ; (8007490 ) + 8007464: 2202 movs r2, #2 + 8007466: f7fe f89f bl 80055a8 + hmac_sha256_final(&ctx, secret, expect); + 800746a: aa0a add r2, sp, #40 ; 0x28 + 800746c: 4621 mov r1, r4 + 800746e: a81b add r0, sp, #108 ; 0x6c + 8007470: f7fe f8b0 bl 80055d4 + return check_equal(expect, check+2, 32); + 8007474: 2220 movs r2, #32 + 8007476: f10d 014a add.w r1, sp, #74 ; 0x4a + 800747a: a80a add r0, sp, #40 ; 0x28 + 800747c: f7fb f919 bl 80026b2 +} + 8007480: b05c add sp, #368 ; 0x170 + 8007482: bd70 pop {r4, r5, r6, pc} + 8007484: 2009e390 .word 0x2009e390 + 8007488: 0801c000 .word 0x0801c000 + 800748c: 2009e2b0 .word 0x2009e2b0 + 8007490: 0800ea44 .word 0x0800ea44 + +08007494 : +{ + 8007494: b570 push {r4, r5, r6, lr} + 8007496: 4604 mov r4, r0 + 8007498: b08a sub sp, #40 ; 0x28 + 800749a: 460d mov r5, r1 + CALL_CHECK(se2_write1(0x69, page_num)); + 800749c: 4601 mov r1, r0 + 800749e: 2069 movs r0, #105 ; 0x69 +{ + 80074a0: 4616 mov r6, r2 + CALL_CHECK(se2_write1(0x69, page_num)); + 80074a2: f7ff feb5 bl 8007210 + 80074a6: b120 cbz r0, 80074b2 + 80074a8: f44f 7185 mov.w r1, #266 ; 0x10a + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 80074ac: 481c ldr r0, [pc, #112] ; (8007520 ) + 80074ae: f006 f8ef bl 800d690 + 80074b2: a901 add r1, sp, #4 + 80074b4: 2022 movs r0, #34 ; 0x22 + 80074b6: f7ff ff29 bl 800730c + 80074ba: 28aa cmp r0, #170 ; 0xaa + 80074bc: d002 beq.n 80074c4 + 80074be: f240 110d movw r1, #269 ; 0x10d + 80074c2: e7f3 b.n 80074ac + CHECK_RIGHT(rx[0] == 33); + 80074c4: f89d 3004 ldrb.w r3, [sp, #4] + 80074c8: 2b21 cmp r3, #33 ; 0x21 + 80074ca: d002 beq.n 80074d2 + 80074cc: f240 110f movw r1, #271 ; 0x10f + 80074d0: e7ec b.n 80074ac + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 80074d2: f89d 3005 ldrb.w r3, [sp, #5] + 80074d6: 2baa cmp r3, #170 ; 0xaa + 80074d8: d002 beq.n 80074e0 + 80074da: f44f 7188 mov.w r1, #272 ; 0x110 + 80074de: e7e5 b.n 80074ac + memcpy(data, rx+2, 32); + 80074e0: f10d 0306 add.w r3, sp, #6 + 80074e4: 462a mov r2, r5 + 80074e6: f10d 0126 add.w r1, sp, #38 ; 0x26 + 80074ea: f853 0b04 ldr.w r0, [r3], #4 + 80074ee: f842 0b04 str.w r0, [r2], #4 + 80074f2: 428b cmp r3, r1 + 80074f4: d1f9 bne.n 80074ea + if(!verify) return; + 80074f6: b186 cbz r6, 800751a + CHECK_RIGHT(se2_verify_page(page_num, data, 0, SE2_SECRETS->pairing)); + 80074f8: 4b0a ldr r3, [pc, #40] ; (8007524 ) + 80074fa: 4a0b ldr r2, [pc, #44] ; (8007528 ) + 80074fc: f893 10b0 ldrb.w r1, [r3, #176] ; 0xb0 + 8007500: 4b0a ldr r3, [pc, #40] ; (800752c ) + 8007502: 4620 mov r0, r4 + 8007504: 29ff cmp r1, #255 ; 0xff + 8007506: bf18 it ne + 8007508: 4613 movne r3, r2 + 800750a: 2200 movs r2, #0 + 800750c: 4629 mov r1, r5 + 800750e: f7ff ff63 bl 80073d8 + 8007512: b910 cbnz r0, 800751a + 8007514: f44f 718b mov.w r1, #278 ; 0x116 + 8007518: e7c8 b.n 80074ac +} + 800751a: b00a add sp, #40 ; 0x28 + 800751c: bd70 pop {r4, r5, r6, pc} + 800751e: bf00 nop + 8007520: 2009e390 .word 0x2009e390 + 8007524: 0801c000 .word 0x0801c000 + 8007528: 0801c0b0 .word 0x0801c0b0 + 800752c: 2009e2b0 .word 0x2009e2b0 + +08007530 : +{ + 8007530: b570 push {r4, r5, r6, lr} + 8007532: b0d6 sub sp, #344 ; 0x158 + 8007534: 461e mov r6, r3 + ASSERT((keynum == 0) || (keynum == 2)); + 8007536: f032 0302 bics.w r3, r2, #2 +{ + 800753a: 460c mov r4, r1 + 800753c: 4615 mov r5, r2 + 800753e: f88d 0007 strb.w r0, [sp, #7] + ASSERT((keynum == 0) || (keynum == 2)); + 8007542: d002 beq.n 800754a + 8007544: 4831 ldr r0, [pc, #196] ; (800760c ) + 8007546: f7f9 fa7f bl 8000a48 + CALL_CHECK(se2_write1(0x4b, (keynum << 6) | page_num)); + 800754a: f89d 1007 ldrb.w r1, [sp, #7] + 800754e: ea41 1182 orr.w r1, r1, r2, lsl #6 + 8007552: b2c9 uxtb r1, r1 + 8007554: 204b movs r0, #75 ; 0x4b + 8007556: f7ff fe5b bl 8007210 + 800755a: b120 cbz r0, 8007566 + 800755c: f44f 71b3 mov.w r1, #358 ; 0x166 + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 8007560: 482b ldr r0, [pc, #172] ; (8007610 ) + 8007562: f006 f895 bl 800d690 + 8007566: a90a add r1, sp, #40 ; 0x28 + 8007568: 202a movs r0, #42 ; 0x2a + 800756a: f7ff fecf bl 800730c + 800756e: 28aa cmp r0, #170 ; 0xaa + 8007570: d002 beq.n 8007578 + 8007572: f240 1169 movw r1, #361 ; 0x169 + 8007576: e7f3 b.n 8007560 + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 8007578: f89d 3029 ldrb.w r3, [sp, #41] ; 0x29 + 800757c: 2baa cmp r3, #170 ; 0xaa + 800757e: d002 beq.n 8007586 + 8007580: f240 116b movw r1, #363 ; 0x16b + 8007584: e7ec b.n 8007560 + memcpy(data, rx+2+8, 32); + 8007586: f10d 0332 add.w r3, sp, #50 ; 0x32 + 800758a: 4622 mov r2, r4 + 800758c: f10d 0152 add.w r1, sp, #82 ; 0x52 + 8007590: f853 0b04 ldr.w r0, [r3], #4 + 8007594: f842 0b04 str.w r0, [r2], #4 + 8007598: 428b cmp r3, r1 + 800759a: d1f9 bne.n 8007590 + hmac_sha256_init(&ctx); + 800759c: a815 add r0, sp, #84 ; 0x54 + 800759e: f7fd fffd bl 800559c + hmac_sha256_update(&ctx, chal, 8); + 80075a2: 2208 movs r2, #8 + 80075a4: f10d 012a add.w r1, sp, #42 ; 0x2a + 80075a8: a815 add r0, sp, #84 ; 0x54 + 80075aa: f7fd fffd bl 80055a8 + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 80075ae: 4b19 ldr r3, [pc, #100] ; (8007614 ) + 80075b0: 4919 ldr r1, [pc, #100] ; (8007618 ) + 80075b2: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80075b6: 33b0 adds r3, #176 ; 0xb0 + 80075b8: 2aff cmp r2, #255 ; 0xff + 80075ba: bf18 it ne + 80075bc: 4619 movne r1, r3 + 80075be: 3160 adds r1, #96 ; 0x60 + 80075c0: 2208 movs r2, #8 + 80075c2: a815 add r0, sp, #84 ; 0x54 + 80075c4: f7fd fff0 bl 80055a8 + hmac_sha256_update(&ctx, &page_num, 1); + 80075c8: 2201 movs r2, #1 + 80075ca: f10d 0107 add.w r1, sp, #7 + 80075ce: a815 add r0, sp, #84 ; 0x54 + 80075d0: f7fd ffea bl 80055a8 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 80075d4: 4911 ldr r1, [pc, #68] ; (800761c ) + 80075d6: 2202 movs r2, #2 + 80075d8: a815 add r0, sp, #84 ; 0x54 + 80075da: f7fd ffe5 bl 80055a8 + hmac_sha256_final(&ctx, secret, otp); + 80075de: aa02 add r2, sp, #8 + 80075e0: 4631 mov r1, r6 + 80075e2: a815 add r0, sp, #84 ; 0x54 + 80075e4: f7fd fff6 bl 80055d4 + xor_mixin(data, otp, 32); + 80075e8: 2220 movs r2, #32 + 80075ea: a902 add r1, sp, #8 + 80075ec: 4620 mov r0, r4 + 80075ee: f7ff fe01 bl 80071f4 + CHECK_RIGHT(se2_verify_page(page_num, data, keynum, secret)); + 80075f2: f89d 0007 ldrb.w r0, [sp, #7] + 80075f6: 4633 mov r3, r6 + 80075f8: 462a mov r2, r5 + 80075fa: 4621 mov r1, r4 + 80075fc: f7ff feec bl 80073d8 + 8007600: b910 cbnz r0, 8007608 + 8007602: f44f 71c0 mov.w r1, #384 ; 0x180 + 8007606: e7ab b.n 8007560 +} + 8007608: b056 add sp, #344 ; 0x158 + 800760a: bd70 pop {r4, r5, r6, pc} + 800760c: 0800e3e0 .word 0x0800e3e0 + 8007610: 2009e390 .word 0x2009e390 + 8007614: 0801c000 .word 0x0801c000 + 8007618: 2009e2b0 .word 0x2009e2b0 + 800761c: 0800ea44 .word 0x0800ea44 + +08007620 : +{ + 8007620: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8007624: 460e mov r6, r1 + ASSERT((keynum == 0) || (keynum == 2)); + 8007626: f032 0102 bics.w r1, r2, #2 +{ + 800762a: b0e4 sub sp, #400 ; 0x190 + 800762c: 4604 mov r4, r0 + 800762e: 4617 mov r7, r2 + 8007630: 4698 mov r8, r3 + ASSERT((keynum == 0) || (keynum == 2)); + 8007632: d002 beq.n 800763a + 8007634: 4849 ldr r0, [pc, #292] ; (800775c ) + 8007636: f7f9 fa07 bl 8000a48 + se2_read_encrypted(page_num, old_data, keynum, secret); + 800763a: a901 add r1, sp, #4 + 800763c: f7ff ff78 bl 8007530 + uint8_t PGDV = page_num | 0x80; + 8007640: f064 037f orn r3, r4, #127 ; 0x7f + rng_buffer(&chal_check[32], 8); + 8007644: 2108 movs r1, #8 + 8007646: a821 add r0, sp, #132 ; 0x84 + uint8_t PGDV = page_num | 0x80; + 8007648: f88d 3002 strb.w r3, [sp, #2] + rng_buffer(&chal_check[32], 8); + 800764c: f7fb f880 bl 8002750 + hmac_sha256_init(&ctx); + 8007650: a823 add r0, sp, #140 ; 0x8c + 8007652: f7fd ffa3 bl 800559c + hmac_sha256_update(&ctx, &chal_check[32], 8); + 8007656: 2208 movs r2, #8 + 8007658: a921 add r1, sp, #132 ; 0x84 + 800765a: a823 add r0, sp, #140 ; 0x8c + 800765c: f7fd ffa4 bl 80055a8 + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 8007660: 4b3f ldr r3, [pc, #252] ; (8007760 ) + 8007662: 4940 ldr r1, [pc, #256] ; (8007764 ) + 8007664: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 8007668: 33b0 adds r3, #176 ; 0xb0 + 800766a: 2aff cmp r2, #255 ; 0xff + 800766c: bf18 it ne + 800766e: 4619 movne r1, r3 + 8007670: 3160 adds r1, #96 ; 0x60 + 8007672: 2208 movs r2, #8 + 8007674: a823 add r0, sp, #140 ; 0x8c + 8007676: f7fd ff97 bl 80055a8 + hmac_sha256_update(&ctx, &PGDV, 1); + 800767a: 2201 movs r2, #1 + 800767c: f10d 0102 add.w r1, sp, #2 + 8007680: a823 add r0, sp, #140 ; 0x8c + 8007682: f7fd ff91 bl 80055a8 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 8007686: 4938 ldr r1, [pc, #224] ; (8007768 ) + 8007688: 2202 movs r2, #2 + 800768a: a823 add r0, sp, #140 ; 0x8c + 800768c: f7fd ff8c bl 80055a8 + ASSERT(ctx.num_pending == 19); + 8007690: 9b63 ldr r3, [sp, #396] ; 0x18c + 8007692: 2b13 cmp r3, #19 + 8007694: d1ce bne.n 8007634 + hmac_sha256_final(&ctx, secret, otp); + 8007696: aa09 add r2, sp, #36 ; 0x24 + 8007698: 4641 mov r1, r8 + 800769a: a823 add r0, sp, #140 ; 0x8c + 800769c: f7fd ff9a bl 80055d4 + memcpy(tmp, data, 32); + 80076a0: 4635 mov r5, r6 + 80076a2: aa11 add r2, sp, #68 ; 0x44 + 80076a4: f106 0c20 add.w ip, r6, #32 + 80076a8: 6828 ldr r0, [r5, #0] + 80076aa: 6869 ldr r1, [r5, #4] + 80076ac: 4613 mov r3, r2 + 80076ae: c303 stmia r3!, {r0, r1} + 80076b0: 3508 adds r5, #8 + 80076b2: 4565 cmp r5, ip + 80076b4: 461a mov r2, r3 + 80076b6: d1f7 bne.n 80076a8 + xor_mixin(tmp, otp, 32); + 80076b8: 2220 movs r2, #32 + 80076ba: a909 add r1, sp, #36 ; 0x24 + 80076bc: a811 add r0, sp, #68 ; 0x44 + 80076be: f7ff fd99 bl 80071f4 + hmac_sha256_init(&ctx); + 80076c2: a823 add r0, sp, #140 ; 0x8c + 80076c4: f7fd ff6a bl 800559c + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 80076c8: 4b25 ldr r3, [pc, #148] ; (8007760 ) + 80076ca: 4926 ldr r1, [pc, #152] ; (8007764 ) + 80076cc: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80076d0: 33b0 adds r3, #176 ; 0xb0 + 80076d2: 2aff cmp r2, #255 ; 0xff + 80076d4: bf18 it ne + 80076d6: 4619 movne r1, r3 + 80076d8: 3160 adds r1, #96 ; 0x60 + 80076da: 2208 movs r2, #8 + 80076dc: a823 add r0, sp, #140 ; 0x8c + 80076de: f7fd ff63 bl 80055a8 + hmac_sha256_update(&ctx, old_data, 32); + 80076e2: 2220 movs r2, #32 + 80076e4: a901 add r1, sp, #4 + 80076e6: a823 add r0, sp, #140 ; 0x8c + 80076e8: f7fd ff5e bl 80055a8 + hmac_sha256_update(&ctx, data, 32); + 80076ec: 2220 movs r2, #32 + 80076ee: 4631 mov r1, r6 + 80076f0: a823 add r0, sp, #140 ; 0x8c + 80076f2: f7fd ff59 bl 80055a8 + hmac_sha256_update(&ctx, &PGDV, 1); + 80076f6: 2201 movs r2, #1 + 80076f8: f10d 0102 add.w r1, sp, #2 + 80076fc: a823 add r0, sp, #140 ; 0x8c + 80076fe: f7fd ff53 bl 80055a8 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 8007702: 4919 ldr r1, [pc, #100] ; (8007768 ) + 8007704: 2202 movs r2, #2 + 8007706: a823 add r0, sp, #140 ; 0x8c + 8007708: f7fd ff4e bl 80055a8 + ASSERT(ctx.num_pending == 75); + 800770c: 9b63 ldr r3, [sp, #396] ; 0x18c + 800770e: 2b4b cmp r3, #75 ; 0x4b + 8007710: d190 bne.n 8007634 + hmac_sha256_final(&ctx, secret, chal_check); + 8007712: aa19 add r2, sp, #100 ; 0x64 + 8007714: 4641 mov r1, r8 + 8007716: a823 add r0, sp, #140 ; 0x8c + 8007718: f7fd ff5c bl 80055d4 + se2_write_buffer(chal_check, sizeof(chal_check)); + 800771c: 2128 movs r1, #40 ; 0x28 + 800771e: a819 add r0, sp, #100 ; 0x64 + 8007720: f7ff fde4 bl 80072ec + uint8_t pn = (keynum << 6) | page_num; + 8007724: ea44 1487 orr.w r4, r4, r7, lsl #6 + CALL_CHECK(se2_write_n(0x99, &pn, tmp, 32)); + 8007728: 2320 movs r3, #32 + 800772a: aa11 add r2, sp, #68 ; 0x44 + 800772c: f10d 0103 add.w r1, sp, #3 + 8007730: 2099 movs r0, #153 ; 0x99 + uint8_t pn = (keynum << 6) | page_num; + 8007732: f88d 4003 strb.w r4, [sp, #3] + CALL_CHECK(se2_write_n(0x99, &pn, tmp, 32)); + 8007736: f7ff fda1 bl 800727c + 800773a: b120 cbz r0, 8007746 + 800773c: f44f 71aa mov.w r1, #340 ; 0x154 + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007740: 480a ldr r0, [pc, #40] ; (800776c ) + 8007742: f005 ffa5 bl 800d690 + 8007746: f7ff fe09 bl 800735c + 800774a: 28aa cmp r0, #170 ; 0xaa + 800774c: d002 beq.n 8007754 + 800774e: f44f 71ab mov.w r1, #342 ; 0x156 + 8007752: e7f5 b.n 8007740 +} + 8007754: b064 add sp, #400 ; 0x190 + 8007756: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + 800775a: bf00 nop + 800775c: 0800e3e0 .word 0x0800e3e0 + 8007760: 0801c000 .word 0x0801c000 + 8007764: 2009e2b0 .word 0x2009e2b0 + 8007768: 0800ea44 .word 0x0800ea44 + 800776c: 2009e390 .word 0x2009e390 + +08007770 : +{ + 8007770: b508 push {r3, lr} + 8007772: 4601 mov r1, r0 + CALL_CHECK(se2_write1(0xaa, page_num)); + 8007774: 20aa movs r0, #170 ; 0xaa + 8007776: f7ff fd4b bl 8007210 + 800777a: b120 cbz r0, 8007786 + 800777c: 4804 ldr r0, [pc, #16] ; (8007790 ) + 800777e: f240 118b movw r1, #395 ; 0x18b + 8007782: f005 ff85 bl 800d690 +} + 8007786: e8bd 4008 ldmia.w sp!, {r3, lr} + return se2_read1(); + 800778a: f7ff bde7 b.w 800735c + 800778e: bf00 nop + 8007790: 2009e390 .word 0x2009e390 + +08007794 : +{ + 8007794: b538 push {r3, r4, r5, lr} + 8007796: 460c mov r4, r1 + 8007798: 4605 mov r5, r0 + if(se2_get_protection(page_num) == flags) { + 800779a: f7ff ffe9 bl 8007770 + 800779e: 42a0 cmp r0, r4 + 80077a0: d011 beq.n 80077c6 + CALL_CHECK(se2_write2(0xc3, page_num, flags)); + 80077a2: 4622 mov r2, r4 + 80077a4: 4629 mov r1, r5 + 80077a6: 20c3 movs r0, #195 ; 0xc3 + 80077a8: f7ff fd4c bl 8007244 + 80077ac: b120 cbz r0, 80077b8 + 80077ae: f240 119b movw r1, #411 ; 0x19b + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 80077b2: 4805 ldr r0, [pc, #20] ; (80077c8 ) + 80077b4: f005 ff6c bl 800d690 + 80077b8: f7ff fdd0 bl 800735c + 80077bc: 28aa cmp r0, #170 ; 0xaa + 80077be: d002 beq.n 80077c6 + 80077c0: f240 119d movw r1, #413 ; 0x19d + 80077c4: e7f5 b.n 80077b2 +} + 80077c6: bd38 pop {r3, r4, r5, pc} + 80077c8: 2009e390 .word 0x2009e390 + +080077cc : +{ + 80077cc: b500 push {lr} + if(setjmp(error_env)) { + 80077ce: 4812 ldr r0, [pc, #72] ; (8007818 ) +{ + 80077d0: b089 sub sp, #36 ; 0x24 + if(setjmp(error_env)) { + 80077d2: f005 ff57 bl 800d684 + 80077d6: b120 cbz r0, 80077e2 + oled_show(screen_se2_issue); + 80077d8: 4810 ldr r0, [pc, #64] ; (800781c ) + 80077da: f7f9 fb33 bl 8000e44 + LOCKUP_FOREVER(); + 80077de: bf30 wfi + 80077e0: e7fd b.n 80077de + rng_delay(); + 80077e2: f7fa ffcb bl 800277c + if(rom_secrets->se2.pairing[0] == 0xff) { + 80077e6: 4b0e ldr r3, [pc, #56] ; (8007820 ) + 80077e8: f893 30b0 ldrb.w r3, [r3, #176] ; 0xb0 + 80077ec: 2bff cmp r3, #255 ; 0xff + 80077ee: d00f beq.n 8007810 + se2_read_page(PGN_ROM_OPTIONS, tmp, true); + 80077f0: 2201 movs r2, #1 + 80077f2: 4669 mov r1, sp + 80077f4: 201c movs r0, #28 + 80077f6: f7ff fe4d bl 8007494 + CHECK_RIGHT(check_equal(&tmp[24], rom_secrets->se2.romid, 8)); + 80077fa: 490a ldr r1, [pc, #40] ; (8007824 ) + 80077fc: 2208 movs r2, #8 + 80077fe: a806 add r0, sp, #24 + 8007800: f7fa ff57 bl 80026b2 + 8007804: b920 cbnz r0, 8007810 + 8007806: 4804 ldr r0, [pc, #16] ; (8007818 ) + 8007808: f240 11b5 movw r1, #437 ; 0x1b5 + 800780c: f005 ff40 bl 800d690 +} + 8007810: b009 add sp, #36 ; 0x24 + 8007812: f85d fb04 ldr.w pc, [sp], #4 + 8007816: bf00 nop + 8007818: 2009e390 .word 0x2009e390 + 800781c: 0800dfce .word 0x0800dfce + 8007820: 0801c000 .word 0x0801c000 + 8007824: 0801c110 .word 0x0801c110 + +08007828 : +{ + 8007828: b510 push {r4, lr} + if(setjmp(error_env)) fatal_mitm(); + 800782a: 4817 ldr r0, [pc, #92] ; (8007888 ) +{ + 800782c: b088 sub sp, #32 + if(setjmp(error_env)) fatal_mitm(); + 800782e: f005 ff29 bl 800d684 + 8007832: 4604 mov r4, r0 + 8007834: b108 cbz r0, 800783a + 8007836: f7f9 f911 bl 8000a5c + uint8_t z32[32] = {0}; + 800783a: 221c movs r2, #28 + 800783c: 4601 mov r1, r0 + 800783e: 9000 str r0, [sp, #0] + 8007840: a801 add r0, sp, #4 + 8007842: f005 ff17 bl 800d674 + se2_write_page(PGN_PUBKEY_S+0, z32); + 8007846: 4669 mov r1, sp + 8007848: 201e movs r0, #30 + 800784a: f7ff fd8f bl 800736c + se2_write_page(PGN_PUBKEY_S+1, z32); + 800784e: 4669 mov r1, sp + 8007850: 201f movs r0, #31 + 8007852: f7ff fd8b bl 800736c + se2_write_buffer(z32, 32); + 8007856: 2120 movs r1, #32 + 8007858: 4668 mov r0, sp + 800785a: f7ff fd47 bl 80072ec + CALL_CHECK(se2_write2(0x3c, (2<<6), 0)); + 800785e: 4622 mov r2, r4 + 8007860: 2180 movs r1, #128 ; 0x80 + 8007862: 203c movs r0, #60 ; 0x3c + 8007864: f7ff fcee bl 8007244 + 8007868: b120 cbz r0, 8007874 + 800786a: f240 11cd movw r1, #461 ; 0x1cd + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 800786e: 4806 ldr r0, [pc, #24] ; (8007888 ) + 8007870: f005 ff0e bl 800d690 + 8007874: f7ff fd72 bl 800735c + 8007878: 28aa cmp r0, #170 ; 0xaa + 800787a: d002 beq.n 8007882 + 800787c: f44f 71e7 mov.w r1, #462 ; 0x1ce + 8007880: e7f5 b.n 800786e +} + 8007882: b008 add sp, #32 + 8007884: bd10 pop {r4, pc} + 8007886: bf00 nop + 8007888: 2009e390 .word 0x2009e390 + +0800788c : +{ + 800788c: b570 push {r4, r5, r6, lr} + if((setjmp(error_env))) { + 800788e: 485b ldr r0, [pc, #364] ; (80079fc ) +{ + 8007890: b090 sub sp, #64 ; 0x40 + if((setjmp(error_env))) { + 8007892: f005 fef7 bl 800d684 + 8007896: 4604 mov r4, r0 + 8007898: b120 cbz r0, 80078a4 + oled_show(screen_se2_issue); + 800789a: 4859 ldr r0, [pc, #356] ; (8007a00 ) + 800789c: f7f9 fad2 bl 8000e44 + LOCKUP_FOREVER(); + 80078a0: bf30 wfi + 80078a2: e7fd b.n 80078a0 + if(rom_secrets->se2.pairing[0] != 0xff) { + 80078a4: 4b57 ldr r3, [pc, #348] ; (8007a04 ) + 80078a6: f893 10b0 ldrb.w r1, [r3, #176] ; 0xb0 + 80078aa: 29ff cmp r1, #255 ; 0xff + 80078ac: f040 80a0 bne.w 80079f0 + memset(&_tbd, 0xff, sizeof(_tbd)); + 80078b0: 4d55 ldr r5, [pc, #340] ; (8007a08 ) + 80078b2: 22e0 movs r2, #224 ; 0xe0 + 80078b4: 4628 mov r0, r5 + 80078b6: f005 fedd bl 800d674 + rng_buffer(_tbd.tpin_key, 32); + 80078ba: 2120 movs r1, #32 + 80078bc: f105 0080 add.w r0, r5, #128 ; 0x80 + 80078c0: f7fa ff46 bl 8002750 + se2_read_page(PGN_ROM_OPTIONS, tmp, false); + 80078c4: 4622 mov r2, r4 + 80078c6: 4669 mov r1, sp + 80078c8: 201c movs r0, #28 + 80078ca: f7ff fde3 bl 8007494 + ASSERT(tmp[1] == 0x00); // check ANON is not set + 80078ce: f89d 3001 ldrb.w r3, [sp, #1] + 80078d2: b113 cbz r3, 80078da + 80078d4: 484d ldr r0, [pc, #308] ; (8007a0c ) + 80078d6: f7f9 f8b7 bl 8000a48 + memcpy(_tbd.romid, tmp+24, 8); + 80078da: ab06 add r3, sp, #24 + 80078dc: cb03 ldmia r3!, {r0, r1} + 80078de: 6628 str r0, [r5, #96] ; 0x60 + 80078e0: 6669 str r1, [r5, #100] ; 0x64 + rng_buffer(tmp, 32); + 80078e2: 4668 mov r0, sp + 80078e4: 2120 movs r1, #32 + 80078e6: f7fa ff33 bl 8002750 + se2_write_page(PGN_SECRET_B, tmp); + 80078ea: 4669 mov r1, sp + 80078ec: 201a movs r0, #26 + 80078ee: f7ff fd3d bl 800736c + se2_pick_keypair(0, true); + 80078f2: 2101 movs r1, #1 + 80078f4: 4620 mov r0, r4 + 80078f6: f7ff fd53 bl 80073a0 + se2_read_page(PGN_PUBKEY_A, &_tbd.pubkey_A[0], false); + 80078fa: 4622 mov r2, r4 + 80078fc: f105 0120 add.w r1, r5, #32 + 8007900: 2010 movs r0, #16 + 8007902: f7ff fdc7 bl 8007494 + memset(tmp, 0, 32); + 8007906: 2620 movs r6, #32 + se2_read_page(PGN_PUBKEY_A+1, &_tbd.pubkey_A[32], false); + 8007908: 4622 mov r2, r4 + 800790a: f105 0140 add.w r1, r5, #64 ; 0x40 + 800790e: 2011 movs r0, #17 + 8007910: f7ff fdc0 bl 8007494 + memset(tmp, 0, 32); + 8007914: 4632 mov r2, r6 + 8007916: 4621 mov r1, r4 + 8007918: 4668 mov r0, sp + 800791a: f005 feab bl 800d674 + se2_write_page(PGN_PRIVKEY_B, tmp); + 800791e: 4669 mov r1, sp + 8007920: 2017 movs r0, #23 + 8007922: f7ff fd23 bl 800736c + se2_write_page(PGN_PRIVKEY_B+1, tmp); + 8007926: 4669 mov r1, sp + 8007928: 2018 movs r0, #24 + 800792a: f7ff fd1f bl 800736c + se2_write_page(PGN_PUBKEY_B, tmp); + 800792e: 4669 mov r1, sp + 8007930: 2012 movs r0, #18 + 8007932: f7ff fd1b bl 800736c + se2_write_page(PGN_PUBKEY_B+1, tmp); + 8007936: 4669 mov r1, sp + 8007938: 2013 movs r0, #19 + 800793a: f7ff fd17 bl 800736c + rng_buffer(_tbd.pairing, 32); + 800793e: 4631 mov r1, r6 + 8007940: 4628 mov r0, r5 + 8007942: f7fa ff05 bl 8002750 + } while(_tbd.pairing[0] == 0xff); + 8007946: 782b ldrb r3, [r5, #0] + 8007948: 2bff cmp r3, #255 ; 0xff + 800794a: d0f8 beq.n 800793e + se2_write_page(PGN_SECRET_A, _tbd.pairing); + 800794c: 4629 mov r1, r5 + 800794e: 2019 movs r0, #25 + rng_buffer(tmp, 32); + 8007950: 466d mov r5, sp + se2_write_page(PGN_SECRET_A, _tbd.pairing); + 8007952: f7ff fd0b bl 800736c + rng_buffer(tmp, 32); + 8007956: 2120 movs r1, #32 + 8007958: 4628 mov r0, r5 + 800795a: f7fa fef9 bl 8002750 + se2_write_page(PGN_SE2_EASY_KEY, tmp); + 800795e: 4629 mov r1, r5 + 8007960: 200e movs r0, #14 + 8007962: f7ff fd03 bl 800736c + memset(tmp, 0, 32); + 8007966: 2220 movs r2, #32 + 8007968: 2100 movs r1, #0 + 800796a: 4628 mov r0, r5 + 800796c: f005 fe82 bl 800d674 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007970: 4626 mov r6, r4 + se2_write_page(pn, tmp); + 8007972: b2f0 uxtb r0, r6 + 8007974: 4629 mov r1, r5 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007976: 3601 adds r6, #1 + se2_write_page(pn, tmp); + 8007978: f7ff fcf8 bl 800736c + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 800797c: 2e0e cmp r6, #14 + 800797e: d1f8 bne.n 8007972 + flash_save_se2_data(&_tbd); + 8007980: 4821 ldr r0, [pc, #132] ; (8007a08 ) + 8007982: f7fa fc2b bl 80021dc + se2_set_protection(PGN_SECRET_A, PROT_WP); + 8007986: 2102 movs r1, #2 + 8007988: 2019 movs r0, #25 + 800798a: f7ff ff03 bl 8007794 + se2_set_protection(PGN_SECRET_B, PROT_WP); + 800798e: 2102 movs r1, #2 + 8007990: 201a movs r0, #26 + 8007992: f7ff feff bl 8007794 + se2_set_protection(PGN_PUBKEY_A, PROT_WP); + 8007996: 2102 movs r1, #2 + 8007998: 2010 movs r0, #16 + 800799a: f7ff fefb bl 8007794 + se2_set_protection(PGN_PUBKEY_B, PROT_WP); + 800799e: 2102 movs r1, #2 + 80079a0: 2012 movs r0, #18 + 80079a2: f7ff fef7 bl 8007794 + se2_set_protection(PGN_SE2_EASY_KEY, PROT_EPH); + 80079a6: 2110 movs r1, #16 + 80079a8: 4630 mov r0, r6 + 80079aa: f7ff fef3 bl 8007794 + se2_set_protection(pn, PROT_EPH); + 80079ae: 2510 movs r5, #16 + 80079b0: b2e0 uxtb r0, r4 + 80079b2: 4629 mov r1, r5 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 80079b4: 3401 adds r4, #1 + se2_set_protection(pn, PROT_EPH); + 80079b6: f7ff feed bl 8007794 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 80079ba: 2c0e cmp r4, #14 + 80079bc: d1f8 bne.n 80079b0 + se2_set_protection(PGN_ROM_OPTIONS, PROT_APH); // not planning to change + 80079be: 2108 movs r1, #8 + 80079c0: 201c movs r0, #28 + 80079c2: f7ff fee7 bl 8007794 + se2_read_page(PGN_DEC_COUNTER, tmp, false); + 80079c6: 2200 movs r2, #0 + 80079c8: a908 add r1, sp, #32 + 80079ca: 201b movs r0, #27 + 80079cc: f7ff fd62 bl 8007494 + if(tmp[2] == 0xff) { + 80079d0: f89d 3022 ldrb.w r3, [sp, #34] ; 0x22 + 80079d4: 2bff cmp r3, #255 ; 0xff + 80079d6: d10d bne.n 80079f4 + tmp[0] = val & 0x0ff; + 80079d8: 2380 movs r3, #128 ; 0x80 + 80079da: f88d 3020 strb.w r3, [sp, #32] + se2_write_page(PGN_DEC_COUNTER, tmp); + 80079de: a908 add r1, sp, #32 + tmp[1] = (val >> 8) & 0x0ff; + 80079e0: 2300 movs r3, #0 + se2_write_page(PGN_DEC_COUNTER, tmp); + 80079e2: 201b movs r0, #27 + tmp[1] = (val >> 8) & 0x0ff; + 80079e4: f88d 3021 strb.w r3, [sp, #33] ; 0x21 + tmp[2] = (val >> 16) & 0x01; + 80079e8: f88d 3022 strb.w r3, [sp, #34] ; 0x22 + se2_write_page(PGN_DEC_COUNTER, tmp); + 80079ec: f7ff fcbe bl 800736c +} + 80079f0: b010 add sp, #64 ; 0x40 + 80079f2: bd70 pop {r4, r5, r6, pc} + puts("ctr set?"); // not expected, but keep going + 80079f4: 4806 ldr r0, [pc, #24] ; (8007a10 ) + 80079f6: f7fd f9d9 bl 8004dac + 80079fa: e7f9 b.n 80079f0 + 80079fc: 2009e390 .word 0x2009e390 + 8007a00: 0800dfce .word 0x0800dfce + 8007a04: 0801c000 .word 0x0801c000 + 8007a08: 2009e2b0 .word 0x2009e2b0 + 8007a0c: 0800e3e0 .word 0x0800e3e0 + 8007a10: 0800ea24 .word 0x0800ea24 + +08007a14 : +{ + 8007a14: b510 push {r4, lr} + 8007a16: b08a sub sp, #40 ; 0x28 + 8007a18: 9001 str r0, [sp, #4] + if(setjmp(error_env)) fatal_mitm(); + 8007a1a: 481e ldr r0, [pc, #120] ; (8007a94 ) + 8007a1c: f005 fe32 bl 800d684 + 8007a20: b108 cbz r0, 8007a26 + 8007a22: f7f9 f81b bl 8000a5c + ASSERT(check_all_ones(rom_secrets->se2.auth_pubkey, 64)); + 8007a26: 481c ldr r0, [pc, #112] ; (8007a98 ) + 8007a28: 2140 movs r1, #64 ; 0x40 + 8007a2a: f7fa fe29 bl 8002680 + 8007a2e: b910 cbnz r0, 8007a36 + 8007a30: 481a ldr r0, [pc, #104] ; (8007a9c ) + 8007a32: f7f9 f809 bl 8000a48 + memcpy(&_tbd, &rom_secrets->se2, sizeof(_tbd)); + 8007a36: 4c1a ldr r4, [pc, #104] ; (8007aa0 ) + 8007a38: 491a ldr r1, [pc, #104] ; (8007aa4 ) + 8007a3a: 22e0 movs r2, #224 ; 0xe0 + 8007a3c: 4620 mov r0, r4 + 8007a3e: f005 fdf1 bl 800d624 + rng_buffer(tmp, 32); + 8007a42: 2120 movs r1, #32 + 8007a44: a802 add r0, sp, #8 + 8007a46: f7fa fe83 bl 8002750 + se2_write_page(PGN_SE2_HARD_KEY, tmp); + 8007a4a: a902 add r1, sp, #8 + 8007a4c: 200f movs r0, #15 + 8007a4e: f7ff fc8d bl 800736c + se2_write_page(PGN_PUBKEY_C, &pubkey[0]); + 8007a52: 9901 ldr r1, [sp, #4] + 8007a54: 2014 movs r0, #20 + 8007a56: f7ff fc89 bl 800736c + se2_write_page(PGN_PUBKEY_C+1, &pubkey[32]); + 8007a5a: 9b01 ldr r3, [sp, #4] + 8007a5c: 2015 movs r0, #21 + 8007a5e: f103 0120 add.w r1, r3, #32 + 8007a62: f7ff fc83 bl 800736c + memcpy(_tbd.auth_pubkey, pubkey, 64); + 8007a66: 9b01 ldr r3, [sp, #4] + 8007a68: 34a0 adds r4, #160 ; 0xa0 + 8007a6a: f103 0240 add.w r2, r3, #64 ; 0x40 + 8007a6e: f853 1b04 ldr.w r1, [r3], #4 + 8007a72: f844 1b04 str.w r1, [r4], #4 + 8007a76: 4293 cmp r3, r2 + 8007a78: d1f9 bne.n 8007a6e + flash_save_se2_data(&_tbd); + 8007a7a: 4809 ldr r0, [pc, #36] ; (8007aa0 ) + 8007a7c: f7fa fbae bl 80021dc + se2_set_protection(PGN_SE2_HARD_KEY, PROT_WP | PROT_ECH | PROT_ECW); + 8007a80: 21c2 movs r1, #194 ; 0xc2 + 8007a82: 200f movs r0, #15 + 8007a84: f7ff fe86 bl 8007794 + se2_set_protection(PGN_PUBKEY_C, PROT_WP | PROT_RP | PROT_AUTH); + 8007a88: 2123 movs r1, #35 ; 0x23 + 8007a8a: 2014 movs r0, #20 + 8007a8c: f7ff fe82 bl 8007794 +} + 8007a90: b00a add sp, #40 ; 0x28 + 8007a92: bd10 pop {r4, pc} + 8007a94: 2009e390 .word 0x2009e390 + 8007a98: 0801c150 .word 0x0801c150 + 8007a9c: 0800e3e0 .word 0x0800e3e0 + 8007aa0: 2009e2b0 .word 0x2009e2b0 + 8007aa4: 0801c0b0 .word 0x0801c0b0 + +08007aa8 : +{ + 8007aa8: b530 push {r4, r5, lr} + 8007aaa: 4614 mov r4, r2 + ASSERT(pin_len >= 0); // 12-12 typical, but empty = blank PIN + 8007aac: 1e0a subs r2, r1, #0 +{ + 8007aae: b0c5 sub sp, #276 ; 0x114 + 8007ab0: 4605 mov r5, r0 + ASSERT(pin_len >= 0); // 12-12 typical, but empty = blank PIN + 8007ab2: da02 bge.n 8007aba + 8007ab4: 4812 ldr r0, [pc, #72] ; (8007b00 ) + 8007ab6: f7f8 ffc7 bl 8000a48 + hmac_sha256_init(&ctx); + 8007aba: a803 add r0, sp, #12 + 8007abc: 9201 str r2, [sp, #4] + 8007abe: f7fd fd6d bl 800559c + hmac_sha256_update(&ctx, (uint8_t *)pin, pin_len); + 8007ac2: 9a01 ldr r2, [sp, #4] + 8007ac4: 4629 mov r1, r5 + 8007ac6: a803 add r0, sp, #12 + 8007ac8: f7fd fd6e bl 80055a8 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, tpin_hash); + 8007acc: 4b0d ldr r3, [pc, #52] ; (8007b04 ) + 8007ace: 490e ldr r1, [pc, #56] ; (8007b08 ) + 8007ad0: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 8007ad4: 33b0 adds r3, #176 ; 0xb0 + 8007ad6: 2aff cmp r2, #255 ; 0xff + 8007ad8: bf18 it ne + 8007ada: 4619 movne r1, r3 + 8007adc: a803 add r0, sp, #12 + 8007ade: 4622 mov r2, r4 + 8007ae0: 3180 adds r1, #128 ; 0x80 + 8007ae2: f7fd fd77 bl 80055d4 + sha256_single(tpin_hash, 32, tpin_hash); + 8007ae6: 4622 mov r2, r4 + 8007ae8: 4620 mov r0, r4 + 8007aea: 2120 movs r1, #32 + 8007aec: f7fd fd36 bl 800555c + sha256_single(tpin_hash, 32, tpin_hash); + 8007af0: 4622 mov r2, r4 + 8007af2: 2120 movs r1, #32 + 8007af4: 4620 mov r0, r4 + 8007af6: f7fd fd31 bl 800555c +} + 8007afa: b045 add sp, #276 ; 0x114 + 8007afc: bd30 pop {r4, r5, pc} + 8007afe: bf00 nop + 8007b00: 0800e3e0 .word 0x0800e3e0 + 8007b04: 0801c000 .word 0x0801c000 + 8007b08: 2009e2b0 .word 0x2009e2b0 + +08007b0c : + +// p256_gen_keypair() +// + void +p256_gen_keypair(uint8_t privkey[32], uint8_t pubkey[64]) +{ + 8007b0c: b538 push {r3, r4, r5, lr} + 8007b0e: 4605 mov r5, r0 + uECC_set_rng(rng_for_uECC); + 8007b10: 4808 ldr r0, [pc, #32] ; (8007b34 ) +{ + 8007b12: 460c mov r4, r1 + uECC_set_rng(rng_for_uECC); + 8007b14: f7fe fedc bl 80068d0 + + int ok = uECC_make_key(pubkey, privkey, uECC_secp256r1()); + 8007b18: f7fe fee0 bl 80068dc + 8007b1c: 4629 mov r1, r5 + 8007b1e: 4602 mov r2, r0 + 8007b20: 4620 mov r0, r4 + 8007b22: f7fe fee3 bl 80068ec + ASSERT(ok == 1); + 8007b26: 2801 cmp r0, #1 + 8007b28: d002 beq.n 8007b30 + 8007b2a: 4803 ldr r0, [pc, #12] ; (8007b38 ) + 8007b2c: f7f8 ff8c bl 8000a48 +} + 8007b30: bd38 pop {r3, r4, r5, pc} + 8007b32: bf00 nop + 8007b34: 080072e1 .word 0x080072e1 + 8007b38: 0800e3e0 .word 0x0800e3e0 + +08007b3c : + +// ps256_ecdh() +// + void +ps256_ecdh(const uint8_t pubkey[64], const uint8_t privkey[32], uint8_t result[32]) +{ + 8007b3c: b513 push {r0, r1, r4, lr} + 8007b3e: 4604 mov r4, r0 + uECC_set_rng(rng_for_uECC); + 8007b40: 4809 ldr r0, [pc, #36] ; (8007b68 ) +{ + 8007b42: e9cd 2100 strd r2, r1, [sp] + uECC_set_rng(rng_for_uECC); + 8007b46: f7fe fec3 bl 80068d0 + + int ok = uECC_shared_secret(pubkey, privkey, result, uECC_secp256r1()); + 8007b4a: f7fe fec7 bl 80068dc + 8007b4e: e9dd 2100 ldrd r2, r1, [sp] + 8007b52: 4603 mov r3, r0 + 8007b54: 4620 mov r0, r4 + 8007b56: f7fe ff09 bl 800696c + ASSERT(ok == 1); + 8007b5a: 2801 cmp r0, #1 + 8007b5c: d002 beq.n 8007b64 + 8007b5e: 4803 ldr r0, [pc, #12] ; (8007b6c ) + 8007b60: f7f8 ff72 bl 8000a48 +} + 8007b64: b002 add sp, #8 + 8007b66: bd10 pop {r4, pc} + 8007b68: 080072e1 .word 0x080072e1 + 8007b6c: 0800e3e0 .word 0x0800e3e0 + +08007b70 : + +// se2_read_hard_secret() +// + static bool +se2_read_hard_secret(uint8_t hard_key[32], const uint8_t pin_digest[32]) +{ + 8007b70: b510 push {r4, lr} + 8007b72: b0e8 sub sp, #416 ; 0x1a0 + 8007b74: e9cd 0102 strd r0, r1, [sp, #8] + if(setjmp(error_env)) { + 8007b78: 4836 ldr r0, [pc, #216] ; (8007c54 ) + 8007b7a: f005 fd83 bl 800d684 + 8007b7e: 2800 cmp r0, #0 + 8007b80: d165 bne.n 8007c4e + // + SHA256_CTX ctx; + + // pick a temp key pair, share public part w/ SE2 + uint8_t tmp_privkey[32], tmp_pubkey[64]; + p256_gen_keypair(tmp_privkey, tmp_pubkey); + 8007b82: a925 add r1, sp, #148 ; 0x94 + 8007b84: a805 add r0, sp, #20 + 8007b86: f7ff ffc1 bl 8007b0c + + // - this can be mitm-ed, but we sign it next so doesn't matter + se2_write_page(PGN_PUBKEY_S, &tmp_pubkey[0]); + 8007b8a: a925 add r1, sp, #148 ; 0x94 + 8007b8c: 201e movs r0, #30 + 8007b8e: f7ff fbed bl 800736c + se2_write_page(PGN_PUBKEY_S+1, &tmp_pubkey[32]); + 8007b92: a92d add r1, sp, #180 ; 0xb4 + 8007b94: 201f movs r0, #31 + 8007b96: f7ff fbe9 bl 800736c + + // pick nonce + uint8_t chal[32+32]; + rng_buffer(chal, sizeof(chal)); + 8007b9a: 2140 movs r1, #64 ; 0x40 + 8007b9c: a835 add r0, sp, #212 ; 0xd4 + 8007b9e: f7fa fdd7 bl 8002750 + se2_write_buffer(chal, sizeof(chal)); + 8007ba2: 2140 movs r1, #64 ; 0x40 + 8007ba4: a835 add r0, sp, #212 ; 0xd4 + 8007ba6: f7ff fba1 bl 80072ec + + // md = ngu.hash.sha256s(T_pubkey + chal[0:32]) + sha256_init(&ctx); + 8007baa: a855 add r0, sp, #340 ; 0x154 + 8007bac: f7fd fc6e bl 800548c + sha256_update(&ctx, tmp_pubkey, 64); + 8007bb0: 2240 movs r2, #64 ; 0x40 + 8007bb2: a925 add r1, sp, #148 ; 0x94 + 8007bb4: a855 add r0, sp, #340 ; 0x154 + 8007bb6: f7fd fc77 bl 80054a8 + sha256_update(&ctx, chal, 32); // only first 32 bytes + 8007bba: 2220 movs r2, #32 + 8007bbc: a935 add r1, sp, #212 ; 0xd4 + 8007bbe: a855 add r0, sp, #340 ; 0x154 + 8007bc0: f7fd fc72 bl 80054a8 + + uint8_t md[32]; + sha256_final(&ctx, md); + 8007bc4: a90d add r1, sp, #52 ; 0x34 + 8007bc6: a855 add r0, sp, #340 ; 0x154 + 8007bc8: f7fd fcb4 bl 8005534 + // Get that digest signed by SE1 now, and doing that requires + // the main pin, because the required slot requires auth by that key. + // - this is the critical step attackers would not be able to emulate w/o SE1 contents + // - fails here if PIN wrong + uint8_t signature[64]; + int arc = ae_sign_authed(KEYNUM_joiner_key, md, signature, KEYNUM_main_pin, pin_digest); + 8007bcc: 9b03 ldr r3, [sp, #12] + 8007bce: 9300 str r3, [sp, #0] + 8007bd0: aa45 add r2, sp, #276 ; 0x114 + 8007bd2: 2303 movs r3, #3 + 8007bd4: a90d add r1, sp, #52 ; 0x34 + 8007bd6: 2007 movs r0, #7 + 8007bd8: f7fb f8f0 bl 8002dbc + CHECK_RIGHT(arc == 0); + 8007bdc: 4604 mov r4, r0 + 8007bde: b120 cbz r0, 8007bea + 8007be0: f240 4152 movw r1, #1106 ; 0x452 + + // "Authenticate ECDSA Public Key" = 0xA8 + // cs_offset=32 ecdh_keynum=0=pubA ECDH=1 WR=0 + uint8_t param = ((32-1) << 3) | (0 << 2) | 0x2; + se2_write_n(0xA8, ¶m, signature, 64); + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007be4: 481b ldr r0, [pc, #108] ; (8007c54 ) + 8007be6: f005 fd53 bl 800d690 + uint8_t param = ((32-1) << 3) | (0 << 2) | 0x2; + 8007bea: 23fa movs r3, #250 ; 0xfa + 8007bec: f88d 3013 strb.w r3, [sp, #19] + se2_write_n(0xA8, ¶m, signature, 64); + 8007bf0: aa45 add r2, sp, #276 ; 0x114 + 8007bf2: 2340 movs r3, #64 ; 0x40 + 8007bf4: f10d 0113 add.w r1, sp, #19 + 8007bf8: 20a8 movs r0, #168 ; 0xa8 + 8007bfa: f7ff fb3f bl 800727c + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007bfe: f7ff fbad bl 800735c + 8007c02: 28aa cmp r0, #170 ; 0xaa + 8007c04: d002 beq.n 8007c0c + 8007c06: f44f 618b mov.w r1, #1112 ; 0x458 + 8007c0a: e7eb b.n 8007be4 + + uint8_t shared_x[32], shared_secret[32]; + ps256_ecdh(rom_secrets->se2.pubkey_A, tmp_privkey, shared_x); + 8007c0c: aa15 add r2, sp, #84 ; 0x54 + 8007c0e: a905 add r1, sp, #20 + 8007c10: 4811 ldr r0, [pc, #68] ; (8007c58 ) + 8007c12: f7ff ff93 bl 8007b3c + + // shared secret S will be SHA over X of shared ECDH point + chal[32:] + // s = ngu.hash.sha256s(x + chal[32:]) + sha256_init(&ctx); + 8007c16: a855 add r0, sp, #340 ; 0x154 + 8007c18: f7fd fc38 bl 800548c + sha256_update(&ctx, shared_x, 32); + 8007c1c: 2220 movs r2, #32 + 8007c1e: a915 add r1, sp, #84 ; 0x54 + 8007c20: a855 add r0, sp, #340 ; 0x154 + 8007c22: f7fd fc41 bl 80054a8 + sha256_update(&ctx, &chal[32], 32); // second half + 8007c26: 2220 movs r2, #32 + 8007c28: a93d add r1, sp, #244 ; 0xf4 + 8007c2a: a855 add r0, sp, #340 ; 0x154 + 8007c2c: f7fd fc3c bl 80054a8 + sha256_final(&ctx, shared_secret); + 8007c30: a91d add r1, sp, #116 ; 0x74 + 8007c32: a855 add r0, sp, #340 ; 0x154 + 8007c34: f7fd fc7e bl 8005534 + + se2_read_encrypted(PGN_SE2_HARD_KEY, hard_key, 2, shared_secret); + 8007c38: 200f movs r0, #15 + 8007c3a: 9902 ldr r1, [sp, #8] + 8007c3c: ab1d add r3, sp, #116 ; 0x74 + 8007c3e: 2202 movs r2, #2 + 8007c40: f7ff fc76 bl 8007530 + + // CONCERN: secret "S" is retained in SE2's sram. No API to clear it. + // - but you'd need to see our copy of that value to make use of it + // - and PIN checked already to get here, so you could re-do anyway + se2_clear_volatile(); + 8007c44: f7ff fdf0 bl 8007828 + + return false; + 8007c48: 4620 mov r0, r4 +} + 8007c4a: b068 add sp, #416 ; 0x1a0 + 8007c4c: bd10 pop {r4, pc} + return true; + 8007c4e: 2001 movs r0, #1 + 8007c50: e7fb b.n 8007c4a + 8007c52: bf00 nop + 8007c54: 2009e390 .word 0x2009e390 + 8007c58: 0801c0d0 .word 0x0801c0d0 + +08007c5c : + +// se2_calc_seed_key() +// + static bool +se2_calc_seed_key(uint8_t aes_key[32], const mcu_key_t *mcu_key, const uint8_t pin_digest[32]) +{ + 8007c5c: b570 push {r4, r5, r6, lr} + 8007c5e: b0d2 sub sp, #328 ; 0x148 + 8007c60: 4614 mov r4, r2 + // Gather key parts from all over. Combine them w/ HMAC into a AES-256 key + uint8_t se1_easy_key[32], se1_hard_key[32]; + se2_read_encrypted(PGN_SE2_EASY_KEY, se1_easy_key, 0, rom_secrets->se2.pairing); + 8007c62: 4b15 ldr r3, [pc, #84] ; (8007cb8 ) + 8007c64: 2200 movs r2, #0 +{ + 8007c66: 4605 mov r5, r0 + 8007c68: 460e mov r6, r1 + se2_read_encrypted(PGN_SE2_EASY_KEY, se1_easy_key, 0, rom_secrets->se2.pairing); + 8007c6a: 200e movs r0, #14 + 8007c6c: a901 add r1, sp, #4 + 8007c6e: f7ff fc5f bl 8007530 + + if(se2_read_hard_secret(se1_hard_key, pin_digest)) return true; + 8007c72: 4621 mov r1, r4 + 8007c74: a809 add r0, sp, #36 ; 0x24 + 8007c76: f7ff ff7b bl 8007b70 + 8007c7a: 4604 mov r4, r0 + 8007c7c: b9c8 cbnz r0, 8007cb2 + + HMAC_CTX ctx; + hmac_sha256_init(&ctx); + 8007c7e: a811 add r0, sp, #68 ; 0x44 + 8007c80: f7fd fc8c bl 800559c + hmac_sha256_update(&ctx, mcu_key->value, 32); + 8007c84: 2220 movs r2, #32 + 8007c86: 4631 mov r1, r6 + 8007c88: a811 add r0, sp, #68 ; 0x44 + 8007c8a: f7fd fc8d bl 80055a8 + hmac_sha256_update(&ctx, se1_hard_key, 32); + 8007c8e: 2220 movs r2, #32 + 8007c90: a909 add r1, sp, #36 ; 0x24 + 8007c92: a811 add r0, sp, #68 ; 0x44 + 8007c94: f7fd fc88 bl 80055a8 + hmac_sha256_update(&ctx, se1_easy_key, 32); + 8007c98: 2220 movs r2, #32 + 8007c9a: a901 add r1, sp, #4 + 8007c9c: a811 add r0, sp, #68 ; 0x44 + 8007c9e: f7fd fc83 bl 80055a8 + + // combine them all using anther MCU key via HMAC-SHA256 + hmac_sha256_final(&ctx, rom_secrets->mcu_hmac_key, aes_key); + 8007ca2: a811 add r0, sp, #68 ; 0x44 + 8007ca4: 4905 ldr r1, [pc, #20] ; (8007cbc ) + 8007ca6: 462a mov r2, r5 + 8007ca8: f7fd fc94 bl 80055d4 + hmac_sha256_init(&ctx); // clear secrets + 8007cac: a811 add r0, sp, #68 ; 0x44 + 8007cae: f7fd fc75 bl 800559c + + return false; +} + 8007cb2: 4620 mov r0, r4 + 8007cb4: b052 add sp, #328 ; 0x148 + 8007cb6: bd70 pop {r4, r5, r6, pc} + 8007cb8: 0801c0b0 .word 0x0801c0b0 + 8007cbc: 0801c090 .word 0x0801c090 + +08007cc0 : +{ + 8007cc0: b5f0 push {r4, r5, r6, r7, lr} + if(i2c_port.Instance == I2C2) { + 8007cc2: 4e1b ldr r6, [pc, #108] ; (8007d30 ) + 8007cc4: 4f1b ldr r7, [pc, #108] ; (8007d34 ) + 8007cc6: 6833 ldr r3, [r6, #0] + 8007cc8: 42bb cmp r3, r7 +{ + 8007cca: b089 sub sp, #36 ; 0x24 + if(i2c_port.Instance == I2C2) { + 8007ccc: d02e beq.n 8007d2c + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8007cce: 4b1a ldr r3, [pc, #104] ; (8007d38 ) + GPIO_InitTypeDef setup = { + 8007cd0: 4d1a ldr r5, [pc, #104] ; (8007d3c ) + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8007cd2: 6cda ldr r2, [r3, #76] ; 0x4c + 8007cd4: f042 0202 orr.w r2, r2, #2 + 8007cd8: 64da str r2, [r3, #76] ; 0x4c + 8007cda: 6cda ldr r2, [r3, #76] ; 0x4c + 8007cdc: f002 0202 and.w r2, r2, #2 + 8007ce0: 9201 str r2, [sp, #4] + 8007ce2: 9a01 ldr r2, [sp, #4] + __HAL_RCC_I2C2_CLK_ENABLE(); + 8007ce4: 6d9a ldr r2, [r3, #88] ; 0x58 + 8007ce6: f442 0280 orr.w r2, r2, #4194304 ; 0x400000 + 8007cea: 659a str r2, [r3, #88] ; 0x58 + 8007cec: 6d9b ldr r3, [r3, #88] ; 0x58 + 8007cee: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 8007cf2: 9302 str r3, [sp, #8] + 8007cf4: 9b02 ldr r3, [sp, #8] + GPIO_InitTypeDef setup = { + 8007cf6: cd0f ldmia r5!, {r0, r1, r2, r3} + 8007cf8: ac03 add r4, sp, #12 + 8007cfa: c40f stmia r4!, {r0, r1, r2, r3} + 8007cfc: 682b ldr r3, [r5, #0] + HAL_GPIO_Init(GPIOB, &setup); + 8007cfe: 4810 ldr r0, [pc, #64] ; (8007d40 ) + GPIO_InitTypeDef setup = { + 8007d00: 6023 str r3, [r4, #0] + HAL_GPIO_Init(GPIOB, &setup); + 8007d02: a903 add r1, sp, #12 + 8007d04: f7f9 f984 bl 8001010 + memset(&i2c_port, 0, sizeof(i2c_port)); + 8007d08: 2244 movs r2, #68 ; 0x44 + 8007d0a: 2100 movs r1, #0 + 8007d0c: f106 0008 add.w r0, r6, #8 + 8007d10: f005 fcb0 bl 800d674 + i2c_port.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + 8007d14: 2301 movs r3, #1 + 8007d16: 60f3 str r3, [r6, #12] + HAL_StatusTypeDef rv = HAL_I2C_Init(&i2c_port); + 8007d18: 4630 mov r0, r6 + i2c_port.Init.Timing = 0x00b03fb8; // 400khz "fast mode" in CubeMX @ 120Mhz (measured ok) + 8007d1a: 4b0a ldr r3, [pc, #40] ; (8007d44 ) + i2c_port.Instance = I2C2; + 8007d1c: 6037 str r7, [r6, #0] + i2c_port.Init.Timing = 0x00b03fb8; // 400khz "fast mode" in CubeMX @ 120Mhz (measured ok) + 8007d1e: 6073 str r3, [r6, #4] + HAL_StatusTypeDef rv = HAL_I2C_Init(&i2c_port); + 8007d20: f003 fdb4 bl 800b88c + ASSERT(rv == HAL_OK); + 8007d24: b110 cbz r0, 8007d2c + 8007d26: 4808 ldr r0, [pc, #32] ; (8007d48 ) + 8007d28: f7f8 fe8e bl 8000a48 +} + 8007d2c: b009 add sp, #36 ; 0x24 + 8007d2e: bdf0 pop {r4, r5, r6, r7, pc} + 8007d30: 2009e3ec .word 0x2009e3ec + 8007d34: 40005800 .word 0x40005800 + 8007d38: 40021000 .word 0x40021000 + 8007d3c: 0800ea30 .word 0x0800ea30 + 8007d40: 48000400 .word 0x48000400 + 8007d44: 00b03fb8 .word 0x00b03fb8 + 8007d48: 0800e3e0 .word 0x0800e3e0 + +08007d4c : +{ + 8007d4c: b5f0 push {r4, r5, r6, r7, lr} + 8007d4e: b089 sub sp, #36 ; 0x24 + se2_setup(); + 8007d50: f7ff ffb6 bl 8007cc0 + if(setjmp(error_env)) fatal_mitm(); + 8007d54: 480f ldr r0, [pc, #60] ; (8007d94 ) + 8007d56: f005 fc95 bl 800d684 + 8007d5a: 4604 mov r4, r0 + 8007d5c: b108 cbz r0, 8007d62 + 8007d5e: f7f8 fe7d bl 8000a5c + uint8_t tmp[32] = {0}; + 8007d62: 9000 str r0, [sp, #0] + 8007d64: 4601 mov r1, r0 + 8007d66: 221c movs r2, #28 + 8007d68: a801 add r0, sp, #4 + 8007d6a: f005 fc83 bl 800d674 + se2_write_encrypted(pn, tmp, 0, SE2_SECRETS->pairing); + 8007d6e: 4f0a ldr r7, [pc, #40] ; (8007d98 ) + 8007d70: 4e0a ldr r6, [pc, #40] ; (8007d9c ) + 8007d72: 4d0b ldr r5, [pc, #44] ; (8007da0 ) + 8007d74: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 8007d78: b2e0 uxtb r0, r4 + 8007d7a: 2bff cmp r3, #255 ; 0xff + 8007d7c: bf0c ite eq + 8007d7e: 4633 moveq r3, r6 + 8007d80: 462b movne r3, r5 + 8007d82: 2200 movs r2, #0 + 8007d84: 4669 mov r1, sp + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007d86: 3401 adds r4, #1 + se2_write_encrypted(pn, tmp, 0, SE2_SECRETS->pairing); + 8007d88: f7ff fc4a bl 8007620 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007d8c: 2c0e cmp r4, #14 + 8007d8e: d1f1 bne.n 8007d74 +} + 8007d90: b009 add sp, #36 ; 0x24 + 8007d92: bdf0 pop {r4, r5, r6, r7, pc} + 8007d94: 2009e390 .word 0x2009e390 + 8007d98: 0801c000 .word 0x0801c000 + 8007d9c: 2009e2b0 .word 0x2009e2b0 + 8007da0: 0801c0b0 .word 0x0801c0b0 + +08007da4 : +{ + 8007da4: b5f0 push {r4, r5, r6, r7, lr} + 8007da6: b087 sub sp, #28 + 8007da8: e9cd 0102 strd r0, r1, [sp, #8] + if(setjmp(error_env)) fatal_mitm(); + 8007dac: 4816 ldr r0, [pc, #88] ; (8007e08 ) +{ + 8007dae: 9201 str r2, [sp, #4] + if(setjmp(error_env)) fatal_mitm(); + 8007db0: f005 fc68 bl 800d684 + 8007db4: b108 cbz r0, 8007dba + 8007db6: f7f8 fe51 bl 8000a5c + se2_read_encrypted(slot_num+1, &data[0], 0, SE2_SECRETS->pairing); + 8007dba: 4f14 ldr r7, [pc, #80] ; (8007e0c ) + 8007dbc: 9005 str r0, [sp, #20] + se2_setup(); + 8007dbe: f7ff ff7f bl 8007cc0 + se2_read_encrypted(slot_num+1, &data[0], 0, SE2_SECRETS->pairing); + 8007dc2: f89d 4008 ldrb.w r4, [sp, #8] + 8007dc6: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 8007dca: 4e11 ldr r6, [pc, #68] ; (8007e10 ) + 8007dcc: 4d11 ldr r5, [pc, #68] ; (8007e14 ) + 8007dce: 9a05 ldr r2, [sp, #20] + 8007dd0: 9901 ldr r1, [sp, #4] + 8007dd2: 9204 str r2, [sp, #16] + 8007dd4: 1c60 adds r0, r4, #1 + 8007dd6: 2bff cmp r3, #255 ; 0xff + 8007dd8: bf0c ite eq + 8007dda: 4633 moveq r3, r6 + 8007ddc: 462b movne r3, r5 + 8007dde: b2c0 uxtb r0, r0 + 8007de0: f7ff fba6 bl 8007530 + if(tc_flags & TC_XPRV_WALLET) { + 8007de4: 9b03 ldr r3, [sp, #12] + 8007de6: 051b lsls r3, r3, #20 + 8007de8: d50c bpl.n 8007e04 + se2_read_encrypted(slot_num+2, &data[32], 0, SE2_SECRETS->pairing); + 8007dea: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 8007dee: 9901 ldr r1, [sp, #4] + 8007df0: 9a04 ldr r2, [sp, #16] + 8007df2: 3402 adds r4, #2 + 8007df4: 2bff cmp r3, #255 ; 0xff + 8007df6: bf0c ite eq + 8007df8: 4633 moveq r3, r6 + 8007dfa: 462b movne r3, r5 + 8007dfc: 3120 adds r1, #32 + 8007dfe: b2e0 uxtb r0, r4 + 8007e00: f7ff fb96 bl 8007530 +} + 8007e04: b007 add sp, #28 + 8007e06: bdf0 pop {r4, r5, r6, r7, pc} + 8007e08: 2009e390 .word 0x2009e390 + 8007e0c: 0801c000 .word 0x0801c000 + 8007e10: 2009e2b0 .word 0x2009e2b0 + 8007e14: 0801c0b0 .word 0x0801c0b0 + +08007e18 : +{ + 8007e18: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8007e1c: b0fe sub sp, #504 ; 0x1f8 + 8007e1e: e9cd 1002 strd r1, r0, [sp, #8] + 8007e22: e9cd 2300 strd r2, r3, [sp] + se2_setup(); + 8007e26: f7ff ff4b bl 8007cc0 + if(setjmp(error_env)) { + 8007e2a: 4864 ldr r0, [pc, #400] ; (8007fbc ) + 8007e2c: f005 fc2a bl 800d684 + 8007e30: 4604 mov r4, r0 + 8007e32: b138 cbz r0, 8007e44 + if(!safety_mode) fatal_mitm(); + 8007e34: 9b01 ldr r3, [sp, #4] + 8007e36: b11b cbz r3, 8007e40 + return false; + 8007e38: 2000 movs r0, #0 +} + 8007e3a: b07e add sp, #504 ; 0x1f8 + 8007e3c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if(!safety_mode) fatal_mitm(); + 8007e40: f7f8 fe0c bl 8000a5c + if(!pin_len) return false; + 8007e44: 9b02 ldr r3, [sp, #8] + 8007e46: 2b00 cmp r3, #0 + 8007e48: d0f6 beq.n 8007e38 + trick_pin_hash(pin, pin_len, tpin_hash); + 8007e4a: 9803 ldr r0, [sp, #12] + se2_read_encrypted(pn, slots[i], 0, SE2_SECRETS->pairing); + 8007e4c: f8df a174 ldr.w sl, [pc, #372] ; 8007fc4 + 8007e50: f8df 9174 ldr.w r9, [pc, #372] ; 8007fc8 + 8007e54: f8df 8174 ldr.w r8, [pc, #372] ; 8007fcc + trick_pin_hash(pin, pin_len, tpin_hash); + 8007e58: aa06 add r2, sp, #24 + 8007e5a: 4619 mov r1, r3 + 8007e5c: f7ff fe24 bl 8007aa8 + 8007e60: ad0e add r5, sp, #56 ; 0x38 + 8007e62: 462f mov r7, r5 + int pn = PGN_TRICK(0); + 8007e64: 4626 mov r6, r4 + se2_read_encrypted(pn, slots[i], 0, SE2_SECRETS->pairing); + 8007e66: f89a 30b0 ldrb.w r3, [sl, #176] ; 0xb0 + 8007e6a: 4639 mov r1, r7 + 8007e6c: 2bff cmp r3, #255 ; 0xff + 8007e6e: bf0c ite eq + 8007e70: 464b moveq r3, r9 + 8007e72: 4643 movne r3, r8 + 8007e74: b2f0 uxtb r0, r6 + 8007e76: 2200 movs r2, #0 + for(int i=0; ipairing); + 8007e7a: f7ff fb59 bl 8007530 + for(int i=0; i + se2_clear_volatile(); + 8007e86: f7ff fccf bl 8007828 + uint32_t blank = 0; + 8007e8a: 2700 movs r7, #0 + int found = -1; + 8007e8c: f04f 36ff mov.w r6, #4294967295 ; 0xffffffff + if(check_equal(here, tpin_hash, 28)) { + 8007e90: f04f 091c mov.w r9, #28 + blank |= (!!check_all_zeros(here, 32)) << i; + 8007e94: f04f 0820 mov.w r8, #32 + if(check_equal(here, tpin_hash, 28)) { + 8007e98: 464a mov r2, r9 + 8007e9a: a906 add r1, sp, #24 + 8007e9c: 4628 mov r0, r5 + 8007e9e: f7fa fc08 bl 80026b2 + blank |= (!!check_all_zeros(here, 32)) << i; + 8007ea2: 4641 mov r1, r8 + if(check_equal(here, tpin_hash, 28)) { + 8007ea4: 2800 cmp r0, #0 + 8007ea6: bf18 it ne + 8007ea8: 4626 movne r6, r4 + blank |= (!!check_all_zeros(here, 32)) << i; + 8007eaa: 4628 mov r0, r5 + 8007eac: f7fa fbf2 bl 8002694 + 8007eb0: 40a0 lsls r0, r4 + for(int i=0; i + rng_delay(); + 8007ec0: f7fa fc5c bl 800277c + memset(found_slot, 0, sizeof(trick_slot_t)); + 8007ec4: 9800 ldr r0, [sp, #0] + 8007ec6: 2280 movs r2, #128 ; 0x80 + 8007ec8: 2100 movs r1, #0 + 8007eca: f005 fbd3 bl 800d674 + if(safety_mode) { + 8007ece: 9b01 ldr r3, [sp, #4] + 8007ed0: b10b cbz r3, 8007ed6 + found_slot->blank_slots = blank; + 8007ed2: 9b00 ldr r3, [sp, #0] + 8007ed4: 65df str r7, [r3, #92] ; 0x5c + if(found >= 0) { + 8007ed6: 1c72 adds r2, r6, #1 + 8007ed8: d069 beq.n 8007fae + found_slot->slot_num = found; + 8007eda: 9b00 ldr r3, [sp, #0] + 8007edc: 0174 lsls r4, r6, #5 + 8007ede: 601e str r6, [r3, #0] + memcpy(meta, &slots[found][28], 4); + 8007ee0: ab15 add r3, sp, #84 ; 0x54 + xor_mixin(meta, &tpin_hash[28], 4); + 8007ee2: 2204 movs r2, #4 + memcpy(meta, &slots[found][28], 4); + 8007ee4: 591b ldr r3, [r3, r4] + 8007ee6: 9305 str r3, [sp, #20] + xor_mixin(meta, &tpin_hash[28], 4); + 8007ee8: a90d add r1, sp, #52 ; 0x34 + 8007eea: a805 add r0, sp, #20 + 8007eec: f7ff f982 bl 80071f4 + memcpy(&found_slot->tc_flags, &meta[0], 2); + 8007ef0: 9b00 ldr r3, [sp, #0] + 8007ef2: f8bd 5014 ldrh.w r5, [sp, #20] + memcpy(&found_slot->tc_arg, &meta[2], 2); + 8007ef6: 9a00 ldr r2, [sp, #0] + memcpy(&found_slot->tc_flags, &meta[0], 2); + 8007ef8: 809d strh r5, [r3, #4] + memcpy(&found_slot->tc_arg, &meta[2], 2); + 8007efa: f8bd 3016 ldrh.w r3, [sp, #22] + 8007efe: 80d3 strh r3, [r2, #6] + if(todo & TC_WORD_WALLET) { + 8007f00: 04eb lsls r3, r5, #19 + 8007f02: d513 bpl.n 8007f2c + if(found+1 < NUM_TRICKS) { + 8007f04: 2e0c cmp r6, #12 + 8007f06: dc0e bgt.n 8007f26 + memcpy(found_slot->xdata, &slots[found+1][0], 32); + 8007f08: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 8007f0c: eb0d 0403 add.w r4, sp, r3 + 8007f10: f5a4 73d0 sub.w r3, r4, #416 ; 0x1a0 + 8007f14: 3208 adds r2, #8 + 8007f16: f5a4 74c0 sub.w r4, r4, #384 ; 0x180 + 8007f1a: f853 1b04 ldr.w r1, [r3], #4 + 8007f1e: f842 1b04 str.w r1, [r2], #4 + 8007f22: 42a3 cmp r3, r4 + 8007f24: d1f9 bne.n 8007f1a + if(!safety_mode && todo) { + 8007f26: 9b01 ldr r3, [sp, #4] + 8007f28: b33b cbz r3, 8007f7a + 8007f2a: e03e b.n 8007faa + } else if(todo & TC_XPRV_WALLET) { + 8007f2c: 052f lsls r7, r5, #20 + 8007f2e: d521 bpl.n 8007f74 + if(found+2 < NUM_TRICKS) { + 8007f30: 2e0b cmp r6, #11 + 8007f32: dcf8 bgt.n 8007f26 + memcpy(&found_slot->xdata[0], &slots[found+1][0], 32); + 8007f34: 9900 ldr r1, [sp, #0] + 8007f36: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 8007f3a: 446b add r3, sp + 8007f3c: f5a3 72d0 sub.w r2, r3, #416 ; 0x1a0 + 8007f40: 3108 adds r1, #8 + 8007f42: f5a3 73c0 sub.w r3, r3, #384 ; 0x180 + 8007f46: f852 0b04 ldr.w r0, [r2], #4 + 8007f4a: f841 0b04 str.w r0, [r1], #4 + 8007f4e: 429a cmp r2, r3 + 8007f50: d1f9 bne.n 8007f46 + memcpy(&found_slot->xdata[32], &slots[found+2][0], 32); + 8007f52: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 8007f56: 9a00 ldr r2, [sp, #0] + 8007f58: eb0d 0403 add.w r4, sp, r3 + 8007f5c: f5a4 73c0 sub.w r3, r4, #384 ; 0x180 + 8007f60: 3228 adds r2, #40 ; 0x28 + 8007f62: f5a4 74b0 sub.w r4, r4, #352 ; 0x160 + 8007f66: f853 1b04 ldr.w r1, [r3], #4 + 8007f6a: f842 1b04 str.w r1, [r2], #4 + 8007f6e: 42a3 cmp r3, r4 + 8007f70: d1f9 bne.n 8007f66 + 8007f72: e7d8 b.n 8007f26 + if(!safety_mode && todo) { + 8007f74: 9b01 ldr r3, [sp, #4] + 8007f76: b9c3 cbnz r3, 8007faa + 8007f78: b1bd cbz r5, 8007faa + if(todo & TC_WIPE) { + 8007f7a: 0428 lsls r0, r5, #16 + 8007f7c: d50a bpl.n 8007f94 + mcu_key_clear(NULL); + 8007f7e: 2000 movs r0, #0 + 8007f80: f7fa fa6a bl 8002458 + if(todo == TC_WIPE) { + 8007f84: f5b5 4f00 cmp.w r5, #32768 ; 0x8000 + 8007f88: d104 bne.n 8007f94 + oled_show(screen_wiped); + 8007f8a: 480d ldr r0, [pc, #52] ; (8007fc0 ) + 8007f8c: f7f8 ff5a bl 8000e44 + LOCKUP_FOREVER(); + 8007f90: bf30 wfi + 8007f92: e7fd b.n 8007f90 + if(todo & TC_BRICK) { + 8007f94: 0469 lsls r1, r5, #17 + 8007f96: d403 bmi.n 8007fa0 + if(todo & TC_REBOOT) { + 8007f98: 05aa lsls r2, r5, #22 + 8007f9a: d504 bpl.n 8007fa6 + NVIC_SystemReset(); + 8007f9c: f7ff f918 bl 80071d0 <__NVIC_SystemReset> + fast_brick(); + 8007fa0: f7fa fb1e bl 80025e0 + 8007fa4: e7f8 b.n 8007f98 + if(todo & TC_FAKE_OUT) { + 8007fa6: 04ab lsls r3, r5, #18 + 8007fa8: d401 bmi.n 8007fae + return true; + 8007faa: 2001 movs r0, #1 + 8007fac: e745 b.n 8007e3a + found_slot->slot_num = -1; + 8007fae: 9a00 ldr r2, [sp, #0] + 8007fb0: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8007fb4: 6013 str r3, [r2, #0] + rng_delay(); + 8007fb6: f7fa fbe1 bl 800277c + 8007fba: e73d b.n 8007e38 + 8007fbc: 2009e390 .word 0x2009e390 + 8007fc0: 0800e310 .word 0x0800e310 + 8007fc4: 0801c000 .word 0x0801c000 + 8007fc8: 2009e2b0 .word 0x2009e2b0 + 8007fcc: 0801c0b0 .word 0x0801c0b0 + +08007fd0 : +{ + 8007fd0: b510 push {r4, lr} + 8007fd2: b0a2 sub sp, #136 ; 0x88 + 8007fd4: 4604 mov r4, r0 + bool is_trick = se2_test_trick_pin("!p", 2, &slot, true); + 8007fd6: 2301 movs r3, #1 + 8007fd8: 481d ldr r0, [pc, #116] ; (8008050 ) + 8007fda: aa02 add r2, sp, #8 + 8007fdc: 2102 movs r1, #2 + 8007fde: f7ff ff1b bl 8007e18 + if(!is_trick) return; + 8007fe2: b390 cbz r0, 800804a + if(num_fails >= slot.tc_arg) { + 8007fe4: f8bd 300e ldrh.w r3, [sp, #14] + 8007fe8: 42a3 cmp r3, r4 + 8007fea: dc2e bgt.n 800804a + if(slot.tc_flags & TC_WIPE) { + 8007fec: f9bd 300c ldrsh.w r3, [sp, #12] + 8007ff0: f8bd 000c ldrh.w r0, [sp, #12] + 8007ff4: 2b00 cmp r3, #0 + 8007ff6: da1c bge.n 8008032 + if(slot.tc_flags & TC_BRICK) { + 8007ff8: f410 4080 ands.w r0, r0, #16384 ; 0x4000 + 8007ffc: d00d beq.n 800801a + const mcu_key_t *cur = mcu_key_get(&valid); + 8007ffe: f10d 0007 add.w r0, sp, #7 + 8008002: f7fa fa09 bl 8002418 + if(valid) { + 8008006: f89d 3007 ldrb.w r3, [sp, #7] + 800800a: b193 cbz r3, 8008032 + mcu_key_clear(cur); + 800800c: f7fa fa24 bl 8002458 + oled_show(screen_wiped); + 8008010: 4810 ldr r0, [pc, #64] ; (8008054 ) + 8008012: f7f8 ff17 bl 8000e44 + LOCKUP_FOREVER(); + 8008016: bf30 wfi + 8008018: e7fd b.n 8008016 + mcu_key_clear(NULL); // does valid key check + 800801a: f7fa fa1d bl 8002458 + if(slot.tc_flags == TC_WIPE) { + 800801e: f8bd 300c ldrh.w r3, [sp, #12] + 8008022: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + 8008026: d104 bne.n 8008032 + oled_show(screen_wiped); + 8008028: 480a ldr r0, [pc, #40] ; (8008054 ) + 800802a: f7f8 ff0b bl 8000e44 + LOCKUP_FOREVER(); + 800802e: bf30 wfi + 8008030: e7fd b.n 800802e + if(slot.tc_flags & TC_BRICK) { + 8008032: f8bd 300c ldrh.w r3, [sp, #12] + 8008036: 045a lsls r2, r3, #17 + 8008038: d501 bpl.n 800803e + fast_brick(); + 800803a: f7fa fad1 bl 80025e0 + if(slot.tc_flags & TC_REBOOT) { + 800803e: f8bd 300c ldrh.w r3, [sp, #12] + 8008042: 059b lsls r3, r3, #22 + 8008044: d501 bpl.n 800804a + NVIC_SystemReset(); + 8008046: f7ff f8c3 bl 80071d0 <__NVIC_SystemReset> +} + 800804a: b022 add sp, #136 ; 0x88 + 800804c: bd10 pop {r4, pc} + 800804e: bf00 nop + 8008050: 0800ea2d .word 0x0800ea2d + 8008054: 0800e310 .word 0x0800e310 + +08008058 : +{ + 8008058: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800805c: b094 sub sp, #80 ; 0x50 + 800805e: 9001 str r0, [sp, #4] + se2_setup(); + 8008060: f7ff fe2e bl 8007cc0 + if(setjmp(error_env)) { + 8008064: 4848 ldr r0, [pc, #288] ; (8008188 ) + 8008066: f005 fb0d bl 800d684 + 800806a: 4604 mov r4, r0 + 800806c: 2800 cmp r0, #0 + 800806e: f040 8088 bne.w 8008182 + if((config->slot_num < 0) || (config->slot_num >= NUM_TRICKS) ) { + 8008072: 9b01 ldr r3, [sp, #4] + 8008074: 681b ldr r3, [r3, #0] + 8008076: 2b0d cmp r3, #13 + 8008078: d804 bhi.n 8008084 + if((config->slot_num >= NUM_TRICKS-1) && (config->tc_flags & TC_WORD_WALLET) ) { + 800807a: d106 bne.n 800808a + 800807c: 9b01 ldr r3, [sp, #4] + 800807e: 889b ldrh r3, [r3, #4] + 8008080: 04d9 lsls r1, r3, #19 + 8008082: d504 bpl.n 800808e + return EPIN_RANGE_ERR; + 8008084: f06f 0466 mvn.w r4, #102 ; 0x66 + 8008088: e01f b.n 80080ca + if((config->slot_num >= NUM_TRICKS-2) && (config->tc_flags & TC_XPRV_WALLET) ) { + 800808a: 2b0c cmp r3, #12 + 800808c: d103 bne.n 8008096 + 800808e: 9b01 ldr r3, [sp, #4] + 8008090: 889b ldrh r3, [r3, #4] + 8008092: 051a lsls r2, r3, #20 + 8008094: d4f6 bmi.n 8008084 + if(config->pin_len > sizeof(config->pin)) { + 8008096: 9b01 ldr r3, [sp, #4] + 8008098: 6d99 ldr r1, [r3, #88] ; 0x58 + 800809a: 2910 cmp r1, #16 + 800809c: d8f2 bhi.n 8008084 + if(config->blank_slots) { + 800809e: 6ddd ldr r5, [r3, #92] ; 0x5c + 80080a0: b31d cbz r5, 80080ea + uint8_t zeros[32] = { 0 }; + 80080a2: 2100 movs r1, #0 + 80080a4: 221c movs r2, #28 + 80080a6: a805 add r0, sp, #20 + 80080a8: 9104 str r1, [sp, #16] + 80080aa: f005 fae3 bl 800d674 + se2_write_encrypted(PGN_TRICK(i), zeros, 0, SE2_SECRETS->pairing); + 80080ae: f8df 80e4 ldr.w r8, [pc, #228] ; 8008194 + 80080b2: 4f36 ldr r7, [pc, #216] ; (800818c ) + 80080b4: 4e36 ldr r6, [pc, #216] ; (8008190 ) + for(int i=0; iblank_slots) { + 80080b8: 9a01 ldr r2, [sp, #4] + uint32_t mask = (1 << i); + 80080ba: 2301 movs r3, #1 + if(mask & config->blank_slots) { + 80080bc: 6dd2 ldr r2, [r2, #92] ; 0x5c + uint32_t mask = (1 << i); + 80080be: 40ab lsls r3, r5 + if(mask & config->blank_slots) { + 80080c0: 4213 tst r3, r2 + 80080c2: d106 bne.n 80080d2 + for(int i=0; i +} + 80080ca: 4620 mov r0, r4 + 80080cc: b014 add sp, #80 ; 0x50 + 80080ce: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + se2_write_encrypted(PGN_TRICK(i), zeros, 0, SE2_SECRETS->pairing); + 80080d2: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + 80080d6: 2200 movs r2, #0 + 80080d8: 2bff cmp r3, #255 ; 0xff + 80080da: bf0c ite eq + 80080dc: 463b moveq r3, r7 + 80080de: 4633 movne r3, r6 + 80080e0: a904 add r1, sp, #16 + 80080e2: b2e8 uxtb r0, r5 + 80080e4: f7ff fa9c bl 8007620 + 80080e8: e7ec b.n 80080c4 + trick_pin_hash(config->pin, config->pin_len, tpin_digest); + 80080ea: 9b01 ldr r3, [sp, #4] + se2_write_encrypted(PGN_TRICK(config->slot_num), tpin_digest, 0, SE2_SECRETS->pairing); + 80080ec: f8df 80a4 ldr.w r8, [pc, #164] ; 8008194 + 80080f0: 4f26 ldr r7, [pc, #152] ; (800818c ) + 80080f2: 4e27 ldr r6, [pc, #156] ; (8008190 ) + trick_pin_hash(config->pin, config->pin_len, tpin_digest); + 80080f4: f103 0048 add.w r0, r3, #72 ; 0x48 + 80080f8: aa0c add r2, sp, #48 ; 0x30 + 80080fa: f7ff fcd5 bl 8007aa8 + memcpy(&meta[0], &config->tc_flags, 2); + 80080fe: 9b01 ldr r3, [sp, #4] + 8008100: 889b ldrh r3, [r3, #4] + 8008102: f8ad 300c strh.w r3, [sp, #12] + memcpy(&meta[2], &config->tc_arg, 2); + 8008106: 9b01 ldr r3, [sp, #4] + xor_mixin(&tpin_digest[28], meta, 4); + 8008108: 2204 movs r2, #4 + memcpy(&meta[2], &config->tc_arg, 2); + 800810a: 88db ldrh r3, [r3, #6] + 800810c: f8ad 300e strh.w r3, [sp, #14] + xor_mixin(&tpin_digest[28], meta, 4); + 8008110: a903 add r1, sp, #12 + 8008112: a813 add r0, sp, #76 ; 0x4c + 8008114: f7ff f86e bl 80071f4 + se2_write_encrypted(PGN_TRICK(config->slot_num), tpin_digest, 0, SE2_SECRETS->pairing); + 8008118: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + 800811c: 9801 ldr r0, [sp, #4] + 800811e: 2bff cmp r3, #255 ; 0xff + 8008120: bf0c ite eq + 8008122: 463b moveq r3, r7 + 8008124: 4633 movne r3, r6 + 8008126: 7800 ldrb r0, [r0, #0] + 8008128: 462a mov r2, r5 + 800812a: a90c add r1, sp, #48 ; 0x30 + 800812c: f7ff fa78 bl 8007620 + if(config->tc_flags & (TC_WORD_WALLET | TC_XPRV_WALLET)) { + 8008130: 9b01 ldr r3, [sp, #4] + 8008132: 889b ldrh r3, [r3, #4] + 8008134: f403 53c0 and.w r3, r3, #6144 ; 0x1800 + 8008138: b9a3 cbnz r3, 8008164 + if(config->tc_flags & TC_XPRV_WALLET) { + 800813a: 9b01 ldr r3, [sp, #4] + 800813c: 889b ldrh r3, [r3, #4] + 800813e: 051b lsls r3, r3, #20 + 8008140: d5c3 bpl.n 80080ca + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 8008142: 9901 ldr r1, [sp, #4] + 0, SE2_SECRETS->pairing); + 8008144: 4b13 ldr r3, [pc, #76] ; (8008194 ) + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 8008146: f851 0b28 ldr.w r0, [r1], #40 + 0, SE2_SECRETS->pairing); + 800814a: f893 50b0 ldrb.w r5, [r3, #176] ; 0xb0 + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 800814e: 4a10 ldr r2, [pc, #64] ; (8008190 ) + 8008150: 4b0e ldr r3, [pc, #56] ; (800818c ) + 8008152: 3002 adds r0, #2 + 8008154: 2dff cmp r5, #255 ; 0xff + 8008156: bf18 it ne + 8008158: 4613 movne r3, r2 + 800815a: b2c0 uxtb r0, r0 + 800815c: 2200 movs r2, #0 + 800815e: f7ff fa5f bl 8007620 + 8008162: e7b2 b.n 80080ca + se2_write_encrypted(PGN_TRICK(config->slot_num+1), &config->xdata[0], + 8008164: 9901 ldr r1, [sp, #4] + 0, SE2_SECRETS->pairing); + 8008166: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + se2_write_encrypted(PGN_TRICK(config->slot_num+1), &config->xdata[0], + 800816a: f851 0b08 ldr.w r0, [r1], #8 + 800816e: 3001 adds r0, #1 + 8008170: 2bff cmp r3, #255 ; 0xff + 8008172: bf0c ite eq + 8008174: 463b moveq r3, r7 + 8008176: 4633 movne r3, r6 + 8008178: 462a mov r2, r5 + 800817a: b2c0 uxtb r0, r0 + 800817c: f7ff fa50 bl 8007620 + 8008180: e7db b.n 800813a + return EPIN_SE2_FAIL; + 8008182: f06f 0472 mvn.w r4, #114 ; 0x72 + 8008186: e7a0 b.n 80080ca + 8008188: 2009e390 .word 0x2009e390 + 800818c: 2009e2b0 .word 0x2009e2b0 + 8008190: 0801c0b0 .word 0x0801c0b0 + 8008194: 0801c000 .word 0x0801c000 + +08008198 : +// + bool +se2_encrypt_secret(const uint8_t secret[], int secret_len, int offset, + uint8_t main_slot[], uint8_t *check_value, + const uint8_t pin_digest[32]) +{ + 8008198: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 800819c: f5ad 7d10 sub.w sp, sp, #576 ; 0x240 + 80081a0: 4699 mov r9, r3 + 80081a2: 4682 mov sl, r0 + 80081a4: 460f mov r7, r1 + 80081a6: 4614 mov r4, r2 + 80081a8: f8dd 8260 ldr.w r8, [sp, #608] ; 0x260 + se2_setup(); + 80081ac: f7ff fd88 bl 8007cc0 + + bool is_valid; + const mcu_key_t *cur = mcu_key_get(&is_valid); + 80081b0: f10d 000b add.w r0, sp, #11 + 80081b4: f7fa f930 bl 8002418 + + if(!is_valid) { + 80081b8: f89d 300b ldrb.w r3, [sp, #11] + 80081bc: b953 cbnz r3, 80081d4 + if(!check_value) { + 80081be: f1b8 0f00 cmp.w r8, #0 + 80081c2: d105 bne.n 80081d0 + // problem: we are not writing the check value but it would be changed. + // ie: change long secret before real secret--unlikely + return true; + 80081c4: 2501 movs r5, #1 + ctx.num_pending = 32; + aes_done(&ctx, check_value, 32, aes_key, nonce); + } + + return false; +} + 80081c6: 4628 mov r0, r5 + 80081c8: f50d 7d10 add.w sp, sp, #576 ; 0x240 + 80081cc: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + cur = mcu_key_pick(); + 80081d0: f7fa f98a bl 80024e8 + if(se2_calc_seed_key(aes_key, cur, pin_digest)) return true; + 80081d4: 4601 mov r1, r0 + 80081d6: 9a99 ldr r2, [sp, #612] ; 0x264 + 80081d8: a807 add r0, sp, #28 + 80081da: f7ff fd3f bl 8007c5c + 80081de: 4605 mov r5, r0 + 80081e0: 2800 cmp r0, #0 + 80081e2: d1ef bne.n 80081c4 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80081e4: 4b16 ldr r3, [pc, #88] ; (8008240 ) + 80081e6: cb0f ldmia r3, {r0, r1, r2, r3} + 80081e8: ae03 add r6, sp, #12 + 80081ea: 46b4 mov ip, r6 + 80081ec: e8ac 0007 stmia.w ip!, {r0, r1, r2} + nonce[15] = offset / AES_BLOCK_SIZE; + 80081f0: 2c00 cmp r4, #0 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80081f2: f82c 3b02 strh.w r3, [ip], #2 + nonce[15] = offset / AES_BLOCK_SIZE; + 80081f6: bfb8 it lt + 80081f8: 340f addlt r4, #15 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80081fa: 0c1b lsrs r3, r3, #16 + 80081fc: f88c 3000 strb.w r3, [ip] + aes_init(&ctx); + 8008200: a80f add r0, sp, #60 ; 0x3c + nonce[15] = offset / AES_BLOCK_SIZE; + 8008202: 1124 asrs r4, r4, #4 + 8008204: 73f4 strb r4, [r6, #15] + aes_init(&ctx); + 8008206: f000 f92b bl 8008460 + aes_add(&ctx, secret, secret_len); + 800820a: 463a mov r2, r7 + 800820c: 4651 mov r1, sl + 800820e: a80f add r0, sp, #60 ; 0x3c + 8008210: f000 f92c bl 800846c + aes_done(&ctx, main_slot, secret_len, aes_key, nonce); + 8008214: 9600 str r6, [sp, #0] + 8008216: ab07 add r3, sp, #28 + 8008218: 463a mov r2, r7 + 800821a: 4649 mov r1, r9 + 800821c: a80f add r0, sp, #60 ; 0x3c + 800821e: f000 f93b bl 8008498 + if(check_value) { + 8008222: f1b8 0f00 cmp.w r8, #0 + 8008226: d0ce beq.n 80081c6 + aes_init(&ctx); + 8008228: a80f add r0, sp, #60 ; 0x3c + 800822a: f000 f919 bl 8008460 + ctx.num_pending = 32; + 800822e: 2220 movs r2, #32 + aes_done(&ctx, check_value, 32, aes_key, nonce); + 8008230: 9600 str r6, [sp, #0] + 8008232: ab07 add r3, sp, #28 + 8008234: 4641 mov r1, r8 + 8008236: a80f add r0, sp, #60 ; 0x3c + ctx.num_pending = 32; + 8008238: 928f str r2, [sp, #572] ; 0x23c + aes_done(&ctx, check_value, 32, aes_key, nonce); + 800823a: f000 f92d bl 8008498 + 800823e: e7c2 b.n 80081c6 + 8008240: 0801c090 .word 0x0801c090 + +08008244 : +// + void +se2_decrypt_secret(uint8_t secret[], int secret_len, int offset, + const uint8_t main_slot[], const uint8_t *check_value, + const uint8_t pin_digest[32], bool *is_valid) +{ + 8008244: b530 push {r4, r5, lr} + 8008246: f5ad 7d1f sub.w sp, sp, #636 ; 0x27c + 800824a: e9cd 2306 strd r2, r3, [sp, #24] + 800824e: 9005 str r0, [sp, #20] + 8008250: 9103 str r1, [sp, #12] + se2_setup(); + 8008252: f7ff fd35 bl 8007cc0 + + const mcu_key_t *cur = mcu_key_get(is_valid); + 8008256: 98a4 ldr r0, [sp, #656] ; 0x290 + 8008258: f7fa f8de bl 8002418 + if(!*is_valid) { + 800825c: 9ba4 ldr r3, [sp, #656] ; 0x290 + const mcu_key_t *cur = mcu_key_get(is_valid); + 800825e: 9004 str r0, [sp, #16] + if(!*is_valid) { + 8008260: 781b ldrb r3, [r3, #0] + 8008262: b133 cbz r3, 8008272 + // no key set? won't be able to decrypt. + return; + } + + int line_num; + if((line_num = setjmp(error_env))) { + 8008264: 4825 ldr r0, [pc, #148] ; (80082fc ) + 8008266: f005 fa0d bl 800d684 + 800826a: b128 cbz r0, 8008278 + // internal failures / broken i2c buses will come here + *is_valid = false; + 800826c: 9aa4 ldr r2, [sp, #656] ; 0x290 + 800826e: 2300 movs r3, #0 + 8008270: 7013 strb r3, [r2, #0] + + // decrypt the real data + aes_init(&ctx); + aes_add(&ctx, main_slot, secret_len); + aes_done(&ctx, secret, secret_len, aes_key, nonce); +} + 8008272: f50d 7d1f add.w sp, sp, #636 ; 0x27c + 8008276: bd30 pop {r4, r5, pc} + if(se2_calc_seed_key(aes_key, cur, pin_digest)) { + 8008278: 9aa3 ldr r2, [sp, #652] ; 0x28c + 800827a: 9904 ldr r1, [sp, #16] + 800827c: a80d add r0, sp, #52 ; 0x34 + 800827e: f7ff fced bl 8007c5c + 8008282: 2800 cmp r0, #0 + 8008284: d1f2 bne.n 800826c + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 8008286: 4b1e ldr r3, [pc, #120] ; (8008300 ) + 8008288: cb0f ldmia r3, {r0, r1, r2, r3} + 800828a: ad09 add r5, sp, #36 ; 0x24 + 800828c: 462c mov r4, r5 + 800828e: c407 stmia r4!, {r0, r1, r2} + 8008290: f824 3b02 strh.w r3, [r4], #2 + 8008294: 0c1b lsrs r3, r3, #16 + 8008296: 7023 strb r3, [r4, #0] + nonce[15] = offset / AES_BLOCK_SIZE; + 8008298: 9b06 ldr r3, [sp, #24] + 800829a: 2b00 cmp r3, #0 + 800829c: bfb8 it lt + 800829e: 330f addlt r3, #15 + 80082a0: 111b asrs r3, r3, #4 + 80082a2: 73eb strb r3, [r5, #15] + if(check_value) { + 80082a4: 9ba2 ldr r3, [sp, #648] ; 0x288 + 80082a6: b1bb cbz r3, 80082d8 + aes_init(&ctx); + 80082a8: a81d add r0, sp, #116 ; 0x74 + 80082aa: f000 f8d9 bl 8008460 + aes_add(&ctx, check_value, 32); + 80082ae: 99a2 ldr r1, [sp, #648] ; 0x288 + 80082b0: 2220 movs r2, #32 + 80082b2: a81d add r0, sp, #116 ; 0x74 + 80082b4: f000 f8da bl 800846c + aes_done(&ctx, got, 32, aes_key, nonce); + 80082b8: ab09 add r3, sp, #36 ; 0x24 + 80082ba: 9300 str r3, [sp, #0] + 80082bc: a915 add r1, sp, #84 ; 0x54 + 80082be: a81d add r0, sp, #116 ; 0x74 + 80082c0: ab0d add r3, sp, #52 ; 0x34 + 80082c2: 2220 movs r2, #32 + 80082c4: f000 f8e8 bl 8008498 + if(!check_all_zeros(got, 32)) { + 80082c8: 2120 movs r1, #32 + 80082ca: a815 add r0, sp, #84 ; 0x54 + 80082cc: f7fa f9e2 bl 8002694 + 80082d0: b910 cbnz r0, 80082d8 + *is_valid = false; + 80082d2: 9ba4 ldr r3, [sp, #656] ; 0x290 + 80082d4: 7018 strb r0, [r3, #0] + return; + 80082d6: e7cc b.n 8008272 + aes_init(&ctx); + 80082d8: a81d add r0, sp, #116 ; 0x74 + 80082da: f000 f8c1 bl 8008460 + aes_add(&ctx, main_slot, secret_len); + 80082de: 9a03 ldr r2, [sp, #12] + 80082e0: 9907 ldr r1, [sp, #28] + 80082e2: a81d add r0, sp, #116 ; 0x74 + 80082e4: f000 f8c2 bl 800846c + aes_done(&ctx, secret, secret_len, aes_key, nonce); + 80082e8: ab09 add r3, sp, #36 ; 0x24 + 80082ea: 9300 str r3, [sp, #0] + 80082ec: 9a03 ldr r2, [sp, #12] + 80082ee: 9905 ldr r1, [sp, #20] + 80082f0: ab0d add r3, sp, #52 ; 0x34 + 80082f2: a81d add r0, sp, #116 ; 0x74 + 80082f4: f000 f8d0 bl 8008498 + 80082f8: e7bb b.n 8008272 + 80082fa: bf00 nop + 80082fc: 2009e390 .word 0x2009e390 + 8008300: 0801c090 .word 0x0801c090 + +08008304 : +// +// Hash up a PIN code for login attempt: to tie it into SE2's contents. +// + void +se2_pin_hash(uint8_t digest_io[32], uint32_t purpose) +{ + 8008304: b5f0 push {r4, r5, r6, r7, lr} + if(purpose != PIN_PURPOSE_NORMAL) { + 8008306: 4b41 ldr r3, [pc, #260] ; (800840c ) +{ + 8008308: b0d5 sub sp, #340 ; 0x154 + if(purpose != PIN_PURPOSE_NORMAL) { + 800830a: 4299 cmp r1, r3 +{ + 800830c: e9cd 0100 strd r0, r1, [sp] + if(purpose != PIN_PURPOSE_NORMAL) { + 8008310: d17a bne.n 8008408 + // do nothing except for real PIN case (ie. not for prefix words) + return; + } + + se2_setup(); + 8008312: f7ff fcd5 bl 8007cc0 + if((setjmp(error_env))) { + 8008316: 483e ldr r0, [pc, #248] ; (8008410 ) + 8008318: f005 f9b4 bl 800d684 + 800831c: 4604 mov r4, r0 + 800831e: b120 cbz r0, 800832a + oled_show(screen_se2_issue); + 8008320: 483c ldr r0, [pc, #240] ; (8008414 ) + 8008322: f7f8 fd8f bl 8000e44 + + LOCKUP_FOREVER(); + 8008326: bf30 wfi + 8008328: e7fd b.n 8008326 + uint8_t rx[34]; // 2 bytes of len+status, then 32 bytes of data + uint8_t tmp[32]; + HMAC_CTX ctx; + + // HMAC(key=tpin_key, msg=given hash so far) + hmac_sha256_init(&ctx); + 800832a: a813 add r0, sp, #76 ; 0x4c + 800832c: f7fd f936 bl 800559c + hmac_sha256_update(&ctx, digest_io, 32); + 8008330: 9900 ldr r1, [sp, #0] + 8008332: 2220 movs r2, #32 + 8008334: a813 add r0, sp, #76 ; 0x4c + 8008336: f7fd f937 bl 80055a8 + hmac_sha256_update(&ctx, (uint8_t *)&purpose, 4); + 800833a: 2204 movs r2, #4 + 800833c: eb0d 0102 add.w r1, sp, r2 + 8008340: a813 add r0, sp, #76 ; 0x4c + 8008342: f7fd f931 bl 80055a8 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, tmp); + 8008346: 4b34 ldr r3, [pc, #208] ; (8008418 ) + 8008348: 4934 ldr r1, [pc, #208] ; (800841c ) + 800834a: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 800834e: 33b0 adds r3, #176 ; 0xb0 + 8008350: 2aff cmp r2, #255 ; 0xff + 8008352: bf18 it ne + 8008354: 4619 movne r1, r3 + 8008356: 3180 adds r1, #128 ; 0x80 + 8008358: aa02 add r2, sp, #8 + 800835a: a813 add r0, sp, #76 ; 0x4c + 800835c: f7fd f93a bl 80055d4 + + // NOTE: exposed as cleartext here + se2_write_buffer(tmp, 32); + 8008360: 2120 movs r1, #32 + 8008362: a802 add r0, sp, #8 + 8008364: f7fe ffc2 bl 80072ec + 8008368: 25aa movs r5, #170 ; 0xaa + se2_write_buffer(rx+2, 32); + } + + // HMAC(key=secret-B, msg=consts+easy_key+buffer+consts) + // - result put in secret-S (ram) + CALL_CHECK(se2_write2(0x3c, (2<<6) | (1<<4) | PGN_SE2_EASY_KEY, 0)); + 800836a: 269e movs r6, #158 ; 0x9e + 800836c: 273c movs r7, #60 ; 0x3c + 800836e: 4622 mov r2, r4 + 8008370: 4631 mov r1, r6 + 8008372: 4638 mov r0, r7 + 8008374: f7fe ff66 bl 8007244 + 8008378: b150 cbz r0, 8008390 + 800837a: f240 511d movw r1, #1309 ; 0x51d + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 800837e: 4824 ldr r0, [pc, #144] ; (8008410 ) + 8008380: f005 f986 bl 800d690 + se2_write_buffer(rx+2, 32); + 8008384: 2120 movs r1, #32 + 8008386: f10d 002a add.w r0, sp, #42 ; 0x2a + 800838a: f7fe ffaf bl 80072ec + 800838e: e7ee b.n 800836e + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8008390: f7fe ffe4 bl 800735c + 8008394: 28aa cmp r0, #170 ; 0xaa + 8008396: d002 beq.n 800839e + 8008398: f240 511e movw r1, #1310 ; 0x51e + 800839c: e7ef b.n 800837e + + // HMAC(key=S, msg=counter+junk), so we have something to read out + // - not 100% clear what contents of 'buffer' are here, but seems + // to be deterministic and unchanged from prev command + CALL_CHECK(se2_write1(0xa5, (2<<5) | PGN_DEC_COUNTER)); + 800839e: 215b movs r1, #91 ; 0x5b + 80083a0: 20a5 movs r0, #165 ; 0xa5 + 80083a2: f7fe ff35 bl 8007210 + 80083a6: b110 cbz r0, 80083ae + 80083a8: f240 5123 movw r1, #1315 ; 0x523 + 80083ac: e7e7 b.n 800837e + + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 80083ae: a90a add r1, sp, #40 ; 0x28 + 80083b0: 2022 movs r0, #34 ; 0x22 + 80083b2: f7fe ffab bl 800730c + 80083b6: 28aa cmp r0, #170 ; 0xaa + 80083b8: d002 beq.n 80083c0 + 80083ba: f240 5125 movw r1, #1317 ; 0x525 + 80083be: e7de b.n 800837e + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 80083c0: f89d 3029 ldrb.w r3, [sp, #41] ; 0x29 + 80083c4: 2baa cmp r3, #170 ; 0xaa + 80083c6: d002 beq.n 80083ce + 80083c8: f240 5126 movw r1, #1318 ; 0x526 + 80083cc: e7d7 b.n 800837e + for(int i=0; i + } + + // one final HMAC because we had to read cleartext from bus + hmac_sha256_init(&ctx); + 80083d2: a813 add r0, sp, #76 ; 0x4c + 80083d4: f7fd f8e2 bl 800559c + hmac_sha256_update(&ctx, rx+2, 32); + 80083d8: 2220 movs r2, #32 + 80083da: f10d 012a add.w r1, sp, #42 ; 0x2a + 80083de: a813 add r0, sp, #76 ; 0x4c + 80083e0: f7fd f8e2 bl 80055a8 + hmac_sha256_update(&ctx, digest_io, 32); + 80083e4: 9900 ldr r1, [sp, #0] + 80083e6: 2220 movs r2, #32 + 80083e8: a813 add r0, sp, #76 ; 0x4c + 80083ea: f7fd f8dd bl 80055a8 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, digest_io); + 80083ee: 4b0a ldr r3, [pc, #40] ; (8008418 ) + 80083f0: 490a ldr r1, [pc, #40] ; (800841c ) + 80083f2: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80083f6: 33b0 adds r3, #176 ; 0xb0 + 80083f8: 2aff cmp r2, #255 ; 0xff + 80083fa: bf18 it ne + 80083fc: 4619 movne r1, r3 + 80083fe: 3180 adds r1, #128 ; 0x80 + 8008400: 9a00 ldr r2, [sp, #0] + 8008402: a813 add r0, sp, #76 ; 0x4c + 8008404: f7fd f8e6 bl 80055d4 +} + 8008408: b055 add sp, #340 ; 0x154 + 800840a: bdf0 pop {r4, r5, r6, r7, pc} + 800840c: 334d1858 .word 0x334d1858 + 8008410: 2009e390 .word 0x2009e390 + 8008414: 0800dfce .word 0x0800dfce + 8008418: 0801c000 .word 0x0801c000 + 800841c: 2009e2b0 .word 0x2009e2b0 + +08008420 : +// +// Read some random bytes, which we know cannot be MitM'ed. +// + void +se2_read_rng(uint8_t value[8]) +{ + 8008420: b500 push {lr} + 8008422: b08b sub sp, #44 ; 0x2c + 8008424: 9001 str r0, [sp, #4] + // funny business means MitM here + se2_setup(); + 8008426: f7ff fc4b bl 8007cc0 + if(setjmp(error_env)) fatal_mitm(); + 800842a: 4809 ldr r0, [pc, #36] ; (8008450 ) + 800842c: f005 f92a bl 800d684 + 8008430: b108 cbz r0, 8008436 + 8008432: f7f8 fb13 bl 8000a5c + + // read a field with "RPS" bytes, and verify those were read true + uint8_t tmp[32]; + se2_read_page(PGN_ROM_OPTIONS, tmp, true); + 8008436: a902 add r1, sp, #8 + 8008438: 2201 movs r2, #1 + 800843a: 201c movs r0, #28 + 800843c: f7ff f82a bl 8007494 + + memcpy(value, &tmp[4], 8); + 8008440: ab03 add r3, sp, #12 + 8008442: cb03 ldmia r3!, {r0, r1} + 8008444: 9b01 ldr r3, [sp, #4] + 8008446: 6018 str r0, [r3, #0] + 8008448: 6059 str r1, [r3, #4] +} + 800844a: b00b add sp, #44 ; 0x2c + 800844c: f85d fb04 ldr.w pc, [sp], #4 + 8008450: 2009e390 .word 0x2009e390 + +08008454 : + uint32_t rv; + + if(((uint32_t)src) & 0x3) { + memcpy(&rv, *src, 4); + } else { + rv = *(uint32_t *)(*src); + 8008454: 6803 ldr r3, [r0, #0] + 8008456: f853 2b04 ldr.w r2, [r3], #4 + } + (*src) += 4; + 800845a: 6003 str r3, [r0, #0] + + return __REV(rv); +} + 800845c: ba10 rev r0, r2 + 800845e: 4770 bx lr + +08008460 : + memset(ctx, 0, sizeof(AES_CTX)); + 8008460: f44f 7201 mov.w r2, #516 ; 0x204 + 8008464: 2100 movs r1, #0 + 8008466: f005 b905 b.w 800d674 + ... + +0800846c : +{ + 800846c: b538 push {r3, r4, r5, lr} + 800846e: 4605 mov r5, r0 + memcpy(ctx->pending+ctx->num_pending, data_in, len); + 8008470: f8d0 0200 ldr.w r0, [r0, #512] ; 0x200 + 8008474: 4428 add r0, r5 +{ + 8008476: 4614 mov r4, r2 + memcpy(ctx->pending+ctx->num_pending, data_in, len); + 8008478: f005 f8d4 bl 800d624 + ctx->num_pending += len; + 800847c: f8d5 2200 ldr.w r2, [r5, #512] ; 0x200 + 8008480: 4422 add r2, r4 + ASSERT(ctx->num_pending < sizeof(ctx->pending)); + 8008482: f5b2 7f00 cmp.w r2, #512 ; 0x200 + ctx->num_pending += len; + 8008486: f8c5 2200 str.w r2, [r5, #512] ; 0x200 + ASSERT(ctx->num_pending < sizeof(ctx->pending)); + 800848a: d302 bcc.n 8008492 + 800848c: 4801 ldr r0, [pc, #4] ; (8008494 ) + 800848e: f7f8 fadb bl 8000a48 +} + 8008492: bd38 pop {r3, r4, r5, pc} + 8008494: 0800e3e0 .word 0x0800e3e0 + +08008498 : +// +// Do the decryption. +// + void +aes_done(AES_CTX *ctx, uint8_t data_out[], uint32_t len, const uint8_t key[32], const uint8_t nonce[AES_BLOCK_SIZE]) +{ + 8008498: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 800849c: 4688 mov r8, r1 + 800849e: 4611 mov r1, r2 + ASSERT(len <= ctx->num_pending); + 80084a0: f8d0 2200 ldr.w r2, [r0, #512] ; 0x200 +{ + 80084a4: b085 sub sp, #20 + ASSERT(len <= ctx->num_pending); + 80084a6: 428a cmp r2, r1 +{ + 80084a8: f8dd 9030 ldr.w r9, [sp, #48] ; 0x30 + 80084ac: 4606 mov r6, r0 + ASSERT(len <= ctx->num_pending); + 80084ae: d202 bcs.n 80084b6 + 80084b0: 4858 ldr r0, [pc, #352] ; (8008614 ) + 80084b2: f7f8 fac9 bl 8000a48 + + // enable clock to block + __HAL_RCC_AES_CLK_ENABLE(); + 80084b6: 4d58 ldr r5, [pc, #352] ; (8008618 ) + + // most changes have to be made w/ module disabled + AES->CR &= ~AES_CR_EN; + 80084b8: 4c58 ldr r4, [pc, #352] ; (800861c ) + __HAL_RCC_AES_CLK_ENABLE(); + 80084ba: 6cea ldr r2, [r5, #76] ; 0x4c + 80084bc: f442 3280 orr.w r2, r2, #65536 ; 0x10000 + 80084c0: 64ea str r2, [r5, #76] ; 0x4c + 80084c2: 6cea ldr r2, [r5, #76] ; 0x4c + 80084c4: f402 3280 and.w r2, r2, #65536 ; 0x10000 + 80084c8: 9201 str r2, [sp, #4] + 80084ca: 9a01 ldr r2, [sp, #4] + AES->CR &= ~AES_CR_EN; + 80084cc: 6822 ldr r2, [r4, #0] + 80084ce: f022 0201 bic.w r2, r2, #1 + 80084d2: 6022 str r2, [r4, #0] + + // set the key size and operation mode + MODIFY_REG(AES->CR, AES_CR_KEYSIZE, CRYP_KEYSIZE_256B); + 80084d4: 6822 ldr r2, [r4, #0] + 80084d6: f442 2280 orr.w r2, r2, #262144 ; 0x40000 + 80084da: 6022 str r2, [r4, #0] + MODIFY_REG(AES->CR, AES_CR_DATATYPE|AES_CR_MODE|AES_CR_CHMOD, + 80084dc: 6827 ldr r7, [r4, #0] + 80084de: f427 3780 bic.w r7, r7, #65536 ; 0x10000 + 80084e2: f027 077e bic.w r7, r7, #126 ; 0x7e + 80084e6: f047 0744 orr.w r7, r7, #68 ; 0x44 + 80084ea: 6027 str r7, [r4, #0] + CRYP_DATATYPE_8B | CRYP_ALGOMODE_ENCRYPT | CRYP_CHAINMODE_AES_CTR); + + // load key and IV values + const uint8_t *K = key; + AES->KEYR7 = word_pump_bytes(&K); + 80084ec: a802 add r0, sp, #8 + const uint8_t *K = key; + 80084ee: 9302 str r3, [sp, #8] + AES->KEYR7 = word_pump_bytes(&K); + 80084f0: f7ff ffb0 bl 8008454 + 80084f4: 63e0 str r0, [r4, #60] ; 0x3c + AES->KEYR6 = word_pump_bytes(&K); + 80084f6: a802 add r0, sp, #8 + 80084f8: f7ff ffac bl 8008454 + 80084fc: 63a0 str r0, [r4, #56] ; 0x38 + AES->KEYR5 = word_pump_bytes(&K); + 80084fe: a802 add r0, sp, #8 + 8008500: f7ff ffa8 bl 8008454 + 8008504: 6360 str r0, [r4, #52] ; 0x34 + AES->KEYR4 = word_pump_bytes(&K); + 8008506: a802 add r0, sp, #8 + 8008508: f7ff ffa4 bl 8008454 + 800850c: 6320 str r0, [r4, #48] ; 0x30 + AES->KEYR3 = word_pump_bytes(&K); + 800850e: a802 add r0, sp, #8 + 8008510: f7ff ffa0 bl 8008454 + 8008514: 61e0 str r0, [r4, #28] + AES->KEYR2 = word_pump_bytes(&K); + 8008516: a802 add r0, sp, #8 + 8008518: f7ff ff9c bl 8008454 + 800851c: 61a0 str r0, [r4, #24] + AES->KEYR1 = word_pump_bytes(&K); + 800851e: a802 add r0, sp, #8 + 8008520: f7ff ff98 bl 8008454 + 8008524: 6160 str r0, [r4, #20] + AES->KEYR0 = word_pump_bytes(&K); + 8008526: a802 add r0, sp, #8 + 8008528: f7ff ff94 bl 8008454 + 800852c: 6120 str r0, [r4, #16] + + if(nonce) { + 800852e: f1b9 0f00 cmp.w r9, #0 + 8008532: d045 beq.n 80085c0 + const uint8_t *N = nonce; + AES->IVR3 = word_pump_bytes(&N); + 8008534: a803 add r0, sp, #12 + const uint8_t *N = nonce; + 8008536: f8cd 900c str.w r9, [sp, #12] + AES->IVR3 = word_pump_bytes(&N); + 800853a: f7ff ff8b bl 8008454 + 800853e: 62e0 str r0, [r4, #44] ; 0x2c + AES->IVR2 = word_pump_bytes(&N); + 8008540: a803 add r0, sp, #12 + 8008542: f7ff ff87 bl 8008454 + 8008546: 62a0 str r0, [r4, #40] ; 0x28 + AES->IVR1 = word_pump_bytes(&N); + 8008548: a803 add r0, sp, #12 + 800854a: f7ff ff83 bl 8008454 + 800854e: 6260 str r0, [r4, #36] ; 0x24 + AES->IVR0 = word_pump_bytes(&N); + 8008550: a803 add r0, sp, #12 + 8008552: f7ff ff7f bl 8008454 + 8008556: 6220 str r0, [r4, #32] + AES->IVR1 = 0; + AES->IVR0 = 0; // maybe should be byte-swapped one, but whatever + } + + // Enable the Peripheral + AES->CR |= AES_CR_EN; + 8008558: 4b30 ldr r3, [pc, #192] ; (800861c ) + 800855a: 681a ldr r2, [r3, #0] + + ASSERT((((uint32_t)&ctx->pending) & 3) == 0); // safe because of special attr + 800855c: 07b0 lsls r0, r6, #30 + AES->CR |= AES_CR_EN; + 800855e: f042 0201 orr.w r2, r2, #1 + 8008562: 601a str r2, [r3, #0] + ASSERT((((uint32_t)&ctx->pending) & 3) == 0); // safe because of special attr + 8008564: d1a4 bne.n 80084b0 + + uint32_t *p = (uint32_t *)ctx->pending; + for(int i=0; i < ctx->num_pending; i += 16) { + 8008566: f06f 070f mvn.w r7, #15 + 800856a: f8d6 0200 ldr.w r0, [r6, #512] ; 0x200 + 800856e: f106 0410 add.w r4, r6, #16 + 8008572: 1bbf subs r7, r7, r6 + 8008574: 193a adds r2, r7, r4 + 8008576: 4282 cmp r2, r0 + 8008578: db2b blt.n 80085d2 + *out = AES->DOUTR; out++; + *out = AES->DOUTR; out++; + *out = AES->DOUTR; + } + + memcpy(data_out, ctx->pending, len); + 800857a: 460a mov r2, r1 + 800857c: 4640 mov r0, r8 + 800857e: 4631 mov r1, r6 + 8008580: f005 f850 bl 800d624 + + memset(ctx, 0, sizeof(AES_CTX)); + 8008584: f44f 7201 mov.w r2, #516 ; 0x204 + 8008588: 2100 movs r1, #0 + 800858a: 4630 mov r0, r6 + 800858c: f005 f872 bl 800d674 + + // reset state of chip block, and leave clock off as well + __HAL_RCC_AES_CLK_ENABLE(); + 8008590: 6ceb ldr r3, [r5, #76] ; 0x4c + 8008592: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8008596: 64eb str r3, [r5, #76] ; 0x4c + 8008598: 6ceb ldr r3, [r5, #76] ; 0x4c + 800859a: f403 3380 and.w r3, r3, #65536 ; 0x10000 + 800859e: 9303 str r3, [sp, #12] + 80085a0: 9b03 ldr r3, [sp, #12] + __HAL_RCC_AES_FORCE_RESET(); + 80085a2: 6aeb ldr r3, [r5, #44] ; 0x2c + 80085a4: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 80085a8: 62eb str r3, [r5, #44] ; 0x2c + __HAL_RCC_AES_RELEASE_RESET(); + 80085aa: 6aeb ldr r3, [r5, #44] ; 0x2c + 80085ac: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 80085b0: 62eb str r3, [r5, #44] ; 0x2c + __HAL_RCC_AES_CLK_DISABLE(); + 80085b2: 6ceb ldr r3, [r5, #76] ; 0x4c + 80085b4: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 80085b8: 64eb str r3, [r5, #76] ; 0x4c +} + 80085ba: b005 add sp, #20 + 80085bc: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + AES->IVR3 = 0; + 80085c0: f8c4 902c str.w r9, [r4, #44] ; 0x2c + AES->IVR2 = 0; + 80085c4: f8c4 9028 str.w r9, [r4, #40] ; 0x28 + AES->IVR1 = 0; + 80085c8: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + AES->IVR0 = 0; // maybe should be byte-swapped one, but whatever + 80085cc: f8c4 9020 str.w r9, [r4, #32] + 80085d0: e7c2 b.n 8008558 + AES->DINR = *p; p++; + 80085d2: f854 2c10 ldr.w r2, [r4, #-16] + 80085d6: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80085d8: f854 2c0c ldr.w r2, [r4, #-12] + 80085dc: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80085de: f854 2c08 ldr.w r2, [r4, #-8] + 80085e2: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80085e4: f854 2c04 ldr.w r2, [r4, #-4] + 80085e8: 609a str r2, [r3, #8] + while(HAL_IS_BIT_CLR(AES->SR, AES_SR_CCF)) { + 80085ea: 685a ldr r2, [r3, #4] + 80085ec: 07d2 lsls r2, r2, #31 + 80085ee: d5fc bpl.n 80085ea + SET_BIT(AES->CR, CRYP_CCF_CLEAR); + 80085f0: 681a ldr r2, [r3, #0] + 80085f2: f042 0280 orr.w r2, r2, #128 ; 0x80 + 80085f6: 601a str r2, [r3, #0] + *out = AES->DOUTR; out++; + 80085f8: 68da ldr r2, [r3, #12] + 80085fa: f844 2c10 str.w r2, [r4, #-16] + *out = AES->DOUTR; out++; + 80085fe: 68da ldr r2, [r3, #12] + 8008600: f844 2c0c str.w r2, [r4, #-12] + *out = AES->DOUTR; out++; + 8008604: 68da ldr r2, [r3, #12] + 8008606: f844 2c08 str.w r2, [r4, #-8] + *out = AES->DOUTR; + 800860a: 68da ldr r2, [r3, #12] + 800860c: f844 2c04 str.w r2, [r4, #-4] + for(int i=0; i < ctx->num_pending; i += 16) { + 8008610: 3410 adds r4, #16 + 8008612: e7af b.n 8008574 + 8008614: 0800e3e0 .word 0x0800e3e0 + 8008618: 40021000 .word 0x40021000 + 800861c: 50060000 .word 0x50060000 + +08008620 : + voltage range. + * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11 + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange) +{ + 8008620: b537 push {r0, r1, r2, r4, r5, lr} + uint32_t vos; + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + + if(__HAL_RCC_PWR_IS_CLK_ENABLED()) + 8008622: 4d1c ldr r5, [pc, #112] ; (8008694 ) + 8008624: 6dab ldr r3, [r5, #88] ; 0x58 + 8008626: 00da lsls r2, r3, #3 +{ + 8008628: 4604 mov r4, r0 + if(__HAL_RCC_PWR_IS_CLK_ENABLED()) + 800862a: d518 bpl.n 800865e + { + vos = HAL_PWREx_GetVoltageRange(); + 800862c: f7fe fd62 bl 80070f4 + __HAL_RCC_PWR_CLK_ENABLE(); + vos = HAL_PWREx_GetVoltageRange(); + __HAL_RCC_PWR_CLK_DISABLE(); + } + + if(vos == PWR_REGULATOR_VOLTAGE_SCALE1) + 8008630: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8008634: d123 bne.n 800867e + { + if(msirange > RCC_MSIRANGE_8) + 8008636: 2c80 cmp r4, #128 ; 0x80 + 8008638: d928 bls.n 800868c + latency = FLASH_LATENCY_2; /* 2WS */ + } + else + { + /* MSI 24Mhz or 32Mhz */ + latency = FLASH_LATENCY_1; /* 1WS */ + 800863a: 2ca0 cmp r4, #160 ; 0xa0 + 800863c: bf8c ite hi + 800863e: 2002 movhi r0, #2 + 8008640: 2001 movls r0, #1 + /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */ + } +#endif + } + + __HAL_FLASH_SET_LATENCY(latency); + 8008642: 4a15 ldr r2, [pc, #84] ; (8008698 ) + 8008644: 6813 ldr r3, [r2, #0] + 8008646: f023 030f bic.w r3, r3, #15 + 800864a: 4303 orrs r3, r0 + 800864c: 6013 str r3, [r2, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != latency) + 800864e: 6813 ldr r3, [r2, #0] + 8008650: f003 030f and.w r3, r3, #15 + { + return HAL_ERROR; + } + + return HAL_OK; +} + 8008654: 1a18 subs r0, r3, r0 + 8008656: bf18 it ne + 8008658: 2001 movne r0, #1 + 800865a: b003 add sp, #12 + 800865c: bd30 pop {r4, r5, pc} + __HAL_RCC_PWR_CLK_ENABLE(); + 800865e: 6dab ldr r3, [r5, #88] ; 0x58 + 8008660: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 8008664: 65ab str r3, [r5, #88] ; 0x58 + 8008666: 6dab ldr r3, [r5, #88] ; 0x58 + 8008668: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 800866c: 9301 str r3, [sp, #4] + 800866e: 9b01 ldr r3, [sp, #4] + vos = HAL_PWREx_GetVoltageRange(); + 8008670: f7fe fd40 bl 80070f4 + __HAL_RCC_PWR_CLK_DISABLE(); + 8008674: 6dab ldr r3, [r5, #88] ; 0x58 + 8008676: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800867a: 65ab str r3, [r5, #88] ; 0x58 + 800867c: e7d8 b.n 8008630 + if(msirange >= RCC_MSIRANGE_8) + 800867e: 2c7f cmp r4, #127 ; 0x7f + 8008680: d806 bhi.n 8008690 + if(msirange == RCC_MSIRANGE_7) + 8008682: f1a4 0370 sub.w r3, r4, #112 ; 0x70 + 8008686: 4258 negs r0, r3 + 8008688: 4158 adcs r0, r3 + 800868a: e7da b.n 8008642 + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + 800868c: 2000 movs r0, #0 + 800868e: e7d8 b.n 8008642 + latency = FLASH_LATENCY_2; /* 2WS */ + 8008690: 2002 movs r0, #2 + 8008692: e7d6 b.n 8008642 + 8008694: 40021000 .word 0x40021000 + 8008698: 40022000 .word 0x40022000 + +0800869c : +{ + 800869c: b5f8 push {r3, r4, r5, r6, r7, lr} + SET_BIT(RCC->CR, RCC_CR_MSION); + 800869e: 4c32 ldr r4, [pc, #200] ; (8008768 ) + 80086a0: 6823 ldr r3, [r4, #0] + 80086a2: f043 0301 orr.w r3, r3, #1 + 80086a6: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80086a8: f7fe fd20 bl 80070ec + 80086ac: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 80086ae: 6823 ldr r3, [r4, #0] + 80086b0: 079b lsls r3, r3, #30 + 80086b2: d543 bpl.n 800873c + MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6); + 80086b4: 6823 ldr r3, [r4, #0] + SystemCoreClock = MSI_VALUE; + 80086b6: 4a2d ldr r2, [pc, #180] ; (800876c ) + MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6); + 80086b8: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 80086bc: f043 0360 orr.w r3, r3, #96 ; 0x60 + 80086c0: 6023 str r3, [r4, #0] + CLEAR_REG(RCC->CFGR); + 80086c2: 2300 movs r3, #0 + 80086c4: 60a3 str r3, [r4, #8] + SystemCoreClock = MSI_VALUE; + 80086c6: 4b2a ldr r3, [pc, #168] ; (8008770 ) + 80086c8: 601a str r2, [r3, #0] + if(HAL_InitTick(uwTickPrio) != HAL_OK) + 80086ca: 4b2a ldr r3, [pc, #168] ; (8008774 ) + 80086cc: 6818 ldr r0, [r3, #0] + 80086ce: f7fe fd0f bl 80070f0 + 80086d2: 4605 mov r5, r0 + 80086d4: 2800 cmp r0, #0 + 80086d6: d145 bne.n 8008764 + tickstart = HAL_GetTick(); + 80086d8: f7fe fd08 bl 80070ec + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 80086dc: f241 3788 movw r7, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 80086e0: 4606 mov r6, r0 + while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + 80086e2: 68a3 ldr r3, [r4, #8] + 80086e4: f013 0f0c tst.w r3, #12 + 80086e8: d130 bne.n 800874c + CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON); + 80086ea: 6822 ldr r2, [r4, #0] + 80086ec: 4b22 ldr r3, [pc, #136] ; (8008778 ) + 80086ee: 4013 ands r3, r2 + 80086f0: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80086f2: f7fe fcfb bl 80070ec + 80086f6: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U) + 80086f8: 6823 ldr r3, [r4, #0] + 80086fa: f013 5328 ands.w r3, r3, #704643072 ; 0x2a000000 + 80086fe: d12b bne.n 8008758 + CLEAR_REG(RCC->PLLCFGR); + 8008700: 60e3 str r3, [r4, #12] + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 ); + 8008702: 68e2 ldr r2, [r4, #12] + 8008704: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8008708: 60e2 str r2, [r4, #12] + CLEAR_REG(RCC->PLLSAI1CFGR); + 800870a: 6123 str r3, [r4, #16] + SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 ); + 800870c: 6922 ldr r2, [r4, #16] + 800870e: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8008712: 6122 str r2, [r4, #16] + CLEAR_REG(RCC->PLLSAI2CFGR); + 8008714: 6163 str r3, [r4, #20] + SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 ); + 8008716: 6962 ldr r2, [r4, #20] + 8008718: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800871c: 6162 str r2, [r4, #20] + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + 800871e: 6822 ldr r2, [r4, #0] + 8008720: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 8008724: 6022 str r2, [r4, #0] + CLEAR_REG(RCC->CIER); + 8008726: 61a3 str r3, [r4, #24] + WRITE_REG(RCC->CICR, 0xFFFFFFFFU); + 8008728: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800872c: 6223 str r3, [r4, #32] + SET_BIT(RCC->CSR, RCC_CSR_RMVF); + 800872e: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008732: f443 0300 orr.w r3, r3, #8388608 ; 0x800000 + 8008736: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + return HAL_OK; + 800873a: e005 b.n 8008748 + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 800873c: f7fe fcd6 bl 80070ec + 8008740: 1b40 subs r0, r0, r5 + 8008742: 2802 cmp r0, #2 + 8008744: d9b3 bls.n 80086ae + return HAL_TIMEOUT; + 8008746: 2503 movs r5, #3 +} + 8008748: 4628 mov r0, r5 + 800874a: bdf8 pop {r3, r4, r5, r6, r7, pc} + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 800874c: f7fe fcce bl 80070ec + 8008750: 1b80 subs r0, r0, r6 + 8008752: 42b8 cmp r0, r7 + 8008754: d9c5 bls.n 80086e2 + 8008756: e7f6 b.n 8008746 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008758: f7fe fcc8 bl 80070ec + 800875c: 1b80 subs r0, r0, r6 + 800875e: 2802 cmp r0, #2 + 8008760: d9ca bls.n 80086f8 + 8008762: e7f0 b.n 8008746 + return HAL_ERROR; + 8008764: 2501 movs r5, #1 + 8008766: e7ef b.n 8008748 + 8008768: 40021000 .word 0x40021000 + 800876c: 003d0900 .word 0x003d0900 + 8008770: 2009e2a8 .word 0x2009e2a8 + 8008774: 2009e2ac .word 0x2009e2ac + 8008778: eafef4ff .word 0xeafef4ff + +0800877c : +{ + 800877c: b570 push {r4, r5, r6, lr} + __MCO1_CLK_ENABLE(); + 800877e: 4c12 ldr r4, [pc, #72] ; (80087c8 ) + 8008780: 6ce3 ldr r3, [r4, #76] ; 0x4c + 8008782: f043 0301 orr.w r3, r3, #1 + 8008786: 64e3 str r3, [r4, #76] ; 0x4c + 8008788: 6ce3 ldr r3, [r4, #76] ; 0x4c +{ + 800878a: b086 sub sp, #24 + __MCO1_CLK_ENABLE(); + 800878c: f003 0301 and.w r3, r3, #1 + 8008790: 9300 str r3, [sp, #0] + 8008792: 9b00 ldr r3, [sp, #0] +{ + 8008794: 4616 mov r6, r2 + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + 8008796: 2302 movs r3, #2 + 8008798: f44f 7280 mov.w r2, #256 ; 0x100 + 800879c: e9cd 2301 strd r2, r3, [sp, #4] +{ + 80087a0: 460d mov r5, r1 + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + 80087a2: 9304 str r3, [sp, #16] + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 80087a4: a901 add r1, sp, #4 + GPIO_InitStruct.Pull = GPIO_NOPULL; + 80087a6: 2300 movs r3, #0 + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 80087a8: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + GPIO_InitStruct.Pull = GPIO_NOPULL; + 80087ac: 9303 str r3, [sp, #12] + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + 80087ae: 9305 str r3, [sp, #20] + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 80087b0: f7f8 fc2e bl 8001010 + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv )); + 80087b4: 68a3 ldr r3, [r4, #8] + 80087b6: f023 43fe bic.w r3, r3, #2130706432 ; 0x7f000000 + 80087ba: ea43 0206 orr.w r2, r3, r6 + 80087be: 432a orrs r2, r5 + 80087c0: 60a2 str r2, [r4, #8] +} + 80087c2: b006 add sp, #24 + 80087c4: bd70 pop {r4, r5, r6, pc} + 80087c6: bf00 nop + 80087c8: 40021000 .word 0x40021000 + +080087cc : + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 80087cc: 4b22 ldr r3, [pc, #136] ; (8008858 ) + 80087ce: 689a ldr r2, [r3, #8] + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 80087d0: 68d9 ldr r1, [r3, #12] + if((sysclk_source == RCC_CFGR_SWS_MSI) || + 80087d2: f012 020c ands.w r2, r2, #12 + 80087d6: d005 beq.n 80087e4 + 80087d8: 2a0c cmp r2, #12 + 80087da: d115 bne.n 8008808 + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 80087dc: f001 0103 and.w r1, r1, #3 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI))) + 80087e0: 2901 cmp r1, #1 + 80087e2: d118 bne.n 8008816 + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 80087e4: 6819 ldr r1, [r3, #0] + msirange = MSIRangeTable[msirange]; + 80087e6: 481d ldr r0, [pc, #116] ; (800885c ) + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 80087e8: 0709 lsls r1, r1, #28 + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 80087ea: bf55 itete pl + 80087ec: f8d3 1094 ldrpl.w r1, [r3, #148] ; 0x94 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 80087f0: 6819 ldrmi r1, [r3, #0] + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 80087f2: f3c1 2103 ubfxpl r1, r1, #8, #4 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 80087f6: f3c1 1103 ubfxmi r1, r1, #4, #4 + msirange = MSIRangeTable[msirange]; + 80087fa: f850 0021 ldr.w r0, [r0, r1, lsl #2] + if(sysclk_source == RCC_CFGR_SWS_MSI) + 80087fe: b34a cbz r2, 8008854 + if(sysclk_source == RCC_CFGR_SWS_PLL) + 8008800: 2a0c cmp r2, #12 + 8008802: d009 beq.n 8008818 + 8008804: 2000 movs r0, #0 + return sysclockfreq; + 8008806: 4770 bx lr + else if(sysclk_source == RCC_CFGR_SWS_HSI) + 8008808: 2a04 cmp r2, #4 + 800880a: d022 beq.n 8008852 + else if(sysclk_source == RCC_CFGR_SWS_HSE) + 800880c: 2a08 cmp r2, #8 + 800880e: 4814 ldr r0, [pc, #80] ; (8008860 ) + 8008810: bf18 it ne + 8008812: 2000 movne r0, #0 + 8008814: 4770 bx lr + uint32_t msirange = 0U, sysclockfreq = 0U; + 8008816: 2000 movs r0, #0 + pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8008818: 68da ldr r2, [r3, #12] + 800881a: f002 0203 and.w r2, r2, #3 + switch (pllsource) + 800881e: 2a02 cmp r2, #2 + 8008820: d015 beq.n 800884e + 8008822: 490f ldr r1, [pc, #60] ; (8008860 ) + 8008824: 2a03 cmp r2, #3 + 8008826: bf08 it eq + 8008828: 4608 moveq r0, r1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 800882a: 68d9 ldr r1, [r3, #12] + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 800882c: 68da ldr r2, [r3, #12] + 800882e: f3c2 2206 ubfx r2, r2, #8, #7 + 8008832: 4342 muls r2, r0 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008834: 68d8 ldr r0, [r3, #12] + 8008836: f3c0 6041 ubfx r0, r0, #25, #2 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 800883a: f3c1 1103 ubfx r1, r1, #4, #4 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 800883e: 3001 adds r0, #1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008840: 3101 adds r1, #1 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008842: 0040 lsls r0, r0, #1 + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 8008844: fbb2 f2f1 udiv r2, r2, r1 + sysclockfreq = pllvco / pllr; + 8008848: fbb2 f0f0 udiv r0, r2, r0 + 800884c: 4770 bx lr + pllvco = HSI_VALUE; + 800884e: 4805 ldr r0, [pc, #20] ; (8008864 ) + 8008850: e7eb b.n 800882a + sysclockfreq = HSI_VALUE; + 8008852: 4804 ldr r0, [pc, #16] ; (8008864 ) +} + 8008854: 4770 bx lr + 8008856: bf00 nop + 8008858: 40021000 .word 0x40021000 + 800885c: 0800e9f4 .word 0x0800e9f4 + 8008860: 007a1200 .word 0x007a1200 + 8008864: 00f42400 .word 0x00f42400 + +08008868 : +{ + 8008868: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + if(RCC_OscInitStruct == NULL) + 800886c: 4605 mov r5, r0 + 800886e: b908 cbnz r0, 8008874 + return HAL_ERROR; + 8008870: 2001 movs r0, #1 + 8008872: e047 b.n 8008904 + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008874: 4c94 ldr r4, [pc, #592] ; (8008ac8 ) + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 8008876: 6803 ldr r3, [r0, #0] + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008878: 68a6 ldr r6, [r4, #8] + pll_config = __HAL_RCC_GET_PLL_OSCSOURCE(); + 800887a: 68e7 ldr r7, [r4, #12] + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 800887c: 06db lsls r3, r3, #27 + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 800887e: f006 060c and.w r6, r6, #12 + pll_config = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8008882: f007 0703 and.w r7, r7, #3 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 8008886: d575 bpl.n 8008974 + if((sysclk_source == RCC_CFGR_SWS_MSI) || + 8008888: b11e cbz r6, 8008892 + 800888a: 2e0c cmp r6, #12 + 800888c: d154 bne.n 8008938 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_MSI))) + 800888e: 2f01 cmp r7, #1 + 8008890: d152 bne.n 8008938 + if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)) + 8008892: 6823 ldr r3, [r4, #0] + 8008894: 0798 lsls r0, r3, #30 + 8008896: d502 bpl.n 800889e + 8008898: 69ab ldr r3, [r5, #24] + 800889a: 2b00 cmp r3, #0 + 800889c: d0e8 beq.n 8008870 + if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE()) + 800889e: 6823 ldr r3, [r4, #0] + 80088a0: 6a28 ldr r0, [r5, #32] + 80088a2: 0719 lsls r1, r3, #28 + 80088a4: bf56 itet pl + 80088a6: f8d4 3094 ldrpl.w r3, [r4, #148] ; 0x94 + 80088aa: 6823 ldrmi r3, [r4, #0] + 80088ac: 091b lsrpl r3, r3, #4 + 80088ae: f003 03f0 and.w r3, r3, #240 ; 0xf0 + 80088b2: 4298 cmp r0, r3 + 80088b4: d929 bls.n 800890a + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + 80088b6: f7ff feb3 bl 8008620 + 80088ba: 2800 cmp r0, #0 + 80088bc: d1d8 bne.n 8008870 + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 80088be: 6823 ldr r3, [r4, #0] + 80088c0: f043 0308 orr.w r3, r3, #8 + 80088c4: 6023 str r3, [r4, #0] + 80088c6: 6823 ldr r3, [r4, #0] + 80088c8: 6a2a ldr r2, [r5, #32] + 80088ca: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 80088ce: 4313 orrs r3, r2 + 80088d0: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 80088d2: 6863 ldr r3, [r4, #4] + 80088d4: 69ea ldr r2, [r5, #28] + 80088d6: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 80088da: ea43 2302 orr.w r3, r3, r2, lsl #8 + 80088de: 6063 str r3, [r4, #4] + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); + 80088e0: f7ff ff74 bl 80087cc + 80088e4: 68a3 ldr r3, [r4, #8] + 80088e6: 4a79 ldr r2, [pc, #484] ; (8008acc ) + 80088e8: f3c3 1303 ubfx r3, r3, #4, #4 + 80088ec: 5cd3 ldrb r3, [r2, r3] + 80088ee: f003 031f and.w r3, r3, #31 + 80088f2: 40d8 lsrs r0, r3 + 80088f4: 4b76 ldr r3, [pc, #472] ; (8008ad0 ) + 80088f6: 6018 str r0, [r3, #0] + status = HAL_InitTick(uwTickPrio); + 80088f8: 4b76 ldr r3, [pc, #472] ; (8008ad4 ) + 80088fa: 6818 ldr r0, [r3, #0] + 80088fc: f7fe fbf8 bl 80070f0 + if(status != HAL_OK) + 8008900: 2800 cmp r0, #0 + 8008902: d037 beq.n 8008974 +} + 8008904: b003 add sp, #12 + 8008906: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 800890a: 6823 ldr r3, [r4, #0] + 800890c: f043 0308 orr.w r3, r3, #8 + 8008910: 6023 str r3, [r4, #0] + 8008912: 6823 ldr r3, [r4, #0] + 8008914: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008918: 4303 orrs r3, r0 + 800891a: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 800891c: 6863 ldr r3, [r4, #4] + 800891e: 69ea ldr r2, [r5, #28] + 8008920: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 8008924: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008928: 6063 str r3, [r4, #4] + if(sysclk_source == RCC_CFGR_SWS_MSI) + 800892a: 2e00 cmp r6, #0 + 800892c: d1d8 bne.n 80088e0 + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + 800892e: f7ff fe77 bl 8008620 + 8008932: 2800 cmp r0, #0 + 8008934: d0d4 beq.n 80088e0 + 8008936: e79b b.n 8008870 + if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF) + 8008938: 69ab ldr r3, [r5, #24] + 800893a: 2b00 cmp r3, #0 + 800893c: d03a beq.n 80089b4 + __HAL_RCC_MSI_ENABLE(); + 800893e: 6823 ldr r3, [r4, #0] + 8008940: f043 0301 orr.w r3, r3, #1 + 8008944: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008946: f7fe fbd1 bl 80070ec + 800894a: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 800894c: 6823 ldr r3, [r4, #0] + 800894e: 079a lsls r2, r3, #30 + 8008950: d528 bpl.n 80089a4 + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 8008952: 6823 ldr r3, [r4, #0] + 8008954: f043 0308 orr.w r3, r3, #8 + 8008958: 6023 str r3, [r4, #0] + 800895a: 6823 ldr r3, [r4, #0] + 800895c: 6a2a ldr r2, [r5, #32] + 800895e: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008962: 4313 orrs r3, r2 + 8008964: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 8008966: 6863 ldr r3, [r4, #4] + 8008968: 69ea ldr r2, [r5, #28] + 800896a: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 800896e: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008972: 6063 str r3, [r4, #4] + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + 8008974: 682b ldr r3, [r5, #0] + 8008976: 07d8 lsls r0, r3, #31 + 8008978: d42d bmi.n 80089d6 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + 800897a: 682b ldr r3, [r5, #0] + 800897c: 0799 lsls r1, r3, #30 + 800897e: d46b bmi.n 8008a58 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + 8008980: 682b ldr r3, [r5, #0] + 8008982: 0718 lsls r0, r3, #28 + 8008984: f100 80a8 bmi.w 8008ad8 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + 8008988: 682b ldr r3, [r5, #0] + 800898a: 0759 lsls r1, r3, #29 + 800898c: f100 80ce bmi.w 8008b2c + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + 8008990: 682b ldr r3, [r5, #0] + 8008992: 069f lsls r7, r3, #26 + 8008994: f100 8137 bmi.w 8008c06 + if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE) + 8008998: 6aab ldr r3, [r5, #40] ; 0x28 + 800899a: 2b00 cmp r3, #0 + 800899c: f040 815d bne.w 8008c5a + return HAL_OK; + 80089a0: 2000 movs r0, #0 + 80089a2: e7af b.n 8008904 + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 80089a4: f7fe fba2 bl 80070ec + 80089a8: eba0 0008 sub.w r0, r0, r8 + 80089ac: 2802 cmp r0, #2 + 80089ae: d9cd bls.n 800894c + return HAL_TIMEOUT; + 80089b0: 2003 movs r0, #3 + 80089b2: e7a7 b.n 8008904 + __HAL_RCC_MSI_DISABLE(); + 80089b4: 6823 ldr r3, [r4, #0] + 80089b6: f023 0301 bic.w r3, r3, #1 + 80089ba: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80089bc: f7fe fb96 bl 80070ec + 80089c0: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) + 80089c2: 6823 ldr r3, [r4, #0] + 80089c4: 079b lsls r3, r3, #30 + 80089c6: d5d5 bpl.n 8008974 + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 80089c8: f7fe fb90 bl 80070ec + 80089cc: eba0 0008 sub.w r0, r0, r8 + 80089d0: 2802 cmp r0, #2 + 80089d2: d9f6 bls.n 80089c2 + 80089d4: e7ec b.n 80089b0 + if((sysclk_source == RCC_CFGR_SWS_HSE) || + 80089d6: 2e08 cmp r6, #8 + 80089d8: d003 beq.n 80089e2 + 80089da: 2e0c cmp r6, #12 + 80089dc: d108 bne.n 80089f0 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSE))) + 80089de: 2f03 cmp r7, #3 + 80089e0: d106 bne.n 80089f0 + if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 80089e2: 6823 ldr r3, [r4, #0] + 80089e4: 039a lsls r2, r3, #14 + 80089e6: d5c8 bpl.n 800897a + 80089e8: 686b ldr r3, [r5, #4] + 80089ea: 2b00 cmp r3, #0 + 80089ec: d1c5 bne.n 800897a + 80089ee: e73f b.n 8008870 + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 80089f0: 686b ldr r3, [r5, #4] + 80089f2: f5b3 3f80 cmp.w r3, #65536 ; 0x10000 + 80089f6: d110 bne.n 8008a1a + 80089f8: 6823 ldr r3, [r4, #0] + 80089fa: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 80089fe: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008a00: f7fe fb74 bl 80070ec + 8008a04: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + 8008a06: 6823 ldr r3, [r4, #0] + 8008a08: 039b lsls r3, r3, #14 + 8008a0a: d4b6 bmi.n 800897a + if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + 8008a0c: f7fe fb6e bl 80070ec + 8008a10: eba0 0008 sub.w r0, r0, r8 + 8008a14: 2864 cmp r0, #100 ; 0x64 + 8008a16: d9f6 bls.n 8008a06 + 8008a18: e7ca b.n 80089b0 + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 8008a1a: f5b3 2fa0 cmp.w r3, #327680 ; 0x50000 + 8008a1e: d104 bne.n 8008a2a + 8008a20: 6823 ldr r3, [r4, #0] + 8008a22: f443 2380 orr.w r3, r3, #262144 ; 0x40000 + 8008a26: 6023 str r3, [r4, #0] + 8008a28: e7e6 b.n 80089f8 + 8008a2a: 6822 ldr r2, [r4, #0] + 8008a2c: f422 3280 bic.w r2, r2, #65536 ; 0x10000 + 8008a30: 6022 str r2, [r4, #0] + 8008a32: 6822 ldr r2, [r4, #0] + 8008a34: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 8008a38: 6022 str r2, [r4, #0] + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + 8008a3a: 2b00 cmp r3, #0 + 8008a3c: d1e0 bne.n 8008a00 + tickstart = HAL_GetTick(); + 8008a3e: f7fe fb55 bl 80070ec + 8008a42: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + 8008a44: 6823 ldr r3, [r4, #0] + 8008a46: 0398 lsls r0, r3, #14 + 8008a48: d597 bpl.n 800897a + if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + 8008a4a: f7fe fb4f bl 80070ec + 8008a4e: eba0 0008 sub.w r0, r0, r8 + 8008a52: 2864 cmp r0, #100 ; 0x64 + 8008a54: d9f6 bls.n 8008a44 + 8008a56: e7ab b.n 80089b0 + if((sysclk_source == RCC_CFGR_SWS_HSI) || + 8008a58: 2e04 cmp r6, #4 + 8008a5a: d003 beq.n 8008a64 + 8008a5c: 2e0c cmp r6, #12 + 8008a5e: d110 bne.n 8008a82 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSI))) + 8008a60: 2f02 cmp r7, #2 + 8008a62: d10e bne.n 8008a82 + if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)) + 8008a64: 6823 ldr r3, [r4, #0] + 8008a66: 0559 lsls r1, r3, #21 + 8008a68: d503 bpl.n 8008a72 + 8008a6a: 68eb ldr r3, [r5, #12] + 8008a6c: 2b00 cmp r3, #0 + 8008a6e: f43f aeff beq.w 8008870 + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8008a72: 6863 ldr r3, [r4, #4] + 8008a74: 692a ldr r2, [r5, #16] + 8008a76: f023 43fe bic.w r3, r3, #2130706432 ; 0x7f000000 + 8008a7a: ea43 6302 orr.w r3, r3, r2, lsl #24 + 8008a7e: 6063 str r3, [r4, #4] + 8008a80: e77e b.n 8008980 + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + 8008a82: 68eb ldr r3, [r5, #12] + 8008a84: b17b cbz r3, 8008aa6 + __HAL_RCC_HSI_ENABLE(); + 8008a86: 6823 ldr r3, [r4, #0] + 8008a88: f443 7380 orr.w r3, r3, #256 ; 0x100 + 8008a8c: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008a8e: f7fe fb2d bl 80070ec + 8008a92: 4607 mov r7, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 8008a94: 6823 ldr r3, [r4, #0] + 8008a96: 055a lsls r2, r3, #21 + 8008a98: d4eb bmi.n 8008a72 + if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + 8008a9a: f7fe fb27 bl 80070ec + 8008a9e: 1bc0 subs r0, r0, r7 + 8008aa0: 2802 cmp r0, #2 + 8008aa2: d9f7 bls.n 8008a94 + 8008aa4: e784 b.n 80089b0 + __HAL_RCC_HSI_DISABLE(); + 8008aa6: 6823 ldr r3, [r4, #0] + 8008aa8: f423 7380 bic.w r3, r3, #256 ; 0x100 + 8008aac: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008aae: f7fe fb1d bl 80070ec + 8008ab2: 4607 mov r7, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + 8008ab4: 6823 ldr r3, [r4, #0] + 8008ab6: 055b lsls r3, r3, #21 + 8008ab8: f57f af62 bpl.w 8008980 + if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + 8008abc: f7fe fb16 bl 80070ec + 8008ac0: 1bc0 subs r0, r0, r7 + 8008ac2: 2802 cmp r0, #2 + 8008ac4: d9f6 bls.n 8008ab4 + 8008ac6: e773 b.n 80089b0 + 8008ac8: 40021000 .word 0x40021000 + 8008acc: 0800e9dc .word 0x0800e9dc + 8008ad0: 2009e2a8 .word 0x2009e2a8 + 8008ad4: 2009e2ac .word 0x2009e2ac + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + 8008ad8: 696b ldr r3, [r5, #20] + 8008ada: b19b cbz r3, 8008b04 + __HAL_RCC_LSI_ENABLE(); + 8008adc: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008ae0: f043 0301 orr.w r3, r3, #1 + 8008ae4: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + tickstart = HAL_GetTick(); + 8008ae8: f7fe fb00 bl 80070ec + 8008aec: 4607 mov r7, r0 + while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U) + 8008aee: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008af2: 079a lsls r2, r3, #30 + 8008af4: f53f af48 bmi.w 8008988 + if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + 8008af8: f7fe faf8 bl 80070ec + 8008afc: 1bc0 subs r0, r0, r7 + 8008afe: 2802 cmp r0, #2 + 8008b00: d9f5 bls.n 8008aee + 8008b02: e755 b.n 80089b0 + __HAL_RCC_LSI_DISABLE(); + 8008b04: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008b08: f023 0301 bic.w r3, r3, #1 + 8008b0c: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + tickstart = HAL_GetTick(); + 8008b10: f7fe faec bl 80070ec + 8008b14: 4607 mov r7, r0 + while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + 8008b16: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008b1a: 079b lsls r3, r3, #30 + 8008b1c: f57f af34 bpl.w 8008988 + if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + 8008b20: f7fe fae4 bl 80070ec + 8008b24: 1bc0 subs r0, r0, r7 + 8008b26: 2802 cmp r0, #2 + 8008b28: d9f5 bls.n 8008b16 + 8008b2a: e741 b.n 80089b0 + if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN)) + 8008b2c: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008b2e: 00df lsls r7, r3, #3 + 8008b30: d429 bmi.n 8008b86 + __HAL_RCC_PWR_CLK_ENABLE(); + 8008b32: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008b34: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 8008b38: 65a3 str r3, [r4, #88] ; 0x58 + 8008b3a: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008b3c: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 8008b40: 9301 str r3, [sp, #4] + 8008b42: 9b01 ldr r3, [sp, #4] + pwrclkchanged = SET; + 8008b44: f04f 0801 mov.w r8, #1 + if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) + 8008b48: 4f9c ldr r7, [pc, #624] ; (8008dbc ) + 8008b4a: 683b ldr r3, [r7, #0] + 8008b4c: 05d8 lsls r0, r3, #23 + 8008b4e: d51d bpl.n 8008b8c + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8008b50: 68ab ldr r3, [r5, #8] + 8008b52: 2b01 cmp r3, #1 + 8008b54: d12b bne.n 8008bae + 8008b56: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008b5a: f043 0301 orr.w r3, r3, #1 + 8008b5e: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + tickstart = HAL_GetTick(); + 8008b62: f7fe fac3 bl 80070ec + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008b66: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8008b6a: 4607 mov r7, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + 8008b6c: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008b70: 079a lsls r2, r3, #30 + 8008b72: d542 bpl.n 8008bfa + if(pwrclkchanged == SET) + 8008b74: f1b8 0f00 cmp.w r8, #0 + 8008b78: f43f af0a beq.w 8008990 + __HAL_RCC_PWR_CLK_DISABLE(); + 8008b7c: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008b7e: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8008b82: 65a3 str r3, [r4, #88] ; 0x58 + 8008b84: e704 b.n 8008990 + FlagStatus pwrclkchanged = RESET; + 8008b86: f04f 0800 mov.w r8, #0 + 8008b8a: e7dd b.n 8008b48 + SET_BIT(PWR->CR1, PWR_CR1_DBP); + 8008b8c: 683b ldr r3, [r7, #0] + 8008b8e: f443 7380 orr.w r3, r3, #256 ; 0x100 + 8008b92: 603b str r3, [r7, #0] + tickstart = HAL_GetTick(); + 8008b94: f7fe faaa bl 80070ec + 8008b98: 4681 mov r9, r0 + while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) + 8008b9a: 683b ldr r3, [r7, #0] + 8008b9c: 05d9 lsls r1, r3, #23 + 8008b9e: d4d7 bmi.n 8008b50 + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 8008ba0: f7fe faa4 bl 80070ec + 8008ba4: eba0 0009 sub.w r0, r0, r9 + 8008ba8: 2802 cmp r0, #2 + 8008baa: d9f6 bls.n 8008b9a + 8008bac: e700 b.n 80089b0 + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8008bae: 2b05 cmp r3, #5 + 8008bb0: d106 bne.n 8008bc0 + 8008bb2: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008bb6: f043 0304 orr.w r3, r3, #4 + 8008bba: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + 8008bbe: e7ca b.n 8008b56 + 8008bc0: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8008bc4: f022 0201 bic.w r2, r2, #1 + 8008bc8: f8c4 2090 str.w r2, [r4, #144] ; 0x90 + 8008bcc: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8008bd0: f022 0204 bic.w r2, r2, #4 + 8008bd4: f8c4 2090 str.w r2, [r4, #144] ; 0x90 + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + 8008bd8: 2b00 cmp r3, #0 + 8008bda: d1c2 bne.n 8008b62 + tickstart = HAL_GetTick(); + 8008bdc: f7fe fa86 bl 80070ec + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008be0: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8008be4: 4607 mov r7, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + 8008be6: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008bea: 079b lsls r3, r3, #30 + 8008bec: d5c2 bpl.n 8008b74 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008bee: f7fe fa7d bl 80070ec + 8008bf2: 1bc0 subs r0, r0, r7 + 8008bf4: 4548 cmp r0, r9 + 8008bf6: d9f6 bls.n 8008be6 + 8008bf8: e6da b.n 80089b0 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008bfa: f7fe fa77 bl 80070ec + 8008bfe: 1bc0 subs r0, r0, r7 + 8008c00: 4548 cmp r0, r9 + 8008c02: d9b3 bls.n 8008b6c + 8008c04: e6d4 b.n 80089b0 + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + 8008c06: 6a6b ldr r3, [r5, #36] ; 0x24 + 8008c08: b19b cbz r3, 8008c32 + __HAL_RCC_HSI48_ENABLE(); + 8008c0a: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008c0e: f043 0301 orr.w r3, r3, #1 + 8008c12: f8c4 3098 str.w r3, [r4, #152] ; 0x98 + tickstart = HAL_GetTick(); + 8008c16: f7fe fa69 bl 80070ec + 8008c1a: 4607 mov r7, r0 + while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U) + 8008c1c: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008c20: 0798 lsls r0, r3, #30 + 8008c22: f53f aeb9 bmi.w 8008998 + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8008c26: f7fe fa61 bl 80070ec + 8008c2a: 1bc0 subs r0, r0, r7 + 8008c2c: 2802 cmp r0, #2 + 8008c2e: d9f5 bls.n 8008c1c + 8008c30: e6be b.n 80089b0 + __HAL_RCC_HSI48_DISABLE(); + 8008c32: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008c36: f023 0301 bic.w r3, r3, #1 + 8008c3a: f8c4 3098 str.w r3, [r4, #152] ; 0x98 + tickstart = HAL_GetTick(); + 8008c3e: f7fe fa55 bl 80070ec + 8008c42: 4607 mov r7, r0 + while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U) + 8008c44: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008c48: 0799 lsls r1, r3, #30 + 8008c4a: f57f aea5 bpl.w 8008998 + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8008c4e: f7fe fa4d bl 80070ec + 8008c52: 1bc0 subs r0, r0, r7 + 8008c54: 2802 cmp r0, #2 + 8008c56: d9f5 bls.n 8008c44 + 8008c58: e6aa b.n 80089b0 + if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON) + 8008c5a: 2b02 cmp r3, #2 + 8008c5c: f040 808c bne.w 8008d78 + pll_config = RCC->PLLCFGR; + 8008c60: 68e3 ldr r3, [r4, #12] + if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8008c62: 6aea ldr r2, [r5, #44] ; 0x2c + 8008c64: f003 0103 and.w r1, r3, #3 + 8008c68: 4291 cmp r1, r2 + 8008c6a: d122 bne.n 8008cb2 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) || + 8008c6c: 6b29 ldr r1, [r5, #48] ; 0x30 + 8008c6e: f003 02f0 and.w r2, r3, #240 ; 0xf0 + 8008c72: 3901 subs r1, #1 + if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8008c74: ebb2 1f01 cmp.w r2, r1, lsl #4 + 8008c78: d11b bne.n 8008cb2 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) || + 8008c7a: 6b69 ldr r1, [r5, #52] ; 0x34 + 8008c7c: f403 42fe and.w r2, r3, #32512 ; 0x7f00 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) || + 8008c80: ebb2 2f01 cmp.w r2, r1, lsl #8 + 8008c84: d115 bne.n 8008cb2 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) || + 8008c86: 6ba9 ldr r1, [r5, #56] ; 0x38 + 8008c88: f003 4278 and.w r2, r3, #4160749568 ; 0xf8000000 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) || + 8008c8c: ebb2 6fc1 cmp.w r2, r1, lsl #27 + 8008c90: d10f bne.n 8008cb2 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) || + 8008c92: 6bea ldr r2, [r5, #60] ; 0x3c + 8008c94: 0852 lsrs r2, r2, #1 + 8008c96: f403 01c0 and.w r1, r3, #6291456 ; 0x600000 + 8008c9a: 3a01 subs r2, #1 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) || + 8008c9c: ebb1 5f42 cmp.w r1, r2, lsl #21 + 8008ca0: d107 bne.n 8008cb2 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos))) + 8008ca2: 6c2a ldr r2, [r5, #64] ; 0x40 + 8008ca4: 0852 lsrs r2, r2, #1 + 8008ca6: f003 63c0 and.w r3, r3, #100663296 ; 0x6000000 + 8008caa: 3a01 subs r2, #1 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) || + 8008cac: ebb3 6f42 cmp.w r3, r2, lsl #25 + 8008cb0: d049 beq.n 8008d46 + if(sysclk_source != RCC_CFGR_SWS_PLL) + 8008cb2: 2e0c cmp r6, #12 + 8008cb4: f43f addc beq.w 8008870 + if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U) + 8008cb8: 6823 ldr r3, [r4, #0] + 8008cba: 015a lsls r2, r3, #5 + 8008cbc: f53f add8 bmi.w 8008870 + || (READ_BIT(RCC->CR, RCC_CR_PLLSAI2ON) != 0U) + 8008cc0: 6823 ldr r3, [r4, #0] + 8008cc2: 00db lsls r3, r3, #3 + 8008cc4: f53f add4 bmi.w 8008870 + __HAL_RCC_PLL_DISABLE(); + 8008cc8: 6823 ldr r3, [r4, #0] + 8008cca: f023 7380 bic.w r3, r3, #16777216 ; 0x1000000 + 8008cce: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008cd0: f7fe fa0c bl 80070ec + 8008cd4: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) + 8008cd6: 6823 ldr r3, [r4, #0] + 8008cd8: 019f lsls r7, r3, #6 + 8008cda: d42e bmi.n 8008d3a + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + 8008cdc: 68e2 ldr r2, [r4, #12] + 8008cde: 4b38 ldr r3, [pc, #224] ; (8008dc0 ) + 8008ce0: 4013 ands r3, r2 + 8008ce2: 6aea ldr r2, [r5, #44] ; 0x2c + 8008ce4: 4313 orrs r3, r2 + 8008ce6: 6b6a ldr r2, [r5, #52] ; 0x34 + 8008ce8: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008cec: 6baa ldr r2, [r5, #56] ; 0x38 + 8008cee: ea43 63c2 orr.w r3, r3, r2, lsl #27 + 8008cf2: 6b2a ldr r2, [r5, #48] ; 0x30 + 8008cf4: 3a01 subs r2, #1 + 8008cf6: ea43 1302 orr.w r3, r3, r2, lsl #4 + 8008cfa: 6bea ldr r2, [r5, #60] ; 0x3c + 8008cfc: 0852 lsrs r2, r2, #1 + 8008cfe: 3a01 subs r2, #1 + 8008d00: ea43 5342 orr.w r3, r3, r2, lsl #21 + 8008d04: 6c2a ldr r2, [r5, #64] ; 0x40 + 8008d06: 0852 lsrs r2, r2, #1 + 8008d08: 3a01 subs r2, #1 + 8008d0a: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8008d0e: 60e3 str r3, [r4, #12] + __HAL_RCC_PLL_ENABLE(); + 8008d10: 6823 ldr r3, [r4, #0] + 8008d12: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8008d16: 6023 str r3, [r4, #0] + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + 8008d18: 68e3 ldr r3, [r4, #12] + 8008d1a: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8008d1e: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8008d20: f7fe f9e4 bl 80070ec + 8008d24: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 8008d26: 6823 ldr r3, [r4, #0] + 8008d28: 0198 lsls r0, r3, #6 + 8008d2a: f53f ae39 bmi.w 80089a0 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008d2e: f7fe f9dd bl 80070ec + 8008d32: 1b40 subs r0, r0, r5 + 8008d34: 2802 cmp r0, #2 + 8008d36: d9f6 bls.n 8008d26 + 8008d38: e63a b.n 80089b0 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008d3a: f7fe f9d7 bl 80070ec + 8008d3e: 1b80 subs r0, r0, r6 + 8008d40: 2802 cmp r0, #2 + 8008d42: d9c8 bls.n 8008cd6 + 8008d44: e634 b.n 80089b0 + if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 8008d46: 6823 ldr r3, [r4, #0] + 8008d48: 0199 lsls r1, r3, #6 + 8008d4a: f53f ae29 bmi.w 80089a0 + __HAL_RCC_PLL_ENABLE(); + 8008d4e: 6823 ldr r3, [r4, #0] + 8008d50: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8008d54: 6023 str r3, [r4, #0] + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + 8008d56: 68e3 ldr r3, [r4, #12] + 8008d58: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8008d5c: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8008d5e: f7fe f9c5 bl 80070ec + 8008d62: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 8008d64: 6823 ldr r3, [r4, #0] + 8008d66: 019a lsls r2, r3, #6 + 8008d68: f53f ae1a bmi.w 80089a0 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008d6c: f7fe f9be bl 80070ec + 8008d70: 1b40 subs r0, r0, r5 + 8008d72: 2802 cmp r0, #2 + 8008d74: d9f6 bls.n 8008d64 + 8008d76: e61b b.n 80089b0 + if(sysclk_source != RCC_CFGR_SWS_PLL) + 8008d78: 2e0c cmp r6, #12 + 8008d7a: f43f ad79 beq.w 8008870 + __HAL_RCC_PLL_DISABLE(); + 8008d7e: 6823 ldr r3, [r4, #0] + 8008d80: f023 7380 bic.w r3, r3, #16777216 ; 0x1000000 + 8008d84: 6023 str r3, [r4, #0] + if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U) + 8008d86: 6823 ldr r3, [r4, #0] + 8008d88: f013 5f20 tst.w r3, #671088640 ; 0x28000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 8008d8c: bf02 ittt eq + 8008d8e: 68e3 ldreq r3, [r4, #12] + 8008d90: f023 0303 biceq.w r3, r3, #3 + 8008d94: 60e3 streq r3, [r4, #12] + __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK); + 8008d96: 68e3 ldr r3, [r4, #12] + 8008d98: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 8008d9c: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 8008da0: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8008da2: f7fe f9a3 bl 80070ec + 8008da6: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) + 8008da8: 6823 ldr r3, [r4, #0] + 8008daa: 019b lsls r3, r3, #6 + 8008dac: f57f adf8 bpl.w 80089a0 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008db0: f7fe f99c bl 80070ec + 8008db4: 1b40 subs r0, r0, r5 + 8008db6: 2802 cmp r0, #2 + 8008db8: d9f6 bls.n 8008da8 + 8008dba: e5f9 b.n 80089b0 + 8008dbc: 40007000 .word 0x40007000 + 8008dc0: 019d800c .word 0x019d800c + +08008dc4 : +{ + 8008dc4: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 8008dc8: 460e mov r6, r1 + if(RCC_ClkInitStruct == NULL) + 8008dca: 4605 mov r5, r0 + 8008dcc: b910 cbnz r0, 8008dd4 + return HAL_ERROR; + 8008dce: 2001 movs r0, #1 +} + 8008dd0: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + if(FLatency > __HAL_FLASH_GET_LATENCY()) + 8008dd4: 4a6f ldr r2, [pc, #444] ; (8008f94 ) + 8008dd6: 6813 ldr r3, [r2, #0] + 8008dd8: f003 030f and.w r3, r3, #15 + 8008ddc: 428b cmp r3, r1 + 8008dde: d335 bcc.n 8008e4c + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + 8008de0: 6829 ldr r1, [r5, #0] + 8008de2: f011 0701 ands.w r7, r1, #1 + 8008de6: d13c bne.n 8008e62 + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + 8008de8: 682a ldr r2, [r5, #0] + 8008dea: 0791 lsls r1, r2, #30 + 8008dec: f140 80b7 bpl.w 8008f5e + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + 8008df0: 4969 ldr r1, [pc, #420] ; (8008f98 ) + 8008df2: 68a8 ldr r0, [r5, #8] + 8008df4: 688b ldr r3, [r1, #8] + 8008df6: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008dfa: 4303 orrs r3, r0 + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + 8008dfc: 608b str r3, [r1, #8] + if(FLatency < __HAL_FLASH_GET_LATENCY()) + 8008dfe: 4965 ldr r1, [pc, #404] ; (8008f94 ) + 8008e00: 680b ldr r3, [r1, #0] + 8008e02: f003 030f and.w r3, r3, #15 + 8008e06: 42b3 cmp r3, r6 + 8008e08: f200 80b1 bhi.w 8008f6e + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 8008e0c: f012 0f04 tst.w r2, #4 + 8008e10: 4c61 ldr r4, [pc, #388] ; (8008f98 ) + 8008e12: f040 80b8 bne.w 8008f86 + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + 8008e16: 0713 lsls r3, r2, #28 + 8008e18: d506 bpl.n 8008e28 + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U)); + 8008e1a: 68a3 ldr r3, [r4, #8] + 8008e1c: 692a ldr r2, [r5, #16] + 8008e1e: f423 5360 bic.w r3, r3, #14336 ; 0x3800 + 8008e22: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 8008e26: 60a3 str r3, [r4, #8] + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); + 8008e28: f7ff fcd0 bl 80087cc + 8008e2c: 68a3 ldr r3, [r4, #8] + 8008e2e: 4a5b ldr r2, [pc, #364] ; (8008f9c ) + 8008e30: f3c3 1303 ubfx r3, r3, #4, #4 + 8008e34: 5cd3 ldrb r3, [r2, r3] + 8008e36: f003 031f and.w r3, r3, #31 + 8008e3a: 40d8 lsrs r0, r3 + 8008e3c: 4b58 ldr r3, [pc, #352] ; (8008fa0 ) + 8008e3e: 6018 str r0, [r3, #0] + status = HAL_InitTick(uwTickPrio); + 8008e40: 4b58 ldr r3, [pc, #352] ; (8008fa4 ) + 8008e42: 6818 ldr r0, [r3, #0] +} + 8008e44: e8bd 43f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + status = HAL_InitTick(uwTickPrio); + 8008e48: f7fe b952 b.w 80070f0 + __HAL_FLASH_SET_LATENCY(FLatency); + 8008e4c: 6813 ldr r3, [r2, #0] + 8008e4e: f023 030f bic.w r3, r3, #15 + 8008e52: 430b orrs r3, r1 + 8008e54: 6013 str r3, [r2, #0] + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8008e56: 6813 ldr r3, [r2, #0] + 8008e58: f003 030f and.w r3, r3, #15 + 8008e5c: 428b cmp r3, r1 + 8008e5e: d1b6 bne.n 8008dce + 8008e60: e7be b.n 8008de0 + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + 8008e62: 686b ldr r3, [r5, #4] + 8008e64: 4c4c ldr r4, [pc, #304] ; (8008f98 ) + 8008e66: 2b03 cmp r3, #3 + 8008e68: d163 bne.n 8008f32 + if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 8008e6a: 6823 ldr r3, [r4, #0] + 8008e6c: 019b lsls r3, r3, #6 + 8008e6e: d5ae bpl.n 8008dce +static uint32_t RCC_GetSysClockFreqFromPLLSource(void) +{ + uint32_t msirange = 0U; + uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */ + + if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI) + 8008e70: 68e3 ldr r3, [r4, #12] + 8008e72: f003 0303 and.w r3, r3, #3 + 8008e76: 2b01 cmp r3, #1 + 8008e78: d145 bne.n 8008f06 + { + /* Get MSI range source */ + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 8008e7a: 6823 ldr r3, [r4, #0] + else + { /* MSIRANGE from RCC_CR applies */ + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + 8008e7c: 4a4a ldr r2, [pc, #296] ; (8008fa8 ) + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 8008e7e: 071f lsls r7, r3, #28 + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 8008e80: bf55 itete pl + 8008e82: f8d4 3094 ldrpl.w r3, [r4, #148] ; 0x94 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 8008e86: 6823 ldrmi r3, [r4, #0] + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 8008e88: f3c3 2303 ubfxpl r3, r3, #8, #4 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 8008e8c: f3c3 1303 ubfxmi r3, r3, #4, #4 + msirange = MSIRangeTable[msirange]; + 8008e90: f852 2023 ldr.w r2, [r2, r3, lsl #2] + } + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM + SYSCLK = PLL_VCO / PLLR + */ + pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8008e94: 68e3 ldr r3, [r4, #12] + 8008e96: f003 0303 and.w r3, r3, #3 + + switch (pllsource) + 8008e9a: 2b02 cmp r3, #2 + 8008e9c: d035 beq.n 8008f0a + 8008e9e: 4843 ldr r0, [pc, #268] ; (8008fac ) + 8008ea0: 2b03 cmp r3, #3 + 8008ea2: bf08 it eq + 8008ea4: 4602 moveq r2, r0 + case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ + default: + pllvco = msirange; + break; + } + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008ea6: 68e0 ldr r0, [r4, #12] + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 8008ea8: 68e3 ldr r3, [r4, #12] + 8008eaa: f3c3 2306 ubfx r3, r3, #8, #7 + 8008eae: 4353 muls r3, r2 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008eb0: 68e2 ldr r2, [r4, #12] + 8008eb2: f3c2 6241 ubfx r2, r2, #25, #2 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008eb6: f3c0 1003 ubfx r0, r0, #4, #4 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008eba: 3201 adds r2, #1 + 8008ebc: 0052 lsls r2, r2, #1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008ebe: 3001 adds r0, #1 + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 8008ec0: fbb3 f3f0 udiv r3, r3, r0 + sysclockfreq = pllvco / pllr; + 8008ec4: fbb3 f3f2 udiv r3, r3, r2 + if(RCC_GetSysClockFreqFromPLLSource() > 80000000U) + 8008ec8: 4a39 ldr r2, [pc, #228] ; (8008fb0 ) + 8008eca: 4293 cmp r3, r2 + 8008ecc: d81f bhi.n 8008f0e + uint32_t hpre = RCC_SYSCLK_DIV1; + 8008ece: 2700 movs r7, #0 + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); + 8008ed0: 68a3 ldr r3, [r4, #8] + 8008ed2: 686a ldr r2, [r5, #4] + 8008ed4: f023 0303 bic.w r3, r3, #3 + 8008ed8: 4313 orrs r3, r2 + 8008eda: 60a3 str r3, [r4, #8] + tickstart = HAL_GetTick(); + 8008edc: f7fe f906 bl 80070ec + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 8008ee0: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8008ee4: 4680 mov r8, r0 + while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 8008ee6: 68a3 ldr r3, [r4, #8] + 8008ee8: 686a ldr r2, [r5, #4] + 8008eea: f003 030c and.w r3, r3, #12 + 8008eee: ebb3 0f82 cmp.w r3, r2, lsl #2 + 8008ef2: f43f af79 beq.w 8008de8 + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 8008ef6: f7fe f8f9 bl 80070ec + 8008efa: eba0 0008 sub.w r0, r0, r8 + 8008efe: 4548 cmp r0, r9 + 8008f00: d9f1 bls.n 8008ee6 + return HAL_TIMEOUT; + 8008f02: 2003 movs r0, #3 + 8008f04: e764 b.n 8008dd0 + uint32_t msirange = 0U; + 8008f06: 2200 movs r2, #0 + 8008f08: e7c4 b.n 8008e94 + pllvco = HSI_VALUE; + 8008f0a: 4a2a ldr r2, [pc, #168] ; (8008fb4 ) + 8008f0c: e7cb b.n 8008ea6 + if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1) + 8008f0e: 68a3 ldr r3, [r4, #8] + 8008f10: f013 0ff0 tst.w r3, #240 ; 0xf0 + 8008f14: d107 bne.n 8008f26 + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2); + 8008f16: 68a3 ldr r3, [r4, #8] + 8008f18: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008f1c: f043 0380 orr.w r3, r3, #128 ; 0x80 + 8008f20: 60a3 str r3, [r4, #8] + hpre = RCC_SYSCLK_DIV2; + 8008f22: 2780 movs r7, #128 ; 0x80 + 8008f24: e7d4 b.n 8008ed0 + else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1)) + 8008f26: 0788 lsls r0, r1, #30 + 8008f28: d5d1 bpl.n 8008ece + 8008f2a: 68ab ldr r3, [r5, #8] + 8008f2c: 2b00 cmp r3, #0 + 8008f2e: d1ce bne.n 8008ece + 8008f30: e7f1 b.n 8008f16 + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + 8008f32: 2b02 cmp r3, #2 + 8008f34: d10a bne.n 8008f4c + if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + 8008f36: 6823 ldr r3, [r4, #0] + 8008f38: f413 3f00 tst.w r3, #131072 ; 0x20000 + if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 8008f3c: f43f af47 beq.w 8008dce + if(HAL_RCC_GetSysClockFreq() > 80000000U) + 8008f40: f7ff fc44 bl 80087cc + 8008f44: 4b1a ldr r3, [pc, #104] ; (8008fb0 ) + 8008f46: 4298 cmp r0, r3 + 8008f48: d9c1 bls.n 8008ece + 8008f4a: e7e4 b.n 8008f16 + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) + 8008f4c: b91b cbnz r3, 8008f56 + if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 8008f4e: 6823 ldr r3, [r4, #0] + 8008f50: f013 0f02 tst.w r3, #2 + 8008f54: e7f2 b.n 8008f3c + if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 8008f56: 6823 ldr r3, [r4, #0] + 8008f58: f413 6f80 tst.w r3, #1024 ; 0x400 + 8008f5c: e7ee b.n 8008f3c + if(hpre == RCC_SYSCLK_DIV2) + 8008f5e: 2f80 cmp r7, #128 ; 0x80 + 8008f60: f47f af4d bne.w 8008dfe + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + 8008f64: 490c ldr r1, [pc, #48] ; (8008f98 ) + 8008f66: 688b ldr r3, [r1, #8] + 8008f68: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008f6c: e746 b.n 8008dfc + __HAL_FLASH_SET_LATENCY(FLatency); + 8008f6e: 680b ldr r3, [r1, #0] + 8008f70: f023 030f bic.w r3, r3, #15 + 8008f74: 4333 orrs r3, r6 + 8008f76: 600b str r3, [r1, #0] + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 8008f78: 680b ldr r3, [r1, #0] + 8008f7a: f003 030f and.w r3, r3, #15 + 8008f7e: 42b3 cmp r3, r6 + 8008f80: f47f af25 bne.w 8008dce + 8008f84: e742 b.n 8008e0c + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider); + 8008f86: 68a3 ldr r3, [r4, #8] + 8008f88: 68e9 ldr r1, [r5, #12] + 8008f8a: f423 63e0 bic.w r3, r3, #1792 ; 0x700 + 8008f8e: 430b orrs r3, r1 + 8008f90: 60a3 str r3, [r4, #8] + 8008f92: e740 b.n 8008e16 + 8008f94: 40022000 .word 0x40022000 + 8008f98: 40021000 .word 0x40021000 + 8008f9c: 0800e9dc .word 0x0800e9dc + 8008fa0: 2009e2a8 .word 0x2009e2a8 + 8008fa4: 2009e2ac .word 0x2009e2ac + 8008fa8: 0800e9f4 .word 0x0800e9f4 + 8008fac: 007a1200 .word 0x007a1200 + 8008fb0: 04c4b400 .word 0x04c4b400 + 8008fb4: 00f42400 .word 0x00f42400 + +08008fb8 : +} + 8008fb8: 4b01 ldr r3, [pc, #4] ; (8008fc0 ) + 8008fba: 6818 ldr r0, [r3, #0] + 8008fbc: 4770 bx lr + 8008fbe: bf00 nop + 8008fc0: 2009e2a8 .word 0x2009e2a8 + +08008fc4 : + return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU)); + 8008fc4: 4b05 ldr r3, [pc, #20] ; (8008fdc ) + 8008fc6: 4a06 ldr r2, [pc, #24] ; (8008fe0 ) + 8008fc8: 689b ldr r3, [r3, #8] + 8008fca: f3c3 2302 ubfx r3, r3, #8, #3 + 8008fce: 5cd3 ldrb r3, [r2, r3] + 8008fd0: 4a04 ldr r2, [pc, #16] ; (8008fe4 ) + 8008fd2: 6810 ldr r0, [r2, #0] + 8008fd4: f003 031f and.w r3, r3, #31 +} + 8008fd8: 40d8 lsrs r0, r3 + 8008fda: 4770 bx lr + 8008fdc: 40021000 .word 0x40021000 + 8008fe0: 0800e9ec .word 0x0800e9ec + 8008fe4: 2009e2a8 .word 0x2009e2a8 + +08008fe8 : + return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU)); + 8008fe8: 4b05 ldr r3, [pc, #20] ; (8009000 ) + 8008fea: 4a06 ldr r2, [pc, #24] ; (8009004 ) + 8008fec: 689b ldr r3, [r3, #8] + 8008fee: f3c3 23c2 ubfx r3, r3, #11, #3 + 8008ff2: 5cd3 ldrb r3, [r2, r3] + 8008ff4: 4a04 ldr r2, [pc, #16] ; (8009008 ) + 8008ff6: 6810 ldr r0, [r2, #0] + 8008ff8: f003 031f and.w r3, r3, #31 +} + 8008ffc: 40d8 lsrs r0, r3 + 8008ffe: 4770 bx lr + 8009000: 40021000 .word 0x40021000 + 8009004: 0800e9ec .word 0x0800e9ec + 8009008: 2009e2a8 .word 0x2009e2a8 + +0800900c : + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \ + 800900c: 233f movs r3, #63 ; 0x3f + 800900e: 6003 str r3, [r0, #0] + if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + 8009010: 4b2e ldr r3, [pc, #184] ; (80090cc ) + 8009012: 681a ldr r2, [r3, #0] + 8009014: 0351 lsls r1, r2, #13 + 8009016: d54a bpl.n 80090ae + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + 8009018: f44f 22a0 mov.w r2, #327680 ; 0x50000 + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + 800901c: 6042 str r2, [r0, #4] + if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION) + 800901e: 681a ldr r2, [r3, #0] + 8009020: f002 0201 and.w r2, r2, #1 + 8009024: 6182 str r2, [r0, #24] + RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos; + 8009026: 685a ldr r2, [r3, #4] + 8009028: f3c2 2207 ubfx r2, r2, #8, #8 + 800902c: 61c2 str r2, [r0, #28] + RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE); + 800902e: 681a ldr r2, [r3, #0] + 8009030: f002 02f0 and.w r2, r2, #240 ; 0xf0 + 8009034: 6202 str r2, [r0, #32] + if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION) + 8009036: 681a ldr r2, [r3, #0] + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + 8009038: f402 7280 and.w r2, r2, #256 ; 0x100 + 800903c: 60c2 str r2, [r0, #12] + RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos; + 800903e: 685a ldr r2, [r3, #4] + 8009040: f3c2 6206 ubfx r2, r2, #24, #7 + 8009044: 6102 str r2, [r0, #16] + if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + 8009046: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800904a: 0752 lsls r2, r2, #29 + 800904c: d536 bpl.n 80090bc + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + 800904e: 2205 movs r2, #5 + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + 8009050: 6082 str r2, [r0, #8] + if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION) + 8009052: f8d3 2094 ldr.w r2, [r3, #148] ; 0x94 + 8009056: f002 0201 and.w r2, r2, #1 + 800905a: 6142 str r2, [r0, #20] + if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON) + 800905c: f8d3 2098 ldr.w r2, [r3, #152] ; 0x98 + 8009060: f002 0201 and.w r2, r2, #1 + 8009064: 6242 str r2, [r0, #36] ; 0x24 + if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON) + 8009066: 681a ldr r2, [r3, #0] + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + 8009068: f012 7f80 tst.w r2, #16777216 ; 0x1000000 + 800906c: bf14 ite ne + 800906e: 2202 movne r2, #2 + 8009070: 2201 moveq r2, #1 + 8009072: 6282 str r2, [r0, #40] ; 0x28 + RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8009074: 68da ldr r2, [r3, #12] + 8009076: f002 0203 and.w r2, r2, #3 + 800907a: 62c2 str r2, [r0, #44] ; 0x2c + RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U; + 800907c: 68da ldr r2, [r3, #12] + 800907e: f3c2 1203 ubfx r2, r2, #4, #4 + 8009082: 3201 adds r2, #1 + 8009084: 6302 str r2, [r0, #48] ; 0x30 + RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009086: 68da ldr r2, [r3, #12] + 8009088: f3c2 2206 ubfx r2, r2, #8, #7 + 800908c: 6342 str r2, [r0, #52] ; 0x34 + RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U); + 800908e: 68da ldr r2, [r3, #12] + 8009090: f3c2 5241 ubfx r2, r2, #21, #2 + 8009094: 3201 adds r2, #1 + 8009096: 0052 lsls r2, r2, #1 + 8009098: 63c2 str r2, [r0, #60] ; 0x3c + RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U); + 800909a: 68da ldr r2, [r3, #12] + 800909c: f3c2 6241 ubfx r2, r2, #25, #2 + 80090a0: 3201 adds r2, #1 + 80090a2: 0052 lsls r2, r2, #1 + 80090a4: 6402 str r2, [r0, #64] ; 0x40 + RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 80090a6: 68db ldr r3, [r3, #12] + 80090a8: 0edb lsrs r3, r3, #27 + 80090aa: 6383 str r3, [r0, #56] ; 0x38 +} + 80090ac: 4770 bx lr + else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON) + 80090ae: 681a ldr r2, [r3, #0] + 80090b0: f412 3280 ands.w r2, r2, #65536 ; 0x10000 + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + 80090b4: bf18 it ne + 80090b6: f44f 3280 movne.w r2, #65536 ; 0x10000 + 80090ba: e7af b.n 800901c + else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + 80090bc: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 80090c0: f012 0201 ands.w r2, r2, #1 + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + 80090c4: bf18 it ne + 80090c6: 2201 movne r2, #1 + 80090c8: e7c2 b.n 8009050 + 80090ca: bf00 nop + 80090cc: 40021000 .word 0x40021000 + +080090d0 : + RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + 80090d0: 230f movs r3, #15 + 80090d2: 6003 str r3, [r0, #0] + RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW); + 80090d4: 4b0b ldr r3, [pc, #44] ; (8009104 ) + 80090d6: 689a ldr r2, [r3, #8] + 80090d8: f002 0203 and.w r2, r2, #3 + 80090dc: 6042 str r2, [r0, #4] + RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE); + 80090de: 689a ldr r2, [r3, #8] + 80090e0: f002 02f0 and.w r2, r2, #240 ; 0xf0 + 80090e4: 6082 str r2, [r0, #8] + RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1); + 80090e6: 689a ldr r2, [r3, #8] + 80090e8: f402 62e0 and.w r2, r2, #1792 ; 0x700 + 80090ec: 60c2 str r2, [r0, #12] + RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U); + 80090ee: 689b ldr r3, [r3, #8] + 80090f0: 08db lsrs r3, r3, #3 + 80090f2: f403 63e0 and.w r3, r3, #1792 ; 0x700 + 80090f6: 6103 str r3, [r0, #16] + *pFLatency = __HAL_FLASH_GET_LATENCY(); + 80090f8: 4b03 ldr r3, [pc, #12] ; (8009108 ) + 80090fa: 681b ldr r3, [r3, #0] + 80090fc: f003 030f and.w r3, r3, #15 + 8009100: 600b str r3, [r1, #0] +} + 8009102: 4770 bx lr + 8009104: 40021000 .word 0x40021000 + 8009108: 40022000 .word 0x40022000 + +0800910c : + SET_BIT(RCC->CR, RCC_CR_CSSON) ; + 800910c: 4a02 ldr r2, [pc, #8] ; (8009118 ) + 800910e: 6813 ldr r3, [r2, #0] + 8009110: f443 2300 orr.w r3, r3, #524288 ; 0x80000 + 8009114: 6013 str r3, [r2, #0] +} + 8009116: 4770 bx lr + 8009118: 40021000 .word 0x40021000 + +0800911c : +} + 800911c: 4770 bx lr + ... + +08009120 : +{ + 8009120: b510 push {r4, lr} + if(__HAL_RCC_GET_IT(RCC_IT_CSS)) + 8009122: 4c05 ldr r4, [pc, #20] ; (8009138 ) + 8009124: 69e3 ldr r3, [r4, #28] + 8009126: 05db lsls r3, r3, #23 + 8009128: d504 bpl.n 8009134 + HAL_RCC_CSSCallback(); + 800912a: f7ff fff7 bl 800911c + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); + 800912e: f44f 7380 mov.w r3, #256 ; 0x100 + 8009132: 6223 str r3, [r4, #32] +} + 8009134: bd10 pop {r4, pc} + 8009136: bf00 nop + 8009138: 40021000 .word 0x40021000 + +0800913c : +#if defined(RCC_PLLP_SUPPORT) + uint32_t pllp = 0U; +#endif /* RCC_PLLP_SUPPORT */ + + /* Handle SAIs */ + if(PeriphClk == RCC_PERIPHCLK_SAI1) + 800913c: f5b0 6f00 cmp.w r0, #2048 ; 0x800 + 8009140: 4a3d ldr r2, [pc, #244] ; (8009238 ) + 8009142: d108 bne.n 8009156 + { + srcclk = __HAL_RCC_GET_SAI1_SOURCE(); + 8009144: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009148: f003 03e0 and.w r3, r3, #224 ; 0xe0 + if(srcclk == RCC_SAI1CLKSOURCE_PIN) + 800914c: 2b60 cmp r3, #96 ; 0x60 + 800914e: d12d bne.n 80091ac + { + frequency = EXTERNAL_SAI1_CLOCK_VALUE; + 8009150: f64b 3080 movw r0, #48000 ; 0xbb80 + 8009154: 4770 bx lr + /* Else, PLL clock output to check below */ + } +#if defined(SAI2) + else + { + if(PeriphClk == RCC_PERIPHCLK_SAI2) + 8009156: f5b0 5f80 cmp.w r0, #4096 ; 0x1000 + 800915a: d12a bne.n 80091b2 + { + srcclk = __HAL_RCC_GET_SAI2_SOURCE(); + 800915c: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009160: f403 63e0 and.w r3, r3, #1792 ; 0x700 + if(srcclk == RCC_SAI2CLKSOURCE_PIN) + 8009164: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 8009168: d0f2 beq.n 8009150 + if(frequency == 0U) + { + pllvco = InputFrequency; + +#if defined(SAI2) + if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL)) + 800916a: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800916e: d15c bne.n 800922a + { + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != 0U)) + 8009170: 6810 ldr r0, [r2, #0] + 8009172: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009176: d05d beq.n 8009234 + 8009178: 68d0 ldr r0, [r2, #12] + 800917a: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 800917e: d059 beq.n 8009234 + { + /* f(PLL Source) / PLLM */ + pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009180: 68d0 ldr r0, [r2, #12] + 8009182: f3c0 1003 ubfx r0, r0, #4, #4 + 8009186: 3001 adds r0, #1 + 8009188: fbb1 f0f0 udiv r0, r1, r0 + /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */ + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 800918c: 68d1 ldr r1, [r2, #12] +#if defined(RCC_PLLP_DIV_2_31_SUPPORT) + pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 800918e: 68d3 ldr r3, [r2, #12] +#endif + if(pllp == 0U) + 8009190: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009192: f3c1 2106 ubfx r1, r1, #8, #7 + if(pllp == 0U) + 8009196: d105 bne.n 80091a4 + { + if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U) + 8009198: 68d3 ldr r3, [r2, #12] + { + pllp = 17U; + } + else + { + pllp = 7U; + 800919a: f413 3f00 tst.w r3, #131072 ; 0x20000 + 800919e: bf14 ite ne + 80091a0: 2311 movne r3, #17 + 80091a2: 2307 moveq r3, #7 + } + } + frequency = (pllvco * plln) / pllp; + 80091a4: 4348 muls r0, r1 + 80091a6: fbb0 f0f3 udiv r0, r0, r3 + 80091aa: 4770 bx lr + if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL)) + 80091ac: 2b40 cmp r3, #64 ; 0x40 + 80091ae: d0df beq.n 8009170 + else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */ + 80091b0: b9ab cbnz r3, 80091de + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)) + 80091b2: 6810 ldr r0, [r2, #0] + 80091b4: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 80091b8: d03c beq.n 8009234 + 80091ba: 6910 ldr r0, [r2, #16] + 80091bc: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 80091c0: d038 beq.n 8009234 + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 80091c2: 6913 ldr r3, [r2, #16] + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 80091c4: 6910 ldr r0, [r2, #16] + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 80091c6: f3c3 1303 ubfx r3, r3, #4, #4 + 80091ca: 3301 adds r3, #1 + 80091cc: fbb1 f1f3 udiv r1, r1, r3 + pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos; + 80091d0: 6913 ldr r3, [r2, #16] + if(pllp == 0U) + 80091d2: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 80091d4: f3c0 2006 ubfx r0, r0, #8, #7 + if(pllp == 0U) + 80091d8: d1e4 bne.n 80091a4 + if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U) + 80091da: 6913 ldr r3, [r2, #16] + 80091dc: e7dd b.n 800919a + else if((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI)) + 80091de: 2b80 cmp r3, #128 ; 0x80 + 80091e0: d106 bne.n 80091f0 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 80091e2: 6810 ldr r0, [r2, #0] + frequency = HSI_VALUE; + 80091e4: 4b15 ldr r3, [pc, #84] ; (800923c ) + 80091e6: f410 6080 ands.w r0, r0, #1024 ; 0x400 + 80091ea: bf18 it ne + 80091ec: 4618 movne r0, r3 + 80091ee: 4770 bx lr + else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2)) + 80091f0: 2b20 cmp r3, #32 + 80091f2: d002 beq.n 80091fa + 80091f4: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 80091f8: d115 bne.n 8009226 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI2RDY) && (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != 0U)) + 80091fa: 6810 ldr r0, [r2, #0] + 80091fc: f010 5000 ands.w r0, r0, #536870912 ; 0x20000000 + 8009200: d018 beq.n 8009234 + 8009202: 6950 ldr r0, [r2, #20] + 8009204: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 8009208: d014 beq.n 8009234 + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U)); + 800920a: 6953 ldr r3, [r2, #20] + 800920c: f3c3 1303 ubfx r3, r3, #4, #4 + 8009210: 3301 adds r3, #1 + 8009212: fbb1 f0f3 udiv r0, r1, r3 + plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 8009216: 6951 ldr r1, [r2, #20] + pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos; + 8009218: 6953 ldr r3, [r2, #20] + if(pllp == 0U) + 800921a: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 800921c: f3c1 2106 ubfx r1, r1, #8, #7 + if(pllp == 0U) + 8009220: d1c0 bne.n 80091a4 + if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != 0U) + 8009222: 6953 ldr r3, [r2, #20] + 8009224: e7b9 b.n 800919a + 8009226: 2000 movs r0, #0 + /* No clock source, frequency default init at 0 */ + } + } + + + return frequency; + 8009228: 4770 bx lr + else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */ + 800922a: 2b00 cmp r3, #0 + 800922c: d0c1 beq.n 80091b2 + else if((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI)) + 800922e: f5b3 6f80 cmp.w r3, #1024 ; 0x400 + 8009232: e7d5 b.n 80091e0 +} + 8009234: 4770 bx lr + 8009236: bf00 nop + 8009238: 40021000 .word 0x40021000 + 800923c: 00f42400 .word 0x00f42400 + +08009240 : +{ + 8009240: b5f8 push {r3, r4, r5, r6, r7, lr} + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009242: 4c3c ldr r4, [pc, #240] ; (8009334 ) + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source) + 8009244: 6803 ldr r3, [r0, #0] + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009246: 68e2 ldr r2, [r4, #12] +{ + 8009248: 4605 mov r5, r0 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800924a: 0790 lsls r0, r2, #30 +{ + 800924c: 460f mov r7, r1 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800924e: d023 beq.n 8009298 + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source) + 8009250: 68e2 ldr r2, [r4, #12] + 8009252: f002 0203 and.w r2, r2, #3 + 8009256: 429a cmp r2, r3 + 8009258: d16a bne.n 8009330 + || + 800925a: 2a00 cmp r2, #0 + 800925c: d068 beq.n 8009330 + __HAL_RCC_PLLSAI1_DISABLE(); + 800925e: 6823 ldr r3, [r4, #0] + 8009260: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 8009264: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8009266: f7fd ff41 bl 80070ec + 800926a: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 800926c: 6823 ldr r3, [r4, #0] + 800926e: 011a lsls r2, r3, #4 + 8009270: d42d bmi.n 80092ce + MODIFY_REG(RCC->PLLSAI1CFGR, + 8009272: 68ab ldr r3, [r5, #8] + 8009274: 021e lsls r6, r3, #8 + 8009276: 686b ldr r3, [r5, #4] + 8009278: 3b01 subs r3, #1 + 800927a: 0118 lsls r0, r3, #4 + if(Divider == DIVIDER_P_UPDATE) + 800927c: b377 cbz r7, 80092dc + else if(Divider == DIVIDER_Q_UPDATE) + 800927e: 2f01 cmp r7, #1 + 8009280: d145 bne.n 800930e + MODIFY_REG(RCC->PLLSAI1CFGR, + 8009282: 692b ldr r3, [r5, #16] + 8009284: 6927 ldr r7, [r4, #16] + 8009286: 085b lsrs r3, r3, #1 + 8009288: 1e59 subs r1, r3, #1 + 800928a: 4b2b ldr r3, [pc, #172] ; (8009338 ) + 800928c: 403b ands r3, r7 + 800928e: 4333 orrs r3, r6 + 8009290: 4303 orrs r3, r0 + 8009292: ea43 5341 orr.w r3, r3, r1, lsl #21 + 8009296: e029 b.n 80092ec + switch(PllSai1->PLLSAI1Source) + 8009298: 2b02 cmp r3, #2 + 800929a: d00d beq.n 80092b8 + 800929c: 2b03 cmp r3, #3 + 800929e: d00f beq.n 80092c0 + 80092a0: 2b01 cmp r3, #1 + 80092a2: d145 bne.n 8009330 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) + 80092a4: 6822 ldr r2, [r4, #0] + 80092a6: f012 0f02 tst.w r2, #2 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80092aa: d041 beq.n 8009330 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai1->PLLSAI1Source); + 80092ac: 68e0 ldr r0, [r4, #12] + 80092ae: f020 0003 bic.w r0, r0, #3 + 80092b2: 4318 orrs r0, r3 + 80092b4: 60e0 str r0, [r4, #12] + if(status == HAL_OK) + 80092b6: e7d2 b.n 800925e + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) + 80092b8: 6822 ldr r2, [r4, #0] + 80092ba: f412 6f80 tst.w r2, #1024 ; 0x400 + 80092be: e7f4 b.n 80092aa + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY)) + 80092c0: 6822 ldr r2, [r4, #0] + 80092c2: 0391 lsls r1, r2, #14 + 80092c4: d4f2 bmi.n 80092ac + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80092c6: 6822 ldr r2, [r4, #0] + 80092c8: f412 2f80 tst.w r2, #262144 ; 0x40000 + 80092cc: e7ed b.n 80092aa + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 80092ce: f7fd ff0d bl 80070ec + 80092d2: 1b80 subs r0, r0, r6 + 80092d4: 2802 cmp r0, #2 + 80092d6: d9c9 bls.n 800926c + status = HAL_TIMEOUT; + 80092d8: 2003 movs r0, #3 +} + 80092da: bdf8 pop {r3, r4, r5, r6, r7, pc} + MODIFY_REG(RCC->PLLSAI1CFGR, + 80092dc: 68e9 ldr r1, [r5, #12] + 80092de: 6922 ldr r2, [r4, #16] + 80092e0: ea46 63c1 orr.w r3, r6, r1, lsl #27 + 80092e4: 4915 ldr r1, [pc, #84] ; (800933c ) + 80092e6: 4011 ands r1, r2 + 80092e8: 430b orrs r3, r1 + 80092ea: 4303 orrs r3, r0 + MODIFY_REG(RCC->PLLSAI1CFGR, + 80092ec: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1_ENABLE(); + 80092ee: 6823 ldr r3, [r4, #0] + 80092f0: f043 6380 orr.w r3, r3, #67108864 ; 0x4000000 + 80092f4: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80092f6: f7fd fef9 bl 80070ec + 80092fa: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 80092fc: 6823 ldr r3, [r4, #0] + 80092fe: 011b lsls r3, r3, #4 + 8009300: d510 bpl.n 8009324 + __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut); + 8009302: 6923 ldr r3, [r4, #16] + 8009304: 69aa ldr r2, [r5, #24] + 8009306: 4313 orrs r3, r2 + 8009308: 6123 str r3, [r4, #16] + 800930a: 2000 movs r0, #0 + return status; + 800930c: e7e5 b.n 80092da + MODIFY_REG(RCC->PLLSAI1CFGR, + 800930e: 696b ldr r3, [r5, #20] + 8009310: 6921 ldr r1, [r4, #16] + 8009312: 085b lsrs r3, r3, #1 + 8009314: 1e5a subs r2, r3, #1 + 8009316: 4b0a ldr r3, [pc, #40] ; (8009340 ) + 8009318: 400b ands r3, r1 + 800931a: 4333 orrs r3, r6 + 800931c: 4303 orrs r3, r0 + 800931e: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8009322: e7e3 b.n 80092ec + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 8009324: f7fd fee2 bl 80070ec + 8009328: 1b80 subs r0, r0, r6 + 800932a: 2802 cmp r0, #2 + 800932c: d9e6 bls.n 80092fc + 800932e: e7d3 b.n 80092d8 + status = HAL_ERROR; + 8009330: 2001 movs r0, #1 + 8009332: e7d2 b.n 80092da + 8009334: 40021000 .word 0x40021000 + 8009338: ff9f800f .word 0xff9f800f + 800933c: 07ff800f .word 0x07ff800f + 8009340: f9ff800f .word 0xf9ff800f + +08009344 : +static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider) + 8009344: b570 push {r4, r5, r6, lr} + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009346: 4c2f ldr r4, [pc, #188] ; (8009404 ) + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source) + 8009348: 6803 ldr r3, [r0, #0] + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800934a: 68e2 ldr r2, [r4, #12] +static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider) + 800934c: 4605 mov r5, r0 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800934e: 0790 lsls r0, r2, #30 + 8009350: d026 beq.n 80093a0 + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source) + 8009352: 68e2 ldr r2, [r4, #12] + 8009354: f002 0203 and.w r2, r2, #3 + 8009358: 429a cmp r2, r3 + 800935a: d151 bne.n 8009400 + || + 800935c: 2a00 cmp r2, #0 + 800935e: d04f beq.n 8009400 + __HAL_RCC_PLLSAI2_DISABLE(); + 8009360: 6823 ldr r3, [r4, #0] + 8009362: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8009366: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8009368: f7fd fec0 bl 80070ec + 800936c: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 800936e: 6823 ldr r3, [r4, #0] + 8009370: 009a lsls r2, r3, #2 + 8009372: d430 bmi.n 80093d6 + MODIFY_REG(RCC->PLLSAI2CFGR, + 8009374: e9d5 2302 ldrd r2, r3, [r5, #8] + 8009378: 06db lsls r3, r3, #27 + 800937a: 6961 ldr r1, [r4, #20] + 800937c: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8009380: 4a21 ldr r2, [pc, #132] ; (8009408 ) + 8009382: 400a ands r2, r1 + 8009384: 4313 orrs r3, r2 + 8009386: 686a ldr r2, [r5, #4] + 8009388: 3a01 subs r2, #1 + 800938a: ea43 1302 orr.w r3, r3, r2, lsl #4 + 800938e: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2_ENABLE(); + 8009390: 6823 ldr r3, [r4, #0] + 8009392: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 8009396: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8009398: f7fd fea8 bl 80070ec + 800939c: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 800939e: e026 b.n 80093ee + switch(PllSai2->PLLSAI2Source) + 80093a0: 2b02 cmp r3, #2 + 80093a2: d00d beq.n 80093c0 + 80093a4: 2b03 cmp r3, #3 + 80093a6: d00f beq.n 80093c8 + 80093a8: 2b01 cmp r3, #1 + 80093aa: d129 bne.n 8009400 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) + 80093ac: 6822 ldr r2, [r4, #0] + 80093ae: f012 0f02 tst.w r2, #2 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80093b2: d025 beq.n 8009400 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai2->PLLSAI2Source); + 80093b4: 68e0 ldr r0, [r4, #12] + 80093b6: f020 0003 bic.w r0, r0, #3 + 80093ba: 4318 orrs r0, r3 + 80093bc: 60e0 str r0, [r4, #12] + if(status == HAL_OK) + 80093be: e7cf b.n 8009360 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) + 80093c0: 6822 ldr r2, [r4, #0] + 80093c2: f412 6f80 tst.w r2, #1024 ; 0x400 + 80093c6: e7f4 b.n 80093b2 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY)) + 80093c8: 6822 ldr r2, [r4, #0] + 80093ca: 0391 lsls r1, r2, #14 + 80093cc: d4f2 bmi.n 80093b4 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80093ce: 6822 ldr r2, [r4, #0] + 80093d0: f412 2f80 tst.w r2, #262144 ; 0x40000 + 80093d4: e7ed b.n 80093b2 + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 80093d6: f7fd fe89 bl 80070ec + 80093da: 1b80 subs r0, r0, r6 + 80093dc: 2802 cmp r0, #2 + 80093de: d9c6 bls.n 800936e + status = HAL_TIMEOUT; + 80093e0: 2003 movs r0, #3 +} + 80093e2: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 80093e4: f7fd fe82 bl 80070ec + 80093e8: 1b80 subs r0, r0, r6 + 80093ea: 2802 cmp r0, #2 + 80093ec: d8f8 bhi.n 80093e0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 80093ee: 6823 ldr r3, [r4, #0] + 80093f0: 009b lsls r3, r3, #2 + 80093f2: d5f7 bpl.n 80093e4 + __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut); + 80093f4: 6963 ldr r3, [r4, #20] + 80093f6: 69aa ldr r2, [r5, #24] + 80093f8: 4313 orrs r3, r2 + 80093fa: 6163 str r3, [r4, #20] + 80093fc: 2000 movs r0, #0 + return status; + 80093fe: e7f0 b.n 80093e2 + status = HAL_ERROR; + 8009400: 2001 movs r0, #1 + 8009402: e7ee b.n 80093e2 + 8009404: 40021000 .word 0x40021000 + 8009408: 07ff800f .word 0x07ff800f + +0800940c : +{ + 800940c: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)) + 8009410: 6806 ldr r6, [r0, #0] + 8009412: f416 6600 ands.w r6, r6, #2048 ; 0x800 +{ + 8009416: 4604 mov r4, r0 + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)) + 8009418: d007 beq.n 800942a + switch(PeriphClkInit->Sai1ClockSelection) + 800941a: 6ec1 ldr r1, [r0, #108] ; 0x6c + 800941c: 2940 cmp r1, #64 ; 0x40 + 800941e: d022 beq.n 8009466 + 8009420: d812 bhi.n 8009448 + 8009422: b331 cbz r1, 8009472 + 8009424: 2920 cmp r1, #32 + 8009426: d02b beq.n 8009480 + 8009428: 2601 movs r6, #1 + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2)) + 800942a: 6823 ldr r3, [r4, #0] + 800942c: 04db lsls r3, r3, #19 + 800942e: d509 bpl.n 8009444 + switch(PeriphClkInit->Sai2ClockSelection) + 8009430: 6f21 ldr r1, [r4, #112] ; 0x70 + 8009432: f5b1 7f00 cmp.w r1, #512 ; 0x200 + 8009436: d02f beq.n 8009498 + 8009438: d826 bhi.n 8009488 + 800943a: b399 cbz r1, 80094a4 + 800943c: f5b1 7f80 cmp.w r1, #256 ; 0x100 + 8009440: d073 beq.n 800952a + 8009442: 2601 movs r6, #1 + 8009444: 4635 mov r5, r6 + 8009446: e03c b.n 80094c2 + switch(PeriphClkInit->Sai1ClockSelection) + 8009448: 2960 cmp r1, #96 ; 0x60 + 800944a: d001 beq.n 8009450 + 800944c: 2980 cmp r1, #128 ; 0x80 + 800944e: d1eb bne.n 8009428 + __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); + 8009450: 4a3b ldr r2, [pc, #236] ; (8009540 ) + 8009452: 6ee1 ldr r1, [r4, #108] ; 0x6c + 8009454: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009458: f023 03e0 bic.w r3, r3, #224 ; 0xe0 + 800945c: 430b orrs r3, r1 + 800945e: f8c2 309c str.w r3, [r2, #156] ; 0x9c + 8009462: 2600 movs r6, #0 + 8009464: e7e1 b.n 800942a + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 8009466: 4a36 ldr r2, [pc, #216] ; (8009540 ) + 8009468: 68d3 ldr r3, [r2, #12] + 800946a: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 800946e: 60d3 str r3, [r2, #12] + if(ret == HAL_OK) + 8009470: e7ee b.n 8009450 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); + 8009472: 3004 adds r0, #4 + 8009474: f7ff fee4 bl 8009240 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 8009478: 4606 mov r6, r0 + if(ret == HAL_OK) + 800947a: 2800 cmp r0, #0 + 800947c: d1d5 bne.n 800942a + 800947e: e7e7 b.n 8009450 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 8009480: 3020 adds r0, #32 + 8009482: f7ff ff5f bl 8009344 + 8009486: e7f7 b.n 8009478 + switch(PeriphClkInit->Sai2ClockSelection) + 8009488: f5b1 7f40 cmp.w r1, #768 ; 0x300 + 800948c: d002 beq.n 8009494 + 800948e: f5b1 6f80 cmp.w r1, #1024 ; 0x400 + 8009492: d1d6 bne.n 8009442 + 8009494: 4635 mov r5, r6 + 8009496: e009 b.n 80094ac + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 8009498: 4a29 ldr r2, [pc, #164] ; (8009540 ) + 800949a: 68d3 ldr r3, [r2, #12] + 800949c: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 80094a0: 60d3 str r3, [r2, #12] + break; + 80094a2: e7f7 b.n 8009494 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); + 80094a4: 1d20 adds r0, r4, #4 + 80094a6: f7ff fecb bl 8009240 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 80094aa: 4605 mov r5, r0 + if(ret == HAL_OK) + 80094ac: 2d00 cmp r5, #0 + 80094ae: d141 bne.n 8009534 + __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); + 80094b0: 4a23 ldr r2, [pc, #140] ; (8009540 ) + 80094b2: 6f21 ldr r1, [r4, #112] ; 0x70 + 80094b4: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 80094b8: f423 63e0 bic.w r3, r3, #1792 ; 0x700 + 80094bc: 430b orrs r3, r1 + 80094be: f8c2 309c str.w r3, [r2, #156] ; 0x9c + if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) + 80094c2: 6823 ldr r3, [r4, #0] + 80094c4: 039f lsls r7, r3, #14 + 80094c6: f140 817d bpl.w 80097c4 + if(__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U) + 80094ca: 4f1d ldr r7, [pc, #116] ; (8009540 ) + 80094cc: 6dbb ldr r3, [r7, #88] ; 0x58 + 80094ce: 00d8 lsls r0, r3, #3 + 80094d0: d432 bmi.n 8009538 + __HAL_RCC_PWR_CLK_ENABLE(); + 80094d2: 6dbb ldr r3, [r7, #88] ; 0x58 + 80094d4: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 80094d8: 65bb str r3, [r7, #88] ; 0x58 + 80094da: 6dbb ldr r3, [r7, #88] ; 0x58 + 80094dc: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 80094e0: 9301 str r3, [sp, #4] + 80094e2: 9b01 ldr r3, [sp, #4] + pwrclkchanged = SET; + 80094e4: f04f 0801 mov.w r8, #1 + SET_BIT(PWR->CR1, PWR_CR1_DBP); + 80094e8: f8df 9058 ldr.w r9, [pc, #88] ; 8009544 + 80094ec: f8d9 3000 ldr.w r3, [r9] + 80094f0: f443 7380 orr.w r3, r3, #256 ; 0x100 + 80094f4: f8c9 3000 str.w r3, [r9] + tickstart = HAL_GetTick(); + 80094f8: f7fd fdf8 bl 80070ec + 80094fc: 4682 mov sl, r0 + while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U) + 80094fe: f8d9 3000 ldr.w r3, [r9] + 8009502: 05d9 lsls r1, r3, #23 + 8009504: d520 bpl.n 8009548 + if(ret == HAL_OK) + 8009506: bb35 cbnz r5, 8009556 + tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL); + 8009508: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + if((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection)) + 800950c: f413 7340 ands.w r3, r3, #768 ; 0x300 + 8009510: f040 812e bne.w 8009770 + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + 8009514: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 8009518: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 800951c: f423 7340 bic.w r3, r3, #768 ; 0x300 + 8009520: 4313 orrs r3, r2 + 8009522: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + 8009526: 4635 mov r5, r6 + 8009528: e015 b.n 8009556 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 800952a: f104 0020 add.w r0, r4, #32 + 800952e: f7ff ff09 bl 8009344 + 8009532: e7ba b.n 80094aa + 8009534: 462e mov r6, r5 + 8009536: e7c4 b.n 80094c2 + FlagStatus pwrclkchanged = RESET; + 8009538: f04f 0800 mov.w r8, #0 + 800953c: e7d4 b.n 80094e8 + 800953e: bf00 nop + 8009540: 40021000 .word 0x40021000 + 8009544: 40007000 .word 0x40007000 + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 8009548: f7fd fdd0 bl 80070ec + 800954c: eba0 000a sub.w r0, r0, sl + 8009550: 2802 cmp r0, #2 + 8009552: d9d4 bls.n 80094fe + ret = HAL_TIMEOUT; + 8009554: 2503 movs r5, #3 + if(pwrclkchanged == SET) + 8009556: f1b8 0f00 cmp.w r8, #0 + 800955a: d003 beq.n 8009564 + __HAL_RCC_PWR_CLK_DISABLE(); + 800955c: 6dbb ldr r3, [r7, #88] ; 0x58 + 800955e: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8009562: 65bb str r3, [r7, #88] ; 0x58 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + 8009564: 6823 ldr r3, [r4, #0] + 8009566: 07d8 lsls r0, r3, #31 + 8009568: d508 bpl.n 800957c + __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); + 800956a: 49b2 ldr r1, [pc, #712] ; (8009834 ) + 800956c: 6be0 ldr r0, [r4, #60] ; 0x3c + 800956e: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009572: f022 0203 bic.w r2, r2, #3 + 8009576: 4302 orrs r2, r0 + 8009578: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + 800957c: 0799 lsls r1, r3, #30 + 800957e: d508 bpl.n 8009592 + __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); + 8009580: 49ac ldr r1, [pc, #688] ; (8009834 ) + 8009582: 6c20 ldr r0, [r4, #64] ; 0x40 + 8009584: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009588: f022 020c bic.w r2, r2, #12 + 800958c: 4302 orrs r2, r0 + 800958e: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3) + 8009592: 075a lsls r2, r3, #29 + 8009594: d508 bpl.n 80095a8 + __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); + 8009596: 49a7 ldr r1, [pc, #668] ; (8009834 ) + 8009598: 6c60 ldr r0, [r4, #68] ; 0x44 + 800959a: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 800959e: f022 0230 bic.w r2, r2, #48 ; 0x30 + 80095a2: 4302 orrs r2, r0 + 80095a4: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4) + 80095a8: 071f lsls r7, r3, #28 + 80095aa: d508 bpl.n 80095be + __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection); + 80095ac: 49a1 ldr r1, [pc, #644] ; (8009834 ) + 80095ae: 6ca0 ldr r0, [r4, #72] ; 0x48 + 80095b0: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80095b4: f022 02c0 bic.w r2, r2, #192 ; 0xc0 + 80095b8: 4302 orrs r2, r0 + 80095ba: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5) + 80095be: 06de lsls r6, r3, #27 + 80095c0: d508 bpl.n 80095d4 + __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection); + 80095c2: 499c ldr r1, [pc, #624] ; (8009834 ) + 80095c4: 6ce0 ldr r0, [r4, #76] ; 0x4c + 80095c6: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80095ca: f422 7240 bic.w r2, r2, #768 ; 0x300 + 80095ce: 4302 orrs r2, r0 + 80095d0: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) + 80095d4: 0698 lsls r0, r3, #26 + 80095d6: d508 bpl.n 80095ea + __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection); + 80095d8: 4996 ldr r1, [pc, #600] ; (8009834 ) + 80095da: 6d20 ldr r0, [r4, #80] ; 0x50 + 80095dc: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80095e0: f422 6240 bic.w r2, r2, #3072 ; 0xc00 + 80095e4: 4302 orrs r2, r0 + 80095e6: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1)) + 80095ea: 0599 lsls r1, r3, #22 + 80095ec: d508 bpl.n 8009600 + __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); + 80095ee: 4991 ldr r1, [pc, #580] ; (8009834 ) + 80095f0: 6e60 ldr r0, [r4, #100] ; 0x64 + 80095f2: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80095f6: f422 2240 bic.w r2, r2, #786432 ; 0xc0000 + 80095fa: 4302 orrs r2, r0 + 80095fc: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2)) + 8009600: 055a lsls r2, r3, #21 + 8009602: d508 bpl.n 8009616 + __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection); + 8009604: 498b ldr r1, [pc, #556] ; (8009834 ) + 8009606: 6ea0 ldr r0, [r4, #104] ; 0x68 + 8009608: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 800960c: f422 1240 bic.w r2, r2, #3145728 ; 0x300000 + 8009610: 4302 orrs r2, r0 + 8009612: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + 8009616: 065f lsls r7, r3, #25 + 8009618: d508 bpl.n 800962c + __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); + 800961a: 4986 ldr r1, [pc, #536] ; (8009834 ) + 800961c: 6d60 ldr r0, [r4, #84] ; 0x54 + 800961e: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009622: f422 5240 bic.w r2, r2, #12288 ; 0x3000 + 8009626: 4302 orrs r2, r0 + 8009628: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2) + 800962c: 061e lsls r6, r3, #24 + 800962e: d508 bpl.n 8009642 + __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection); + 8009630: 4980 ldr r1, [pc, #512] ; (8009834 ) + 8009632: 6da0 ldr r0, [r4, #88] ; 0x58 + 8009634: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009638: f422 4240 bic.w r2, r2, #49152 ; 0xc000 + 800963c: 4302 orrs r2, r0 + 800963e: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3) + 8009642: 05d8 lsls r0, r3, #23 + 8009644: d508 bpl.n 8009658 + __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection); + 8009646: 497b ldr r1, [pc, #492] ; (8009834 ) + 8009648: 6de0 ldr r0, [r4, #92] ; 0x5c + 800964a: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 800964e: f422 3240 bic.w r2, r2, #196608 ; 0x30000 + 8009652: 4302 orrs r2, r0 + 8009654: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4) + 8009658: 02d9 lsls r1, r3, #11 + 800965a: d508 bpl.n 800966e + __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection); + 800965c: 4975 ldr r1, [pc, #468] ; (8009834 ) + 800965e: 6e20 ldr r0, [r4, #96] ; 0x60 + 8009660: f8d1 209c ldr.w r2, [r1, #156] ; 0x9c + 8009664: f022 0203 bic.w r2, r2, #3 + 8009668: 4302 orrs r2, r0 + 800966a: f8c1 209c str.w r2, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB)) + 800966e: 049a lsls r2, r3, #18 + 8009670: d510 bpl.n 8009694 + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8009672: 4a70 ldr r2, [pc, #448] ; (8009834 ) + 8009674: 6f61 ldr r1, [r4, #116] ; 0x74 + 8009676: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 800967a: f023 6340 bic.w r3, r3, #201326592 ; 0xc000000 + 800967e: 430b orrs r3, r1 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL) + 8009680: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8009684: f8c2 3088 str.w r3, [r2, #136] ; 0x88 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL) + 8009688: f040 809e bne.w 80097c8 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 800968c: 68d3 ldr r3, [r2, #12] + 800968e: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 8009692: 60d3 str r3, [r2, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1)) + 8009694: 6823 ldr r3, [r4, #0] + 8009696: 031b lsls r3, r3, #12 + 8009698: d50f bpl.n 80096ba + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 800969a: 6fa1 ldr r1, [r4, #120] ; 0x78 + 800969c: 4b65 ldr r3, [pc, #404] ; (8009834 ) + 800969e: f5b1 4f80 cmp.w r1, #16384 ; 0x4000 + 80096a2: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 80096a6: f040 809b bne.w 80097e0 + 80096aa: f442 4280 orr.w r2, r2, #16384 ; 0x4000 + 80096ae: f8c3 209c str.w r2, [r3, #156] ; 0x9c + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 80096b2: 68da ldr r2, [r3, #12] + 80096b4: f442 3280 orr.w r2, r2, #65536 ; 0x10000 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 80096b8: 60da str r2, [r3, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG)) + 80096ba: 6823 ldr r3, [r4, #0] + 80096bc: 035f lsls r7, r3, #13 + 80096be: d510 bpl.n 80096e2 + __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection); + 80096c0: 4a5c ldr r2, [pc, #368] ; (8009834 ) + 80096c2: 6fe1 ldr r1, [r4, #124] ; 0x7c + 80096c4: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 80096c8: f023 6340 bic.w r3, r3, #201326592 ; 0xc000000 + 80096cc: 430b orrs r3, r1 + if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL) + 80096ce: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection); + 80096d2: f8c2 3088 str.w r3, [r2, #136] ; 0x88 + if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL) + 80096d6: f040 80a1 bne.w 800981c + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 80096da: 68d3 ldr r3, [r2, #12] + 80096dc: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 80096e0: 60d3 str r3, [r2, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC) + 80096e2: 6823 ldr r3, [r4, #0] + 80096e4: 045e lsls r6, r3, #17 + 80096e6: d513 bpl.n 8009710 + __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); + 80096e8: 4952 ldr r1, [pc, #328] ; (8009834 ) + 80096ea: f8d4 2080 ldr.w r2, [r4, #128] ; 0x80 + 80096ee: f8d1 3088 ldr.w r3, [r1, #136] ; 0x88 + 80096f2: f023 5340 bic.w r3, r3, #805306368 ; 0x30000000 + 80096f6: 4313 orrs r3, r2 + if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1) + 80096f8: f1b2 5f80 cmp.w r2, #268435456 ; 0x10000000 + __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); + 80096fc: f8c1 3088 str.w r3, [r1, #136] ; 0x88 + if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1) + 8009700: d106 bne.n 8009710 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE); + 8009702: 2102 movs r1, #2 + 8009704: 1d20 adds r0, r4, #4 + 8009706: f7ff fd9b bl 8009240 + if(ret != HAL_OK) + 800970a: 2800 cmp r0, #0 + 800970c: bf18 it ne + 800970e: 4605 movne r5, r0 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1) + 8009710: 6822 ldr r2, [r4, #0] + 8009712: 03d0 lsls r0, r2, #15 + 8009714: d509 bpl.n 800972a + __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection); + 8009716: 4947 ldr r1, [pc, #284] ; (8009834 ) + 8009718: f8d4 0084 ldr.w r0, [r4, #132] ; 0x84 + 800971c: f8d1 309c ldr.w r3, [r1, #156] ; 0x9c + 8009720: f023 0304 bic.w r3, r3, #4 + 8009724: 4303 orrs r3, r0 + 8009726: f8c1 309c str.w r3, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1AUDIO) == RCC_PERIPHCLK_DFSDM1AUDIO) + 800972a: 0291 lsls r1, r2, #10 + 800972c: d509 bpl.n 8009742 + __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection); + 800972e: 4941 ldr r1, [pc, #260] ; (8009834 ) + 8009730: f8d4 0088 ldr.w r0, [r4, #136] ; 0x88 + 8009734: f8d1 309c ldr.w r3, [r1, #156] ; 0x9c + 8009738: f023 0318 bic.w r3, r3, #24 + 800973c: 4303 orrs r3, r0 + 800973e: f8c1 309c str.w r3, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI) + 8009742: 01d3 lsls r3, r2, #7 + 8009744: d510 bpl.n 8009768 + __HAL_RCC_OSPI_CONFIG(PeriphClkInit->OspiClockSelection); + 8009746: 4a3b ldr r2, [pc, #236] ; (8009834 ) + 8009748: f8d4 108c ldr.w r1, [r4, #140] ; 0x8c + 800974c: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009750: f423 1340 bic.w r3, r3, #3145728 ; 0x300000 + 8009754: 430b orrs r3, r1 + 8009756: f8c2 309c str.w r3, [r2, #156] ; 0x9c + if(PeriphClkInit->OspiClockSelection == RCC_OSPICLKSOURCE_PLL) + 800975a: f5b1 1f00 cmp.w r1, #2097152 ; 0x200000 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 800975e: bf02 ittt eq + 8009760: 68d3 ldreq r3, [r2, #12] + 8009762: f443 1380 orreq.w r3, r3, #1048576 ; 0x100000 + 8009766: 60d3 streq r3, [r2, #12] +} + 8009768: 4628 mov r0, r5 + 800976a: b002 add sp, #8 + 800976c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection)) + 8009770: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8009774: 429a cmp r2, r3 + 8009776: f43f aecd beq.w 8009514 + tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + 800977a: f8d7 2090 ldr.w r2, [r7, #144] ; 0x90 + __HAL_RCC_BACKUPRESET_FORCE(); + 800977e: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 8009782: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8009786: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + __HAL_RCC_BACKUPRESET_RELEASE(); + 800978a: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + 800978e: f422 7140 bic.w r1, r2, #768 ; 0x300 + __HAL_RCC_BACKUPRESET_RELEASE(); + 8009792: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) + 8009796: 07d2 lsls r2, r2, #31 + __HAL_RCC_BACKUPRESET_RELEASE(); + 8009798: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + RCC->BDCR = tmpregister; + 800979c: f8c7 1090 str.w r1, [r7, #144] ; 0x90 + if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) + 80097a0: f57f aeb8 bpl.w 8009514 + tickstart = HAL_GetTick(); + 80097a4: f7fd fca2 bl 80070ec + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 80097a8: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 80097ac: 4605 mov r5, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + 80097ae: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 80097b2: 079b lsls r3, r3, #30 + 80097b4: f53f aeae bmi.w 8009514 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 80097b8: f7fd fc98 bl 80070ec + 80097bc: 1b40 subs r0, r0, r5 + 80097be: 4548 cmp r0, r9 + 80097c0: d9f5 bls.n 80097ae + 80097c2: e6c7 b.n 8009554 + 80097c4: 4635 mov r5, r6 + 80097c6: e6cd b.n 8009564 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1) + 80097c8: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 80097cc: f47f af62 bne.w 8009694 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 80097d0: 2101 movs r1, #1 + 80097d2: 1d20 adds r0, r4, #4 + 80097d4: f7ff fd34 bl 8009240 + if(ret != HAL_OK) + 80097d8: 2800 cmp r0, #0 + 80097da: bf18 it ne + 80097dc: 4605 movne r5, r0 + 80097de: e759 b.n 8009694 + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 80097e0: f422 4280 bic.w r2, r2, #16384 ; 0x4000 + 80097e4: f8c3 209c str.w r2, [r3, #156] ; 0x9c + 80097e8: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80097ec: f022 6240 bic.w r2, r2, #201326592 ; 0xc000000 + 80097f0: 430a orrs r2, r1 + if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) /* PLL "Q" ? */ + 80097f2: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 80097f6: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) /* PLL "Q" ? */ + 80097fa: d103 bne.n 8009804 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 80097fc: 68da ldr r2, [r3, #12] + 80097fe: f442 1280 orr.w r2, r2, #1048576 ; 0x100000 + 8009802: e759 b.n 80096b8 + else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1) + 8009804: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 8009808: f47f af57 bne.w 80096ba + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 800980c: 2101 movs r1, #1 + 800980e: 1d20 adds r0, r4, #4 + 8009810: f7ff fd16 bl 8009240 + if(ret != HAL_OK) + 8009814: 2800 cmp r0, #0 + 8009816: bf18 it ne + 8009818: 4605 movne r5, r0 + 800981a: e74e b.n 80096ba + else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1) + 800981c: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 8009820: f47f af5f bne.w 80096e2 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 8009824: 2101 movs r1, #1 + 8009826: 1d20 adds r0, r4, #4 + 8009828: f7ff fd0a bl 8009240 + if(ret != HAL_OK) + 800982c: 2800 cmp r0, #0 + 800982e: bf18 it ne + 8009830: 4605 movne r5, r0 + 8009832: e756 b.n 80096e2 + 8009834: 40021000 .word 0x40021000 + +08009838 : + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \ + 8009838: 4b5b ldr r3, [pc, #364] ; (80099a8 ) + 800983a: 6003 str r3, [r0, #0] + PeriphClkInit->PLLSAI1.PLLSAI1Source = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC) >> RCC_PLLCFGR_PLLSRC_Pos; + 800983c: 4b5b ldr r3, [pc, #364] ; (80099ac ) + 800983e: 68d9 ldr r1, [r3, #12] + 8009840: f001 0103 and.w r1, r1, #3 + 8009844: 6041 str r1, [r0, #4] + PeriphClkInit->PLLSAI1.PLLSAI1M = (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U; + 8009846: 691a ldr r2, [r3, #16] + 8009848: f3c2 1203 ubfx r2, r2, #4, #4 + 800984c: 3201 adds r2, #1 + 800984e: 6082 str r2, [r0, #8] + PeriphClkInit->PLLSAI1.PLLSAI1N = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009850: 691a ldr r2, [r3, #16] + 8009852: f3c2 2206 ubfx r2, r2, #8, #7 + 8009856: 60c2 str r2, [r0, #12] + PeriphClkInit->PLLSAI1.PLLSAI1P = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) >> RCC_PLLSAI1CFGR_PLLSAI1P_Pos) << 4U) + 7U; + 8009858: 691a ldr r2, [r3, #16] + 800985a: 0b52 lsrs r2, r2, #13 + 800985c: f002 0210 and.w r2, r2, #16 + 8009860: 3207 adds r2, #7 + 8009862: 6102 str r2, [r0, #16] + PeriphClkInit->PLLSAI1.PLLSAI1Q = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) * 2U; + 8009864: 691a ldr r2, [r3, #16] + 8009866: f3c2 5241 ubfx r2, r2, #21, #2 + 800986a: 3201 adds r2, #1 + 800986c: 0052 lsls r2, r2, #1 + 800986e: 6142 str r2, [r0, #20] + PeriphClkInit->PLLSAI1.PLLSAI1R = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U; + 8009870: 691a ldr r2, [r3, #16] + PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source; + 8009872: 6201 str r1, [r0, #32] + PeriphClkInit->PLLSAI1.PLLSAI1R = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U; + 8009874: f3c2 6241 ubfx r2, r2, #25, #2 + 8009878: 3201 adds r2, #1 + 800987a: 0052 lsls r2, r2, #1 + 800987c: 6182 str r2, [r0, #24] + PeriphClkInit->PLLSAI2.PLLSAI2M = (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U; + 800987e: 695a ldr r2, [r3, #20] + 8009880: f3c2 1203 ubfx r2, r2, #4, #4 + 8009884: 3201 adds r2, #1 + 8009886: 6242 str r2, [r0, #36] ; 0x24 + PeriphClkInit->PLLSAI2.PLLSAI2N = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 8009888: 695a ldr r2, [r3, #20] + 800988a: f3c2 2206 ubfx r2, r2, #8, #7 + 800988e: 6282 str r2, [r0, #40] ; 0x28 + PeriphClkInit->PLLSAI2.PLLSAI2P = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) >> RCC_PLLSAI2CFGR_PLLSAI2P_Pos) << 4U) + 7U; + 8009890: 695a ldr r2, [r3, #20] + 8009892: 0b52 lsrs r2, r2, #13 + 8009894: f002 0210 and.w r2, r2, #16 + 8009898: 3207 adds r2, #7 + 800989a: 62c2 str r2, [r0, #44] ; 0x2c + PeriphClkInit->PLLSAI2.PLLSAI2Q = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2Q) >> RCC_PLLSAI2CFGR_PLLSAI2Q_Pos) + 1U) * 2U; + 800989c: 695a ldr r2, [r3, #20] + 800989e: f3c2 5241 ubfx r2, r2, #21, #2 + 80098a2: 3201 adds r2, #1 + 80098a4: 0052 lsls r2, r2, #1 + 80098a6: 6302 str r2, [r0, #48] ; 0x30 + PeriphClkInit->PLLSAI2.PLLSAI2R = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R)>> RCC_PLLSAI2CFGR_PLLSAI2R_Pos) + 1U) * 2U; + 80098a8: 695a ldr r2, [r3, #20] + 80098aa: f3c2 6241 ubfx r2, r2, #25, #2 + 80098ae: 3201 adds r2, #1 + 80098b0: 0052 lsls r2, r2, #1 + 80098b2: 6342 str r2, [r0, #52] ; 0x34 + PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); + 80098b4: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098b8: f002 0203 and.w r2, r2, #3 + 80098bc: 63c2 str r2, [r0, #60] ; 0x3c + PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); + 80098be: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098c2: f002 020c and.w r2, r2, #12 + 80098c6: 6402 str r2, [r0, #64] ; 0x40 + PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE(); + 80098c8: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098cc: f002 0230 and.w r2, r2, #48 ; 0x30 + 80098d0: 6442 str r2, [r0, #68] ; 0x44 + PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE(); + 80098d2: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098d6: f002 02c0 and.w r2, r2, #192 ; 0xc0 + 80098da: 6482 str r2, [r0, #72] ; 0x48 + PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE(); + 80098dc: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098e0: f402 7240 and.w r2, r2, #768 ; 0x300 + 80098e4: 64c2 str r2, [r0, #76] ; 0x4c + PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); + 80098e6: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098ea: f402 6240 and.w r2, r2, #3072 ; 0xc00 + 80098ee: 6502 str r2, [r0, #80] ; 0x50 + PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); + 80098f0: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098f4: f402 5240 and.w r2, r2, #12288 ; 0x3000 + 80098f8: 6542 str r2, [r0, #84] ; 0x54 + PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE(); + 80098fa: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 80098fe: f402 4240 and.w r2, r2, #49152 ; 0xc000 + 8009902: 6582 str r2, [r0, #88] ; 0x58 + PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE(); + 8009904: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009908: f402 3240 and.w r2, r2, #196608 ; 0x30000 + 800990c: 65c2 str r2, [r0, #92] ; 0x5c + PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE(); + 800990e: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009912: f002 0203 and.w r2, r2, #3 + 8009916: 6602 str r2, [r0, #96] ; 0x60 + PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); + 8009918: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 800991c: f402 2240 and.w r2, r2, #786432 ; 0xc0000 + 8009920: 6642 str r2, [r0, #100] ; 0x64 + PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE(); + 8009922: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009926: f402 1240 and.w r2, r2, #3145728 ; 0x300000 + 800992a: 6682 str r2, [r0, #104] ; 0x68 + PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); + 800992c: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009930: f002 02e0 and.w r2, r2, #224 ; 0xe0 + 8009934: 66c2 str r2, [r0, #108] ; 0x6c + PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); + 8009936: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 800993a: f402 62e0 and.w r2, r2, #1792 ; 0x700 + 800993e: 6702 str r2, [r0, #112] ; 0x70 + PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); + 8009940: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 8009944: f402 7240 and.w r2, r2, #768 ; 0x300 + 8009948: f8c0 2090 str.w r2, [r0, #144] ; 0x90 + PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); + 800994c: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009950: f002 6240 and.w r2, r2, #201326592 ; 0xc000000 + 8009954: 6742 str r2, [r0, #116] ; 0x74 + PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE(); + 8009956: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 800995a: 0452 lsls r2, r2, #17 + 800995c: bf56 itet pl + 800995e: f8d3 2088 ldrpl.w r2, [r3, #136] ; 0x88 + 8009962: f44f 4280 movmi.w r2, #16384 ; 0x4000 + 8009966: f002 6240 andpl.w r2, r2, #201326592 ; 0xc000000 + 800996a: 6782 str r2, [r0, #120] ; 0x78 + PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE(); + 800996c: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009970: f002 6240 and.w r2, r2, #201326592 ; 0xc000000 + 8009974: 67c2 str r2, [r0, #124] ; 0x7c + PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE(); + 8009976: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 800997a: f002 5240 and.w r2, r2, #805306368 ; 0x30000000 + 800997e: f8c0 2080 str.w r2, [r0, #128] ; 0x80 + PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE(); + 8009982: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009986: f002 0204 and.w r2, r2, #4 + 800998a: f8c0 2084 str.w r2, [r0, #132] ; 0x84 + PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); + 800998e: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009992: f002 0218 and.w r2, r2, #24 + 8009996: f8c0 2088 str.w r2, [r0, #136] ; 0x88 + PeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE(); + 800999a: f8d3 309c ldr.w r3, [r3, #156] ; 0x9c + 800999e: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + 80099a2: f8c0 308c str.w r3, [r0, #140] ; 0x8c +} + 80099a6: 4770 bx lr + 80099a8: 013f7fff .word 0x013f7fff + 80099ac: 40021000 .word 0x40021000 + +080099b0 : + if(PeriphClk == RCC_PERIPHCLK_RTC) + 80099b0: f5b0 3f00 cmp.w r0, #131072 ; 0x20000 +{ + 80099b4: b4f0 push {r4, r5, r6, r7} + 80099b6: 4d9a ldr r5, [pc, #616] ; (8009c20 ) + if(PeriphClk == RCC_PERIPHCLK_RTC) + 80099b8: d11c bne.n 80099f4 + srcclk = __HAL_RCC_GET_RTC_SOURCE(); + 80099ba: f8d5 3090 ldr.w r3, [r5, #144] ; 0x90 + 80099be: f403 7340 and.w r3, r3, #768 ; 0x300 + switch(srcclk) + 80099c2: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 80099c6: f000 8085 beq.w 8009ad4 + 80099ca: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 80099ce: d00a beq.n 80099e6 + 80099d0: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 80099d4: d154 bne.n 8009a80 + if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + 80099d6: f8d5 0090 ldr.w r0, [r5, #144] ; 0x90 + frequency = LSE_VALUE; + 80099da: f010 0002 ands.w r0, r0, #2 + 80099de: bf18 it ne + 80099e0: f44f 4000 movne.w r0, #32768 ; 0x8000 + 80099e4: e11a b.n 8009c1c + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) + 80099e6: 6828 ldr r0, [r5, #0] + frequency = HSE_VALUE / 32U; + 80099e8: 4b8e ldr r3, [pc, #568] ; (8009c24 ) + 80099ea: f410 3000 ands.w r0, r0, #131072 ; 0x20000 + frequency = HSI_VALUE; + 80099ee: bf18 it ne + 80099f0: 4618 movne r0, r3 + 80099f2: e113 b.n 8009c1c + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 80099f4: 68eb ldr r3, [r5, #12] + 80099f6: f003 0303 and.w r3, r3, #3 + switch(pll_oscsource) + 80099fa: 2b02 cmp r3, #2 + 80099fc: d02f beq.n 8009a5e + 80099fe: 2b03 cmp r3, #3 + 8009a00: d034 beq.n 8009a6c + 8009a02: 2b01 cmp r3, #1 + 8009a04: d137 bne.n 8009a76 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) + 8009a06: 6829 ldr r1, [r5, #0] + 8009a08: f011 0102 ands.w r1, r1, #2 + 8009a0c: d00c beq.n 8009a28 + pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)]; + 8009a0e: 682b ldr r3, [r5, #0] + 8009a10: 4a85 ldr r2, [pc, #532] ; (8009c28 ) + 8009a12: 0719 lsls r1, r3, #28 + 8009a14: bf4b itete mi + 8009a16: 682b ldrmi r3, [r5, #0] + 8009a18: f8d5 3094 ldrpl.w r3, [r5, #148] ; 0x94 + 8009a1c: f3c3 1303 ubfxmi r3, r3, #4, #4 + 8009a20: f3c3 2303 ubfxpl r3, r3, #8, #4 + 8009a24: f852 1023 ldr.w r1, [r2, r3, lsl #2] + switch(PeriphClk) + 8009a28: f5b0 6f80 cmp.w r0, #1024 ; 0x400 + 8009a2c: f000 8226 beq.w 8009e7c + 8009a30: d858 bhi.n 8009ae4 + 8009a32: 2820 cmp r0, #32 + 8009a34: f000 81be beq.w 8009db4 + 8009a38: d824 bhi.n 8009a84 + 8009a3a: 2808 cmp r0, #8 + 8009a3c: d81d bhi.n 8009a7a + 8009a3e: 2800 cmp r0, #0 + 8009a40: f000 80ec beq.w 8009c1c + 8009a44: 3801 subs r0, #1 + 8009a46: 2807 cmp r0, #7 + 8009a48: d81a bhi.n 8009a80 + 8009a4a: e8df f010 tbh [pc, r0, lsl #1] + 8009a4e: 0164 .short 0x0164 + 8009a50: 00190177 .word 0x00190177 + 8009a54: 00190189 .word 0x00190189 + 8009a58: 00190019 .word 0x00190019 + 8009a5c: 0196 .short 0x0196 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 8009a5e: 6829 ldr r1, [r5, #0] + pllvco = HSI_VALUE; + 8009a60: 4b72 ldr r3, [pc, #456] ; (8009c2c ) + 8009a62: f411 6180 ands.w r1, r1, #1024 ; 0x400 + pllvco = HSE_VALUE; + 8009a66: bf18 it ne + 8009a68: 4619 movne r1, r3 + 8009a6a: e7dd b.n 8009a28 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) + 8009a6c: 6829 ldr r1, [r5, #0] + pllvco = HSE_VALUE; + 8009a6e: 4b70 ldr r3, [pc, #448] ; (8009c30 ) + 8009a70: f411 3100 ands.w r1, r1, #131072 ; 0x20000 + 8009a74: e7f7 b.n 8009a66 + switch(pll_oscsource) + 8009a76: 2100 movs r1, #0 + 8009a78: e7d6 b.n 8009a28 + switch(PeriphClk) + 8009a7a: 2810 cmp r0, #16 + 8009a7c: f000 818a beq.w 8009d94 + 8009a80: 2000 movs r0, #0 + 8009a82: e0cb b.n 8009c1c + 8009a84: f5b0 7f80 cmp.w r0, #256 ; 0x100 + 8009a88: f000 81ea beq.w 8009e60 + 8009a8c: d80f bhi.n 8009aae + 8009a8e: 2840 cmp r0, #64 ; 0x40 + 8009a90: f000 81d5 beq.w 8009e3e + 8009a94: 2880 cmp r0, #128 ; 0x80 + 8009a96: d1f3 bne.n 8009a80 + srcclk = __HAL_RCC_GET_I2C2_SOURCE(); + 8009a98: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009a9c: f403 4340 and.w r3, r3, #49152 ; 0xc000 + switch(srcclk) + 8009aa0: f5b3 4f80 cmp.w r3, #16384 ; 0x4000 + 8009aa4: f000 8157 beq.w 8009d56 + 8009aa8: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + 8009aac: e1d0 b.n 8009e50 + switch(PeriphClk) + 8009aae: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8009ab2: d1e5 bne.n 8009a80 + srcclk = __HAL_RCC_GET_LPTIM1_SOURCE(); + 8009ab4: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009ab8: f403 2340 and.w r3, r3, #786432 ; 0xc0000 + switch(srcclk) + 8009abc: f5b3 2f00 cmp.w r3, #524288 ; 0x80000 + 8009ac0: f000 8137 beq.w 8009d32 + 8009ac4: f200 81d7 bhi.w 8009e76 + 8009ac8: 2b00 cmp r3, #0 + 8009aca: f000 81c6 beq.w 8009e5a + 8009ace: f5b3 2f80 cmp.w r3, #262144 ; 0x40000 + 8009ad2: d1d5 bne.n 8009a80 + if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) + 8009ad4: f8d5 0094 ldr.w r0, [r5, #148] ; 0x94 + frequency = LSI_VALUE; + 8009ad8: f010 0002 ands.w r0, r0, #2 + 8009adc: bf18 it ne + 8009ade: f44f 40fa movne.w r0, #32000 ; 0x7d00 + 8009ae2: e09b b.n 8009c1c + switch(PeriphClk) + 8009ae4: f5b0 2f80 cmp.w r0, #262144 ; 0x40000 + 8009ae8: d040 beq.n 8009b6c + 8009aea: d819 bhi.n 8009b20 + 8009aec: f5b0 5f00 cmp.w r0, #8192 ; 0x2000 + 8009af0: d03c beq.n 8009b6c + 8009af2: d808 bhi.n 8009b06 + 8009af4: f5b0 6f00 cmp.w r0, #2048 ; 0x800 + 8009af8: d002 beq.n 8009b00 + 8009afa: f5b0 5f80 cmp.w r0, #4096 ; 0x1000 + 8009afe: d1bf bne.n 8009a80 +} + 8009b00: bcf0 pop {r4, r5, r6, r7} + frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco); + 8009b02: f7ff bb1b b.w 800913c + switch(PeriphClk) + 8009b06: f5b0 4f80 cmp.w r0, #16384 ; 0x4000 + 8009b0a: f000 8163 beq.w 8009dd4 + 8009b0e: f5b0 3f80 cmp.w r0, #65536 ; 0x10000 + 8009b12: d1b5 bne.n 8009a80 + srcclk = __HAL_RCC_GET_DFSDM1_SOURCE(); + 8009b14: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK2) + 8009b18: 075a lsls r2, r3, #29 + 8009b1a: f100 811c bmi.w 8009d56 + 8009b1e: e105 b.n 8009d2c + switch(PeriphClk) + 8009b20: f5b0 1f00 cmp.w r0, #2097152 ; 0x200000 + 8009b24: f000 817c beq.w 8009e20 + 8009b28: d80f bhi.n 8009b4a + 8009b2a: f5b0 2f00 cmp.w r0, #524288 ; 0x80000 + 8009b2e: f000 8081 beq.w 8009c34 + 8009b32: f5b0 1f80 cmp.w r0, #1048576 ; 0x100000 + 8009b36: d1a3 bne.n 8009a80 + srcclk = __HAL_RCC_GET_I2C4_SOURCE(); + 8009b38: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 8009b3c: f003 0303 and.w r3, r3, #3 + switch(srcclk) + 8009b40: 2b01 cmp r3, #1 + 8009b42: f000 8108 beq.w 8009d56 + 8009b46: 2b02 cmp r3, #2 + 8009b48: e182 b.n 8009e50 + switch(PeriphClk) + 8009b4a: f1b0 7f80 cmp.w r0, #16777216 ; 0x1000000 + 8009b4e: d197 bne.n 8009a80 + srcclk = __HAL_RCC_GET_OSPI_SOURCE(); + 8009b50: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 8009b54: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + switch(srcclk) + 8009b58: f5b3 1f80 cmp.w r3, #1048576 ; 0x100000 + 8009b5c: d033 beq.n 8009bc6 + 8009b5e: f5b3 1f00 cmp.w r3, #2097152 ; 0x200000 + 8009b62: f000 819c beq.w 8009e9e + 8009b66: 2b00 cmp r3, #0 + 8009b68: d18a bne.n 8009a80 + 8009b6a: e0f4 b.n 8009d56 + srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL); + 8009b6c: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009b70: f003 6340 and.w r3, r3, #201326592 ; 0xc000000 + switch(srcclk) + 8009b74: f1b3 6f00 cmp.w r3, #134217728 ; 0x8000000 + 8009b78: d037 beq.n 8009bea + 8009b7a: d820 bhi.n 8009bbe + 8009b7c: 2b00 cmp r3, #0 + 8009b7e: f000 80c4 beq.w 8009d0a + 8009b82: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + 8009b86: f47f af7b bne.w 8009a80 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY)) + 8009b8a: 6828 ldr r0, [r5, #0] + 8009b8c: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 8009b90: d044 beq.n 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN)) + 8009b92: 6928 ldr r0, [r5, #16] + 8009b94: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009b98: d040 beq.n 8009c1c + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009b9a: 692f ldr r7, [r5, #16] + 8009b9c: f3c7 2706 ubfx r7, r7, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009ba0: 4379 muls r1, r7 + 8009ba2: 692f ldr r7, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009ba4: 6928 ldr r0, [r5, #16] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009ba6: f3c7 1703 ubfx r7, r7, #4, #4 + 8009baa: 3701 adds r7, #1 + 8009bac: fbb1 f1f7 udiv r1, r1, r7 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009bb0: f3c0 5041 ubfx r0, r0, #21, #2 + 8009bb4: 3001 adds r0, #1 + 8009bb6: 0040 lsls r0, r0, #1 + 8009bb8: fbb1 f0f0 udiv r0, r1, r0 + 8009bbc: e02e b.n 8009c1c + 8009bbe: f1b3 6f40 cmp.w r3, #201326592 ; 0xc000000 + 8009bc2: f47f af5d bne.w 8009a80 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) + 8009bc6: 6828 ldr r0, [r5, #0] + 8009bc8: f010 0002 ands.w r0, r0, #2 + 8009bcc: d026 beq.n 8009c1c + frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)]; + 8009bce: 682b ldr r3, [r5, #0] + 8009bd0: 4a15 ldr r2, [pc, #84] ; (8009c28 ) + 8009bd2: 071b lsls r3, r3, #28 + 8009bd4: bf4b itete mi + 8009bd6: 682b ldrmi r3, [r5, #0] + 8009bd8: f8d5 3094 ldrpl.w r3, [r5, #148] ; 0x94 + 8009bdc: f3c3 1303 ubfxmi r3, r3, #4, #4 + 8009be0: f3c3 2303 ubfxpl r3, r3, #8, #4 + 8009be4: f852 0023 ldr.w r0, [r2, r3, lsl #2] + 8009be8: e018 b.n 8009c1c + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009bea: 6828 ldr r0, [r5, #0] + 8009bec: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009bf0: d014 beq.n 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 8009bf2: 68e8 ldr r0, [r5, #12] + 8009bf4: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009bf8: d010 beq.n 8009c1c + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009bfa: 68e8 ldr r0, [r5, #12] + 8009bfc: f3c0 2006 ubfx r0, r0, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c00: 4348 muls r0, r1 + 8009c02: 68e9 ldr r1, [r5, #12] + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009c04: 68ed ldr r5, [r5, #12] + 8009c06: f3c5 5541 ubfx r5, r5, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c0a: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009c0e: 3501 adds r5, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c10: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009c12: 006d lsls r5, r5, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c14: fbb0 f0f1 udiv r0, r0, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009c18: fbb0 f0f5 udiv r0, r0, r5 +} + 8009c1c: bcf0 pop {r4, r5, r6, r7} + 8009c1e: 4770 bx lr + 8009c20: 40021000 .word 0x40021000 + 8009c24: 0003d090 .word 0x0003d090 + 8009c28: 0800e9f4 .word 0x0800e9f4 + 8009c2c: 00f42400 .word 0x00f42400 + 8009c30: 007a1200 .word 0x007a1200 + if(HAL_IS_BIT_SET(RCC->CCIPR2, RCC_CCIPR2_SDMMCSEL)) /* PLL "P" ? */ + 8009c34: f8d5 009c ldr.w r0, [r5, #156] ; 0x9c + 8009c38: f410 4080 ands.w r0, r0, #16384 ; 0x4000 + 8009c3c: d01f beq.n 8009c7e + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009c3e: 6828 ldr r0, [r5, #0] + 8009c40: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009c44: d0ea beq.n 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN)) + 8009c46: 68e8 ldr r0, [r5, #12] + 8009c48: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 8009c4c: d0e6 beq.n 8009c1c + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009c4e: 68ee ldr r6, [r5, #12] + 8009c50: f3c6 2606 ubfx r6, r6, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c54: fb01 f006 mul.w r0, r1, r6 + 8009c58: 68ee ldr r6, [r5, #12] + pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 8009c5a: 68eb ldr r3, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c5c: f3c6 1603 ubfx r6, r6, #4, #4 + if(pllp == 0U) + 8009c60: 0edb lsrs r3, r3, #27 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009c62: f106 0601 add.w r6, r6, #1 + 8009c66: fbb0 f0f6 udiv r0, r0, r6 + if(pllp == 0U) + 8009c6a: d105 bne.n 8009c78 + if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U) + 8009c6c: 68eb ldr r3, [r5, #12] + pllp = 7U; + 8009c6e: f413 3f00 tst.w r3, #131072 ; 0x20000 + 8009c72: bf14 ite ne + 8009c74: 2311 movne r3, #17 + 8009c76: 2307 moveq r3, #7 + frequency = (pllvco / pllp); + 8009c78: fbb0 f0f3 udiv r0, r0, r3 + 8009c7c: e7ce b.n 8009c1c + srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL); + 8009c7e: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009c82: f003 6340 and.w r3, r3, #201326592 ; 0xc000000 + switch(srcclk) + 8009c86: f1b3 6f00 cmp.w r3, #134217728 ; 0x8000000 + 8009c8a: d024 beq.n 8009cd6 + 8009c8c: d81e bhi.n 8009ccc + 8009c8e: 2b00 cmp r3, #0 + 8009c90: d03b beq.n 8009d0a + 8009c92: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + 8009c96: d1c1 bne.n 8009c1c + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY)) + 8009c98: 6828 ldr r0, [r5, #0] + 8009c9a: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 8009c9e: d0bd beq.n 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN)) + 8009ca0: 6928 ldr r0, [r5, #16] + 8009ca2: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009ca6: d0b9 beq.n 8009c1c + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009ca8: 692a ldr r2, [r5, #16] + 8009caa: f3c2 2206 ubfx r2, r2, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009cae: 434a muls r2, r1 + 8009cb0: 6929 ldr r1, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009cb2: 6928 ldr r0, [r5, #16] + 8009cb4: f3c0 5041 ubfx r0, r0, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009cb8: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009cbc: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009cbe: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009cc0: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009cc2: fbb2 f2f1 udiv r2, r2, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009cc6: fbb2 f0f0 udiv r0, r2, r0 + 8009cca: e7a7 b.n 8009c1c + 8009ccc: f1b3 6f40 cmp.w r3, #201326592 ; 0xc000000 + 8009cd0: f43f af79 beq.w 8009bc6 + 8009cd4: e7a2 b.n 8009c1c + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009cd6: 6828 ldr r0, [r5, #0] + 8009cd8: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009cdc: d09e beq.n 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 8009cde: 68e8 ldr r0, [r5, #12] + 8009ce0: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009ce4: d09a beq.n 8009c1c + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009ce6: 68ec ldr r4, [r5, #12] + 8009ce8: f3c4 2406 ubfx r4, r4, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009cec: 434c muls r4, r1 + 8009cee: 68e9 ldr r1, [r5, #12] + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009cf0: 68e8 ldr r0, [r5, #12] + 8009cf2: f3c0 5041 ubfx r0, r0, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009cf6: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009cfa: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009cfc: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009cfe: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009d00: fbb4 f4f1 udiv r4, r4, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009d04: fbb4 f0f0 udiv r0, r4, r0 + 8009d08: e788 b.n 8009c1c + if(HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */ + 8009d0a: f8d5 0098 ldr.w r0, [r5, #152] ; 0x98 + frequency = HSI48_VALUE; + 8009d0e: 4b6f ldr r3, [pc, #444] ; (8009ecc ) + 8009d10: f010 0002 ands.w r0, r0, #2 + 8009d14: e66b b.n 80099ee + srcclk = __HAL_RCC_GET_USART1_SOURCE(); + 8009d16: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d1a: f003 0303 and.w r3, r3, #3 + switch(srcclk) + 8009d1e: 2b02 cmp r3, #2 + 8009d20: d007 beq.n 8009d32 + 8009d22: 2b03 cmp r3, #3 + 8009d24: f43f ae57 beq.w 80099d6 + 8009d28: 2b01 cmp r3, #1 + 8009d2a: d014 beq.n 8009d56 +} + 8009d2c: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetPCLK2Freq(); + 8009d2e: f7ff b95b b.w 8008fe8 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 8009d32: 6828 ldr r0, [r5, #0] + frequency = HSI_VALUE; + 8009d34: 4b66 ldr r3, [pc, #408] ; (8009ed0 ) + 8009d36: f410 6080 ands.w r0, r0, #1024 ; 0x400 + 8009d3a: e658 b.n 80099ee + srcclk = __HAL_RCC_GET_USART2_SOURCE(); + 8009d3c: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d40: f003 030c and.w r3, r3, #12 + switch(srcclk) + 8009d44: 2b08 cmp r3, #8 + 8009d46: d0f4 beq.n 8009d32 + 8009d48: d808 bhi.n 8009d5c + 8009d4a: 2b00 cmp r3, #0 + 8009d4c: f000 8085 beq.w 8009e5a + 8009d50: 2b04 cmp r3, #4 + 8009d52: f47f ae95 bne.w 8009a80 +} + 8009d56: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetSysClockFreq(); + 8009d58: f7fe bd38 b.w 80087cc + 8009d5c: 2b0c cmp r3, #12 + 8009d5e: e639 b.n 80099d4 + srcclk = __HAL_RCC_GET_USART3_SOURCE(); + 8009d60: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d64: f003 0330 and.w r3, r3, #48 ; 0x30 + switch(srcclk) + 8009d68: 2b20 cmp r3, #32 + 8009d6a: d0e2 beq.n 8009d32 + 8009d6c: d803 bhi.n 8009d76 + 8009d6e: 2b00 cmp r3, #0 + 8009d70: d073 beq.n 8009e5a + 8009d72: 2b10 cmp r3, #16 + 8009d74: e7ed b.n 8009d52 + 8009d76: 2b30 cmp r3, #48 ; 0x30 + 8009d78: e62c b.n 80099d4 + srcclk = __HAL_RCC_GET_UART4_SOURCE(); + 8009d7a: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d7e: f003 03c0 and.w r3, r3, #192 ; 0xc0 + switch(srcclk) + 8009d82: 2b80 cmp r3, #128 ; 0x80 + 8009d84: d0d5 beq.n 8009d32 + 8009d86: d803 bhi.n 8009d90 + 8009d88: 2b00 cmp r3, #0 + 8009d8a: d066 beq.n 8009e5a + 8009d8c: 2b40 cmp r3, #64 ; 0x40 + 8009d8e: e7e0 b.n 8009d52 + 8009d90: 2bc0 cmp r3, #192 ; 0xc0 + 8009d92: e61f b.n 80099d4 + srcclk = __HAL_RCC_GET_UART5_SOURCE(); + 8009d94: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d98: f403 7340 and.w r3, r3, #768 ; 0x300 + switch(srcclk) + 8009d9c: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 8009da0: d0c7 beq.n 8009d32 + 8009da2: d804 bhi.n 8009dae + 8009da4: 2b00 cmp r3, #0 + 8009da6: d058 beq.n 8009e5a + 8009da8: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 8009dac: e7d1 b.n 8009d52 + 8009dae: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 8009db2: e60f b.n 80099d4 + srcclk = __HAL_RCC_GET_LPUART1_SOURCE(); + 8009db4: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009db8: f403 6340 and.w r3, r3, #3072 ; 0xc00 + switch(srcclk) + 8009dbc: f5b3 6f00 cmp.w r3, #2048 ; 0x800 + 8009dc0: d0b7 beq.n 8009d32 + 8009dc2: d804 bhi.n 8009dce + 8009dc4: 2b00 cmp r3, #0 + 8009dc6: d048 beq.n 8009e5a + 8009dc8: f5b3 6f80 cmp.w r3, #1024 ; 0x400 + 8009dcc: e7c1 b.n 8009d52 + 8009dce: f5b3 6f40 cmp.w r3, #3072 ; 0xc00 + 8009dd2: e5ff b.n 80099d4 + srcclk = __HAL_RCC_GET_ADC_SOURCE(); + 8009dd4: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009dd8: f003 5340 and.w r3, r3, #805306368 ; 0x30000000 + switch(srcclk) + 8009ddc: f1b3 5f80 cmp.w r3, #268435456 ; 0x10000000 + 8009de0: d002 beq.n 8009de8 + 8009de2: f1b3 5f40 cmp.w r3, #805306368 ; 0x30000000 + 8009de6: e7b4 b.n 8009d52 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != 0U)) + 8009de8: 6828 ldr r0, [r5, #0] + 8009dea: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 8009dee: f43f af15 beq.w 8009c1c + 8009df2: 6928 ldr r0, [r5, #16] + 8009df4: f010 7080 ands.w r0, r0, #16777216 ; 0x1000000 + 8009df8: f43f af10 beq.w 8009c1c + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009dfc: 692b ldr r3, [r5, #16] + 8009dfe: f3c3 2306 ubfx r3, r3, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e02: 434b muls r3, r1 + 8009e04: 6929 ldr r1, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 8009e06: 6928 ldr r0, [r5, #16] + 8009e08: f3c0 6041 ubfx r0, r0, #25, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e0c: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 8009e10: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e12: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 8009e14: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e16: fbb3 f3f1 udiv r3, r3, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 8009e1a: fbb3 f0f0 udiv r0, r3, r0 + 8009e1e: e6fd b.n 8009c1c + srcclk = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); + 8009e20: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 8009e24: f003 0318 and.w r3, r3, #24 + switch(srcclk) + 8009e28: 2b08 cmp r3, #8 + 8009e2a: d082 beq.n 8009d32 + 8009e2c: 2b10 cmp r3, #16 + 8009e2e: f43f aeca beq.w 8009bc6 + 8009e32: 2b00 cmp r3, #0 + 8009e34: f47f ae24 bne.w 8009a80 + frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco); + 8009e38: f44f 6000 mov.w r0, #2048 ; 0x800 + 8009e3c: e660 b.n 8009b00 + srcclk = __HAL_RCC_GET_I2C1_SOURCE(); + 8009e3e: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009e42: f403 5340 and.w r3, r3, #12288 ; 0x3000 + switch(srcclk) + 8009e46: f5b3 5f80 cmp.w r3, #4096 ; 0x1000 + 8009e4a: d084 beq.n 8009d56 + 8009e4c: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 8009e50: f43f af6f beq.w 8009d32 + 8009e54: 2b00 cmp r3, #0 + 8009e56: f47f ae13 bne.w 8009a80 +} + 8009e5a: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetPCLK1Freq(); + 8009e5c: f7ff b8b2 b.w 8008fc4 + srcclk = __HAL_RCC_GET_I2C3_SOURCE(); + 8009e60: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009e64: f403 3340 and.w r3, r3, #196608 ; 0x30000 + switch(srcclk) + 8009e68: f5b3 3f80 cmp.w r3, #65536 ; 0x10000 + 8009e6c: f43f af73 beq.w 8009d56 + 8009e70: f5b3 3f00 cmp.w r3, #131072 ; 0x20000 + 8009e74: e7ec b.n 8009e50 + 8009e76: f5b3 2f40 cmp.w r3, #786432 ; 0xc0000 + 8009e7a: e5ab b.n 80099d4 + srcclk = __HAL_RCC_GET_LPTIM2_SOURCE(); + 8009e7c: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009e80: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + switch(srcclk) + 8009e84: f5b3 1f00 cmp.w r3, #2097152 ; 0x200000 + 8009e88: f43f af53 beq.w 8009d32 + 8009e8c: d804 bhi.n 8009e98 + 8009e8e: 2b00 cmp r3, #0 + 8009e90: d0e3 beq.n 8009e5a + 8009e92: f5b3 1f80 cmp.w r3, #1048576 ; 0x100000 + 8009e96: e61c b.n 8009ad2 + 8009e98: f5b3 1f40 cmp.w r3, #3145728 ; 0x300000 + 8009e9c: e59a b.n 80099d4 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009e9e: 6828 ldr r0, [r5, #0] + 8009ea0: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009ea4: f43f aeba beq.w 8009c1c + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 8009ea8: 68e8 ldr r0, [r5, #12] + 8009eaa: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009eae: f43f aeb5 beq.w 8009c1c + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009eb2: 68e8 ldr r0, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009eb4: 68eb ldr r3, [r5, #12] + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009eb6: f3c0 2006 ubfx r0, r0, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009eba: f3c3 1303 ubfx r3, r3, #4, #4 + 8009ebe: 4341 muls r1, r0 + 8009ec0: 3301 adds r3, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009ec2: 68e8 ldr r0, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009ec4: fbb1 f1f3 udiv r1, r1, r3 + 8009ec8: e672 b.n 8009bb0 + 8009eca: bf00 nop + 8009ecc: 02dc6c00 .word 0x02dc6c00 + 8009ed0: 00f42400 .word 0x00f42400 + +08009ed4 : +{ + 8009ed4: b570 push {r4, r5, r6, lr} + __HAL_RCC_PLLSAI1_DISABLE(); + 8009ed6: 4c20 ldr r4, [pc, #128] ; (8009f58 ) + 8009ed8: 6823 ldr r3, [r4, #0] + 8009eda: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 8009ede: 6023 str r3, [r4, #0] +{ + 8009ee0: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 8009ee2: f7fd f903 bl 80070ec + 8009ee6: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 8009ee8: 6823 ldr r3, [r4, #0] + 8009eea: 011a lsls r2, r3, #4 + 8009eec: d423 bmi.n 8009f36 + __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1M, PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R); + 8009eee: e9d5 2302 ldrd r2, r3, [r5, #8] + 8009ef2: 06db lsls r3, r3, #27 + 8009ef4: 6921 ldr r1, [r4, #16] + 8009ef6: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8009efa: 4a18 ldr r2, [pc, #96] ; (8009f5c ) + 8009efc: 400a ands r2, r1 + 8009efe: 4313 orrs r3, r2 + 8009f00: 686a ldr r2, [r5, #4] + 8009f02: 3a01 subs r2, #1 + 8009f04: ea43 1302 orr.w r3, r3, r2, lsl #4 + 8009f08: 692a ldr r2, [r5, #16] + 8009f0a: 0852 lsrs r2, r2, #1 + 8009f0c: 3a01 subs r2, #1 + 8009f0e: ea43 5342 orr.w r3, r3, r2, lsl #21 + 8009f12: 696a ldr r2, [r5, #20] + 8009f14: 0852 lsrs r2, r2, #1 + 8009f16: 3a01 subs r2, #1 + 8009f18: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8009f1c: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut); + 8009f1e: 6923 ldr r3, [r4, #16] + 8009f20: 69aa ldr r2, [r5, #24] + 8009f22: 4313 orrs r3, r2 + 8009f24: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1_ENABLE(); + 8009f26: 6823 ldr r3, [r4, #0] + 8009f28: f043 6380 orr.w r3, r3, #67108864 ; 0x4000000 + 8009f2c: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8009f2e: f7fd f8dd bl 80070ec + 8009f32: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 8009f34: e00b b.n 8009f4e + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 8009f36: f7fd f8d9 bl 80070ec + 8009f3a: 1b80 subs r0, r0, r6 + 8009f3c: 2802 cmp r0, #2 + 8009f3e: d9d3 bls.n 8009ee8 + status = HAL_TIMEOUT; + 8009f40: 2003 movs r0, #3 +} + 8009f42: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 8009f44: f7fd f8d2 bl 80070ec + 8009f48: 1b40 subs r0, r0, r5 + 8009f4a: 2802 cmp r0, #2 + 8009f4c: d8f8 bhi.n 8009f40 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 8009f4e: 6823 ldr r3, [r4, #0] + 8009f50: 011b lsls r3, r3, #4 + 8009f52: d5f7 bpl.n 8009f44 + 8009f54: 2000 movs r0, #0 + return status; + 8009f56: e7f4 b.n 8009f42 + 8009f58: 40021000 .word 0x40021000 + 8009f5c: 019d800f .word 0x019d800f + +08009f60 : +{ + 8009f60: b538 push {r3, r4, r5, lr} + __HAL_RCC_PLLSAI1_DISABLE(); + 8009f62: 4c11 ldr r4, [pc, #68] ; (8009fa8 ) + 8009f64: 6823 ldr r3, [r4, #0] + 8009f66: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 8009f6a: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8009f6c: f7fd f8be bl 80070ec + 8009f70: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 8009f72: 6823 ldr r3, [r4, #0] + 8009f74: f013 6300 ands.w r3, r3, #134217728 ; 0x8000000 + 8009f78: d10f bne.n 8009f9a + HAL_StatusTypeDef status = HAL_OK; + 8009f7a: 4618 mov r0, r3 + __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN); + 8009f7c: 6923 ldr r3, [r4, #16] + 8009f7e: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 8009f82: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 8009f86: 6123 str r3, [r4, #16] + if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI2RDY)) == 0U) + 8009f88: 6823 ldr r3, [r4, #0] + 8009f8a: f013 5f08 tst.w r3, #570425344 ; 0x22000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 8009f8e: bf02 ittt eq + 8009f90: 68e3 ldreq r3, [r4, #12] + 8009f92: f023 0303 biceq.w r3, r3, #3 + 8009f96: 60e3 streq r3, [r4, #12] +} + 8009f98: bd38 pop {r3, r4, r5, pc} + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 8009f9a: f7fd f8a7 bl 80070ec + 8009f9e: 1b40 subs r0, r0, r5 + 8009fa0: 2802 cmp r0, #2 + 8009fa2: d9e6 bls.n 8009f72 + status = HAL_TIMEOUT; + 8009fa4: 2003 movs r0, #3 + 8009fa6: e7e9 b.n 8009f7c + 8009fa8: 40021000 .word 0x40021000 + +08009fac : +{ + 8009fac: b570 push {r4, r5, r6, lr} + __HAL_RCC_PLLSAI2_DISABLE(); + 8009fae: 4c20 ldr r4, [pc, #128] ; (800a030 ) + 8009fb0: 6823 ldr r3, [r4, #0] + 8009fb2: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8009fb6: 6023 str r3, [r4, #0] +{ + 8009fb8: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 8009fba: f7fd f897 bl 80070ec + 8009fbe: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 8009fc0: 6823 ldr r3, [r4, #0] + 8009fc2: 009a lsls r2, r3, #2 + 8009fc4: d423 bmi.n 800a00e + __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2Q, PLLSAI2Init->PLLSAI2R); + 8009fc6: e9d5 2302 ldrd r2, r3, [r5, #8] + 8009fca: 06db lsls r3, r3, #27 + 8009fcc: 6961 ldr r1, [r4, #20] + 8009fce: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8009fd2: 4a18 ldr r2, [pc, #96] ; (800a034 ) + 8009fd4: 400a ands r2, r1 + 8009fd6: 4313 orrs r3, r2 + 8009fd8: 686a ldr r2, [r5, #4] + 8009fda: 3a01 subs r2, #1 + 8009fdc: ea43 1302 orr.w r3, r3, r2, lsl #4 + 8009fe0: 692a ldr r2, [r5, #16] + 8009fe2: 0852 lsrs r2, r2, #1 + 8009fe4: 3a01 subs r2, #1 + 8009fe6: ea43 5342 orr.w r3, r3, r2, lsl #21 + 8009fea: 696a ldr r2, [r5, #20] + 8009fec: 0852 lsrs r2, r2, #1 + 8009fee: 3a01 subs r2, #1 + 8009ff0: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8009ff4: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut); + 8009ff6: 6963 ldr r3, [r4, #20] + 8009ff8: 69aa ldr r2, [r5, #24] + 8009ffa: 4313 orrs r3, r2 + 8009ffc: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2_ENABLE(); + 8009ffe: 6823 ldr r3, [r4, #0] + 800a000: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800a004: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a006: f7fd f871 bl 80070ec + 800a00a: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 800a00c: e00b b.n 800a026 + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a00e: f7fd f86d bl 80070ec + 800a012: 1b80 subs r0, r0, r6 + 800a014: 2802 cmp r0, #2 + 800a016: d9d3 bls.n 8009fc0 + status = HAL_TIMEOUT; + 800a018: 2003 movs r0, #3 +} + 800a01a: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a01c: f7fd f866 bl 80070ec + 800a020: 1b40 subs r0, r0, r5 + 800a022: 2802 cmp r0, #2 + 800a024: d8f8 bhi.n 800a018 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 800a026: 6823 ldr r3, [r4, #0] + 800a028: 009b lsls r3, r3, #2 + 800a02a: d5f7 bpl.n 800a01c + 800a02c: 2000 movs r0, #0 + return status; + 800a02e: e7f4 b.n 800a01a + 800a030: 40021000 .word 0x40021000 + 800a034: 019d800f .word 0x019d800f + +0800a038 : +{ + 800a038: b538 push {r3, r4, r5, lr} + __HAL_RCC_PLLSAI2_DISABLE(); + 800a03a: 4c11 ldr r4, [pc, #68] ; (800a080 ) + 800a03c: 6823 ldr r3, [r4, #0] + 800a03e: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800a042: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a044: f7fd f852 bl 80070ec + 800a048: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 800a04a: 6823 ldr r3, [r4, #0] + 800a04c: f013 5300 ands.w r3, r3, #536870912 ; 0x20000000 + 800a050: d10f bne.n 800a072 + HAL_StatusTypeDef status = HAL_OK; + 800a052: 4618 mov r0, r3 + __HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2QEN|RCC_PLLSAI2CFGR_PLLSAI2REN); + 800a054: 6963 ldr r3, [r4, #20] + 800a056: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 800a05a: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 800a05e: 6163 str r3, [r4, #20] + if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY)) == 0U) + 800a060: 6823 ldr r3, [r4, #0] + 800a062: f013 6f20 tst.w r3, #167772160 ; 0xa000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 800a066: bf02 ittt eq + 800a068: 68e3 ldreq r3, [r4, #12] + 800a06a: f023 0303 biceq.w r3, r3, #3 + 800a06e: 60e3 streq r3, [r4, #12] +} + 800a070: bd38 pop {r3, r4, r5, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a072: f7fd f83b bl 80070ec + 800a076: 1b40 subs r0, r0, r5 + 800a078: 2802 cmp r0, #2 + 800a07a: d9e6 bls.n 800a04a + status = HAL_TIMEOUT; + 800a07c: 2003 movs r0, #3 + 800a07e: e7e9 b.n 800a054 + 800a080: 40021000 .word 0x40021000 + +0800a084 : + __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk); + 800a084: 4a03 ldr r2, [pc, #12] ; (800a094 ) + 800a086: 6893 ldr r3, [r2, #8] + 800a088: f423 4300 bic.w r3, r3, #32768 ; 0x8000 + 800a08c: 4318 orrs r0, r3 + 800a08e: 6090 str r0, [r2, #8] +} + 800a090: 4770 bx lr + 800a092: bf00 nop + 800a094: 40021000 .word 0x40021000 + +0800a098 : + __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange); + 800a098: 4a04 ldr r2, [pc, #16] ; (800a0ac ) + 800a09a: f8d2 3094 ldr.w r3, [r2, #148] ; 0x94 + 800a09e: f423 6370 bic.w r3, r3, #3840 ; 0xf00 + 800a0a2: ea43 1000 orr.w r0, r3, r0, lsl #4 + 800a0a6: f8c2 0094 str.w r0, [r2, #148] ; 0x94 +} + 800a0aa: 4770 bx lr + 800a0ac: 40021000 .word 0x40021000 + +0800a0b0 : + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); + 800a0b0: 4a03 ldr r2, [pc, #12] ; (800a0c0 ) + 800a0b2: f8d2 3090 ldr.w r3, [r2, #144] ; 0x90 + 800a0b6: f043 0320 orr.w r3, r3, #32 + 800a0ba: f8c2 3090 str.w r3, [r2, #144] ; 0x90 +} + 800a0be: 4770 bx lr + 800a0c0: 40021000 .word 0x40021000 + +0800a0c4 : + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + 800a0c4: 4b05 ldr r3, [pc, #20] ; (800a0dc ) + 800a0c6: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800a0ca: f022 0220 bic.w r2, r2, #32 + 800a0ce: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS); + 800a0d2: 699a ldr r2, [r3, #24] + 800a0d4: f422 7200 bic.w r2, r2, #512 ; 0x200 + 800a0d8: 619a str r2, [r3, #24] +} + 800a0da: 4770 bx lr + 800a0dc: 40021000 .word 0x40021000 + +0800a0e0 : + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + 800a0e0: 4b0a ldr r3, [pc, #40] ; (800a10c ) + 800a0e2: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800a0e6: f042 0220 orr.w r2, r2, #32 + 800a0ea: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS); + 800a0ee: 699a ldr r2, [r3, #24] + 800a0f0: f442 7200 orr.w r2, r2, #512 ; 0x200 + 800a0f4: 619a str r2, [r3, #24] + __HAL_RCC_LSECSS_EXTI_ENABLE_IT(); + 800a0f6: f5a3 3386 sub.w r3, r3, #68608 ; 0x10c00 + 800a0fa: 681a ldr r2, [r3, #0] + 800a0fc: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 800a100: 601a str r2, [r3, #0] + __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE(); + 800a102: 689a ldr r2, [r3, #8] + 800a104: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 800a108: 609a str r2, [r3, #8] +} + 800a10a: 4770 bx lr + 800a10c: 40021000 .word 0x40021000 + +0800a110 : +} + 800a110: 4770 bx lr + ... + +0800a114 : +{ + 800a114: b510 push {r4, lr} + if(__HAL_RCC_GET_IT(RCC_IT_LSECSS)) + 800a116: 4c05 ldr r4, [pc, #20] ; (800a12c ) + 800a118: 69e3 ldr r3, [r4, #28] + 800a11a: 059b lsls r3, r3, #22 + 800a11c: d504 bpl.n 800a128 + HAL_RCCEx_LSECSS_Callback(); + 800a11e: f7ff fff7 bl 800a110 + __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS); + 800a122: f44f 7300 mov.w r3, #512 ; 0x200 + 800a126: 6223 str r3, [r4, #32] +} + 800a128: bd10 pop {r4, pc} + 800a12a: bf00 nop + 800a12c: 40021000 .word 0x40021000 + +0800a130 : + SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; + 800a130: 4a02 ldr r2, [pc, #8] ; (800a13c ) + 800a132: 6813 ldr r3, [r2, #0] + 800a134: f043 0304 orr.w r3, r3, #4 + 800a138: 6013 str r3, [r2, #0] +} + 800a13a: 4770 bx lr + 800a13c: 40021000 .word 0x40021000 + +0800a140 : + CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; + 800a140: 4a02 ldr r2, [pc, #8] ; (800a14c ) + 800a142: 6813 ldr r3, [r2, #0] + 800a144: f023 0304 bic.w r3, r3, #4 + 800a148: 6013 str r3, [r2, #0] +} + 800a14a: 4770 bx lr + 800a14c: 40021000 .word 0x40021000 + +0800a150 : + MODIFY_REG(RCC->DLYCFGR, RCC_DLYCFGR_OCTOSPI1_DLY|RCC_DLYCFGR_OCTOSPI2_DLY, (Delay1 | (Delay2 << RCC_DLYCFGR_OCTOSPI2_DLY_Pos))) ; + 800a150: 4a05 ldr r2, [pc, #20] ; (800a168 ) + 800a152: f8d2 30a4 ldr.w r3, [r2, #164] ; 0xa4 + 800a156: f023 03ff bic.w r3, r3, #255 ; 0xff + 800a15a: 4318 orrs r0, r3 + 800a15c: ea40 1101 orr.w r1, r0, r1, lsl #4 + 800a160: f8c2 10a4 str.w r1, [r2, #164] ; 0xa4 +} + 800a164: 4770 bx lr + 800a166: bf00 nop + 800a168: 40021000 .word 0x40021000 + +0800a16c : + __HAL_RCC_CRS_FORCE_RESET(); + 800a16c: 4b10 ldr r3, [pc, #64] ; (800a1b0 ) + 800a16e: 6b9a ldr r2, [r3, #56] ; 0x38 + 800a170: f042 7280 orr.w r2, r2, #16777216 ; 0x1000000 + 800a174: 639a str r2, [r3, #56] ; 0x38 + __HAL_RCC_CRS_RELEASE_RESET(); + 800a176: 6b9a ldr r2, [r3, #56] ; 0x38 + 800a178: f022 7280 bic.w r2, r2, #16777216 ; 0x1000000 + 800a17c: 639a str r2, [r3, #56] ; 0x38 + value = (pInit->Prescaler | pInit->Source | pInit->Polarity); + 800a17e: e9d0 3200 ldrd r3, r2, [r0] + 800a182: 4313 orrs r3, r2 + 800a184: 6882 ldr r2, [r0, #8] + 800a186: 4313 orrs r3, r2 + value |= pInit->ReloadValue; + 800a188: 68c2 ldr r2, [r0, #12] + 800a18a: 4313 orrs r3, r2 + value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos); + 800a18c: 6902 ldr r2, [r0, #16] + 800a18e: ea43 4302 orr.w r3, r3, r2, lsl #16 + WRITE_REG(CRS->CFGR, value); + 800a192: 4a08 ldr r2, [pc, #32] ; (800a1b4 ) + 800a194: 6053 str r3, [r2, #4] + MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos)); + 800a196: 6813 ldr r3, [r2, #0] + 800a198: 6941 ldr r1, [r0, #20] + 800a19a: f423 537c bic.w r3, r3, #16128 ; 0x3f00 + 800a19e: ea43 2301 orr.w r3, r3, r1, lsl #8 + 800a1a2: 6013 str r3, [r2, #0] + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); + 800a1a4: 6813 ldr r3, [r2, #0] + 800a1a6: f043 0360 orr.w r3, r3, #96 ; 0x60 + 800a1aa: 6013 str r3, [r2, #0] +} + 800a1ac: 4770 bx lr + 800a1ae: bf00 nop + 800a1b0: 40021000 .word 0x40021000 + 800a1b4: 40006000 .word 0x40006000 + +0800a1b8 : + SET_BIT(CRS->CR, CRS_CR_SWSYNC); + 800a1b8: 4a02 ldr r2, [pc, #8] ; (800a1c4 ) + 800a1ba: 6813 ldr r3, [r2, #0] + 800a1bc: f043 0380 orr.w r3, r3, #128 ; 0x80 + 800a1c0: 6013 str r3, [r2, #0] +} + 800a1c2: 4770 bx lr + 800a1c4: 40006000 .word 0x40006000 + +0800a1c8 : + pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); + 800a1c8: 4b07 ldr r3, [pc, #28] ; (800a1e8 ) + 800a1ca: 685a ldr r2, [r3, #4] + 800a1cc: b292 uxth r2, r2 + 800a1ce: 6002 str r2, [r0, #0] + pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos); + 800a1d0: 681a ldr r2, [r3, #0] + 800a1d2: f3c2 2205 ubfx r2, r2, #8, #6 + 800a1d6: 6042 str r2, [r0, #4] + pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos); + 800a1d8: 689a ldr r2, [r3, #8] + 800a1da: 0c12 lsrs r2, r2, #16 + 800a1dc: 6082 str r2, [r0, #8] + pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); + 800a1de: 689b ldr r3, [r3, #8] + 800a1e0: f403 4300 and.w r3, r3, #32768 ; 0x8000 + 800a1e4: 60c3 str r3, [r0, #12] +} + 800a1e6: 4770 bx lr + 800a1e8: 40006000 .word 0x40006000 + +0800a1ec : +{ + 800a1ec: b5f8 push {r3, r4, r5, r6, r7, lr} + 800a1ee: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 800a1f0: f7fc ff7c bl 80070ec + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + 800a1f4: 4c1e ldr r4, [pc, #120] ; (800a270 ) + tickstart = HAL_GetTick(); + 800a1f6: 4606 mov r6, r0 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + 800a1f8: 2701 movs r7, #1 + if(Timeout != HAL_MAX_DELAY) + 800a1fa: 1c68 adds r0, r5, #1 + 800a1fc: d12f bne.n 800a25e + crsstatus = RCC_CRS_TIMEOUT; + 800a1fe: 2000 movs r0, #0 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + 800a200: 68a2 ldr r2, [r4, #8] + 800a202: 07d1 lsls r1, r2, #31 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + 800a204: bf48 it mi + 800a206: 60e7 strmi r7, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + 800a208: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCOK; + 800a20a: bf48 it mi + 800a20c: f040 0002 orrmi.w r0, r0, #2 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + 800a210: 0792 lsls r2, r2, #30 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN); + 800a212: bf44 itt mi + 800a214: 2202 movmi r2, #2 + 800a216: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + 800a218: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCWARN; + 800a21a: bf48 it mi + 800a21c: f040 0004 orrmi.w r0, r0, #4 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + 800a220: 0553 lsls r3, r2, #21 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF); + 800a222: bf44 itt mi + 800a224: 2204 movmi r2, #4 + 800a226: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + 800a228: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_TRIMOVF; + 800a22a: bf48 it mi + 800a22c: f040 0020 orrmi.w r0, r0, #32 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + 800a230: 05d1 lsls r1, r2, #23 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR); + 800a232: bf44 itt mi + 800a234: 2204 movmi r2, #4 + 800a236: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + 800a238: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCERR; + 800a23a: bf48 it mi + 800a23c: f040 0008 orrmi.w r0, r0, #8 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + 800a240: 0592 lsls r2, r2, #22 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS); + 800a242: bf44 itt mi + 800a244: 2204 movmi r2, #4 + 800a246: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + 800a248: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCMISS; + 800a24a: bf48 it mi + 800a24c: f040 0010 orrmi.w r0, r0, #16 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + 800a250: 0713 lsls r3, r2, #28 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); + 800a252: bf44 itt mi + 800a254: 2208 movmi r2, #8 + 800a256: 60e2 strmi r2, [r4, #12] + } while(RCC_CRS_NONE == crsstatus); + 800a258: 2800 cmp r0, #0 + 800a25a: d0ce beq.n 800a1fa +} + 800a25c: bdf8 pop {r3, r4, r5, r6, r7, pc} + if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + 800a25e: f7fc ff45 bl 80070ec + 800a262: 1b80 subs r0, r0, r6 + 800a264: 42a8 cmp r0, r5 + 800a266: d801 bhi.n 800a26c + 800a268: 2d00 cmp r5, #0 + 800a26a: d1c8 bne.n 800a1fe + crsstatus = RCC_CRS_TIMEOUT; + 800a26c: 2001 movs r0, #1 + 800a26e: e7c7 b.n 800a200 + 800a270: 40006000 .word 0x40006000 + +0800a274 : + 800a274: 4770 bx lr + +0800a276 : + 800a276: 4770 bx lr + +0800a278 : + 800a278: 4770 bx lr + +0800a27a : +} + 800a27a: 4770 bx lr + +0800a27c : + uint32_t itflags = READ_REG(CRS->ISR); + 800a27c: 491b ldr r1, [pc, #108] ; (800a2ec ) +{ + 800a27e: b508 push {r3, lr} + uint32_t itflags = READ_REG(CRS->ISR); + 800a280: 688b ldr r3, [r1, #8] + uint32_t itsources = READ_REG(CRS->CR); + 800a282: 680a ldr r2, [r1, #0] + if(((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U)) + 800a284: 07d8 lsls r0, r3, #31 + 800a286: d506 bpl.n 800a296 + 800a288: 07d0 lsls r0, r2, #31 + 800a28a: d504 bpl.n 800a296 + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + 800a28c: 2301 movs r3, #1 + 800a28e: 60cb str r3, [r1, #12] + HAL_RCCEx_CRS_SyncOkCallback(); + 800a290: f7ff fff0 bl 800a274 +} + 800a294: bd08 pop {r3, pc} + else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U)) + 800a296: 0798 lsls r0, r3, #30 + 800a298: d507 bpl.n 800a2aa + 800a29a: 0791 lsls r1, r2, #30 + 800a29c: d505 bpl.n 800a2aa + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + 800a29e: 4b13 ldr r3, [pc, #76] ; (800a2ec ) + 800a2a0: 2202 movs r2, #2 + 800a2a2: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_SyncWarnCallback(); + 800a2a4: f7ff ffe7 bl 800a276 + 800a2a8: e7f4 b.n 800a294 + else if(((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U)) + 800a2aa: 0718 lsls r0, r3, #28 + 800a2ac: d507 bpl.n 800a2be + 800a2ae: 0711 lsls r1, r2, #28 + 800a2b0: d505 bpl.n 800a2be + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + 800a2b2: 4b0e ldr r3, [pc, #56] ; (800a2ec ) + 800a2b4: 2208 movs r2, #8 + 800a2b6: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_ExpectedSyncCallback(); + 800a2b8: f7ff ffde bl 800a278 + 800a2bc: e7ea b.n 800a294 + if(((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U)) + 800a2be: 0758 lsls r0, r3, #29 + 800a2c0: d5e8 bpl.n 800a294 + 800a2c2: 0751 lsls r1, r2, #29 + 800a2c4: d5e6 bpl.n 800a294 + crserror |= RCC_CRS_SYNCERR; + 800a2c6: f413 7080 ands.w r0, r3, #256 ; 0x100 + 800a2ca: bf18 it ne + 800a2cc: 2008 movne r0, #8 + if((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U) + 800a2ce: 059a lsls r2, r3, #22 + crserror |= RCC_CRS_SYNCMISS; + 800a2d0: bf48 it mi + 800a2d2: f040 0010 orrmi.w r0, r0, #16 + if((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U) + 800a2d6: 055b lsls r3, r3, #21 + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + 800a2d8: 4b04 ldr r3, [pc, #16] ; (800a2ec ) + 800a2da: f04f 0204 mov.w r2, #4 + crserror |= RCC_CRS_TRIMOVF; + 800a2de: bf48 it mi + 800a2e0: f040 0020 orrmi.w r0, r0, #32 + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + 800a2e4: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_ErrorCallback(crserror); + 800a2e6: f7ff ffc8 bl 800a27a +} + 800a2ea: e7d3 b.n 800a294 + 800a2ec: 40006000 .word 0x40006000 + +0800a2f0 : + * processing is suspended when possible and the Peripheral feeding point reached at + * suspension time is stored in the handle for resumption later on. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + 800a2f0: b573 push {r0, r1, r4, r5, r6, lr} + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + + for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U) + { + /* Write input data 4 bytes at a time */ + HASH->DIN = *(uint32_t*)inputaddr; + 800a2f2: 4d1e ldr r5, [pc, #120] ; (800a36c ) + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800a2f4: 9101 str r1, [sp, #4] +{ + 800a2f6: 4604 mov r4, r0 + for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U) + 800a2f8: 2100 movs r1, #0 + 800a2fa: 4291 cmp r1, r2 + 800a2fc: d221 bcs.n 800a342 + HASH->DIN = *(uint32_t*)inputaddr; + 800a2fe: 9b01 ldr r3, [sp, #4] + 800a300: 681b ldr r3, [r3, #0] + 800a302: 606b str r3, [r5, #4] + inputaddr+=4U; + 800a304: 9b01 ldr r3, [sp, #4] + + /* If the suspension flag has been raised and if the processing is not about + to end, suspend processing */ + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a306: f894 0036 ldrb.w r0, [r4, #54] ; 0x36 + inputaddr+=4U; + 800a30a: 3304 adds r3, #4 + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a30c: 2801 cmp r0, #1 + inputaddr+=4U; + 800a30e: 9301 str r3, [sp, #4] + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a310: f101 0304 add.w r3, r1, #4 + 800a314: d127 bne.n 800a366 + 800a316: 4293 cmp r3, r2 + 800a318: d225 bcs.n 800a366 + { + /* Wait for DINIS = 1, which occurs when 16 32-bit locations are free + in the input buffer */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800a31a: 6a6e ldr r6, [r5, #36] ; 0x24 + 800a31c: 07f6 lsls r6, r6, #31 + 800a31e: d522 bpl.n 800a366 + /* Reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + + /* Depending whether the key or the input data were fed to the Peripheral, the feeding point + reached at suspension time is not saved in the same handle fields */ + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a320: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a324: 2500 movs r5, #0 + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a326: 2b02 cmp r3, #2 + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a328: f884 5036 strb.w r5, [r4, #54] ; 0x36 + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a32c: d001 beq.n 800a332 + 800a32e: 2b04 cmp r3, #4 + 800a330: d109 bne.n 800a346 + { + /* Save current reading and writing locations of Input and Output buffers */ + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + /* Save the number of bytes that remain to be processed at this point */ + hhash->HashInCount = Size - (buffercounter + 4U); + 800a332: 3a04 subs r2, #4 + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + 800a334: 9b01 ldr r3, [sp, #4] + 800a336: 60e3 str r3, [r4, #12] + hhash->HashInCount = Size - (buffercounter + 4U); + 800a338: 1a52 subs r2, r2, r1 + 800a33a: 6222 str r2, [r4, #32] + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + + /* Set the HASH state to Suspended and exit to stop entering data */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a33c: 2308 movs r3, #8 + 800a33e: f884 3035 strb.w r3, [r4, #53] ; 0x35 + } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) */ + } /* if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4) < Size)) */ + } /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */ + + /* At this point, all the data have been entered to the Peripheral: exit */ + return HAL_OK; + 800a342: 2000 movs r0, #0 + 800a344: e00d b.n 800a362 + else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)) + 800a346: 2b03 cmp r3, #3 + 800a348: d001 beq.n 800a34e + 800a34a: 2b05 cmp r3, #5 + 800a34c: d105 bne.n 800a35a + hhash->HashKeyCount = Size - (buffercounter + 4U); + 800a34e: 3a04 subs r2, #4 + hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr; + 800a350: 9b01 ldr r3, [sp, #4] + 800a352: 6163 str r3, [r4, #20] + hhash->HashKeyCount = Size - (buffercounter + 4U); + 800a354: 1a52 subs r2, r2, r1 + 800a356: 62a2 str r2, [r4, #40] ; 0x28 + 800a358: e7f0 b.n 800a33c + hhash->State = HAL_HASH_STATE_READY; + 800a35a: f884 0035 strb.w r0, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800a35e: f884 5034 strb.w r5, [r4, #52] ; 0x34 +} + 800a362: b002 add sp, #8 + 800a364: bd70 pop {r4, r5, r6, pc} + 800a366: 4619 mov r1, r3 + 800a368: e7c7 b.n 800a2fa + 800a36a: bf00 nop + 800a36c: 50060400 .word 0x50060400 + +0800a370 : + */ +static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size) +{ + uint32_t msgdigest = (uint32_t)pMsgDigest; + + switch(Size) + 800a370: 291c cmp r1, #28 + 800a372: d027 beq.n 800a3c4 + 800a374: d804 bhi.n 800a380 + 800a376: 2910 cmp r1, #16 + 800a378: d005 beq.n 800a386 + 800a37a: 2914 cmp r1, #20 + 800a37c: d011 beq.n 800a3a2 + 800a37e: 4770 bx lr + 800a380: 2920 cmp r1, #32 + 800a382: d037 beq.n 800a3f4 + 800a384: 4770 bx lr + { + /* Read the message digest */ + case 16: /* MD5 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a386: 4b29 ldr r3, [pc, #164] ; (800a42c ) + 800a388: 68da ldr r2, [r3, #12] + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); + 800a38a: ba12 rev r2, r2 + 800a38c: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a38e: 691a ldr r2, [r3, #16] + 800a390: ba12 rev r2, r2 + 800a392: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a394: 695a ldr r2, [r3, #20] + 800a396: ba12 rev r2, r2 + 800a398: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a39a: 699b ldr r3, [r3, #24] + 800a39c: ba1b rev r3, r3 + 800a39e: 60c3 str r3, [r0, #12] + break; + 800a3a0: 4770 bx lr + case 20: /* SHA1 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a3a2: 4b22 ldr r3, [pc, #136] ; (800a42c ) + 800a3a4: 68da ldr r2, [r3, #12] + 800a3a6: ba12 rev r2, r2 + 800a3a8: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a3aa: 691a ldr r2, [r3, #16] + 800a3ac: ba12 rev r2, r2 + 800a3ae: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a3b0: 695a ldr r2, [r3, #20] + 800a3b2: ba12 rev r2, r2 + 800a3b4: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a3b6: 699a ldr r2, [r3, #24] + 800a3b8: ba12 rev r2, r2 + 800a3ba: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a3bc: 69db ldr r3, [r3, #28] + 800a3be: ba1b rev r3, r3 + 800a3c0: 6103 str r3, [r0, #16] + break; + 800a3c2: 4770 bx lr + case 28: /* SHA224 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a3c4: 4b19 ldr r3, [pc, #100] ; (800a42c ) + 800a3c6: 68da ldr r2, [r3, #12] + 800a3c8: ba12 rev r2, r2 + 800a3ca: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a3cc: 691a ldr r2, [r3, #16] + 800a3ce: ba12 rev r2, r2 + 800a3d0: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a3d2: 695a ldr r2, [r3, #20] + 800a3d4: ba12 rev r2, r2 + 800a3d6: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a3d8: 699a ldr r2, [r3, #24] + 800a3da: ba12 rev r2, r2 + 800a3dc: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a3de: 69db ldr r3, [r3, #28] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a3e0: 4a13 ldr r2, [pc, #76] ; (800a430 ) + 800a3e2: ba1b rev r3, r3 + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a3e4: 6103 str r3, [r0, #16] + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a3e6: 6a53 ldr r3, [r2, #36] ; 0x24 + 800a3e8: ba1b rev r3, r3 + 800a3ea: 6143 str r3, [r0, #20] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + 800a3ec: 6a93 ldr r3, [r2, #40] ; 0x28 + 800a3ee: ba1b rev r3, r3 + 800a3f0: 6183 str r3, [r0, #24] + break; + 800a3f2: 4770 bx lr + case 32: /* SHA256 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a3f4: 4b0d ldr r3, [pc, #52] ; (800a42c ) + 800a3f6: 68da ldr r2, [r3, #12] + 800a3f8: ba12 rev r2, r2 + 800a3fa: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a3fc: 691a ldr r2, [r3, #16] + 800a3fe: ba12 rev r2, r2 + 800a400: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a402: 695a ldr r2, [r3, #20] + 800a404: ba12 rev r2, r2 + 800a406: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a408: 699a ldr r2, [r3, #24] + 800a40a: ba12 rev r2, r2 + 800a40c: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a40e: 69db ldr r3, [r3, #28] + 800a410: ba1b rev r3, r3 + 800a412: 6103 str r3, [r0, #16] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a414: 4b06 ldr r3, [pc, #24] ; (800a430 ) + 800a416: 6a5a ldr r2, [r3, #36] ; 0x24 + 800a418: ba12 rev r2, r2 + 800a41a: 6142 str r2, [r0, #20] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + 800a41c: 6a9a ldr r2, [r3, #40] ; 0x28 + 800a41e: ba12 rev r2, r2 + 800a420: 6182 str r2, [r0, #24] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]); + 800a422: 6adb ldr r3, [r3, #44] ; 0x2c + 800a424: ba1b rev r3, r3 + 800a426: 61c3 str r3, [r0, #28] + break; + default: + break; + } +} + 800a428: 4770 bx lr + 800a42a: bf00 nop + 800a42c: 50060400 .word 0x50060400 + 800a430: 50060700 .word 0x50060700 + +0800a434 : + * @param Status the Flag status (SET or RESET). + * @param Timeout Timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + 800a434: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 800a438: 4604 mov r4, r0 + 800a43a: 460e mov r6, r1 + 800a43c: 4691 mov r9, r2 + 800a43e: 461d mov r5, r3 + uint32_t tickstart = HAL_GetTick(); + 800a440: f7fc fe54 bl 80070ec + 800a444: f8df 805c ldr.w r8, [pc, #92] ; 800a4a4 + 800a448: 4607 mov r7, r0 + + /* Wait until flag is set */ + if(Status == RESET) + 800a44a: f1b9 0f00 cmp.w r9, #0 + 800a44e: d021 beq.n 800a494 + } + } + } + else + { + while(__HAL_HASH_GET_FLAG(Flag) != RESET) + 800a450: f8d8 3024 ldr.w r3, [r8, #36] ; 0x24 + 800a454: ea36 0303 bics.w r3, r6, r3 + 800a458: d121 bne.n 800a49e + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + 800a45a: 1c6b adds r3, r5, #1 + 800a45c: d0f8 beq.n 800a450 + { + if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U)) + 800a45e: f7fc fe45 bl 80070ec + 800a462: 1bc0 subs r0, r0, r7 + 800a464: 42a8 cmp r0, r5 + 800a466: d80a bhi.n 800a47e + 800a468: 2d00 cmp r5, #0 + 800a46a: d1f1 bne.n 800a450 + 800a46c: e007 b.n 800a47e + if(Timeout != HAL_MAX_DELAY) + 800a46e: 1c6a adds r2, r5, #1 + 800a470: d010 beq.n 800a494 + if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U)) + 800a472: f7fc fe3b bl 80070ec + 800a476: 1bc0 subs r0, r0, r7 + 800a478: 42a8 cmp r0, r5 + 800a47a: d800 bhi.n 800a47e + 800a47c: b955 cbnz r5, 800a494 + { + /* Set State to Ready to be able to restart later on */ + hhash->State = HAL_HASH_STATE_READY; + 800a47e: 2301 movs r3, #1 + 800a480: f884 3035 strb.w r3, [r4, #53] ; 0x35 + /* Store time out issue in handle status */ + hhash->Status = HAL_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + 800a484: 2200 movs r2, #0 + hhash->Status = HAL_TIMEOUT; + 800a486: 2303 movs r3, #3 + 800a488: f884 302c strb.w r3, [r4, #44] ; 0x2c + __HAL_UNLOCK(hhash); + 800a48c: f884 2034 strb.w r2, [r4, #52] ; 0x34 + + return HAL_TIMEOUT; + 800a490: 4618 mov r0, r3 + 800a492: e005 b.n 800a4a0 + while(__HAL_HASH_GET_FLAG(Flag) == RESET) + 800a494: f8d8 3024 ldr.w r3, [r8, #36] ; 0x24 + 800a498: ea36 0303 bics.w r3, r6, r3 + 800a49c: d1e7 bne.n 800a46e + } + } + } + } + return HAL_OK; + 800a49e: 2000 movs r0, #0 +} + 800a4a0: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + 800a4a4: 50060400 .word 0x50060400 + +0800a4a8 : +} + 800a4a8: 4770 bx lr + ... + +0800a4ac : +{ + 800a4ac: b538 push {r3, r4, r5, lr} + if(hhash == NULL) + 800a4ae: 4604 mov r4, r0 + 800a4b0: b328 cbz r0, 800a4fe + if(hhash->State == HAL_HASH_STATE_RESET) + 800a4b2: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + 800a4b6: f003 02ff and.w r2, r3, #255 ; 0xff + 800a4ba: b91b cbnz r3, 800a4c4 + hhash->Lock = HAL_UNLOCKED; + 800a4bc: f880 2034 strb.w r2, [r0, #52] ; 0x34 + HAL_HASH_MspInit(hhash); + 800a4c0: f7ff fff2 bl 800a4a8 + hhash->HashInCount = 0; + 800a4c4: 2000 movs r0, #0 + MODIFY_REG(HASH->CR, HASH_CR_DATATYPE, hhash->Init.DataType); + 800a4c6: 4a0f ldr r2, [pc, #60] ; (800a504 ) + hhash->HashBuffSize = 0; + 800a4c8: 61e0 str r0, [r4, #28] + hhash->State = HAL_HASH_STATE_BUSY; + 800a4ca: 2302 movs r3, #2 + hhash->Phase = HAL_HASH_PHASE_READY; + 800a4cc: 2101 movs r1, #1 + hhash->State = HAL_HASH_STATE_BUSY; + 800a4ce: f884 3035 strb.w r3, [r4, #53] ; 0x35 + hhash->Phase = HAL_HASH_PHASE_READY; + 800a4d2: f884 102d strb.w r1, [r4, #45] ; 0x2d + hhash->HashInCount = 0; + 800a4d6: 6220 str r0, [r4, #32] + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a4d8: 86e0 strh r0, [r4, #54] ; 0x36 + hhash->HashITCounter = 0; + 800a4da: 6260 str r0, [r4, #36] ; 0x24 + hhash->NbWordsAlreadyPushed = 0; + 800a4dc: 63a0 str r0, [r4, #56] ; 0x38 + MODIFY_REG(HASH->CR, HASH_CR_DATATYPE, hhash->Init.DataType); + 800a4de: 6813 ldr r3, [r2, #0] + 800a4e0: 6825 ldr r5, [r4, #0] + 800a4e2: f023 0330 bic.w r3, r3, #48 ; 0x30 + 800a4e6: 432b orrs r3, r5 + 800a4e8: 6013 str r3, [r2, #0] +__HAL_HASH_RESET_MDMAT(); + 800a4ea: 6813 ldr r3, [r2, #0] + 800a4ec: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 800a4f0: 6013 str r3, [r2, #0] + hhash->State = HAL_HASH_STATE_READY; + 800a4f2: f884 1035 strb.w r1, [r4, #53] ; 0x35 + hhash->Status = HAL_OK; + 800a4f6: f884 002c strb.w r0, [r4, #44] ; 0x2c + hhash->ErrorCode = HAL_HASH_ERROR_NONE; + 800a4fa: 63e0 str r0, [r4, #60] ; 0x3c +} + 800a4fc: bd38 pop {r3, r4, r5, pc} + return HAL_ERROR; + 800a4fe: 2001 movs r0, #1 + 800a500: e7fc b.n 800a4fc + 800a502: bf00 nop + 800a504: 50060400 .word 0x50060400 + +0800a508 : + 800a508: 4770 bx lr + +0800a50a : + 800a50a: 4770 bx lr + +0800a50c : + 800a50c: 4770 bx lr + +0800a50e : + 800a50e: 4770 bx lr + +0800a510 : +{ + 800a510: b570 push {r4, r5, r6, lr} + * suspension time is stored in the handle for resumption later on. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash) +{ + if (hhash->State == HAL_HASH_STATE_BUSY) + 800a512: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + 800a516: 2b02 cmp r3, #2 +{ + 800a518: 4604 mov r4, r0 + if (hhash->State == HAL_HASH_STATE_BUSY) + 800a51a: b2da uxtb r2, r3 + 800a51c: f040 80e7 bne.w 800a6ee + { + /* ITCounter must not be equal to 0 at this point. Report an error if this is the case. */ + if(hhash->HashITCounter == 0U) + 800a520: 6a43 ldr r3, [r0, #36] ; 0x24 + 800a522: 4d74 ldr r5, [pc, #464] ; (800a6f4 ) + 800a524: b94b cbnz r3, 800a53a + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a526: 6a2b ldr r3, [r5, #32] + 800a528: f023 0303 bic.w r3, r3, #3 + 800a52c: 622b str r3, [r5, #32] + /* HASH state set back to Ready to prevent any issue in user code + present in HAL_HASH_ErrorCallback() */ + hhash->State = HAL_HASH_STATE_READY; + 800a52e: 2301 movs r3, #1 + 800a530: f880 3035 strb.w r3, [r0, #53] ; 0x35 + hhash->Status = HASH_IT(hhash); + 800a534: f884 302c strb.w r3, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800a538: e099 b.n 800a66e + return HAL_ERROR; + } + else if (hhash->HashITCounter == 1U) + 800a53a: 6a43 ldr r3, [r0, #36] ; 0x24 + 800a53c: 2b01 cmp r3, #1 + } + else + { + /* Cruise speed reached, HashITCounter remains equal to 3 until the end of + the HASH processing or the end of the current step for HMAC processing. */ + hhash->HashITCounter = 3U; + 800a53e: bf16 itet ne + 800a540: 2303 movne r3, #3 + hhash->HashITCounter = 2U; + 800a542: 6242 streq r2, [r0, #36] ; 0x24 + hhash->HashITCounter = 3U; + 800a544: 6243 strne r3, [r0, #36] ; 0x24 + } + + /* If digest is ready */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) + 800a546: 6a6b ldr r3, [r5, #36] ; 0x24 + 800a548: f013 0302 ands.w r3, r3, #2 + 800a54c: d022 beq.n 800a594 + { + /* Read the digest */ + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800a54e: 682a ldr r2, [r5, #0] + 800a550: 4b69 ldr r3, [pc, #420] ; (800a6f8 ) + 800a552: 6900 ldr r0, [r0, #16] + 800a554: 421a tst r2, r3 + 800a556: d019 beq.n 800a58c + 800a558: 682a ldr r2, [r5, #0] + 800a55a: 401a ands r2, r3 + 800a55c: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800a560: d016 beq.n 800a590 + 800a562: 682a ldr r2, [r5, #0] + 800a564: 4393 bics r3, r2 + 800a566: bf0c ite eq + 800a568: 2120 moveq r1, #32 + 800a56a: 2110 movne r1, #16 + 800a56c: f7ff ff00 bl 800a370 + + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a570: 6a2b ldr r3, [r5, #32] + 800a572: f023 0303 bic.w r3, r3, #3 + 800a576: 622b str r3, [r5, #32] + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + 800a578: 2301 movs r3, #1 + 800a57a: f884 3035 strb.w r3, [r4, #53] ; 0x35 + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + 800a57e: f884 302d strb.w r3, [r4, #45] ; 0x2d + /* Call digest computation complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->DgstCpltCallback(hhash); +#else + HAL_HASH_DgstCpltCallback(hhash); + 800a582: 4620 mov r0, r4 + 800a584: f7ff ffc2 bl 800a50c + hhash->Status = HAL_OK; + 800a588: 2300 movs r3, #0 + 800a58a: e015 b.n 800a5b8 + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800a58c: 2114 movs r1, #20 + 800a58e: e7ed b.n 800a56c + 800a590: 211c movs r1, #28 + 800a592: e7eb b.n 800a56c + + return HAL_OK; + } + + /* If Peripheral ready to accept new data */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800a594: 6a6a ldr r2, [r5, #36] ; 0x24 + 800a596: 07d2 lsls r2, r2, #31 + 800a598: d5f6 bpl.n 800a588 + { + + /* If the suspension flag has been raised and if the processing is not about + to end, suspend processing */ + if ( (hhash->HashInCount != 0U) && (hhash->SuspendRequest == HAL_HASH_SUSPEND)) + 800a59a: 6a02 ldr r2, [r0, #32] + 800a59c: b17a cbz r2, 800a5be + 800a59e: f890 2036 ldrb.w r2, [r0, #54] ; 0x36 + 800a5a2: 2a01 cmp r2, #1 + 800a5a4: d10b bne.n 800a5be + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a5a6: 6a2a ldr r2, [r5, #32] + 800a5a8: f022 0203 bic.w r2, r2, #3 + 800a5ac: 622a str r2, [r5, #32] + + /* Reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a5ae: 2208 movs r2, #8 + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a5b0: f880 3036 strb.w r3, [r0, #54] ; 0x36 + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a5b4: f880 2035 strb.w r2, [r0, #53] ; 0x35 + hhash->Status = HAL_OK; + 800a5b8: f884 302c strb.w r3, [r4, #44] ; 0x2c +} + 800a5bc: e076 b.n 800a6ac + uint32_t buffercounter; + uint32_t inputcounter; + uint32_t ret = HASH_DIGEST_CALCULATION_NOT_STARTED; + + /* If there are more than 64 bytes remaining to be entered */ + if(hhash->HashInCount > 64U) + 800a5be: 6a21 ldr r1, [r4, #32] + { + inputaddr = (uint32_t)hhash->pHashInBuffPtr; + 800a5c0: 68e3 ldr r3, [r4, #12] + if(hhash->HashInCount > 64U) + 800a5c2: 2940 cmp r1, #64 ; 0x40 + inputaddr = (uint32_t)hhash->pHashInBuffPtr; + 800a5c4: 461a mov r2, r3 + if(hhash->HashInCount > 64U) + 800a5c6: d91c bls.n 800a602 + 800a5c8: f103 0140 add.w r1, r3, #64 ; 0x40 + /* Write the Input block in the Data IN register + (16 32-bit words, or 64 bytes are entered) */ + for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) + { + HASH->DIN = *(uint32_t*)inputaddr; + 800a5cc: f853 0b04 ldr.w r0, [r3], #4 + 800a5d0: 6068 str r0, [r5, #4] + for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) + 800a5d2: 4299 cmp r1, r3 + 800a5d4: d1fa bne.n 800a5cc + inputaddr+=4U; + } + /* If this is the start of input data entering, an additional word + must be entered to start up the HASH processing */ + if(hhash->HashITCounter == 2U) + 800a5d6: 6a63 ldr r3, [r4, #36] ; 0x24 + 800a5d8: 2b02 cmp r3, #2 + 800a5da: d10d bne.n 800a5f8 + { + HASH->DIN = *(uint32_t*)inputaddr; + 800a5dc: 680b ldr r3, [r1, #0] + 800a5de: 606b str r3, [r5, #4] + if(hhash->HashInCount >= 68U) + 800a5e0: 6a23 ldr r3, [r4, #32] + 800a5e2: 2b43 cmp r3, #67 ; 0x43 + 800a5e4: d905 bls.n 800a5f2 + { + /* There are still data waiting to be entered in the Peripheral. + Decrement buffer counter and set pointer to the proper + memory location for the next data entering round. */ + hhash->HashInCount -= 68U; + 800a5e6: 6a23 ldr r3, [r4, #32] + 800a5e8: 3b44 subs r3, #68 ; 0x44 + 800a5ea: 6223 str r3, [r4, #32] + hhash->pHashInBuffPtr+= 68U; + 800a5ec: 3244 adds r2, #68 ; 0x44 + { + /* 64 bytes have been entered and there are still some remaining: + Decrement buffer counter and set pointer to the proper + memory location for the next data entering round.*/ + hhash->HashInCount -= 64U; + hhash->pHashInBuffPtr+= 64U; + 800a5ee: 60e2 str r2, [r4, #12] + /* Reset buffer counter */ + hhash->HashInCount = 0; + } + + /* Return whether or digest calculation has started */ + return ret; + 800a5f0: e7ca b.n 800a588 + hhash->HashInCount = 0U; + 800a5f2: 2300 movs r3, #0 + 800a5f4: 6223 str r3, [r4, #32] + return ret; + 800a5f6: e7c7 b.n 800a588 + hhash->HashInCount -= 64U; + 800a5f8: 6a23 ldr r3, [r4, #32] + 800a5fa: 3b40 subs r3, #64 ; 0x40 + 800a5fc: 6223 str r3, [r4, #32] + hhash->pHashInBuffPtr+= 64U; + 800a5fe: 3240 adds r2, #64 ; 0x40 + 800a600: e7f5 b.n 800a5ee + inputcounter = hhash->HashInCount; + 800a602: 6a22 ldr r2, [r4, #32] + __HAL_HASH_DISABLE_IT(HASH_IT_DINI); + 800a604: 6a29 ldr r1, [r5, #32] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a606: 3203 adds r2, #3 + __HAL_HASH_DISABLE_IT(HASH_IT_DINI); + 800a608: f021 0101 bic.w r1, r1, #1 + 800a60c: f022 0203 bic.w r2, r2, #3 + 800a610: 6229 str r1, [r5, #32] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a612: 441a add r2, r3 + 800a614: 4293 cmp r3, r2 + 800a616: d10b bne.n 800a630 + if (hhash->Accumulation == 1U) + 800a618: 6c23 ldr r3, [r4, #64] ; 0x40 + 800a61a: 2b01 cmp r3, #1 + 800a61c: d10c bne.n 800a638 + hhash->Accumulation = 0U; + 800a61e: 2500 movs r5, #0 + 800a620: 6425 str r5, [r4, #64] ; 0x40 + HAL_HASH_InCpltCallback(hhash); + 800a622: 4620 mov r0, r4 + hhash->State = HAL_HASH_STATE_READY; + 800a624: f884 3035 strb.w r3, [r4, #53] ; 0x35 + HAL_HASH_InCpltCallback(hhash); + 800a628: f7ff ff6f bl 800a50a + hhash->HashInCount = 0; + 800a62c: 6225 str r5, [r4, #32] + return ret; + 800a62e: e7ab b.n 800a588 + HASH->DIN = *(uint32_t*)inputaddr; + 800a630: f853 1b04 ldr.w r1, [r3], #4 + 800a634: 6069 str r1, [r5, #4] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a636: e7ed b.n 800a614 + __HAL_HASH_START_DIGEST(); + 800a638: 68ab ldr r3, [r5, #8] + 800a63a: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800a63e: 60ab str r3, [r5, #8] + hhash->HashInCount = 0; + 800a640: 2300 movs r3, #0 + 800a642: 6223 str r3, [r4, #32] + HAL_HASH_InCpltCallback(hhash); + 800a644: 4620 mov r0, r4 + 800a646: f7ff ff60 bl 800a50a + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) + 800a64a: f894 602d ldrb.w r6, [r4, #45] ; 0x2d + 800a64e: 2e03 cmp r6, #3 + 800a650: d12d bne.n 800a6ae + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK) + 800a652: f44f 737a mov.w r3, #1000 ; 0x3e8 + 800a656: 2201 movs r2, #1 + 800a658: 2108 movs r1, #8 + 800a65a: 4620 mov r0, r4 + 800a65c: f7ff feea bl 800a434 + 800a660: b168 cbz r0, 800a67e + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a662: 6a2b ldr r3, [r5, #32] + 800a664: f023 0303 bic.w r3, r3, #3 + 800a668: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a66a: f884 602c strb.w r6, [r4, #44] ; 0x2c + hhash->ErrorCode |= HAL_HASH_ERROR_IT; + 800a66e: 6be3 ldr r3, [r4, #60] ; 0x3c + 800a670: f043 0301 orr.w r3, r3, #1 + 800a674: 63e3 str r3, [r4, #60] ; 0x3c + HAL_HASH_ErrorCallback(hhash); + 800a676: 4620 mov r0, r4 + 800a678: f7ff ff49 bl 800a50e + 800a67c: e784 b.n 800a588 + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */ + 800a67e: 2304 movs r3, #4 + 800a680: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); /* Set NBLW for the input message */ + 800a684: 68ab ldr r3, [r5, #8] + 800a686: 69e2 ldr r2, [r4, #28] + 800a688: f023 031f bic.w r3, r3, #31 + 800a68c: f002 0103 and.w r1, r2, #3 + 800a690: ea43 03c1 orr.w r3, r3, r1, lsl #3 + 800a694: 60ab str r3, [r5, #8] + hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr; /* Set the input data address */ + 800a696: 69a3 ldr r3, [r4, #24] + hhash->HashInCount = hhash->HashBuffSize; /* Set the input data size (in bytes) */ + 800a698: 6222 str r2, [r4, #32] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a69a: 60e3 str r3, [r4, #12] + hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start of a new phase */ + 800a69c: 2301 movs r3, #1 + 800a69e: 6263 str r3, [r4, #36] ; 0x24 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */ + 800a6a0: 6a2b ldr r3, [r5, #32] + 800a6a2: f043 0301 orr.w r3, r3, #1 + 800a6a6: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a6a8: f884 002c strb.w r0, [r4, #44] ; 0x2c +} + 800a6ac: bd70 pop {r4, r5, r6, pc} + else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) + 800a6ae: 2e04 cmp r6, #4 + 800a6b0: f47f af6a bne.w 800a588 + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK) + 800a6b4: f44f 737a mov.w r3, #1000 ; 0x3e8 + 800a6b8: 2201 movs r2, #1 + 800a6ba: 2108 movs r1, #8 + 800a6bc: 4620 mov r0, r4 + 800a6be: f7ff feb9 bl 800a434 + 800a6c2: b128 cbz r0, 800a6d0 + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a6c4: 6a2b ldr r3, [r5, #32] + 800a6c6: f023 0303 bic.w r3, r3, #3 + 800a6ca: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a6cc: 2303 movs r3, #3 + 800a6ce: e731 b.n 800a534 + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */ + 800a6d0: 2305 movs r3, #5 + 800a6d2: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); /* Set NBLW for the key */ + 800a6d6: 68ab ldr r3, [r5, #8] + 800a6d8: 6862 ldr r2, [r4, #4] + 800a6da: f023 031f bic.w r3, r3, #31 + 800a6de: f002 0103 and.w r1, r2, #3 + 800a6e2: ea43 03c1 orr.w r3, r3, r1, lsl #3 + 800a6e6: 60ab str r3, [r5, #8] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a6e8: 68a3 ldr r3, [r4, #8] + hhash->HashInCount = hhash->Init.KeySize; /* Set the key size (in bytes) */ + 800a6ea: 6222 str r2, [r4, #32] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a6ec: e7d5 b.n 800a69a + hhash->Status = HASH_IT(hhash); + 800a6ee: 2302 movs r3, #2 + 800a6f0: e720 b.n 800a534 + 800a6f2: bf00 nop + 800a6f4: 50060400 .word 0x50060400 + 800a6f8: 00040080 .word 0x00040080 + +0800a6fc : + return hhash->State; + 800a6fc: f890 0035 ldrb.w r0, [r0, #53] ; 0x35 +} + 800a700: 4770 bx lr + +0800a702 : +} + 800a702: f890 002c ldrb.w r0, [r0, #44] ; 0x2c + 800a706: 4770 bx lr + +0800a708 : + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->IMR,HASH_IT_DINI|HASH_IT_DCI); + 800a708: 4b0e ldr r3, [pc, #56] ; (800a744 ) + 800a70a: 6a1a ldr r2, [r3, #32] + 800a70c: f002 0203 and.w r2, r2, #3 + 800a710: 600a str r2, [r1, #0] + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->STR,HASH_STR_NBLW); + 800a712: 689a ldr r2, [r3, #8] + 800a714: f002 021f and.w r2, r2, #31 + 800a718: 604a str r2, [r1, #4] + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->CR,HASH_CR_DMAE|HASH_CR_DATATYPE|HASH_CR_MODE|HASH_CR_ALGO|HASH_CR_LKEY|HASH_CR_MDMAT); + 800a71a: 681b ldr r3, [r3, #0] + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800a71c: 4a0a ldr r2, [pc, #40] ; (800a748 ) + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->CR,HASH_CR_DMAE|HASH_CR_DATATYPE|HASH_CR_MODE|HASH_CR_ALGO|HASH_CR_LKEY|HASH_CR_MDMAT); + 800a71e: f023 437f bic.w r3, r3, #4278190080 ; 0xff000000 + 800a722: f423 037a bic.w r3, r3, #16384000 ; 0xfa0000 + 800a726: f423 435f bic.w r3, r3, #57088 ; 0xdf00 + 800a72a: f023 0307 bic.w r3, r3, #7 + 800a72e: 608b str r3, [r1, #8] + uint32_t csr_ptr = (uint32_t)HASH->CSR; + 800a730: 4b06 ldr r3, [pc, #24] ; (800a74c ) + mem_ptr+=4U; + 800a732: 310c adds r1, #12 + *(uint32_t*)(mem_ptr) = *(uint32_t*)(csr_ptr); + 800a734: f853 0b04 ldr.w r0, [r3], #4 + 800a738: f841 0b04 str.w r0, [r1], #4 + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800a73c: 4293 cmp r3, r2 + 800a73e: d1f9 bne.n 800a734 +} + 800a740: 4770 bx lr + 800a742: bf00 nop + 800a744: 50060400 .word 0x50060400 + 800a748: 500605d0 .word 0x500605d0 + 800a74c: 500604f8 .word 0x500604f8 + +0800a750 : + WRITE_REG(HASH->IMR, (*(uint32_t*)(mem_ptr))); + 800a750: 4b0a ldr r3, [pc, #40] ; (800a77c ) + 800a752: 680a ldr r2, [r1, #0] + 800a754: 621a str r2, [r3, #32] + WRITE_REG(HASH->STR, (*(uint32_t*)(mem_ptr))); + 800a756: 684a ldr r2, [r1, #4] + 800a758: 609a str r2, [r3, #8] + WRITE_REG(HASH->CR, (*(uint32_t*)(mem_ptr))); + 800a75a: 688a ldr r2, [r1, #8] + 800a75c: 601a str r2, [r3, #0] + __HAL_HASH_INIT(); + 800a75e: 681a ldr r2, [r3, #0] + 800a760: f042 0204 orr.w r2, r2, #4 + 800a764: 601a str r2, [r3, #0] + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800a766: 4a06 ldr r2, [pc, #24] ; (800a780 ) + mem_ptr+=4U; + 800a768: 310c adds r1, #12 + uint32_t csr_ptr = (uint32_t)HASH->CSR; + 800a76a: 33f8 adds r3, #248 ; 0xf8 + WRITE_REG((*(uint32_t*)(csr_ptr)), (*(uint32_t*)(mem_ptr))); + 800a76c: f851 0b04 ldr.w r0, [r1], #4 + 800a770: f843 0b04 str.w r0, [r3], #4 + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800a774: 4293 cmp r3, r2 + 800a776: d1f9 bne.n 800a76c +} + 800a778: 4770 bx lr + 800a77a: bf00 nop + 800a77c: 50060400 .word 0x50060400 + 800a780: 500605d0 .word 0x500605d0 + +0800a784 : + hhash->SuspendRequest = HAL_HASH_SUSPEND; + 800a784: 2301 movs r3, #1 + 800a786: f880 3036 strb.w r3, [r0, #54] ; 0x36 +} + 800a78a: 4770 bx lr + +0800a78c : + return hhash->ErrorCode; + 800a78c: 6bc0 ldr r0, [r0, #60] ; 0x3c +} + 800a78e: 4770 bx lr + +0800a790 : + * @param Timeout Timeout value. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout, uint32_t Algorithm) +{ + 800a790: b5f8 push {r3, r4, r5, r6, r7, lr} + 800a792: 461e mov r6, r3 + uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */ + uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */ + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a794: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + + + /* Initiate HASH processing in case of start or resumption */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800a798: 2b01 cmp r3, #1 +{ + 800a79a: 4604 mov r4, r0 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a79c: b2d8 uxtb r0, r3 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800a79e: d001 beq.n 800a7a4 + 800a7a0: 2808 cmp r0, #8 + 800a7a2: d17a bne.n 800a89a + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (pOutBuffer == NULL)) + 800a7a4: b101 cbz r1, 800a7a8 + 800a7a6: b926 cbnz r6, 800a7b2 + { + hhash->State = HAL_HASH_STATE_READY; + 800a7a8: 2501 movs r5, #1 + 800a7aa: f884 5035 strb.w r5, [r4, #53] ; 0x35 + } + else + { + return HAL_BUSY; + } +} + 800a7ae: 4628 mov r0, r5 + 800a7b0: bdf8 pop {r3, r4, r5, r6, r7, pc} + __HAL_LOCK(hhash); + 800a7b2: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800a7b6: 2b01 cmp r3, #1 + 800a7b8: d06f beq.n 800a89a + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800a7ba: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + __HAL_LOCK(hhash); + 800a7be: 2501 movs r5, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800a7c0: 42ab cmp r3, r5 + __HAL_LOCK(hhash); + 800a7c2: f884 5034 strb.w r5, [r4, #52] ; 0x34 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800a7c6: d148 bne.n 800a85a + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800a7c8: 4f36 ldr r7, [pc, #216] ; (800a8a4 ) + 800a7ca: 9b07 ldr r3, [sp, #28] + hhash->State = HAL_HASH_STATE_BUSY; + 800a7cc: f04f 0c02 mov.w ip, #2 + 800a7d0: f884 c035 strb.w ip, [r4, #53] ; 0x35 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800a7d4: 683d ldr r5, [r7, #0] + 800a7d6: f425 25a0 bic.w r5, r5, #327680 ; 0x50000 + 800a7da: f025 05c4 bic.w r5, r5, #196 ; 0xc4 + 800a7de: 431d orrs r5, r3 + 800a7e0: f045 0504 orr.w r5, r5, #4 + 800a7e4: 603d str r5, [r7, #0] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800a7e6: 68b8 ldr r0, [r7, #8] + 800a7e8: f002 0303 and.w r3, r2, #3 + 800a7ec: f020 001f bic.w r0, r0, #31 + 800a7f0: ea40 03c3 orr.w r3, r0, r3, lsl #3 + 800a7f4: 60bb str r3, [r7, #8] + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800a7f6: f884 c02d strb.w ip, [r4, #45] ; 0x2d + hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp); + 800a7fa: 4620 mov r0, r4 + 800a7fc: f7ff fd78 bl 800a2f0 + 800a800: 4605 mov r5, r0 + 800a802: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800a806: 2800 cmp r0, #0 + 800a808: d1d1 bne.n 800a7ae + if (hhash->State != HAL_HASH_STATE_SUSPENDED) + 800a80a: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800a80e: 2b08 cmp r3, #8 + 800a810: d03b beq.n 800a88a + __HAL_HASH_START_DIGEST(); + 800a812: 4f24 ldr r7, [pc, #144] ; (800a8a4 ) + 800a814: 68bb ldr r3, [r7, #8] + 800a816: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800a81a: 60bb str r3, [r7, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800a81c: 4602 mov r2, r0 + 800a81e: 9b06 ldr r3, [sp, #24] + 800a820: 2102 movs r1, #2 + 800a822: 4620 mov r0, r4 + 800a824: f7ff fe06 bl 800a434 + 800a828: 2800 cmp r0, #0 + 800a82a: d138 bne.n 800a89e + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800a82c: 683a ldr r2, [r7, #0] + 800a82e: 4b1e ldr r3, [pc, #120] ; (800a8a8 ) + 800a830: 421a tst r2, r3 + 800a832: d02e beq.n 800a892 + 800a834: 683a ldr r2, [r7, #0] + 800a836: 401a ands r2, r3 + 800a838: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800a83c: d02b beq.n 800a896 + 800a83e: 683a ldr r2, [r7, #0] + 800a840: 4393 bics r3, r2 + 800a842: bf0c ite eq + 800a844: 2120 moveq r1, #32 + 800a846: 2110 movne r1, #16 + 800a848: 4630 mov r0, r6 + 800a84a: f7ff fd91 bl 800a370 + hhash->State = HAL_HASH_STATE_READY; + 800a84e: 2301 movs r3, #1 + 800a850: f884 3035 strb.w r3, [r4, #53] ; 0x35 + hhash->Phase = HAL_HASH_PHASE_READY; + 800a854: f884 302d strb.w r3, [r4, #45] ; 0x2d + 800a858: e017 b.n 800a88a + else if (hhash->Phase == HAL_HASH_PHASE_PROCESS) + 800a85a: 2b02 cmp r3, #2 + 800a85c: d113 bne.n 800a886 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800a85e: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800a862: 2b08 cmp r3, #8 + __HAL_HASH_SET_NBVALIDBITS(Size); + 800a864: bf15 itete ne + 800a866: 4d0f ldrne r5, [pc, #60] ; (800a8a4 ) + Size_tmp = hhash->HashInCount; + 800a868: 6a22 ldreq r2, [r4, #32] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800a86a: 68a8 ldrne r0, [r5, #8] + pInBuffer_tmp = hhash->pHashInBuffPtr; + 800a86c: 68e1 ldreq r1, [r4, #12] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800a86e: bf1f itttt ne + 800a870: f002 0303 andne.w r3, r2, #3 + 800a874: f020 001f bicne.w r0, r0, #31 + 800a878: ea40 03c3 orrne.w r3, r0, r3, lsl #3 + 800a87c: 60ab strne r3, [r5, #8] + hhash->State = HAL_HASH_STATE_BUSY; + 800a87e: 2302 movs r3, #2 + 800a880: f884 3035 strb.w r3, [r4, #53] ; 0x35 + 800a884: e7b9 b.n 800a7fa + hhash->State = HAL_HASH_STATE_READY; + 800a886: f884 5035 strb.w r5, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800a88a: 2300 movs r3, #0 + 800a88c: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800a890: e78d b.n 800a7ae + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800a892: 2114 movs r1, #20 + 800a894: e7d8 b.n 800a848 + 800a896: 211c movs r1, #28 + 800a898: e7d6 b.n 800a848 + return HAL_BUSY; + 800a89a: 2502 movs r5, #2 + 800a89c: e787 b.n 800a7ae + return HAL_TIMEOUT; + 800a89e: 2503 movs r5, #3 + 800a8a0: e785 b.n 800a7ae + 800a8a2: bf00 nop + 800a8a4: 50060400 .word 0x50060400 + 800a8a8: 00040080 .word 0x00040080 + +0800a8ac : +{ + 800a8ac: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5); + 800a8ae: 2480 movs r4, #128 ; 0x80 + 800a8b0: 9401 str r4, [sp, #4] + 800a8b2: 9c04 ldr r4, [sp, #16] + 800a8b4: 9400 str r4, [sp, #0] + 800a8b6: f7ff ff6b bl 800a790 +} + 800a8ba: b002 add sp, #8 + 800a8bc: bd10 pop {r4, pc} + +0800a8be : + 800a8be: f7ff bff5 b.w 800a8ac + +0800a8c2 : +{ + 800a8c2: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1); + 800a8c4: 2400 movs r4, #0 + 800a8c6: 9401 str r4, [sp, #4] + 800a8c8: 9c04 ldr r4, [sp, #16] + 800a8ca: 9400 str r4, [sp, #0] + 800a8cc: f7ff ff60 bl 800a790 +} + 800a8d0: b002 add sp, #8 + 800a8d2: bd10 pop {r4, pc} + +0800a8d4 : + 800a8d4: f7ff bff5 b.w 800a8c2 + +0800a8d8 : + * @param Size length of the input buffer in bytes, must be a multiple of 4. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm) +{ + 800a8d8: b570 push {r4, r5, r6, lr} + uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */ + uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */ + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a8da: f890 5035 ldrb.w r5, [r0, #53] ; 0x35 +{ + 800a8de: 4604 mov r4, r0 + + /* Make sure the input buffer size (in bytes) is a multiple of 4 */ + if ((Size % 4U) != 0U) + 800a8e0: 0790 lsls r0, r2, #30 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a8e2: b2ed uxtb r5, r5 + if ((Size % 4U) != 0U) + 800a8e4: d13e bne.n 800a964 + { + return HAL_ERROR; + } + + /* Initiate HASH processing in case of start or resumption */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800a8e6: 2d01 cmp r5, #1 + 800a8e8: d001 beq.n 800a8ee + 800a8ea: 2d08 cmp r5, #8 + 800a8ec: d13c bne.n 800a968 + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U)) + 800a8ee: b101 cbz r1, 800a8f2 + 800a8f0: b91a cbnz r2, 800a8fa + { + hhash->State = HAL_HASH_STATE_READY; + 800a8f2: 2001 movs r0, #1 + 800a8f4: f884 0035 strb.w r0, [r4, #53] ; 0x35 + { + return HAL_BUSY; + } + + +} + 800a8f8: bd70 pop {r4, r5, r6, pc} + __HAL_LOCK(hhash); + 800a8fa: f894 0034 ldrb.w r0, [r4, #52] ; 0x34 + 800a8fe: 2801 cmp r0, #1 + 800a900: d032 beq.n 800a968 + 800a902: 2001 movs r0, #1 + 800a904: f884 0034 strb.w r0, [r4, #52] ; 0x34 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800a908: f894 0035 ldrb.w r0, [r4, #53] ; 0x35 + 800a90c: 2808 cmp r0, #8 + 800a90e: f04f 0002 mov.w r0, #2 + hhash->State = HAL_HASH_STATE_BUSY; + 800a912: f884 0035 strb.w r0, [r4, #53] ; 0x35 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800a916: d113 bne.n 800a940 + pInBuffer_tmp = hhash->pHashInBuffPtr; /* pInBuffer_tmp is set to the input data address */ + 800a918: 68e1 ldr r1, [r4, #12] + Size_tmp = hhash->HashInCount; /* Size_tmp contains the input data size in bytes */ + 800a91a: 6a22 ldr r2, [r4, #32] + hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp); + 800a91c: 4620 mov r0, r4 + 800a91e: f7ff fce7 bl 800a2f0 + 800a922: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800a926: 2800 cmp r0, #0 + 800a928: d1e6 bne.n 800a8f8 + if (hhash->State != HAL_HASH_STATE_SUSPENDED) + 800a92a: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800a92e: 2b08 cmp r3, #8 + hhash->State = HAL_HASH_STATE_READY; + 800a930: bf1c itt ne + 800a932: 2301 movne r3, #1 + 800a934: f884 3035 strbne.w r3, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800a938: 2300 movs r3, #0 + 800a93a: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800a93e: e7db b.n 800a8f8 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800a940: f894 002d ldrb.w r0, [r4, #45] ; 0x2d + 800a944: 2801 cmp r0, #1 + 800a946: d109 bne.n 800a95c + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800a948: 4e08 ldr r6, [pc, #32] ; (800a96c ) + 800a94a: 6830 ldr r0, [r6, #0] + 800a94c: f420 20a0 bic.w r0, r0, #327680 ; 0x50000 + 800a950: f020 00c4 bic.w r0, r0, #196 ; 0xc4 + 800a954: 4318 orrs r0, r3 + 800a956: f040 0004 orr.w r0, r0, #4 + 800a95a: 6030 str r0, [r6, #0] + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800a95c: 2302 movs r3, #2 + 800a95e: f884 302d strb.w r3, [r4, #45] ; 0x2d + 800a962: e7db b.n 800a91c + return HAL_ERROR; + 800a964: 2001 movs r0, #1 + 800a966: e7c7 b.n 800a8f8 + return HAL_BUSY; + 800a968: 2002 movs r0, #2 + 800a96a: e7c5 b.n 800a8f8 + 800a96c: 50060400 .word 0x50060400 + +0800a970 : + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_MD5); + 800a970: 2380 movs r3, #128 ; 0x80 + 800a972: f7ff bfb1 b.w 800a8d8 + +0800a976 : + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA1); + 800a976: 2300 movs r3, #0 + 800a978: f7ff bfae b.w 800a8d8 + +0800a97c : + * @param Size length of the input buffer in bytes, must be a multiple of 4. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm) +{ + 800a97c: b567 push {r0, r1, r2, r5, r6, lr} + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a97e: f890 5035 ldrb.w r5, [r0, #53] ; 0x35 + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800a982: 9101 str r1, [sp, #4] + uint32_t SizeVar = Size; + + /* Make sure the input buffer size (in bytes) is a multiple of 4 */ + if ((Size % 4U) != 0U) + 800a984: 0796 lsls r6, r2, #30 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800a986: b2ed uxtb r5, r5 + if ((Size % 4U) != 0U) + 800a988: d154 bne.n 800aa34 + { + return HAL_ERROR; + } + + /* Initiate HASH processing in case of start or resumption */ + if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800a98a: 2d01 cmp r5, #1 + 800a98c: d001 beq.n 800a992 + 800a98e: 2d08 cmp r5, #8 + 800a990: d152 bne.n 800aa38 + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U)) + 800a992: b101 cbz r1, 800a996 + 800a994: b92a cbnz r2, 800a9a2 + { + hhash->State = HAL_HASH_STATE_READY; + 800a996: 2301 movs r3, #1 + 800a998: f880 3035 strb.w r3, [r0, #53] ; 0x35 + else + { + return HAL_BUSY; + } + +} + 800a99c: 4618 mov r0, r3 + 800a99e: b003 add sp, #12 + 800a9a0: bd60 pop {r5, r6, pc} + __HAL_LOCK(hhash); + 800a9a2: f890 1034 ldrb.w r1, [r0, #52] ; 0x34 + 800a9a6: 2901 cmp r1, #1 + 800a9a8: d046 beq.n 800aa38 + 800a9aa: 2101 movs r1, #1 + 800a9ac: f880 1034 strb.w r1, [r0, #52] ; 0x34 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800a9b0: f890 1035 ldrb.w r1, [r0, #53] ; 0x35 + 800a9b4: 4d21 ldr r5, [pc, #132] ; (800aa3c ) + 800a9b6: 2908 cmp r1, #8 + 800a9b8: f04f 0102 mov.w r1, #2 + hhash->State = HAL_HASH_STATE_BUSY; + 800a9bc: f880 1035 strb.w r1, [r0, #53] ; 0x35 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800a9c0: d109 bne.n 800a9d6 + hhash->Accumulation = 1U; + 800a9c2: 2301 movs r3, #1 + 800a9c4: 6403 str r3, [r0, #64] ; 0x40 + __HAL_UNLOCK(hhash); + 800a9c6: 2300 movs r3, #0 + 800a9c8: f880 3034 strb.w r3, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI); + 800a9cc: 6a2a ldr r2, [r5, #32] + 800a9ce: f042 0201 orr.w r2, r2, #1 + 800a9d2: 622a str r2, [r5, #32] + return HAL_OK; + 800a9d4: e7e2 b.n 800a99c + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800a9d6: f890 602d ldrb.w r6, [r0, #45] ; 0x2d + 800a9da: 2e01 cmp r6, #1 + 800a9dc: d11b bne.n 800aa16 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800a9de: 6829 ldr r1, [r5, #0] + 800a9e0: f421 21a0 bic.w r1, r1, #327680 ; 0x50000 + 800a9e4: f021 01c4 bic.w r1, r1, #196 ; 0xc4 + 800a9e8: 4319 orrs r1, r3 + 800a9ea: f041 0104 orr.w r1, r1, #4 + 800a9ee: 6029 str r1, [r5, #0] + hhash->HashITCounter = 1; + 800a9f0: 6246 str r6, [r0, #36] ; 0x24 + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800a9f2: 2302 movs r3, #2 + 800a9f4: f880 302d strb.w r3, [r0, #45] ; 0x2d + while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 0U)) + 800a9f8: 6a6b ldr r3, [r5, #36] ; 0x24 + 800a9fa: 07d9 lsls r1, r3, #31 + 800a9fc: d400 bmi.n 800aa00 + 800a9fe: b96a cbnz r2, 800aa1c + if ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) || (SizeVar == 0U)) + 800aa00: 6a6b ldr r3, [r5, #36] ; 0x24 + 800aa02: 07db lsls r3, r3, #31 + 800aa04: d500 bpl.n 800aa08 + 800aa06: b98a cbnz r2, 800aa2c + hhash->State = HAL_HASH_STATE_READY; + 800aa08: 2301 movs r3, #1 + 800aa0a: f880 3035 strb.w r3, [r0, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800aa0e: 2300 movs r3, #0 + 800aa10: f880 3034 strb.w r3, [r0, #52] ; 0x34 + return HAL_OK; + 800aa14: e7c2 b.n 800a99c + hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */ + 800aa16: 2303 movs r3, #3 + 800aa18: 6243 str r3, [r0, #36] ; 0x24 + 800aa1a: e7ea b.n 800a9f2 + HASH->DIN = *(uint32_t*)inputaddr; + 800aa1c: 9b01 ldr r3, [sp, #4] + 800aa1e: 681b ldr r3, [r3, #0] + 800aa20: 606b str r3, [r5, #4] + inputaddr+=4U; + 800aa22: 9b01 ldr r3, [sp, #4] + 800aa24: 3304 adds r3, #4 + 800aa26: 9301 str r3, [sp, #4] + SizeVar-=4U; + 800aa28: 3a04 subs r2, #4 + 800aa2a: e7e5 b.n 800a9f8 + hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data + 800aa2c: 6202 str r2, [r0, #32] + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; /* Points at data which will be fed to the Peripheral at + 800aa2e: 9b01 ldr r3, [sp, #4] + 800aa30: 60c3 str r3, [r0, #12] + 800aa32: e7c6 b.n 800a9c2 + return HAL_ERROR; + 800aa34: 2301 movs r3, #1 + 800aa36: e7b1 b.n 800a99c + return HAL_BUSY; + 800aa38: 2302 movs r3, #2 + 800aa3a: e7af b.n 800a99c + 800aa3c: 50060400 .word 0x50060400 + +0800aa40 : + return HASH_Accumulate_IT(hhash, pInBuffer, Size,HASH_ALGOSELECTION_MD5); + 800aa40: 2380 movs r3, #128 ; 0x80 + 800aa42: f7ff bf9b b.w 800a97c + +0800aa46 : + return HASH_Accumulate_IT(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA1); + 800aa46: 2300 movs r3, #0 + 800aa48: f7ff bf98 b.w 800a97c + +0800aa4c : + * @param pOutBuffer pointer to the computed digest. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Algorithm) +{ + 800aa4c: b573 push {r0, r1, r4, r5, r6, lr} + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800aa4e: f890 4035 ldrb.w r4, [r0, #53] ; 0x35 + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800aa52: 9101 str r1, [sp, #4] + uint32_t polling_step = 0U; + uint32_t initialization_skipped = 0U; + uint32_t SizeVar = Size; + + /* If State is ready or suspended, start or resume IT-based HASH processing */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800aa54: 2c01 cmp r4, #1 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800aa56: b2e5 uxtb r5, r4 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800aa58: d001 beq.n 800aa5e + 800aa5a: 2d08 cmp r5, #8 + 800aa5c: d17f bne.n 800ab5e + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL)) + 800aa5e: b109 cbz r1, 800aa64 + 800aa60: b102 cbz r2, 800aa64 + 800aa62: b92b cbnz r3, 800aa70 + { + hhash->State = HAL_HASH_STATE_READY; + 800aa64: 2201 movs r2, #1 + 800aa66: f880 2035 strb.w r2, [r0, #53] ; 0x35 + else + { + return HAL_BUSY; + } + +} + 800aa6a: 4610 mov r0, r2 + 800aa6c: b002 add sp, #8 + 800aa6e: bd70 pop {r4, r5, r6, pc} + __HAL_LOCK(hhash); + 800aa70: f890 4034 ldrb.w r4, [r0, #52] ; 0x34 + 800aa74: 2c01 cmp r4, #1 + 800aa76: f04f 0402 mov.w r4, #2 + 800aa7a: d072 beq.n 800ab62 + hhash->State = HAL_HASH_STATE_BUSY; + 800aa7c: f880 4035 strb.w r4, [r0, #53] ; 0x35 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aa80: f890 402d ldrb.w r4, [r0, #45] ; 0x2d + __HAL_LOCK(hhash); + 800aa84: 2601 movs r6, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aa86: 42b4 cmp r4, r6 + __HAL_LOCK(hhash); + 800aa88: f880 6034 strb.w r6, [r0, #52] ; 0x34 + hhash->HashITCounter = 1; + 800aa8c: 4c36 ldr r4, [pc, #216] ; (800ab68 ) + 800aa8e: 6246 str r6, [r0, #36] ; 0x24 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aa90: d115 bne.n 800aabe + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800aa92: 6825 ldr r5, [r4, #0] + 800aa94: 9e06 ldr r6, [sp, #24] + 800aa96: f425 25a0 bic.w r5, r5, #327680 ; 0x50000 + 800aa9a: f025 05c4 bic.w r5, r5, #196 ; 0xc4 + 800aa9e: 4335 orrs r5, r6 + 800aaa0: f045 0504 orr.w r5, r5, #4 + 800aaa4: 6025 str r5, [r4, #0] + __HAL_HASH_SET_NBVALIDBITS(SizeVar); + 800aaa6: 68a6 ldr r6, [r4, #8] + 800aaa8: f002 0503 and.w r5, r2, #3 + 800aaac: f026 061f bic.w r6, r6, #31 + 800aab0: ea46 05c5 orr.w r5, r6, r5, lsl #3 + 800aab4: 60a5 str r5, [r4, #8] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800aab6: e9c0 1303 strd r1, r3, [r0, #12] + hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data + 800aaba: 6202 str r2, [r0, #32] + uint32_t initialization_skipped = 0U; + 800aabc: 2600 movs r6, #0 + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800aabe: 2102 movs r1, #2 + 800aac0: f880 102d strb.w r1, [r0, #45] ; 0x2d + uint32_t polling_step = 0U; + 800aac4: 2100 movs r1, #0 + while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 3U)) + 800aac6: 6a65 ldr r5, [r4, #36] ; 0x24 + 800aac8: 07ed lsls r5, r5, #31 + 800aaca: d401 bmi.n 800aad0 + 800aacc: 2a03 cmp r2, #3 + 800aace: d80d bhi.n 800aaec + if (polling_step == 1U) + 800aad0: b349 cbz r1, 800ab26 + if (SizeVar == 0U) + 800aad2: b9a2 cbnz r2, 800aafe + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800aad4: 6103 str r3, [r0, #16] + __HAL_HASH_START_DIGEST(); + 800aad6: 68a3 ldr r3, [r4, #8] + 800aad8: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800aadc: 60a3 str r3, [r4, #8] + __HAL_UNLOCK(hhash); + 800aade: f880 2034 strb.w r2, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DCI); + 800aae2: 6a23 ldr r3, [r4, #32] + 800aae4: f043 0302 orr.w r3, r3, #2 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800aae8: 6223 str r3, [r4, #32] + return HAL_OK; + 800aaea: e7be b.n 800aa6a + HASH->DIN = *(uint32_t*)inputaddr; + 800aaec: 9901 ldr r1, [sp, #4] + 800aaee: 6809 ldr r1, [r1, #0] + 800aaf0: 6061 str r1, [r4, #4] + inputaddr+=4U; + 800aaf2: 9901 ldr r1, [sp, #4] + 800aaf4: 3104 adds r1, #4 + 800aaf6: 9101 str r1, [sp, #4] + SizeVar-=4U; + 800aaf8: 3a04 subs r2, #4 + polling_step = 1U; /* note that some words are entered before enabling the interrupt */ + 800aafa: 2101 movs r1, #1 + 800aafc: e7e3 b.n 800aac6 + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800aafe: 6a61 ldr r1, [r4, #36] ; 0x24 + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800ab00: f002 0503 and.w r5, r2, #3 + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800ab04: f011 0101 ands.w r1, r1, #1 + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800ab08: ea4f 05c5 mov.w r5, r5, lsl #3 + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800ab0c: d012 beq.n 800ab34 + hhash->HashInCount = SizeVar; + 800ab0e: 6202 str r2, [r0, #32] + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + 800ab10: 9a01 ldr r2, [sp, #4] + 800ab12: 60c2 str r2, [r0, #12] + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800ab14: 68a2 ldr r2, [r4, #8] + 800ab16: f022 021f bic.w r2, r2, #31 + 800ab1a: 432a orrs r2, r5 + 800ab1c: 60a2 str r2, [r4, #8] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800ab1e: 6103 str r3, [r0, #16] + if (initialization_skipped == 1U) + 800ab20: b10e cbz r6, 800ab26 + hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */ + 800ab22: 2303 movs r3, #3 + 800ab24: 6243 str r3, [r0, #36] ; 0x24 + __HAL_UNLOCK(hhash); + 800ab26: 2200 movs r2, #0 + 800ab28: f880 2034 strb.w r2, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800ab2c: 6a23 ldr r3, [r4, #32] + 800ab2e: f043 0303 orr.w r3, r3, #3 + 800ab32: e7d9 b.n 800aae8 + __HAL_HASH_SET_NBVALIDBITS(SizeVar); + 800ab34: 68a2 ldr r2, [r4, #8] + 800ab36: f022 021f bic.w r2, r2, #31 + 800ab3a: 432a orrs r2, r5 + 800ab3c: 60a2 str r2, [r4, #8] + HASH->DIN = *(uint32_t*)inputaddr; + 800ab3e: 9a01 ldr r2, [sp, #4] + 800ab40: 6812 ldr r2, [r2, #0] + 800ab42: 6062 str r2, [r4, #4] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800ab44: 6103 str r3, [r0, #16] + __HAL_HASH_START_DIGEST(); + 800ab46: 68a3 ldr r3, [r4, #8] + 800ab48: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800ab4c: 60a3 str r3, [r4, #8] + __HAL_UNLOCK(hhash); + 800ab4e: f880 1034 strb.w r1, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DCI); + 800ab52: 6a23 ldr r3, [r4, #32] + 800ab54: f043 0302 orr.w r3, r3, #2 + 800ab58: 6223 str r3, [r4, #32] + return HAL_OK; + 800ab5a: 460a mov r2, r1 + 800ab5c: e785 b.n 800aa6a + return HAL_BUSY; + 800ab5e: 2202 movs r2, #2 + 800ab60: e783 b.n 800aa6a + 800ab62: 4622 mov r2, r4 + 800ab64: e781 b.n 800aa6a + 800ab66: bf00 nop + 800ab68: 50060400 .word 0x50060400 + +0800ab6c : +{ + 800ab6c: b513 push {r0, r1, r4, lr} + return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer,HASH_ALGOSELECTION_MD5); + 800ab6e: 2480 movs r4, #128 ; 0x80 + 800ab70: 9400 str r4, [sp, #0] + 800ab72: f7ff ff6b bl 800aa4c +} + 800ab76: b002 add sp, #8 + 800ab78: bd10 pop {r4, pc} + +0800ab7a : + 800ab7a: f7ff bff7 b.w 800ab6c + +0800ab7e : +{ + 800ab7e: b513 push {r0, r1, r4, lr} + return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer,HASH_ALGOSELECTION_SHA1); + 800ab80: 2400 movs r4, #0 + 800ab82: 9400 str r4, [sp, #0] + 800ab84: f7ff ff62 bl 800aa4c +} + 800ab88: b002 add sp, #8 + 800ab8a: bd10 pop {r4, pc} + +0800ab8c : + 800ab8c: f7ff bff7 b.w 800ab7e + +0800ab90 : + * @param pOutBuffer pointer to the computed digest. + * @param Timeout Timeout value. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 800ab90: b570 push {r4, r5, r6, lr} + 800ab92: 4613 mov r3, r2 + + if(hhash->State == HAL_HASH_STATE_READY) + 800ab94: f890 2035 ldrb.w r2, [r0, #53] ; 0x35 + 800ab98: 2a01 cmp r2, #1 +{ + 800ab9a: 4605 mov r5, r0 + 800ab9c: 460e mov r6, r1 + if(hhash->State == HAL_HASH_STATE_READY) + 800ab9e: b2d4 uxtb r4, r2 + 800aba0: d12f bne.n 800ac02 + { + /* Check parameter */ + if (pOutBuffer == NULL) + 800aba2: b341 cbz r1, 800abf6 + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hhash); + 800aba4: f890 2034 ldrb.w r2, [r0, #52] ; 0x34 + 800aba8: 2a01 cmp r2, #1 + 800abaa: f04f 0102 mov.w r1, #2 + 800abae: d028 beq.n 800ac02 + 800abb0: f880 4034 strb.w r4, [r0, #52] ; 0x34 + + /* Change the HASH state to busy */ + hhash->State = HAL_HASH_STATE_BUSY; + 800abb4: f880 1035 strb.w r1, [r0, #53] ; 0x35 + + /* Wait for DCIS flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800abb8: 2200 movs r2, #0 + 800abba: f7ff fc3b bl 800a434 + 800abbe: 4604 mov r4, r0 + 800abc0: bb08 cbnz r0, 800ac06 + { + return HAL_TIMEOUT; + } + + /* Read the message digest */ + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800abc2: 4a12 ldr r2, [pc, #72] ; (800ac0c ) + 800abc4: 4b12 ldr r3, [pc, #72] ; (800ac10 ) + 800abc6: 6811 ldr r1, [r2, #0] + 800abc8: 4219 tst r1, r3 + 800abca: d016 beq.n 800abfa + 800abcc: 6811 ldr r1, [r2, #0] + 800abce: 4019 ands r1, r3 + 800abd0: f5b1 2f80 cmp.w r1, #262144 ; 0x40000 + 800abd4: d013 beq.n 800abfe + 800abd6: 6812 ldr r2, [r2, #0] + 800abd8: 4393 bics r3, r2 + 800abda: bf0c ite eq + 800abdc: 2120 moveq r1, #32 + 800abde: 2110 movne r1, #16 + 800abe0: 4630 mov r0, r6 + 800abe2: f7ff fbc5 bl 800a370 + + /* Change the HASH state to ready */ + hhash->State = HAL_HASH_STATE_READY; + 800abe6: 2301 movs r3, #1 + 800abe8: f885 3035 strb.w r3, [r5, #53] ; 0x35 + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + 800abec: f885 302d strb.w r3, [r5, #45] ; 0x2d + + /* Process UnLock */ + __HAL_UNLOCK(hhash); + 800abf0: 2300 movs r3, #0 + 800abf2: f885 3034 strb.w r3, [r5, #52] ; 0x34 + else + { + return HAL_BUSY; + } + +} + 800abf6: 4620 mov r0, r4 + 800abf8: bd70 pop {r4, r5, r6, pc} + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800abfa: 2114 movs r1, #20 + 800abfc: e7f0 b.n 800abe0 + 800abfe: 211c movs r1, #28 + 800ac00: e7ee b.n 800abe0 + return HAL_BUSY; + 800ac02: 2402 movs r4, #2 + 800ac04: e7f7 b.n 800abf6 + return HAL_TIMEOUT; + 800ac06: 2403 movs r4, #3 + 800ac08: e7f5 b.n 800abf6 + 800ac0a: bf00 nop + 800ac0c: 50060400 .word 0x50060400 + 800ac10: 00040080 .word 0x00040080 + +0800ac14 : + * @param Timeout Timeout value. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HMAC_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout, uint32_t Algorithm) +{ + 800ac14: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800ac18: 4604 mov r4, r0 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ac1a: f890 0035 ldrb.w r0, [r0, #53] ; 0x35 + + /* If State is ready or suspended, start or resume polling-based HASH processing */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800ac1e: 2801 cmp r0, #1 +{ + 800ac20: e9dd 7e06 ldrd r7, lr, [sp, #24] + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ac24: b2c5 uxtb r5, r0 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800ac26: d002 beq.n 800ac2e + 800ac28: 2d08 cmp r5, #8 + 800ac2a: f040 80df bne.w 800adec + { + /* Check input parameters */ + if ((pInBuffer == NULL) || /*(Size == 0U) ||*/ (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) || (pOutBuffer == NULL)) + 800ac2e: b139 cbz r1, 800ac40 + 800ac30: f8d4 c008 ldr.w ip, [r4, #8] + 800ac34: f1bc 0f00 cmp.w ip, #0 + 800ac38: d002 beq.n 800ac40 + 800ac3a: 6865 ldr r5, [r4, #4] + 800ac3c: b105 cbz r5, 800ac40 + 800ac3e: b923 cbnz r3, 800ac4a + { + hhash->State = HAL_HASH_STATE_READY; + 800ac40: 2001 movs r0, #1 + 800ac42: f884 0035 strb.w r0, [r4, #53] ; 0x35 + return HMAC_Processing(hhash, Timeout); + + } + else + { + return HAL_BUSY; + 800ac46: 4605 mov r5, r0 + 800ac48: e05b b.n 800ad02 + __HAL_LOCK(hhash); + 800ac4a: f894 0034 ldrb.w r0, [r4, #52] ; 0x34 + 800ac4e: 2801 cmp r0, #1 + 800ac50: f04f 0002 mov.w r0, #2 + 800ac54: d0f7 beq.n 800ac46 + hhash->State = HAL_HASH_STATE_BUSY; + 800ac56: f884 0035 strb.w r0, [r4, #53] ; 0x35 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ac5a: f894 002d ldrb.w r0, [r4, #45] ; 0x2d + __HAL_LOCK(hhash); + 800ac5e: 2601 movs r6, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ac60: 42b0 cmp r0, r6 + __HAL_LOCK(hhash); + 800ac62: f884 6034 strb.w r6, [r4, #52] ; 0x34 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ac66: d118 bne.n 800ac9a + if(hhash->Init.KeySize > 64U) + 800ac68: 4e61 ldr r6, [pc, #388] ; (800adf0 ) + 800ac6a: f8df 818c ldr.w r8, [pc, #396] ; 800adf8 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + 800ac6e: 6830 ldr r0, [r6, #0] + 800ac70: ea00 0008 and.w r0, r0, r8 + 800ac74: ea40 000e orr.w r0, r0, lr + if(hhash->Init.KeySize > 64U) + 800ac78: 2d40 cmp r5, #64 ; 0x40 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + 800ac7a: bf88 it hi + 800ac7c: f440 3080 orrhi.w r0, r0, #65536 ; 0x10000 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT); + 800ac80: f040 0044 orr.w r0, r0, #68 ; 0x44 + 800ac84: 6030 str r0, [r6, #0] + hhash->pHashInBuffPtr = pInBuffer; /* Input data address, HMAC_Processing input parameter for Step 2 */ + 800ac86: e9c4 1303 strd r1, r3, [r4, #12] + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + 800ac8a: 2003 movs r0, #3 + hhash->HashInCount = Size; /* Input data size, HMAC_Processing input parameter for Step 2 */ + 800ac8c: 6222 str r2, [r4, #32] + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + 800ac8e: f884 002d strb.w r0, [r4, #45] ; 0x2d + hhash->HashBuffSize = Size; /* Store the input buffer size for the whole HMAC process */ + 800ac92: 61e2 str r2, [r4, #28] + hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address, HMAC_Processing input parameter for Step 1 and Step 3 */ + 800ac94: f8c4 c014 str.w ip, [r4, #20] + hhash->HashKeyCount = hhash->Init.KeySize; /* Key size, HMAC_Processing input parameter for Step 1 and Step 3 */ + 800ac98: 62a5 str r5, [r4, #40] ; 0x28 + if ((hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_1) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_2) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_3)) + 800ac9a: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + 800ac9e: 1eda subs r2, r3, #3 + 800aca0: 2a02 cmp r2, #2 + 800aca2: d906 bls.n 800acb2 + hhash->State = HAL_HASH_STATE_READY; + 800aca4: 2001 movs r0, #1 + __HAL_UNLOCK(hhash); + 800aca6: 2300 movs r3, #0 + hhash->State = HAL_HASH_STATE_READY; + 800aca8: f884 0035 strb.w r0, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800acac: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_ERROR; + 800acb0: e7c9 b.n 800ac46 + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) + 800acb2: 2b03 cmp r3, #3 + 800acb4: 4e4e ldr r6, [pc, #312] ; (800adf0 ) + 800acb6: d155 bne.n 800ad64 + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800acb8: 68b3 ldr r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800acba: 6961 ldr r1, [r4, #20] + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800acbc: f023 031f bic.w r3, r3, #31 + 800acc0: f005 0503 and.w r5, r5, #3 + 800acc4: ea43 05c5 orr.w r5, r3, r5, lsl #3 + 800acc8: 60b5 str r5, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800acca: 6aa2 ldr r2, [r4, #40] ; 0x28 + 800accc: 4620 mov r0, r4 + 800acce: f7ff fb0f bl 800a2f0 + 800acd2: 4605 mov r5, r0 + 800acd4: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800acd8: b998 cbnz r0, 800ad02 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800acda: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800acde: 2b08 cmp r3, #8 + 800ace0: d103 bne.n 800acea + __HAL_UNLOCK(hhash); + 800ace2: 2000 movs r0, #0 + 800ace4: f884 0034 strb.w r0, [r4, #52] ; 0x34 + return HAL_OK; + 800ace8: e7ad b.n 800ac46 + __HAL_HASH_START_DIGEST(); + 800acea: 68b3 ldr r3, [r6, #8] + 800acec: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800acf0: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + 800acf2: 2201 movs r2, #1 + 800acf4: 463b mov r3, r7 + 800acf6: 2108 movs r1, #8 + 800acf8: 4620 mov r0, r4 + 800acfa: f7ff fb9b bl 800a434 + 800acfe: b118 cbz r0, 800ad08 + return HAL_TIMEOUT; + 800ad00: 2503 movs r5, #3 + } +} + 800ad02: 4628 mov r0, r5 + 800ad04: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; + 800ad08: 2304 movs r3, #4 + 800ad0a: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); + 800ad0e: 68b3 ldr r3, [r6, #8] + 800ad10: 69e2 ldr r2, [r4, #28] + hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount); + 800ad12: 68e1 ldr r1, [r4, #12] + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); + 800ad14: f002 0203 and.w r2, r2, #3 + 800ad18: f023 031f bic.w r3, r3, #31 + 800ad1c: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 800ad20: 60b3 str r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount); + 800ad22: 6a22 ldr r2, [r4, #32] + 800ad24: 4620 mov r0, r4 + 800ad26: f7ff fae3 bl 800a2f0 + 800ad2a: 4605 mov r5, r0 + 800ad2c: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800ad30: 2800 cmp r0, #0 + 800ad32: d1e6 bne.n 800ad02 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800ad34: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800ad38: 2b08 cmp r3, #8 + 800ad3a: d0d2 beq.n 800ace2 + __HAL_HASH_START_DIGEST(); + 800ad3c: 68b3 ldr r3, [r6, #8] + 800ad3e: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800ad42: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + 800ad44: 2201 movs r2, #1 + 800ad46: 463b mov r3, r7 + 800ad48: 2108 movs r1, #8 + 800ad4a: 4620 mov r0, r4 + 800ad4c: f7ff fb72 bl 800a434 + 800ad50: 2800 cmp r0, #0 + 800ad52: d1d5 bne.n 800ad00 + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; + 800ad54: 2305 movs r3, #5 + 800ad56: f884 302d strb.w r3, [r4, #45] ; 0x2d + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + 800ad5a: 68a3 ldr r3, [r4, #8] + 800ad5c: 6163 str r3, [r4, #20] + hhash->HashKeyCount = hhash->Init.KeySize; + 800ad5e: 6863 ldr r3, [r4, #4] + 800ad60: 62a3 str r3, [r4, #40] ; 0x28 + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3) + 800ad62: e001 b.n 800ad68 + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) + 800ad64: 2b04 cmp r3, #4 + 800ad66: d0d2 beq.n 800ad0e + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800ad68: 68b3 ldr r3, [r6, #8] + 800ad6a: 6862 ldr r2, [r4, #4] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800ad6c: 6961 ldr r1, [r4, #20] + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800ad6e: f002 0203 and.w r2, r2, #3 + 800ad72: f023 031f bic.w r3, r3, #31 + 800ad76: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 800ad7a: 60b3 str r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800ad7c: 6aa2 ldr r2, [r4, #40] ; 0x28 + 800ad7e: 4620 mov r0, r4 + 800ad80: f7ff fab6 bl 800a2f0 + 800ad84: 4605 mov r5, r0 + 800ad86: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800ad8a: 2800 cmp r0, #0 + 800ad8c: d1b9 bne.n 800ad02 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800ad8e: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800ad92: 2b08 cmp r3, #8 + 800ad94: d0a5 beq.n 800ace2 + __HAL_HASH_START_DIGEST(); + 800ad96: 68b3 ldr r3, [r6, #8] + 800ad98: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800ad9c: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800ad9e: 4602 mov r2, r0 + 800ada0: 463b mov r3, r7 + 800ada2: 2102 movs r1, #2 + 800ada4: 4620 mov r0, r4 + 800ada6: f7ff fb45 bl 800a434 + 800adaa: 4605 mov r5, r0 + 800adac: 2800 cmp r0, #0 + 800adae: d1a7 bne.n 800ad00 + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800adb0: 6832 ldr r2, [r6, #0] + 800adb2: 4b10 ldr r3, [pc, #64] ; (800adf4 ) + 800adb4: 6920 ldr r0, [r4, #16] + 800adb6: 421a tst r2, r3 + 800adb8: d014 beq.n 800ade4 + 800adba: 6832 ldr r2, [r6, #0] + 800adbc: 401a ands r2, r3 + 800adbe: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800adc2: d011 beq.n 800ade8 + 800adc4: 6832 ldr r2, [r6, #0] + 800adc6: 4393 bics r3, r2 + 800adc8: bf0c ite eq + 800adca: 2120 moveq r1, #32 + 800adcc: 2110 movne r1, #16 + 800adce: f7ff facf bl 800a370 + hhash->Phase = HAL_HASH_PHASE_READY; + 800add2: 2301 movs r3, #1 + 800add4: f884 302d strb.w r3, [r4, #45] ; 0x2d + hhash->State = HAL_HASH_STATE_READY; + 800add8: f884 3035 strb.w r3, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800addc: 2300 movs r3, #0 + 800adde: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800ade2: e78e b.n 800ad02 + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800ade4: 2114 movs r1, #20 + 800ade6: e7f2 b.n 800adce + 800ade8: 211c movs r1, #28 + 800adea: e7f0 b.n 800adce + return HAL_BUSY; + 800adec: 2502 movs r5, #2 + 800adee: e788 b.n 800ad02 + 800adf0: 50060400 .word 0x50060400 + 800adf4: 00040080 .word 0x00040080 + 800adf8: fffaff3b .word 0xfffaff3b + +0800adfc : + * @param Tickstart : Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, + FlagStatus State, uint32_t Tickstart, uint32_t Timeout) +{ + 800adfc: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800ae00: f8dd 8018 ldr.w r8, [sp, #24] + 800ae04: 4604 mov r4, r0 + 800ae06: 460e mov r6, r1 + 800ae08: 4615 mov r5, r2 + 800ae0a: 461f mov r7, r3 + /* Wait until flag is in expected state */ + while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State) + 800ae0c: 6822 ldr r2, [r4, #0] + 800ae0e: 6a13 ldr r3, [r2, #32] + 800ae10: 4233 tst r3, r6 + 800ae12: bf14 ite ne + 800ae14: 2301 movne r3, #1 + 800ae16: 2300 moveq r3, #0 + 800ae18: 42ab cmp r3, r5 + 800ae1a: d101 bne.n 800ae20 + + return HAL_ERROR; + } + } + } + return HAL_OK; + 800ae1c: 2000 movs r0, #0 + 800ae1e: e012 b.n 800ae46 + if (Timeout != HAL_MAX_DELAY) + 800ae20: f1b8 3fff cmp.w r8, #4294967295 ; 0xffffffff + 800ae24: d0f3 beq.n 800ae0e + if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800ae26: f7fc f961 bl 80070ec + 800ae2a: 1bc0 subs r0, r0, r7 + 800ae2c: 4540 cmp r0, r8 + 800ae2e: d802 bhi.n 800ae36 + 800ae30: f1b8 0f00 cmp.w r8, #0 + 800ae34: d1ea bne.n 800ae0c + hospi->State = HAL_OSPI_STATE_ERROR; + 800ae36: f44f 7300 mov.w r3, #512 ; 0x200 + 800ae3a: 6463 str r3, [r4, #68] ; 0x44 + hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT; + 800ae3c: 6ca3 ldr r3, [r4, #72] ; 0x48 + 800ae3e: f043 0301 orr.w r3, r3, #1 + 800ae42: 64a3 str r3, [r4, #72] ; 0x48 + 800ae44: 2001 movs r0, #1 +} + 800ae46: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +0800ae4a : +} + 800ae4a: 4770 bx lr + +0800ae4c : +{ + 800ae4c: b5f0 push {r4, r5, r6, r7, lr} + 800ae4e: b085 sub sp, #20 + 800ae50: 4604 mov r4, r0 + uint32_t tickstart = HAL_GetTick(); + 800ae52: f7fc f94b bl 80070ec + 800ae56: 4603 mov r3, r0 + if (hospi == NULL) + 800ae58: 2c00 cmp r4, #0 + 800ae5a: d05d beq.n 800af18 + hospi->ErrorCode = HAL_OSPI_ERROR_NONE; + 800ae5c: 2000 movs r0, #0 + 800ae5e: 64a0 str r0, [r4, #72] ; 0x48 + if (hospi->State == HAL_OSPI_STATE_RESET) + 800ae60: 6c66 ldr r6, [r4, #68] ; 0x44 + 800ae62: 2e00 cmp r6, #0 + 800ae64: d156 bne.n 800af14 + HAL_OSPI_MspInit(hospi); + 800ae66: 4620 mov r0, r4 + 800ae68: 9303 str r3, [sp, #12] + 800ae6a: f7ff ffee bl 800ae4a + MODIFY_REG(hospi->Instance->DCR1, + 800ae6e: 6b20 ldr r0, [r4, #48] ; 0x30 + 800ae70: 68e1 ldr r1, [r4, #12] + 800ae72: 6825 ldr r5, [r4, #0] + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800ae74: 9b03 ldr r3, [sp, #12] + MODIFY_REG(hospi->Instance->DCR1, + 800ae76: 68af ldr r7, [r5, #8] + 800ae78: 4301 orrs r1, r0 + 800ae7a: 69e0 ldr r0, [r4, #28] + 800ae7c: 4301 orrs r1, r0 + 800ae7e: 4827 ldr r0, [pc, #156] ; (800af1c ) + 800ae80: 4038 ands r0, r7 + 800ae82: 4301 orrs r1, r0 + 800ae84: 6920 ldr r0, [r4, #16] + 800ae86: 3801 subs r0, #1 + 800ae88: ea41 4100 orr.w r1, r1, r0, lsl #16 + 800ae8c: 6960 ldr r0, [r4, #20] + 800ae8e: 3801 subs r0, #1 + hospi->Timeout = Timeout; + 800ae90: f241 3288 movw r2, #5000 ; 0x1388 + MODIFY_REG(hospi->Instance->DCR1, + 800ae94: ea41 2100 orr.w r1, r1, r0, lsl #8 + hospi->Timeout = Timeout; + 800ae98: 64e2 str r2, [r4, #76] ; 0x4c + MODIFY_REG(hospi->Instance->DCR1, + 800ae9a: 60a9 str r1, [r5, #8] + hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos); + 800ae9c: 6ae1 ldr r1, [r4, #44] ; 0x2c + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos)); + 800ae9e: 6860 ldr r0, [r4, #4] + hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos); + 800aea0: 0409 lsls r1, r1, #16 + 800aea2: 6129 str r1, [r5, #16] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos)); + 800aea4: 6829 ldr r1, [r5, #0] + 800aea6: 3801 subs r0, #1 + 800aea8: f421 51f8 bic.w r1, r1, #7936 ; 0x1f00 + 800aeac: ea41 2100 orr.w r1, r1, r0, lsl #8 + 800aeb0: 6029 str r1, [r5, #0] + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800aeb2: 4620 mov r0, r4 + 800aeb4: 9200 str r2, [sp, #0] + 800aeb6: 2120 movs r1, #32 + 800aeb8: 4632 mov r2, r6 + 800aeba: f7ff ff9f bl 800adfc + if (status == HAL_OK) + 800aebe: bb48 cbnz r0, 800af14 + MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos)); + 800aec0: 6823 ldr r3, [r4, #0] + 800aec2: 6a22 ldr r2, [r4, #32] + 800aec4: 68d9 ldr r1, [r3, #12] + 800aec6: 3a01 subs r2, #1 + 800aec8: f021 01ff bic.w r1, r1, #255 ; 0xff + 800aecc: 430a orrs r2, r1 + 800aece: 60da str r2, [r3, #12] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad); + 800aed0: 681a ldr r2, [r3, #0] + 800aed2: 68a1 ldr r1, [r4, #8] + 800aed4: f022 0240 bic.w r2, r2, #64 ; 0x40 + 800aed8: 430a orrs r2, r1 + 800aeda: 601a str r2, [r3, #0] + MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle)); + 800aedc: e9d4 2509 ldrd r2, r5, [r4, #36] ; 0x24 + 800aee0: f8d3 1108 ldr.w r1, [r3, #264] ; 0x108 + 800aee4: 432a orrs r2, r5 + 800aee6: f021 41a0 bic.w r1, r1, #1342177280 ; 0x50000000 + 800aeea: 430a orrs r2, r1 + 800aeec: f8c3 2108 str.w r2, [r3, #264] ; 0x108 + __HAL_OSPI_ENABLE(hospi); + 800aef0: 681a ldr r2, [r3, #0] + 800aef2: f042 0201 orr.w r2, r2, #1 + 800aef6: 601a str r2, [r3, #0] + if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE) + 800aef8: 69a2 ldr r2, [r4, #24] + 800aefa: 2a02 cmp r2, #2 + SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK); + 800aefc: bf02 ittt eq + 800aefe: 689a ldreq r2, [r3, #8] + 800af00: f042 0202 orreq.w r2, r2, #2 + 800af04: 609a streq r2, [r3, #8] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800af06: 68e3 ldr r3, [r4, #12] + 800af08: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT; + 800af0c: bf0c ite eq + 800af0e: 2301 moveq r3, #1 + hospi->State = HAL_OSPI_STATE_READY; + 800af10: 2302 movne r3, #2 + 800af12: 6463 str r3, [r4, #68] ; 0x44 +} + 800af14: b005 add sp, #20 + 800af16: bdf0 pop {r4, r5, r6, r7, pc} + status = HAL_ERROR; + 800af18: 2001 movs r0, #1 + 800af1a: e7fb b.n 800af14 + 800af1c: f8e0f8f4 .word 0xf8e0f8f4 + +0800af20 : +{ + 800af20: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800af24: 4605 mov r5, r0 + 800af26: b085 sub sp, #20 + 800af28: 460c mov r4, r1 + 800af2a: 9202 str r2, [sp, #8] + uint32_t tickstart = HAL_GetTick(); + 800af2c: f7fc f8de bl 80070ec + state = hospi->State; + 800af30: 6c6a ldr r2, [r5, #68] ; 0x44 + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800af32: 2a02 cmp r2, #2 + uint32_t tickstart = HAL_GetTick(); + 800af34: ee07 0a90 vmov s15, r0 + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800af38: d105 bne.n 800af46 + 800af3a: 68ea ldr r2, [r5, #12] + 800af3c: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + 800af40: d107 bne.n 800af52 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800af42: 2310 movs r3, #16 + 800af44: e109 b.n 800b15a + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800af46: 2a14 cmp r2, #20 + 800af48: f040 8084 bne.w 800b054 + ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) || + 800af4c: 6822 ldr r2, [r4, #0] + 800af4e: 2a02 cmp r2, #2 + ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG))) + 800af50: d1f7 bne.n 800af42 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); + 800af52: 9a02 ldr r2, [sp, #8] + 800af54: 9200 str r2, [sp, #0] + 800af56: ee17 3a90 vmov r3, s15 + 800af5a: 2200 movs r2, #0 + 800af5c: 2120 movs r1, #32 + 800af5e: 4628 mov r0, r5 + 800af60: edcd 7a03 vstr s15, [sp, #12] + 800af64: f7ff ff4a bl 800adfc + if (status == HAL_OK) + 800af68: eddd 7a03 vldr s15, [sp, #12] + 800af6c: 2800 cmp r0, #0 + 800af6e: f040 80b9 bne.w 800b0e4 +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *ccr_reg, *tcr_reg, *ir_reg, *abr_reg; + + /* Re-initialize the value of the functional mode */ + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); + 800af72: 6829 ldr r1, [r5, #0] + hospi->ErrorCode = HAL_OSPI_ERROR_NONE; + 800af74: 64a8 str r0, [r5, #72] ; 0x48 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); + 800af76: 680a ldr r2, [r1, #0] + 800af78: f022 5240 bic.w r2, r2, #805306368 ; 0x30000000 + 800af7c: 600a str r2, [r1, #0] + + /* Configure the flash ID */ + if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE) + 800af7e: 68aa ldr r2, [r5, #8] + 800af80: b92a cbnz r2, 800af8e + { + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId); + 800af82: 680a ldr r2, [r1, #0] + 800af84: 6866 ldr r6, [r4, #4] + 800af86: f022 0280 bic.w r2, r2, #128 ; 0x80 + 800af8a: 4332 orrs r2, r6 + 800af8c: 600a str r2, [r1, #0] + } + + if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) + 800af8e: 6822 ldr r2, [r4, #0] + ir_reg = &(hospi->Instance->IR); + abr_reg = &(hospi->Instance->ABR); + } + + /* Configure the CCR register with DQS and SIOO modes */ + *ccr_reg = (cmd->DQSMode | cmd->SIOOMode); + 800af90: e9d4 6712 ldrd r6, r7, [r4, #72] ; 0x48 + if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) + 800af94: 2a02 cmp r2, #2 + ccr_reg = &(hospi->Instance->WCCR); + 800af96: bf0c ite eq + 800af98: f501 72c0 addeq.w r2, r1, #384 ; 0x180 + ccr_reg = &(hospi->Instance->CCR); + 800af9c: f501 7280 addne.w r2, r1, #256 ; 0x100 + *ccr_reg = (cmd->DQSMode | cmd->SIOOMode); + 800afa0: ea46 0607 orr.w r6, r6, r7 + 800afa4: 6016 str r6, [r2, #0] + + if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) + 800afa6: 6ae6 ldr r6, [r4, #44] ; 0x2c + tcr_reg = &(hospi->Instance->WTCR); + 800afa8: bf03 ittte eq + 800afaa: f501 7cc4 addeq.w ip, r1, #392 ; 0x188 + ir_reg = &(hospi->Instance->WIR); + 800afae: f501 7ec8 addeq.w lr, r1, #400 ; 0x190 + abr_reg = &(hospi->Instance->WABR); + 800afb2: f501 78d0 addeq.w r8, r1, #416 ; 0x1a0 + tcr_reg = &(hospi->Instance->TCR); + 800afb6: f501 7c84 addne.w ip, r1, #264 ; 0x108 + ir_reg = &(hospi->Instance->IR); + 800afba: bf1c itt ne + 800afbc: f501 7e88 addne.w lr, r1, #272 ; 0x110 + abr_reg = &(hospi->Instance->ABR); + 800afc0: f501 7890 addne.w r8, r1, #288 ; 0x120 + if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) + 800afc4: b16e cbz r6, 800afe2 + { + /* Configure the ABR register with alternate bytes value */ + *abr_reg = cmd->AlternateBytes; + 800afc6: 6aa6 ldr r6, [r4, #40] ; 0x28 + 800afc8: f8c8 6000 str.w r6, [r8] + + /* Configure the CCR register with alternate bytes communication parameters */ + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE), + 800afcc: 6ae3 ldr r3, [r4, #44] ; 0x2c + 800afce: 6b67 ldr r7, [r4, #52] ; 0x34 + 800afd0: 6816 ldr r6, [r2, #0] + 800afd2: 431f orrs r7, r3 + 800afd4: 6b23 ldr r3, [r4, #48] ; 0x30 + 800afd6: f426 187c bic.w r8, r6, #4128768 ; 0x3f0000 + 800afda: 431f orrs r7, r3 + 800afdc: ea47 0708 orr.w r7, r7, r8 + 800afe0: 6017 str r7, [r2, #0] + (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize)); + } + + /* Configure the TCR register with the number of dummy cycles */ + MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles); + 800afe2: f8dc 7000 ldr.w r7, [ip] + 800afe6: 6c66 ldr r6, [r4, #68] ; 0x44 + 800afe8: f027 071f bic.w r7, r7, #31 + 800afec: 433e orrs r6, r7 + 800afee: f8cc 6000 str.w r6, [ip] + + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800aff2: f8d4 c038 ldr.w ip, [r4, #56] ; 0x38 + 800aff6: f1bc 0f00 cmp.w ip, #0 + 800affa: d004 beq.n 800b006 + { + if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) + 800affc: 6827 ldr r7, [r4, #0] + 800affe: b917 cbnz r7, 800b006 + { + /* Configure the DLR register with the number of data */ + hospi->Instance->DLR = (cmd->NbData - 1U); + 800b000: 6be7 ldr r7, [r4, #60] ; 0x3c + 800b002: 3f01 subs r7, #1 + 800b004: 640f str r7, [r1, #64] ; 0x40 + } + } + + if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) + 800b006: 68e6 ldr r6, [r4, #12] + { + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b008: 69e7 ldr r7, [r4, #28] + if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) + 800b00a: 2e00 cmp r6, #0 + 800b00c: f000 8082 beq.w 800b114 + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + { + /* ---- Command with instruction, address and data ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b010: e9d4 8904 ldrd r8, r9, [r4, #16] + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b014: 2f00 cmp r7, #0 + 800b016: d040 beq.n 800b09a + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b018: e9d4 ab08 ldrd sl, fp, [r4, #32] + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b01c: f1bc 0f00 cmp.w ip, #0 + 800b020: d01e beq.n 800b060 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b022: ea4c 0606 orr.w r6, ip, r6 + 800b026: 433e orrs r6, r7 + 800b028: ea46 0909 orr.w r9, r6, r9 + 800b02c: ea49 0808 orr.w r8, r9, r8 + 800b030: 6813 ldr r3, [r2, #0] + 800b032: 6c26 ldr r6, [r4, #64] ; 0x40 + 800b034: 4f52 ldr r7, [pc, #328] ; (800b180 ) + 800b036: ea48 0b0b orr.w fp, r8, fp + 800b03a: ea4b 0b0a orr.w fp, fp, sl + 800b03e: ea4b 0606 orr.w r6, fp, r6 + 800b042: 401f ands r7, r3 + 800b044: 433e orrs r6, r7 + + /* The DHQC bit is linked with DDTR bit which should be activated */ + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE)) + { + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b046: 6016 str r6, [r2, #0] + } + } + + /* Configure the IR register with the instruction value */ + *ir_reg = cmd->Instruction; + 800b048: 68a2 ldr r2, [r4, #8] + 800b04a: f8ce 2000 str.w r2, [lr] + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), + (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize)); + } + + /* Configure the AR register with the instruction value */ + hospi->Instance->AR = cmd->Address; + 800b04e: 69a2 ldr r2, [r4, #24] + 800b050: 648a str r2, [r1, #72] ; 0x48 + if (status == HAL_OK) + 800b052: e038 b.n 800b0c6 + ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) || + 800b054: 2a24 cmp r2, #36 ; 0x24 + 800b056: f47f af74 bne.w 800af42 + ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG))) + 800b05a: 6822 ldr r2, [r4, #0] + 800b05c: 2a01 cmp r2, #1 + 800b05e: e777 b.n 800af50 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b060: 433e orrs r6, r7 + 800b062: f8d2 c000 ldr.w ip, [r2] + 800b066: ea46 0609 orr.w r6, r6, r9 + 800b06a: ea46 0608 orr.w r6, r6, r8 + 800b06e: ea46 060b orr.w r6, r6, fp + 800b072: f42c 5c7c bic.w ip, ip, #16128 ; 0x3f00 + 800b076: ea46 060a orr.w r6, r6, sl + 800b07a: f02c 0c3f bic.w ip, ip, #63 ; 0x3f + 800b07e: ea46 060c orr.w r6, r6, ip + 800b082: 6016 str r6, [r2, #0] + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + 800b084: 6aae ldr r6, [r5, #40] ; 0x28 + 800b086: f1b6 5f80 cmp.w r6, #268435456 ; 0x10000000 + 800b08a: d1dd bne.n 800b048 + 800b08c: 6966 ldr r6, [r4, #20] + 800b08e: 2e08 cmp r6, #8 + 800b090: d1da bne.n 800b048 + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b092: 6816 ldr r6, [r2, #0] + 800b094: f046 6600 orr.w r6, r6, #134217728 ; 0x8000000 + 800b098: e7d5 b.n 800b046 + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b09a: f1bc 0f00 cmp.w ip, #0 + 800b09e: d024 beq.n 800b0ea + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b0a0: ea4c 0106 orr.w r1, ip, r6 + 800b0a4: 6817 ldr r7, [r2, #0] + 800b0a6: 6c26 ldr r6, [r4, #64] ; 0x40 + 800b0a8: ea41 0109 orr.w r1, r1, r9 + 800b0ac: ea41 0108 orr.w r1, r1, r8 + 800b0b0: f027 6a70 bic.w sl, r7, #251658240 ; 0xf000000 + 800b0b4: 4331 orrs r1, r6 + 800b0b6: f02a 0a3f bic.w sl, sl, #63 ; 0x3f + 800b0ba: ea41 010a orr.w r1, r1, sl + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b0be: 6011 str r1, [r2, #0] + *ir_reg = cmd->Instruction; + 800b0c0: 68a2 ldr r2, [r4, #8] + 800b0c2: f8ce 2000 str.w r2, [lr] + if (cmd->DataMode == HAL_OSPI_DATA_NONE) + 800b0c6: 6ba2 ldr r2, [r4, #56] ; 0x38 + 800b0c8: 2a00 cmp r2, #0 + 800b0ca: d149 bne.n 800b160 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); + 800b0cc: 9b02 ldr r3, [sp, #8] + 800b0ce: 9300 str r3, [sp, #0] + 800b0d0: 2201 movs r2, #1 + 800b0d2: ee17 3a90 vmov r3, s15 + 800b0d6: 2102 movs r1, #2 + 800b0d8: 4628 mov r0, r5 + 800b0da: f7ff fe8f bl 800adfc + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); + 800b0de: 682b ldr r3, [r5, #0] + 800b0e0: 2202 movs r2, #2 + 800b0e2: 625a str r2, [r3, #36] ; 0x24 +} + 800b0e4: b005 add sp, #20 + 800b0e6: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE), + 800b0ea: 6811 ldr r1, [r2, #0] + 800b0ec: ea46 0609 orr.w r6, r6, r9 + 800b0f0: ea46 0808 orr.w r8, r6, r8 + 800b0f4: f021 063f bic.w r6, r1, #63 ; 0x3f + 800b0f8: ea48 0606 orr.w r6, r8, r6 + 800b0fc: 6016 str r6, [r2, #0] + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + 800b0fe: 6aa9 ldr r1, [r5, #40] ; 0x28 + 800b100: f1b1 5f80 cmp.w r1, #268435456 ; 0x10000000 + 800b104: d1dc bne.n 800b0c0 + 800b106: 6961 ldr r1, [r4, #20] + 800b108: 2908 cmp r1, #8 + 800b10a: d1d9 bne.n 800b0c0 + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b10c: 6811 ldr r1, [r2, #0] + 800b10e: f041 6100 orr.w r1, r1, #134217728 ; 0x8000000 + 800b112: e7d4 b.n 800b0be + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b114: b307 cbz r7, 800b158 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b116: e9d4 9808 ldrd r9, r8, [r4, #32] + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b11a: f1bc 0f00 cmp.w ip, #0 + 800b11e: d011 beq.n 800b144 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE | + 800b120: f8d2 e000 ldr.w lr, [r2] + 800b124: 6c23 ldr r3, [r4, #64] ; 0x40 + 800b126: ea4c 0607 orr.w r6, ip, r7 + 800b12a: ea46 0608 orr.w r6, r6, r8 + 800b12e: ea46 0609 orr.w r6, r6, r9 + 800b132: f02e 6e70 bic.w lr, lr, #251658240 ; 0xf000000 + 800b136: 431e orrs r6, r3 + 800b138: f42e 5e7c bic.w lr, lr, #16128 ; 0x3f00 + 800b13c: ea46 060e orr.w r6, r6, lr + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), + 800b140: 6016 str r6, [r2, #0] + 800b142: e784 b.n 800b04e + 800b144: f8d2 c000 ldr.w ip, [r2] + 800b148: ea48 0607 orr.w r6, r8, r7 + 800b14c: ea46 0609 orr.w r6, r6, r9 + 800b150: f42c 577c bic.w r7, ip, #16128 ; 0x3f00 + 800b154: 433e orrs r6, r7 + 800b156: e7f3 b.n 800b140 + } + else + { + /* ---- Invalid command configuration (no instruction, no address) ---- */ + status = HAL_ERROR; + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; + 800b158: 2308 movs r3, #8 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b15a: 64ab str r3, [r5, #72] ; 0x48 + status = HAL_ERROR; + 800b15c: 2001 movs r0, #1 + 800b15e: e7c1 b.n 800b0e4 + if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) + 800b160: 6823 ldr r3, [r4, #0] + 800b162: b90b cbnz r3, 800b168 + hospi->State = HAL_OSPI_STATE_CMD_CFG; + 800b164: 2304 movs r3, #4 + 800b166: e005 b.n 800b174 + else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) + 800b168: 2b01 cmp r3, #1 + if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG) + 800b16a: 6c6b ldr r3, [r5, #68] ; 0x44 + else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) + 800b16c: d104 bne.n 800b178 + if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG) + 800b16e: 2b24 cmp r3, #36 ; 0x24 + 800b170: d0f8 beq.n 800b164 + hospi->State = HAL_OSPI_STATE_READ_CMD_CFG; + 800b172: 2314 movs r3, #20 + hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG; + 800b174: 646b str r3, [r5, #68] ; 0x44 + 800b176: e7b5 b.n 800b0e4 + if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG) + 800b178: 2b14 cmp r3, #20 + 800b17a: d0f3 beq.n 800b164 + hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG; + 800b17c: 2324 movs r3, #36 ; 0x24 + 800b17e: e7f9 b.n 800b174 + 800b180: f0ffc0c0 .word 0xf0ffc0c0 + +0800b184 : +{ + 800b184: b5f0 push {r4, r5, r6, r7, lr} + 800b186: 4604 mov r4, r0 + 800b188: b085 sub sp, #20 + 800b18a: 460f mov r7, r1 + 800b18c: 4616 mov r6, r2 + uint32_t tickstart = HAL_GetTick(); + 800b18e: f7fb ffad bl 80070ec + __IO uint32_t *data_reg = &hospi->Instance->DR; + 800b192: 6825 ldr r5, [r4, #0] + uint32_t tickstart = HAL_GetTick(); + 800b194: 4603 mov r3, r0 + uint32_t addr_reg = hospi->Instance->AR; + 800b196: 6ca8 ldr r0, [r5, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b198: f8d5 c110 ldr.w ip, [r5, #272] ; 0x110 + if (pData == NULL) + 800b19c: b91f cbnz r7, 800b1a6 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; + 800b19e: 2308 movs r3, #8 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b1a0: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b1a2: 2001 movs r0, #1 + 800b1a4: e034 b.n 800b210 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b1a6: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b1a8: 2a04 cmp r2, #4 + 800b1aa: d13b bne.n 800b224 + hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; + 800b1ac: 6c2a ldr r2, [r5, #64] ; 0x40 + hospi->pBuffPtr = pData; + 800b1ae: 6367 str r7, [r4, #52] ; 0x34 + hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; + 800b1b0: 3201 adds r2, #1 + 800b1b2: 63e2 str r2, [r4, #60] ; 0x3c + hospi->XferSize = hospi->XferCount; + 800b1b4: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b1b6: 63a2 str r2, [r4, #56] ; 0x38 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b1b8: 6829 ldr r1, [r5, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b1ba: 68e2 ldr r2, [r4, #12] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b1bc: f021 5140 bic.w r1, r1, #805306368 ; 0x30000000 + 800b1c0: f041 5180 orr.w r1, r1, #268435456 ; 0x10000000 + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b1c4: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b1c8: 6029 str r1, [r5, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b1ca: d123 bne.n 800b214 + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b1cc: 64a8 str r0, [r5, #72] ; 0x48 + status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout); + 800b1ce: 9600 str r6, [sp, #0] + 800b1d0: 2201 movs r2, #1 + 800b1d2: 2106 movs r1, #6 + 800b1d4: 4620 mov r0, r4 + 800b1d6: 9303 str r3, [sp, #12] + 800b1d8: f7ff fe10 bl 800adfc + if (status != HAL_OK) + 800b1dc: b9c0 cbnz r0, 800b210 + *hospi->pBuffPtr = *((__IO uint8_t *)data_reg); + 800b1de: 6b62 ldr r2, [r4, #52] ; 0x34 + 800b1e0: f895 1050 ldrb.w r1, [r5, #80] ; 0x50 + 800b1e4: 7011 strb r1, [r2, #0] + hospi->pBuffPtr++; + 800b1e6: 6b62 ldr r2, [r4, #52] ; 0x34 + } while(hospi->XferCount > 0U); + 800b1e8: 9b03 ldr r3, [sp, #12] + hospi->pBuffPtr++; + 800b1ea: 3201 adds r2, #1 + 800b1ec: 6362 str r2, [r4, #52] ; 0x34 + hospi->XferCount--; + 800b1ee: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b1f0: 3a01 subs r2, #1 + 800b1f2: 63e2 str r2, [r4, #60] ; 0x3c + } while(hospi->XferCount > 0U); + 800b1f4: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b1f6: 2a00 cmp r2, #0 + 800b1f8: d1e9 bne.n 800b1ce + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); + 800b1fa: 9600 str r6, [sp, #0] + 800b1fc: 2201 movs r2, #1 + 800b1fe: 2102 movs r1, #2 + 800b200: 4620 mov r0, r4 + 800b202: f7ff fdfb bl 800adfc + if (status == HAL_OK) + 800b206: b918 cbnz r0, 800b210 + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); + 800b208: 6822 ldr r2, [r4, #0] + 800b20a: 2302 movs r3, #2 + 800b20c: 6253 str r3, [r2, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_READY; + 800b20e: 6463 str r3, [r4, #68] ; 0x44 +} + 800b210: b005 add sp, #20 + 800b212: bdf0 pop {r4, r5, r6, r7, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b214: f8d5 2100 ldr.w r2, [r5, #256] ; 0x100 + 800b218: f412 6fe0 tst.w r2, #1792 ; 0x700 + 800b21c: d1d6 bne.n 800b1cc + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b21e: f8c5 c110 str.w ip, [r5, #272] ; 0x110 + 800b222: e7d4 b.n 800b1ce + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b224: 2310 movs r3, #16 + 800b226: e7bb b.n 800b1a0 + +0800b228 : +{ + 800b228: e92d 41ff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr} + 800b22c: 4604 mov r4, r0 + 800b22e: 4616 mov r6, r2 + 800b230: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800b232: f7fb ff5b bl 80070ec + uint32_t addr_reg = hospi->Instance->AR; + 800b236: 6822 ldr r2, [r4, #0] + 800b238: 6c97 ldr r7, [r2, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b23a: f8d2 8110 ldr.w r8, [r2, #272] ; 0x110 + if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE)) + 800b23e: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b240: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b242: 4603 mov r3, r0 + if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE)) + 800b244: d13c bne.n 800b2c0 + 800b246: 68ea ldr r2, [r5, #12] + 800b248: f5b2 0f80 cmp.w r2, #4194304 ; 0x400000 + 800b24c: d138 bne.n 800b2c0 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); + 800b24e: 9003 str r0, [sp, #12] + 800b250: 9600 str r6, [sp, #0] + 800b252: 2200 movs r2, #0 + 800b254: 2120 movs r1, #32 + 800b256: 4620 mov r0, r4 + 800b258: f7ff fdd0 bl 800adfc + if (status == HAL_OK) + 800b25c: bb28 cbnz r0, 800b2aa + WRITE_REG (hospi->Instance->PSMAR, cfg->Match); + 800b25e: 6822 ldr r2, [r4, #0] + 800b260: 6829 ldr r1, [r5, #0] + 800b262: f8c2 1088 str.w r1, [r2, #136] ; 0x88 + WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); + 800b266: 6869 ldr r1, [r5, #4] + 800b268: f8c2 1080 str.w r1, [r2, #128] ; 0x80 + WRITE_REG (hospi->Instance->PIR, cfg->Interval); + 800b26c: 6929 ldr r1, [r5, #16] + 800b26e: f8c2 1090 str.w r1, [r2, #144] ; 0x90 + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b272: e9d5 1502 ldrd r1, r5, [r5, #8] + 800b276: 6810 ldr r0, [r2, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b278: 9b03 ldr r3, [sp, #12] + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b27a: 4329 orrs r1, r5 + 800b27c: f020 5043 bic.w r0, r0, #817889280 ; 0x30c00000 + 800b280: 4301 orrs r1, r0 + 800b282: f041 5100 orr.w r1, r1, #536870912 ; 0x20000000 + 800b286: 6011 str r1, [r2, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b288: 68e1 ldr r1, [r4, #12] + 800b28a: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 800b28e: d10f bne.n 800b2b0 + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b290: 6497 str r7, [r2, #72] ; 0x48 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout); + 800b292: 9600 str r6, [sp, #0] + 800b294: 2201 movs r2, #1 + 800b296: 2108 movs r1, #8 + 800b298: 4620 mov r0, r4 + 800b29a: f7ff fdaf bl 800adfc + if (status == HAL_OK) + 800b29e: b920 cbnz r0, 800b2aa + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM); + 800b2a0: 6823 ldr r3, [r4, #0] + 800b2a2: 2208 movs r2, #8 + 800b2a4: 625a str r2, [r3, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_READY; + 800b2a6: 2302 movs r3, #2 + 800b2a8: 6463 str r3, [r4, #68] ; 0x44 +} + 800b2aa: b004 add sp, #16 + 800b2ac: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b2b0: f8d2 1100 ldr.w r1, [r2, #256] ; 0x100 + 800b2b4: f411 6fe0 tst.w r1, #1792 ; 0x700 + 800b2b8: d1ea bne.n 800b290 + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b2ba: f8c2 8110 str.w r8, [r2, #272] ; 0x110 + 800b2be: e7e8 b.n 800b292 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b2c0: 2310 movs r3, #16 + 800b2c2: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b2c4: 2001 movs r0, #1 + 800b2c6: e7f0 b.n 800b2aa + +0800b2c8 : +{ + 800b2c8: b5f7 push {r0, r1, r2, r4, r5, r6, r7, lr} + 800b2ca: 4604 mov r4, r0 + 800b2cc: 460f mov r7, r1 + uint32_t tickstart = HAL_GetTick(); + 800b2ce: f7fb ff0d bl 80070ec + uint32_t addr_reg = hospi->Instance->AR; + 800b2d2: 6822 ldr r2, [r4, #0] + 800b2d4: 6c95 ldr r5, [r2, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b2d6: f8d2 6110 ldr.w r6, [r2, #272] ; 0x110 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b2da: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b2dc: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b2de: 4603 mov r3, r0 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b2e0: d132 bne.n 800b348 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b2e2: 6ce2 ldr r2, [r4, #76] ; 0x4c + 800b2e4: 9200 str r2, [sp, #0] + 800b2e6: 2120 movs r1, #32 + 800b2e8: 2200 movs r2, #0 + 800b2ea: 4620 mov r0, r4 + 800b2ec: f7ff fd86 bl 800adfc + if (status == HAL_OK) + 800b2f0: bb00 cbnz r0, 800b334 + WRITE_REG (hospi->Instance->PSMAR, cfg->Match); + 800b2f2: 6823 ldr r3, [r4, #0] + 800b2f4: 683a ldr r2, [r7, #0] + 800b2f6: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); + 800b2fa: 687a ldr r2, [r7, #4] + 800b2fc: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + WRITE_REG (hospi->Instance->PIR, cfg->Interval); + 800b300: 693a ldr r2, [r7, #16] + 800b302: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b306: e9d7 2702 ldrd r2, r7, [r7, #8] + 800b30a: 6819 ldr r1, [r3, #0] + 800b30c: 433a orrs r2, r7 + 800b30e: f021 5143 bic.w r1, r1, #817889280 ; 0x30c00000 + 800b312: 430a orrs r2, r1 + 800b314: f042 5200 orr.w r2, r2, #536870912 ; 0x20000000 + 800b318: 601a str r2, [r3, #0] + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM); + 800b31a: 2209 movs r2, #9 + 800b31c: 625a str r2, [r3, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING; + 800b31e: 2248 movs r2, #72 ; 0x48 + 800b320: 6462 str r2, [r4, #68] ; 0x44 + __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE); + 800b322: 681a ldr r2, [r3, #0] + 800b324: f442 2210 orr.w r2, r2, #589824 ; 0x90000 + 800b328: 601a str r2, [r3, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b32a: 68e2 ldr r2, [r4, #12] + 800b32c: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + 800b330: d102 bne.n 800b338 + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b332: 649d str r5, [r3, #72] ; 0x48 +} + 800b334: b003 add sp, #12 + 800b336: bdf0 pop {r4, r5, r6, r7, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b338: f8d3 2100 ldr.w r2, [r3, #256] ; 0x100 + 800b33c: f412 6fe0 tst.w r2, #1792 ; 0x700 + 800b340: d1f7 bne.n 800b332 + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b342: f8c3 6110 str.w r6, [r3, #272] ; 0x110 + 800b346: e7f5 b.n 800b334 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b348: 2310 movs r3, #16 + 800b34a: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b34c: 2001 movs r0, #1 + 800b34e: e7f1 b.n 800b334 + +0800b350 : +{ + 800b350: b573 push {r0, r1, r4, r5, r6, lr} + 800b352: 4604 mov r4, r0 + 800b354: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800b356: f7fb fec9 bl 80070ec + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b35a: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b35c: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b35e: 4603 mov r3, r0 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b360: d121 bne.n 800b3a6 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b362: 6ce2 ldr r2, [r4, #76] ; 0x4c + 800b364: 9200 str r2, [sp, #0] + 800b366: 2120 movs r1, #32 + 800b368: 2200 movs r2, #0 + 800b36a: 4620 mov r0, r4 + 800b36c: f7ff fd46 bl 800adfc + if (status == HAL_OK) + 800b370: b9b8 cbnz r0, 800b3a2 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b372: 682e ldr r6, [r5, #0] + WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod); + 800b374: 6822 ldr r2, [r4, #0] + hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + 800b376: 2388 movs r3, #136 ; 0x88 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b378: 2e08 cmp r6, #8 + hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + 800b37a: 6463 str r3, [r4, #68] ; 0x44 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b37c: d108 bne.n 800b390 + WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod); + 800b37e: 686b ldr r3, [r5, #4] + 800b380: f8c2 3130 str.w r3, [r2, #304] ; 0x130 + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO); + 800b384: 2310 movs r3, #16 + 800b386: 6253 str r3, [r2, #36] ; 0x24 + __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO); + 800b388: 6811 ldr r1, [r2, #0] + 800b38a: f441 1180 orr.w r1, r1, #1048576 ; 0x100000 + 800b38e: 6011 str r1, [r2, #0] + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE), + 800b390: 6813 ldr r3, [r2, #0] + 800b392: f023 5340 bic.w r3, r3, #805306368 ; 0x30000000 + 800b396: f023 0308 bic.w r3, r3, #8 + 800b39a: 4333 orrs r3, r6 + 800b39c: f043 5340 orr.w r3, r3, #805306368 ; 0x30000000 + 800b3a0: 6013 str r3, [r2, #0] +} + 800b3a2: b002 add sp, #8 + 800b3a4: bd70 pop {r4, r5, r6, pc} + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b3a6: 2310 movs r3, #16 + 800b3a8: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b3aa: 2001 movs r0, #1 + 800b3ac: e7f9 b.n 800b3a2 + +0800b3ae : + if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U) + 800b3ae: 6c43 ldr r3, [r0, #68] ; 0x44 + 800b3b0: f013 0308 ands.w r3, r3, #8 + 800b3b4: d10a bne.n 800b3cc + hospi->Init.FifoThreshold = Threshold; + 800b3b6: 6041 str r1, [r0, #4] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos)); + 800b3b8: 6800 ldr r0, [r0, #0] + 800b3ba: 6802 ldr r2, [r0, #0] + 800b3bc: 3901 subs r1, #1 + 800b3be: f422 52f8 bic.w r2, r2, #7936 ; 0x1f00 + 800b3c2: ea42 2101 orr.w r1, r2, r1, lsl #8 + 800b3c6: 6001 str r1, [r0, #0] + HAL_StatusTypeDef status = HAL_OK; + 800b3c8: 4618 mov r0, r3 + 800b3ca: 4770 bx lr + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b3cc: 2310 movs r3, #16 + 800b3ce: 6483 str r3, [r0, #72] ; 0x48 + status = HAL_ERROR; + 800b3d0: 2001 movs r0, #1 +} + 800b3d2: 4770 bx lr + +0800b3d4 : + return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U); + 800b3d4: 6803 ldr r3, [r0, #0] + 800b3d6: 6818 ldr r0, [r3, #0] + 800b3d8: f3c0 2004 ubfx r0, r0, #8, #5 +} + 800b3dc: 3001 adds r0, #1 + 800b3de: 4770 bx lr + +0800b3e0 : + hospi->Timeout = Timeout; + 800b3e0: 64c1 str r1, [r0, #76] ; 0x4c +} + 800b3e2: 2000 movs r0, #0 + 800b3e4: 4770 bx lr + +0800b3e6 : + return hospi->ErrorCode; + 800b3e6: 6c80 ldr r0, [r0, #72] ; 0x48 +} + 800b3e8: 4770 bx lr + +0800b3ea : + return hospi->State; + 800b3ea: 6c40 ldr r0, [r0, #68] ; 0x44 +} + 800b3ec: 4770 bx lr + ... + +0800b3f0 : +{ + 800b3f0: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + if (hospi->Instance == OCTOSPI1) + 800b3f4: 6802 ldr r2, [r0, #0] + other_instance = 0U; + 800b3f6: 4bbf ldr r3, [pc, #764] ; (800b6f4 ) + * @retval HAL status + */ +static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t reg, value = 0U; + 800b3f8: f8df 8304 ldr.w r8, [pc, #772] ; 800b700 + other_instance = 0U; + 800b3fc: 429a cmp r2, r3 +{ + 800b3fe: b08b sub sp, #44 ; 0x2c + } + + /* Get the information about the instance */ + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + { + reg = OCTOSPIM->PCR[index]; + 800b400: 4bbd ldr r3, [pc, #756] ; (800b6f8 ) + other_instance = 0U; + 800b402: bf0b itete eq + 800b404: f04f 0a01 moveq.w sl, #1 + 800b408: f04f 0a00 movne.w sl, #0 + 800b40c: 2000 moveq r0, #0 + 800b40e: 2001 movne r0, #1 + for (index = 0U; index < OSPI_NB_INSTANCE; index++) + 800b410: 466a mov r2, sp + instance = 1U; + 800b412: 2501 movs r5, #1 + cfg->ClkPort = 0U; + 800b414: 2700 movs r7, #0 + cfg->DQSPort = 0U; + 800b416: e9c2 7700 strd r7, r7, [r2] + cfg->IOLowPort = 0U; + 800b41a: e9c2 7702 strd r7, r7, [r2, #8] + uint32_t reg, value = 0U; + 800b41e: 2d02 cmp r5, #2 + 800b420: bf0c ite eq + 800b422: 46c4 moveq ip, r8 + 800b424: f04f 0c00 movne.w ip, #0 + cfg->IOHighPort = 0U; + 800b428: 6117 str r7, [r2, #16] + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + 800b42a: f04f 0e00 mov.w lr, #0 + reg = OCTOSPIM->PCR[index]; + 800b42e: eb03 048e add.w r4, r3, lr, lsl #2 + { + /* The clock is enabled on this port */ + if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC)) + { + /* The clock correspond to the instance passed as parameter */ + cfg->ClkPort = index+1U; + 800b432: f10e 0601 add.w r6, lr, #1 + reg = OCTOSPIM->PCR[index]; + 800b436: 6864 ldr r4, [r4, #4] + if ((reg & OCTOSPIM_PCR_CLKEN) != 0U) + 800b438: f014 0f01 tst.w r4, #1 + 800b43c: d005 beq.n 800b44a + if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC)) + 800b43e: ea84 0e0c eor.w lr, r4, ip + 800b442: f01e 0f02 tst.w lr, #2 + cfg->ClkPort = index+1U; + 800b446: bf08 it eq + 800b448: 6016 streq r6, [r2, #0] + } + } + + if ((reg & OCTOSPIM_PCR_DQSEN) != 0U) + 800b44a: f014 0f10 tst.w r4, #16 + 800b44e: d005 beq.n 800b45c + { + /* The DQS is enabled on this port */ + if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC)) + 800b450: ea84 0e0c eor.w lr, r4, ip + 800b454: f01e 0f20 tst.w lr, #32 + { + /* The DQS correspond to the instance passed as parameter */ + cfg->DQSPort = index+1U; + 800b458: bf08 it eq + 800b45a: 6056 streq r6, [r2, #4] + } + } + + if ((reg & OCTOSPIM_PCR_NCSEN) != 0U) + 800b45c: f414 7f80 tst.w r4, #256 ; 0x100 + 800b460: d005 beq.n 800b46e + { + /* The nCS is enabled on this port */ + if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC)) + 800b462: ea84 0e0c eor.w lr, r4, ip + 800b466: f41e 7f00 tst.w lr, #512 ; 0x200 + { + /* The nCS correspond to the instance passed as parameter */ + cfg->NCSPort = index+1U; + 800b46a: bf08 it eq + 800b46c: 6096 streq r6, [r2, #8] + } + } + + if ((reg & OCTOSPIM_PCR_IOLEN) != 0U) + 800b46e: f414 3f80 tst.w r4, #65536 ; 0x10000 + 800b472: d00d beq.n 800b490 + { + /* The IO Low is enabled on this port */ + if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1)) + 800b474: ea84 0e0c eor.w lr, r4, ip + 800b478: f41e 2f80 tst.w lr, #262144 ; 0x40000 + 800b47c: d108 bne.n 800b490 + { + /* The IO Low correspond to the instance passed as parameter */ + if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U) + 800b47e: f414 3f00 tst.w r4, #131072 ; 0x20000 + { + cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); + 800b482: bf0c ite eq + 800b484: f446 3e80 orreq.w lr, r6, #65536 ; 0x10000 + } + else + { + cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); + 800b488: f046 7e80 orrne.w lr, r6, #16777216 ; 0x1000000 + 800b48c: f8c2 e00c str.w lr, [r2, #12] + } + } + } + + if ((reg & OCTOSPIM_PCR_IOHEN) != 0U) + 800b490: f014 7f80 tst.w r4, #16777216 ; 0x1000000 + 800b494: d00b beq.n 800b4ae + { + /* The IO High is enabled on this port */ + if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1)) + 800b496: ea84 0e0c eor.w lr, r4, ip + 800b49a: f01e 6f80 tst.w lr, #67108864 ; 0x4000000 + 800b49e: d106 bne.n 800b4ae + { + /* The IO High correspond to the instance passed as parameter */ + if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U) + 800b4a0: 01a4 lsls r4, r4, #6 + { + cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); + 800b4a2: bf54 ite pl + 800b4a4: f446 3480 orrpl.w r4, r6, #65536 ; 0x10000 + } + else + { + cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); + 800b4a8: f046 7480 orrmi.w r4, r6, #16777216 ; 0x1000000 + 800b4ac: 6114 str r4, [r2, #16] + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + 800b4ae: 2e02 cmp r6, #2 + 800b4b0: f04f 0e01 mov.w lr, #1 + 800b4b4: d1bb bne.n 800b42e + for (index = 0U; index < OSPI_NB_INSTANCE; index++) + 800b4b6: 2d02 cmp r5, #2 + 800b4b8: f102 0214 add.w r2, r2, #20 + 800b4bc: f040 8117 bne.w 800b6ee + if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U) + 800b4c0: 4c8c ldr r4, [pc, #560] ; (800b6f4 ) + 800b4c2: 6825 ldr r5, [r4, #0] + 800b4c4: ea15 050e ands.w r5, r5, lr + CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); + 800b4c8: bf1e ittt ne + 800b4ca: 6822 ldrne r2, [r4, #0] + 800b4cc: f022 0201 bicne.w r2, r2, #1 + 800b4d0: 6022 strne r2, [r4, #0] + if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U) + 800b4d2: 4a8a ldr r2, [pc, #552] ; (800b6fc ) + 800b4d4: 6814 ldr r4, [r2, #0] + ospi_enabled |= 0x1U; + 800b4d6: bf18 it ne + 800b4d8: 4675 movne r5, lr + if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U) + 800b4da: 07e6 lsls r6, r4, #31 + CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b4dc: bf42 ittt mi + 800b4de: 6814 ldrmi r4, [r2, #0] + 800b4e0: f024 0401 bicmi.w r4, r4, #1 + 800b4e4: 6014 strmi r4, [r2, #0] + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b4e6: aa0a add r2, sp, #40 ; 0x28 + 800b4e8: f04f 0414 mov.w r4, #20 + 800b4ec: fb04 2400 mla r4, r4, r0, r2 + ospi_enabled |= 0x2U; + 800b4f0: bf48 it mi + 800b4f2: f045 0b02 orrmi.w fp, r5, #2 + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b4f6: f854 2c20 ldr.w r2, [r4, #-32] + 800b4fa: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 800b4fe: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b502: bf58 it pl + 800b504: 46ab movpl fp, r5 + 800b506: 6856 ldr r6, [r2, #4] + 800b508: f426 7680 bic.w r6, r6, #256 ; 0x100 + 800b50c: 6056 str r6, [r2, #4] + if (IOM_cfg[instance].ClkPort != 0U) + 800b50e: f854 2c28 ldr.w r2, [r4, #-40] + 800b512: b382 cbz r2, 800b576 + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); + 800b514: 3a01 subs r2, #1 + 800b516: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b51a: 6856 ldr r6, [r2, #4] + 800b51c: f026 0601 bic.w r6, r6, #1 + 800b520: 6056 str r6, [r2, #4] + if (IOM_cfg[instance].DQSPort != 0U) + 800b522: f854 2c24 ldr.w r2, [r4, #-36] + 800b526: b132 cbz r2, 800b536 + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); + 800b528: 3a01 subs r2, #1 + 800b52a: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b52e: 6854 ldr r4, [r2, #4] + 800b530: f024 0410 bic.w r4, r4, #16 + 800b534: 6054 str r4, [r2, #4] + if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b536: 2214 movs r2, #20 + 800b538: ac0a add r4, sp, #40 ; 0x28 + 800b53a: fb02 4200 mla r2, r2, r0, r4 + 800b53e: f852 2c1c ldr.w r2, [r2, #-28] + 800b542: b142 cbz r2, 800b556 + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN); + 800b544: 3a01 subs r2, #1 + 800b546: f002 0201 and.w r2, r2, #1 + 800b54a: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b54e: 6854 ldr r4, [r2, #4] + 800b550: f424 3480 bic.w r4, r4, #65536 ; 0x10000 + 800b554: 6054 str r4, [r2, #4] + if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800b556: 2214 movs r2, #20 + 800b558: ac0a add r4, sp, #40 ; 0x28 + 800b55a: fb02 4200 mla r2, r2, r0, r4 + 800b55e: f852 2c18 ldr.w r2, [r2, #-24] + 800b562: b142 cbz r2, 800b576 + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN); + 800b564: 3a01 subs r2, #1 + 800b566: f002 0201 and.w r2, r2, #1 + 800b56a: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b56e: 6854 ldr r4, [r2, #4] + 800b570: f024 7480 bic.w r4, r4, #16777216 ; 0x1000000 + 800b574: 6054 str r4, [r2, #4] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b576: aa0a add r2, sp, #40 ; 0x28 + 800b578: f04f 0914 mov.w r9, #20 + 800b57c: fb09 290a mla r9, r9, sl, r2 + 800b580: f8d1 c000 ldr.w ip, [r1] + 800b584: f859 8c28 ldr.w r8, [r9, #-40] + (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) + 800b588: f859 4c18 ldr.w r4, [r9, #-24] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b58c: 45c4 cmp ip, r8 + (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) || + 800b58e: e9d1 6e01 ldrd r6, lr, [r1, #4] + (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) + 800b592: e9d1 2103 ldrd r2, r1, [r1, #12] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b596: d00d beq.n 800b5b4 + 800b598: f859 7c24 ldr.w r7, [r9, #-36] + 800b59c: 42b7 cmp r7, r6 + 800b59e: d009 beq.n 800b5b4 + 800b5a0: f859 7c20 ldr.w r7, [r9, #-32] + 800b5a4: 45be cmp lr, r7 + 800b5a6: d005 beq.n 800b5b4 + (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) || + 800b5a8: f859 7c1c ldr.w r7, [r9, #-28] + 800b5ac: 4297 cmp r7, r2 + 800b5ae: d001 beq.n 800b5b4 + 800b5b0: 428c cmp r4, r1 + 800b5b2: d142 bne.n 800b63a + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); + 800b5b4: f108 38ff add.w r8, r8, #4294967295 ; 0xffffffff + 800b5b8: eb03 0888 add.w r8, r3, r8, lsl #2 + 800b5bc: f8d8 7004 ldr.w r7, [r8, #4] + 800b5c0: f027 0701 bic.w r7, r7, #1 + 800b5c4: f8c8 7004 str.w r7, [r8, #4] + if (IOM_cfg[other_instance].DQSPort != 0U) + 800b5c8: 2714 movs r7, #20 + 800b5ca: f10d 0828 add.w r8, sp, #40 ; 0x28 + 800b5ce: fb07 870a mla r7, r7, sl, r8 + 800b5d2: f857 7c24 ldr.w r7, [r7, #-36] + 800b5d6: b147 cbz r7, 800b5ea + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); + 800b5d8: 3f01 subs r7, #1 + 800b5da: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b5de: f8d7 8004 ldr.w r8, [r7, #4] + 800b5e2: f028 0810 bic.w r8, r8, #16 + 800b5e6: f8c7 8004 str.w r8, [r7, #4] + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b5ea: 2714 movs r7, #20 + 800b5ec: f10d 0828 add.w r8, sp, #40 ; 0x28 + 800b5f0: fb07 8a0a mla sl, r7, sl, r8 + 800b5f4: f85a 7c20 ldr.w r7, [sl, #-32] + 800b5f8: 3f01 subs r7, #1 + 800b5fa: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b5fe: f8d7 8004 ldr.w r8, [r7, #4] + 800b602: f428 7880 bic.w r8, r8, #256 ; 0x100 + 800b606: f8c7 8004 str.w r8, [r7, #4] + if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b60a: f85a 7c1c ldr.w r7, [sl, #-28] + 800b60e: b157 cbz r7, 800b626 + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN); + 800b610: 3f01 subs r7, #1 + 800b612: f007 0701 and.w r7, r7, #1 + 800b616: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b61a: f8d7 8004 ldr.w r8, [r7, #4] + 800b61e: f428 3880 bic.w r8, r8, #65536 ; 0x10000 + 800b622: f8c7 8004 str.w r8, [r7, #4] + if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800b626: b144 cbz r4, 800b63a + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN); + 800b628: 3c01 subs r4, #1 + 800b62a: f004 0401 and.w r4, r4, #1 + 800b62e: eb03 0484 add.w r4, r3, r4, lsl #2 + 800b632: 6867 ldr r7, [r4, #4] + 800b634: f027 7780 bic.w r7, r7, #16777216 ; 0x1000000 + 800b638: 6067 str r7, [r4, #4] + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b63a: f10e 3eff add.w lr, lr, #4294967295 ; 0xffffffff + 800b63e: eb03 0e8e add.w lr, r3, lr, lsl #2 + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b642: f10c 3cff add.w ip, ip, #4294967295 ; 0xffffffff + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b646: f8de 4004 ldr.w r4, [lr, #4] + 800b64a: f424 7440 bic.w r4, r4, #768 ; 0x300 + 800b64e: ea44 2440 orr.w r4, r4, r0, lsl #9 + 800b652: f444 7480 orr.w r4, r4, #256 ; 0x100 + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b656: eb03 0c8c add.w ip, r3, ip, lsl #2 + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b65a: f8ce 4004 str.w r4, [lr, #4] + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b65e: f8dc 4004 ldr.w r4, [ip, #4] + 800b662: f024 0403 bic.w r4, r4, #3 + 800b666: ea44 0440 orr.w r4, r4, r0, lsl #1 + 800b66a: f044 0401 orr.w r4, r4, #1 + 800b66e: f8cc 4004 str.w r4, [ip, #4] + if (cfg->DQSPort != 0U) + 800b672: b156 cbz r6, 800b68a + MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos))); + 800b674: 3e01 subs r6, #1 + 800b676: eb03 0686 add.w r6, r3, r6, lsl #2 + 800b67a: 6874 ldr r4, [r6, #4] + 800b67c: f024 0430 bic.w r4, r4, #48 ; 0x30 + 800b680: ea44 1440 orr.w r4, r4, r0, lsl #5 + 800b684: f044 0410 orr.w r4, r4, #16 + 800b688: 6074 str r4, [r6, #4] + if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U) + 800b68a: 03d4 lsls r4, r2, #15 + 800b68c: d53a bpl.n 800b704 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), + 800b68e: 3a01 subs r2, #1 + 800b690: f002 0201 and.w r2, r2, #1 + 800b694: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b698: 6854 ldr r4, [r2, #4] + 800b69a: f424 24e0 bic.w r4, r4, #458752 ; 0x70000 + 800b69e: ea44 4480 orr.w r4, r4, r0, lsl #18 + 800b6a2: f444 3480 orr.w r4, r4, #65536 ; 0x10000 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b6a6: 6054 str r4, [r2, #4] + if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U) + 800b6a8: 03ca lsls r2, r1, #15 + 800b6aa: d53a bpl.n 800b722 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), + 800b6ac: 3901 subs r1, #1 + 800b6ae: f001 0101 and.w r1, r1, #1 + 800b6b2: eb03 0381 add.w r3, r3, r1, lsl #2 + 800b6b6: 685a ldr r2, [r3, #4] + 800b6b8: f422 22e0 bic.w r2, r2, #458752 ; 0x70000 + 800b6bc: ea42 4080 orr.w r0, r2, r0, lsl #18 + 800b6c0: f440 3040 orr.w r0, r0, #196608 ; 0x30000 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b6c4: 6058 str r0, [r3, #4] + if ((ospi_enabled & 0x1U) != 0U) + 800b6c6: b125 cbz r5, 800b6d2 + SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); + 800b6c8: 4a0a ldr r2, [pc, #40] ; (800b6f4 ) + 800b6ca: 6813 ldr r3, [r2, #0] + 800b6cc: f043 0301 orr.w r3, r3, #1 + 800b6d0: 6013 str r3, [r2, #0] + if ((ospi_enabled & 0x2U) != 0U) + 800b6d2: f01b 0f02 tst.w fp, #2 + SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b6d6: bf1c itt ne + 800b6d8: 4a08 ldrne r2, [pc, #32] ; (800b6fc ) + 800b6da: 6813 ldrne r3, [r2, #0] +} + 800b6dc: f04f 0000 mov.w r0, #0 + SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b6e0: bf1c itt ne + 800b6e2: f043 0301 orrne.w r3, r3, #1 + 800b6e6: 6013 strne r3, [r2, #0] +} + 800b6e8: b00b add sp, #44 ; 0x2c + 800b6ea: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 800b6ee: 4635 mov r5, r6 + 800b6f0: e691 b.n 800b416 + 800b6f2: bf00 nop + 800b6f4: a0001000 .word 0xa0001000 + 800b6f8: 50061c00 .word 0x50061c00 + 800b6fc: a0001400 .word 0xa0001400 + 800b700: 04040222 .word 0x04040222 + else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b704: 2a00 cmp r2, #0 + 800b706: d0cf beq.n 800b6a8 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b708: 3a01 subs r2, #1 + 800b70a: f002 0201 and.w r2, r2, #1 + 800b70e: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b712: 6854 ldr r4, [r2, #4] + 800b714: f024 64e0 bic.w r4, r4, #117440512 ; 0x7000000 + 800b718: ea44 6480 orr.w r4, r4, r0, lsl #26 + 800b71c: f044 7480 orr.w r4, r4, #16777216 ; 0x1000000 + 800b720: e7c1 b.n 800b6a6 + else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800b722: 2900 cmp r1, #0 + 800b724: d0cf beq.n 800b6c6 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b726: 3901 subs r1, #1 + 800b728: f001 0101 and.w r1, r1, #1 + 800b72c: eb03 0381 add.w r3, r3, r1, lsl #2 + 800b730: 685a ldr r2, [r3, #4] + 800b732: f022 62e0 bic.w r2, r2, #117440512 ; 0x7000000 + 800b736: ea42 6080 orr.w r0, r2, r0, lsl #26 + 800b73a: f040 7040 orr.w r0, r0, #50331648 ; 0x3000000 + 800b73e: e7c1 b.n 800b6c4 + +0800b740 : + * @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request. + * @retval None + */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, + uint32_t Request) +{ + 800b740: b530 push {r4, r5, lr} + 800b742: 9d03 ldr r5, [sp, #12] + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_TRANSFER_MODE(Mode)); + assert_param(IS_TRANSFER_REQUEST(Request)); + + /* update CR2 register */ + MODIFY_REG(hi2c->Instance->CR2, + 800b744: 6804 ldr r4, [r0, #0] + 800b746: ea45 4202 orr.w r2, r5, r2, lsl #16 + 800b74a: 431a orrs r2, r3 + 800b74c: 4b05 ldr r3, [pc, #20] ; (800b764 ) + 800b74e: 6860 ldr r0, [r4, #4] + 800b750: f3c1 0109 ubfx r1, r1, #0, #10 + 800b754: ea43 5355 orr.w r3, r3, r5, lsr #21 + 800b758: 430a orrs r2, r1 + 800b75a: ea20 0003 bic.w r0, r0, r3 + 800b75e: 4302 orrs r2, r0 + 800b760: 6062 str r2, [r4, #4] + ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \ + (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | + (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); +} + 800b762: bd30 pop {r4, r5, pc} + 800b764: 03ff63ff .word 0x03ff63ff + +0800b768 : + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800b768: 6803 ldr r3, [r0, #0] +{ + 800b76a: b570 push {r4, r5, r6, lr} + 800b76c: 4604 mov r4, r0 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800b76e: 6998 ldr r0, [r3, #24] + 800b770: f010 0010 ands.w r0, r0, #16 +{ + 800b774: 460d mov r5, r1 + 800b776: 4616 mov r6, r2 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800b778: d116 bne.n 800b7a8 +} + 800b77a: bd70 pop {r4, r5, r6, pc} + if (Timeout != HAL_MAX_DELAY) + 800b77c: 1c6a adds r2, r5, #1 + 800b77e: d014 beq.n 800b7aa + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800b780: f7fb fcb4 bl 80070ec + 800b784: 1b80 subs r0, r0, r6 + 800b786: 4285 cmp r5, r0 + 800b788: d300 bcc.n 800b78c + 800b78a: b96d cbnz r5, 800b7a8 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800b78c: 6c63 ldr r3, [r4, #68] ; 0x44 + 800b78e: f043 0320 orr.w r3, r3, #32 + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + 800b792: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800b794: 2320 movs r3, #32 + 800b796: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800b79a: 2300 movs r3, #0 + 800b79c: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800b7a0: f884 3040 strb.w r3, [r4, #64] ; 0x40 + return HAL_ERROR; + 800b7a4: 2001 movs r0, #1 + 800b7a6: e7e8 b.n 800b77a + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + 800b7a8: 6823 ldr r3, [r4, #0] + 800b7aa: 699a ldr r2, [r3, #24] + 800b7ac: 0690 lsls r0, r2, #26 + 800b7ae: d5e5 bpl.n 800b77c + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + 800b7b0: 2210 movs r2, #16 + 800b7b2: 61da str r2, [r3, #28] + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800b7b4: 2220 movs r2, #32 + 800b7b6: 61da str r2, [r3, #28] + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) + 800b7b8: 699a ldr r2, [r3, #24] + 800b7ba: 0791 lsls r1, r2, #30 + hi2c->Instance->TXDR = 0x00U; + 800b7bc: bf44 itt mi + 800b7be: 2200 movmi r2, #0 + 800b7c0: 629a strmi r2, [r3, #40] ; 0x28 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + 800b7c2: 699a ldr r2, [r3, #24] + 800b7c4: 07d2 lsls r2, r2, #31 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE); + 800b7c6: bf5e ittt pl + 800b7c8: 699a ldrpl r2, [r3, #24] + 800b7ca: f042 0201 orrpl.w r2, r2, #1 + 800b7ce: 619a strpl r2, [r3, #24] + I2C_RESET_CR2(hi2c); + 800b7d0: 685a ldr r2, [r3, #4] + 800b7d2: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800b7d6: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800b7da: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800b7de: f022 0201 bic.w r2, r2, #1 + 800b7e2: 605a str r2, [r3, #4] + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + 800b7e4: 6c63 ldr r3, [r4, #68] ; 0x44 + 800b7e6: f043 0304 orr.w r3, r3, #4 + 800b7ea: e7d2 b.n 800b792 + +0800b7ec : +{ + 800b7ec: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800b7f0: 9f06 ldr r7, [sp, #24] + 800b7f2: 4604 mov r4, r0 + 800b7f4: 4688 mov r8, r1 + 800b7f6: 4616 mov r6, r2 + 800b7f8: 461d mov r5, r3 + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) + 800b7fa: 6822 ldr r2, [r4, #0] + 800b7fc: 6993 ldr r3, [r2, #24] + 800b7fe: ea38 0303 bics.w r3, r8, r3 + 800b802: bf0c ite eq + 800b804: 2301 moveq r3, #1 + 800b806: 2300 movne r3, #0 + 800b808: 42b3 cmp r3, r6 + 800b80a: d001 beq.n 800b810 + return HAL_OK; + 800b80c: 2000 movs r0, #0 + 800b80e: e015 b.n 800b83c + if (Timeout != HAL_MAX_DELAY) + 800b810: 1c6b adds r3, r5, #1 + 800b812: d0f3 beq.n 800b7fc + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800b814: f7fb fc6a bl 80070ec + 800b818: 1bc0 subs r0, r0, r7 + 800b81a: 42a8 cmp r0, r5 + 800b81c: d801 bhi.n 800b822 + 800b81e: 2d00 cmp r5, #0 + 800b820: d1eb bne.n 800b7fa + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800b822: 6c63 ldr r3, [r4, #68] ; 0x44 + 800b824: f043 0320 orr.w r3, r3, #32 + 800b828: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800b82a: 2320 movs r3, #32 + 800b82c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800b830: 2300 movs r3, #0 + 800b832: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800b836: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800b83a: 2001 movs r0, #1 +} + 800b83c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +0800b840 : +{ + 800b840: b570 push {r4, r5, r6, lr} + 800b842: 4604 mov r4, r0 + 800b844: 460d mov r5, r1 + 800b846: 4616 mov r6, r2 + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + 800b848: 6823 ldr r3, [r4, #0] + 800b84a: 699b ldr r3, [r3, #24] + 800b84c: 069b lsls r3, r3, #26 + 800b84e: d501 bpl.n 800b854 + return HAL_OK; + 800b850: 2000 movs r0, #0 +} + 800b852: bd70 pop {r4, r5, r6, pc} + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800b854: 4632 mov r2, r6 + 800b856: 4629 mov r1, r5 + 800b858: 4620 mov r0, r4 + 800b85a: f7ff ff85 bl 800b768 + 800b85e: b990 cbnz r0, 800b886 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800b860: f7fb fc44 bl 80070ec + 800b864: 1b80 subs r0, r0, r6 + 800b866: 42a8 cmp r0, r5 + 800b868: d801 bhi.n 800b86e + 800b86a: 2d00 cmp r5, #0 + 800b86c: d1ec bne.n 800b848 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800b86e: 6c63 ldr r3, [r4, #68] ; 0x44 + 800b870: f043 0320 orr.w r3, r3, #32 + 800b874: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800b876: 2320 movs r3, #32 + 800b878: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800b87c: 2300 movs r3, #0 + 800b87e: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800b882: f884 3040 strb.w r3, [r4, #64] ; 0x40 + return HAL_ERROR; + 800b886: 2001 movs r0, #1 + 800b888: e7e3 b.n 800b852 + +0800b88a : +} + 800b88a: 4770 bx lr + +0800b88c : +{ + 800b88c: b510 push {r4, lr} + if (hi2c == NULL) + 800b88e: 4604 mov r4, r0 + 800b890: 2800 cmp r0, #0 + 800b892: d04a beq.n 800b92a + if (hi2c->State == HAL_I2C_STATE_RESET) + 800b894: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 + 800b898: f003 02ff and.w r2, r3, #255 ; 0xff + 800b89c: b91b cbnz r3, 800b8a6 + hi2c->Lock = HAL_UNLOCKED; + 800b89e: f880 2040 strb.w r2, [r0, #64] ; 0x40 + HAL_I2C_MspInit(hi2c); + 800b8a2: f7ff fff2 bl 800b88a + hi2c->State = HAL_I2C_STATE_BUSY; + 800b8a6: 2324 movs r3, #36 ; 0x24 + 800b8a8: f884 3041 strb.w r3, [r4, #65] ; 0x41 + __HAL_I2C_DISABLE(hi2c); + 800b8ac: 6823 ldr r3, [r4, #0] + 800b8ae: 681a ldr r2, [r3, #0] + 800b8b0: f022 0201 bic.w r2, r2, #1 + 800b8b4: 601a str r2, [r3, #0] + hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK; + 800b8b6: 6862 ldr r2, [r4, #4] + 800b8b8: f022 6270 bic.w r2, r2, #251658240 ; 0xf000000 + 800b8bc: 611a str r2, [r3, #16] + hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN; + 800b8be: 689a ldr r2, [r3, #8] + 800b8c0: f422 4200 bic.w r2, r2, #32768 ; 0x8000 + 800b8c4: 609a str r2, [r3, #8] + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + 800b8c6: e9d4 2102 ldrd r2, r1, [r4, #8] + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + 800b8ca: 2901 cmp r1, #1 + 800b8cc: d124 bne.n 800b918 + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + 800b8ce: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 800b8d2: 609a str r2, [r3, #8] + hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); + 800b8d4: 685a ldr r2, [r3, #4] + 800b8d6: f042 7200 orr.w r2, r2, #33554432 ; 0x2000000 + 800b8da: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 800b8de: 605a str r2, [r3, #4] + hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE; + 800b8e0: 68da ldr r2, [r3, #12] + 800b8e2: f422 4200 bic.w r2, r2, #32768 ; 0x8000 + 800b8e6: 60da str r2, [r3, #12] + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8)); + 800b8e8: e9d4 2104 ldrd r2, r1, [r4, #16] + 800b8ec: 430a orrs r2, r1 + 800b8ee: 69a1 ldr r1, [r4, #24] + 800b8f0: ea42 2201 orr.w r2, r2, r1, lsl #8 + 800b8f4: 60da str r2, [r3, #12] + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + 800b8f6: e9d4 2107 ldrd r2, r1, [r4, #28] + 800b8fa: 430a orrs r2, r1 + 800b8fc: 601a str r2, [r3, #0] + __HAL_I2C_ENABLE(hi2c); + 800b8fe: 681a ldr r2, [r3, #0] + 800b900: f042 0201 orr.w r2, r2, #1 + 800b904: 601a str r2, [r3, #0] + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800b906: 2000 movs r0, #0 + hi2c->State = HAL_I2C_STATE_READY; + 800b908: 2320 movs r3, #32 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800b90a: 6460 str r0, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800b90c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->PreviousState = I2C_STATE_NONE; + 800b910: 6320 str r0, [r4, #48] ; 0x30 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800b912: f884 0042 strb.w r0, [r4, #66] ; 0x42 +} + 800b916: bd10 pop {r4, pc} + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + 800b918: f442 4204 orr.w r2, r2, #33792 ; 0x8400 + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + 800b91c: 2902 cmp r1, #2 + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + 800b91e: 609a str r2, [r3, #8] + hi2c->Instance->CR2 = (I2C_CR2_ADD10); + 800b920: bf04 itt eq + 800b922: f44f 6200 moveq.w r2, #2048 ; 0x800 + 800b926: 605a streq r2, [r3, #4] + 800b928: e7d4 b.n 800b8d4 + return HAL_ERROR; + 800b92a: 2001 movs r0, #1 + 800b92c: e7f3 b.n 800b916 + +0800b92e : + 800b92e: 4770 bx lr + +0800b930 : +{ + 800b930: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + 800b934: 4698 mov r8, r3 + if (hi2c->State == HAL_I2C_STATE_READY) + 800b936: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 +{ + 800b93a: 9f0a ldr r7, [sp, #40] ; 0x28 + if (hi2c->State == HAL_I2C_STATE_READY) + 800b93c: 2b20 cmp r3, #32 +{ + 800b93e: 4604 mov r4, r0 + 800b940: 460e mov r6, r1 + 800b942: 4691 mov r9, r2 + if (hi2c->State == HAL_I2C_STATE_READY) + 800b944: f040 80a3 bne.w 800ba8e + __HAL_LOCK(hi2c); + 800b948: f890 3040 ldrb.w r3, [r0, #64] ; 0x40 + 800b94c: 2b01 cmp r3, #1 + 800b94e: f000 809e beq.w 800ba8e + 800b952: f04f 0a01 mov.w sl, #1 + 800b956: f880 a040 strb.w sl, [r0, #64] ; 0x40 + tickstart = HAL_GetTick(); + 800b95a: f7fb fbc7 bl 80070ec + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800b95e: 2319 movs r3, #25 + tickstart = HAL_GetTick(); + 800b960: 4605 mov r5, r0 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800b962: 9000 str r0, [sp, #0] + 800b964: 4652 mov r2, sl + 800b966: f44f 4100 mov.w r1, #32768 ; 0x8000 + 800b96a: 4620 mov r0, r4 + 800b96c: f7ff ff3e bl 800b7ec + 800b970: b118 cbz r0, 800b97a + return HAL_ERROR; + 800b972: 2001 movs r0, #1 +} + 800b974: b002 add sp, #8 + 800b976: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hi2c->State = HAL_I2C_STATE_BUSY_TX; + 800b97a: 2321 movs r3, #33 ; 0x21 + 800b97c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_MASTER; + 800b980: 2310 movs r3, #16 + 800b982: f884 3042 strb.w r3, [r4, #66] ; 0x42 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800b986: 6460 str r0, [r4, #68] ; 0x44 + hi2c->XferCount = Size; + 800b988: f8a4 802a strh.w r8, [r4, #42] ; 0x2a + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800b98c: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->pBuffPtr = pData; + 800b98e: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800b992: b29b uxth r3, r3 + 800b994: 2bff cmp r3, #255 ; 0xff + hi2c->XferISR = NULL; + 800b996: 6360 str r0, [r4, #52] ; 0x34 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800b998: 4b3e ldr r3, [pc, #248] ; (800ba94 ) + 800b99a: d927 bls.n 800b9ec + hi2c->XferSize = MAX_NBYTE_SIZE; + 800b99c: 22ff movs r2, #255 ; 0xff + 800b99e: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + 800b9a0: 9300 str r3, [sp, #0] + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800b9a2: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800b9a6: 4631 mov r1, r6 + 800b9a8: 4620 mov r0, r4 + 800b9aa: f7ff fec9 bl 800b740 + while (hi2c->XferCount > 0U) + 800b9ae: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800b9b0: b29b uxth r3, r3 + 800b9b2: 2b00 cmp r3, #0 + 800b9b4: d13e bne.n 800ba34 + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + 800b9b6: 462a mov r2, r5 + 800b9b8: 4639 mov r1, r7 + 800b9ba: 4620 mov r0, r4 + 800b9bc: f7ff ff40 bl 800b840 + 800b9c0: 2800 cmp r0, #0 + 800b9c2: d1d6 bne.n 800b972 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800b9c4: 6823 ldr r3, [r4, #0] + 800b9c6: 2120 movs r1, #32 + 800b9c8: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800b9ca: 685a ldr r2, [r3, #4] + 800b9cc: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800b9d0: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800b9d4: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800b9d8: f022 0201 bic.w r2, r2, #1 + 800b9dc: 605a str r2, [r3, #4] + hi2c->State = HAL_I2C_STATE_READY; + 800b9de: f884 1041 strb.w r1, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800b9e2: f884 0040 strb.w r0, [r4, #64] ; 0x40 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800b9e6: f884 0042 strb.w r0, [r4, #66] ; 0x42 + return HAL_OK; + 800b9ea: e7c3 b.n 800b974 + hi2c->XferSize = hi2c->XferCount; + 800b9ec: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); + 800b9ee: 9300 str r3, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800b9f0: b292 uxth r2, r2 + 800b9f2: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800b9f4: f04f 7300 mov.w r3, #33554432 ; 0x2000000 + 800b9f8: b2d2 uxtb r2, r2 + 800b9fa: e7d4 b.n 800b9a6 + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800b9fc: 462a mov r2, r5 + 800b9fe: 4639 mov r1, r7 + 800ba00: 4620 mov r0, r4 + 800ba02: f7ff feb1 bl 800b768 + 800ba06: 2800 cmp r0, #0 + 800ba08: d1b3 bne.n 800b972 + if (Timeout != HAL_MAX_DELAY) + 800ba0a: 1c7a adds r2, r7, #1 + 800ba0c: d012 beq.n 800ba34 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800ba0e: f7fb fb6d bl 80070ec + 800ba12: 1b40 subs r0, r0, r5 + 800ba14: 4287 cmp r7, r0 + 800ba16: d300 bcc.n 800ba1a + 800ba18: b967 cbnz r7, 800ba34 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800ba1a: 6c63 ldr r3, [r4, #68] ; 0x44 + 800ba1c: f043 0320 orr.w r3, r3, #32 + 800ba20: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800ba22: 2320 movs r3, #32 + 800ba24: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800ba28: 2300 movs r3, #0 + 800ba2a: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800ba2e: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800ba32: e79e b.n 800b972 + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) + 800ba34: 6822 ldr r2, [r4, #0] + 800ba36: 6993 ldr r3, [r2, #24] + 800ba38: 079b lsls r3, r3, #30 + 800ba3a: d5df bpl.n 800b9fc + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + 800ba3c: 6a63 ldr r3, [r4, #36] ; 0x24 + 800ba3e: f813 1b01 ldrb.w r1, [r3], #1 + 800ba42: 6291 str r1, [r2, #40] ; 0x28 + hi2c->pBuffPtr++; + 800ba44: 6263 str r3, [r4, #36] ; 0x24 + hi2c->XferCount--; + 800ba46: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800ba48: 8d22 ldrh r2, [r4, #40] ; 0x28 + hi2c->XferCount--; + 800ba4a: 3b01 subs r3, #1 + 800ba4c: b29b uxth r3, r3 + 800ba4e: 8563 strh r3, [r4, #42] ; 0x2a + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800ba50: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800ba52: 3a01 subs r2, #1 + 800ba54: b292 uxth r2, r2 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800ba56: b29b uxth r3, r3 + hi2c->XferSize--; + 800ba58: 8522 strh r2, [r4, #40] ; 0x28 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800ba5a: 2b00 cmp r3, #0 + 800ba5c: d0a7 beq.n 800b9ae + 800ba5e: 2a00 cmp r2, #0 + 800ba60: d1a5 bne.n 800b9ae + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + 800ba62: 9500 str r5, [sp, #0] + 800ba64: 463b mov r3, r7 + 800ba66: 2180 movs r1, #128 ; 0x80 + 800ba68: 4620 mov r0, r4 + 800ba6a: f7ff febf bl 800b7ec + 800ba6e: 2800 cmp r0, #0 + 800ba70: f47f af7f bne.w 800b972 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800ba74: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800ba76: b29b uxth r3, r3 + 800ba78: 2bff cmp r3, #255 ; 0xff + 800ba7a: d903 bls.n 800ba84 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800ba7c: 22ff movs r2, #255 ; 0xff + 800ba7e: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800ba80: 9000 str r0, [sp, #0] + 800ba82: e78e b.n 800b9a2 + hi2c->XferSize = hi2c->XferCount; + 800ba84: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800ba86: 9000 str r0, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800ba88: b292 uxth r2, r2 + 800ba8a: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800ba8c: e7b2 b.n 800b9f4 + return HAL_BUSY; + 800ba8e: 2002 movs r0, #2 + 800ba90: e770 b.n 800b974 + 800ba92: bf00 nop + 800ba94: 80002000 .word 0x80002000 + +0800ba98 : +{ + 800ba98: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + 800ba9c: 4698 mov r8, r3 + if (hi2c->State == HAL_I2C_STATE_READY) + 800ba9e: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 +{ + 800baa2: 9f0a ldr r7, [sp, #40] ; 0x28 + if (hi2c->State == HAL_I2C_STATE_READY) + 800baa4: 2b20 cmp r3, #32 +{ + 800baa6: 4604 mov r4, r0 + 800baa8: 460e mov r6, r1 + 800baaa: 4691 mov r9, r2 + if (hi2c->State == HAL_I2C_STATE_READY) + 800baac: f040 80be bne.w 800bc2c + __HAL_LOCK(hi2c); + 800bab0: f890 3040 ldrb.w r3, [r0, #64] ; 0x40 + 800bab4: 2b01 cmp r3, #1 + 800bab6: f000 80b9 beq.w 800bc2c + 800baba: f04f 0a01 mov.w sl, #1 + 800babe: f880 a040 strb.w sl, [r0, #64] ; 0x40 + tickstart = HAL_GetTick(); + 800bac2: f7fb fb13 bl 80070ec + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800bac6: 2319 movs r3, #25 + tickstart = HAL_GetTick(); + 800bac8: 4605 mov r5, r0 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800baca: 9000 str r0, [sp, #0] + 800bacc: 4652 mov r2, sl + 800bace: f44f 4100 mov.w r1, #32768 ; 0x8000 + 800bad2: 4620 mov r0, r4 + 800bad4: f7ff fe8a bl 800b7ec + 800bad8: b118 cbz r0, 800bae2 + return HAL_ERROR; + 800bada: 2001 movs r0, #1 +} + 800badc: b002 add sp, #8 + 800bade: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hi2c->State = HAL_I2C_STATE_BUSY_RX; + 800bae2: 2322 movs r3, #34 ; 0x22 + 800bae4: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_MASTER; + 800bae8: 2310 movs r3, #16 + 800baea: f884 3042 strb.w r3, [r4, #66] ; 0x42 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800baee: 6460 str r0, [r4, #68] ; 0x44 + hi2c->XferCount = Size; + 800baf0: f8a4 802a strh.w r8, [r4, #42] ; 0x2a + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800baf4: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->pBuffPtr = pData; + 800baf6: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bafa: b29b uxth r3, r3 + 800bafc: 2bff cmp r3, #255 ; 0xff + hi2c->XferISR = NULL; + 800bafe: 6360 str r0, [r4, #52] ; 0x34 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bb00: 4b4b ldr r3, [pc, #300] ; (800bc30 ) + 800bb02: d909 bls.n 800bb18 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800bb04: 22ff movs r2, #255 ; 0xff + 800bb06: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); + 800bb08: 9300 str r3, [sp, #0] + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bb0a: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bb0e: 4631 mov r1, r6 + 800bb10: 4620 mov r0, r4 + 800bb12: f7ff fe15 bl 800b740 + 800bb16: e052 b.n 800bbbe + hi2c->XferSize = hi2c->XferCount; + 800bb18: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + 800bb1a: 9300 str r3, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800bb1c: b292 uxth r2, r2 + 800bb1e: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bb20: f04f 7300 mov.w r3, #33554432 ; 0x2000000 + 800bb24: b2d2 uxtb r2, r2 + 800bb26: e7f2 b.n 800bb0e + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800bb28: 2120 movs r1, #32 + 800bb2a: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800bb2c: 685a ldr r2, [r3, #4] + 800bb2e: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800bb32: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800bb36: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800bb3a: f022 0201 bic.w r2, r2, #1 + 800bb3e: 605a str r2, [r3, #4] + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800bb40: 2300 movs r3, #0 + 800bb42: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bb44: f884 1041 strb.w r1, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bb48: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800bb4c: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800bb50: e7c3 b.n 800bada + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800bb52: f7fb facb bl 80070ec + 800bb56: 1b40 subs r0, r0, r5 + 800bb58: 4287 cmp r7, r0 + 800bb5a: d300 bcc.n 800bb5e + 800bb5c: b947 cbnz r7, 800bb70 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800bb5e: 6c63 ldr r3, [r4, #68] ; 0x44 + 800bb60: f043 0320 orr.w r3, r3, #32 + 800bb64: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bb66: 2320 movs r3, #32 + 800bb68: f884 3041 strb.w r3, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800bb6c: 2300 movs r3, #0 + 800bb6e: e7ed b.n 800bb4c + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + 800bb70: 6823 ldr r3, [r4, #0] + 800bb72: 699b ldr r3, [r3, #24] + 800bb74: 075b lsls r3, r3, #29 + 800bb76: d410 bmi.n 800bb9a + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800bb78: 462a mov r2, r5 + 800bb7a: 4639 mov r1, r7 + 800bb7c: 4620 mov r0, r4 + 800bb7e: f7ff fdf3 bl 800b768 + 800bb82: 2800 cmp r0, #0 + 800bb84: d1a9 bne.n 800bada + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + 800bb86: 6823 ldr r3, [r4, #0] + 800bb88: 699a ldr r2, [r3, #24] + 800bb8a: 0691 lsls r1, r2, #26 + 800bb8c: d5e1 bpl.n 800bb52 + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U)) + 800bb8e: 699a ldr r2, [r3, #24] + 800bb90: 0752 lsls r2, r2, #29 + 800bb92: d5c9 bpl.n 800bb28 + 800bb94: 8d22 ldrh r2, [r4, #40] ; 0x28 + 800bb96: 2a00 cmp r2, #0 + 800bb98: d0c6 beq.n 800bb28 + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + 800bb9a: 6823 ldr r3, [r4, #0] + 800bb9c: 6a5a ldr r2, [r3, #36] ; 0x24 + 800bb9e: 6a63 ldr r3, [r4, #36] ; 0x24 + 800bba0: 701a strb r2, [r3, #0] + hi2c->pBuffPtr++; + 800bba2: 6a63 ldr r3, [r4, #36] ; 0x24 + hi2c->XferSize--; + 800bba4: 8d22 ldrh r2, [r4, #40] ; 0x28 + hi2c->pBuffPtr++; + 800bba6: 3301 adds r3, #1 + 800bba8: 6263 str r3, [r4, #36] ; 0x24 + hi2c->XferCount--; + 800bbaa: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bbac: 3b01 subs r3, #1 + 800bbae: b29b uxth r3, r3 + 800bbb0: 8563 strh r3, [r4, #42] ; 0x2a + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bbb2: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800bbb4: 3a01 subs r2, #1 + 800bbb6: b292 uxth r2, r2 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bbb8: b29b uxth r3, r3 + hi2c->XferSize--; + 800bbba: 8522 strh r2, [r4, #40] ; 0x28 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bbbc: b9f3 cbnz r3, 800bbfc + while (hi2c->XferCount > 0U) + 800bbbe: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bbc0: b29b uxth r3, r3 + 800bbc2: 2b00 cmp r3, #0 + 800bbc4: d1d4 bne.n 800bb70 + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + 800bbc6: 462a mov r2, r5 + 800bbc8: 4639 mov r1, r7 + 800bbca: 4620 mov r0, r4 + 800bbcc: f7ff fe38 bl 800b840 + 800bbd0: 2800 cmp r0, #0 + 800bbd2: d182 bne.n 800bada + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800bbd4: 6823 ldr r3, [r4, #0] + 800bbd6: 2120 movs r1, #32 + 800bbd8: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800bbda: 685a ldr r2, [r3, #4] + 800bbdc: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800bbe0: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800bbe4: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800bbe8: f022 0201 bic.w r2, r2, #1 + 800bbec: 605a str r2, [r3, #4] + hi2c->State = HAL_I2C_STATE_READY; + 800bbee: f884 1041 strb.w r1, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800bbf2: f884 0040 strb.w r0, [r4, #64] ; 0x40 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bbf6: f884 0042 strb.w r0, [r4, #66] ; 0x42 + return HAL_OK; + 800bbfa: e76f b.n 800badc + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bbfc: 2a00 cmp r2, #0 + 800bbfe: d1de bne.n 800bbbe + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + 800bc00: 9500 str r5, [sp, #0] + 800bc02: 463b mov r3, r7 + 800bc04: 2180 movs r1, #128 ; 0x80 + 800bc06: 4620 mov r0, r4 + 800bc08: f7ff fdf0 bl 800b7ec + 800bc0c: 2800 cmp r0, #0 + 800bc0e: f47f af64 bne.w 800bada + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bc12: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bc14: b29b uxth r3, r3 + 800bc16: 2bff cmp r3, #255 ; 0xff + 800bc18: d903 bls.n 800bc22 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800bc1a: 22ff movs r2, #255 ; 0xff + 800bc1c: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bc1e: 9000 str r0, [sp, #0] + 800bc20: e773 b.n 800bb0a + hi2c->XferSize = hi2c->XferCount; + 800bc22: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bc24: 9000 str r0, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800bc26: b292 uxth r2, r2 + 800bc28: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bc2a: e779 b.n 800bb20 + return HAL_BUSY; + 800bc2c: 2002 movs r0, #2 + 800bc2e: e755 b.n 800badc + 800bc30: 80002400 .word 0x80002400 + +0800bc34 : + * @param hsd Pointer to SD handle + * @param pSCR pointer to the buffer that will contain the SCR value + * @retval error state + */ +static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) +{ + 800bc34: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 800bc38: b086 sub sp, #24 + 800bc3a: 4605 mov r5, r0 + 800bc3c: 4688 mov r8, r1 + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + 800bc3e: f7fb fa55 bl 80070ec + uint32_t index = 0U; + uint32_t tempscr[2U] = {0UL, 0UL}; + uint32_t *scr = pSCR; + + /* Set Block Size To 8 Bytes */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U); + 800bc42: 2108 movs r1, #8 + uint32_t tickstart = HAL_GetTick(); + 800bc44: 4681 mov r9, r0 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U); + 800bc46: 6828 ldr r0, [r5, #0] + 800bc48: f001 f996 bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800bc4c: 4604 mov r4, r0 + 800bc4e: bb48 cbnz r0, 800bca4 + { + return errorstate; + } + + /* Send CMD55 APP_CMD with argument as card's RCA */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U)); + 800bc50: 6ca9 ldr r1, [r5, #72] ; 0x48 + 800bc52: 6828 ldr r0, [r5, #0] + 800bc54: 0409 lsls r1, r1, #16 + 800bc56: f001 fac8 bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800bc5a: 4604 mov r4, r0 + 800bc5c: bb10 cbnz r0, 800bca4 + { + return errorstate; + } + + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = 8U; + 800bc5e: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 800bc62: 2308 movs r3, #8 + 800bc64: e9cd 0300 strd r0, r3, [sp] + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800bc68: 2630 movs r6, #48 ; 0x30 + 800bc6a: 2302 movs r3, #2 + 800bc6c: e9cd 6302 strd r6, r3, [sp, #8] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_ENABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bc70: 4669 mov r1, sp + config.DPSM = SDMMC_DPSM_ENABLE; + 800bc72: 2301 movs r3, #1 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bc74: 6828 ldr r0, [r5, #0] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800bc76: 9404 str r4, [sp, #16] + config.DPSM = SDMMC_DPSM_ENABLE; + 800bc78: 9305 str r3, [sp, #20] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bc7a: f001 f8a1 bl 800cdc0 + + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + errorstate = SDMMC_CmdSendSCR(hsd->Instance); + 800bc7e: 6828 ldr r0, [r5, #0] + 800bc80: f001 fae7 bl 800d252 + if(errorstate != HAL_SD_ERROR_NONE) + 800bc84: 4604 mov r4, r0 + 800bc86: b968 cbnz r0, 800bca4 + uint32_t tempscr[2U] = {0UL, 0UL}; + 800bc88: 4607 mov r7, r0 + 800bc8a: 4606 mov r6, r0 + { + return errorstate; + } + +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DATAEND)) + 800bc8c: f240 5a2a movw sl, #1322 ; 0x52a + 800bc90: 6828 ldr r0, [r5, #0] + 800bc92: 6b42 ldr r2, [r0, #52] ; 0x34 + 800bc94: ea12 0f0a tst.w r2, sl + { + if((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) + 800bc98: 6b42 ldr r2, [r0, #52] ; 0x34 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DATAEND)) + 800bc9a: d007 beq.n 800bcac + return HAL_SD_ERROR_TIMEOUT; + } + } +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800bc9c: 0712 lsls r2, r2, #28 + 800bc9e: d519 bpl.n 800bcd4 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800bca0: 2408 movs r4, #8 + + return HAL_SD_ERROR_DATA_CRC_FAIL; + } + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bca2: 6384 str r4, [r0, #56] ; 0x38 + ((tempscr[0] & SDMMC_16TO23BITS) >> 8) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24)); + + } + + return HAL_SD_ERROR_NONE; +} + 800bca4: 4620 mov r0, r4 + 800bca6: b006 add sp, #24 + 800bca8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) + 800bcac: 0311 lsls r1, r2, #12 + 800bcae: d408 bmi.n 800bcc2 + 800bcb0: b93c cbnz r4, 800bcc2 + tempscr[0] = SDMMC_ReadFIFO(hsd->Instance); + 800bcb2: f001 f849 bl 800cd48 + 800bcb6: 4606 mov r6, r0 + tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); + 800bcb8: 6828 ldr r0, [r5, #0] + 800bcba: f001 f845 bl 800cd48 + index++; + 800bcbe: 2401 movs r4, #1 + tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); + 800bcc0: 4607 mov r7, r0 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800bcc2: f7fb fa13 bl 80070ec + 800bcc6: eba0 0009 sub.w r0, r0, r9 + 800bcca: 3001 adds r0, #1 + 800bccc: d1e0 bne.n 800bc90 + return HAL_SD_ERROR_TIMEOUT; + 800bcce: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + 800bcd2: e7e7 b.n 800bca4 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800bcd4: 6b42 ldr r2, [r0, #52] ; 0x34 + 800bcd6: 0793 lsls r3, r2, #30 + 800bcd8: d501 bpl.n 800bcde + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800bcda: 2402 movs r4, #2 + 800bcdc: e7e1 b.n 800bca2 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800bcde: 6b44 ldr r4, [r0, #52] ; 0x34 + 800bce0: f014 0420 ands.w r4, r4, #32 + 800bce4: d001 beq.n 800bcea + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bce6: 2420 movs r4, #32 + 800bce8: e7db b.n 800bca2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800bcea: 4a04 ldr r2, [pc, #16] ; (800bcfc ) + 800bcec: 6382 str r2, [r0, #56] ; 0x38 + *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24) | ((tempscr[1] & SDMMC_8TO15BITS) << 8) |\ + 800bcee: ba3f rev r7, r7 + 800bcf0: ba36 rev r6, r6 + 800bcf2: f8c8 7000 str.w r7, [r8] + *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24) | ((tempscr[0] & SDMMC_8TO15BITS) << 8) |\ + 800bcf6: f8c8 6004 str.w r6, [r8, #4] + return HAL_SD_ERROR_NONE; + 800bcfa: e7d3 b.n 800bca4 + 800bcfc: 18000f3a .word 0x18000f3a + +0800bd00 : + * of PLL to have SDMMCCK clock between 50 and 120 MHz + * @param hsd SD handle + * @retval SD Card error state + */ +static uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd) +{ + 800bd00: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + 800bd04: 2640 movs r6, #64 ; 0x40 +{ + 800bd06: b096 sub sp, #88 ; 0x58 + 800bd08: 4605 mov r5, r0 + uint32_t SD_hs[16] = {0}; + 800bd0a: 4632 mov r2, r6 + 800bd0c: 2100 movs r1, #0 + 800bd0e: a806 add r0, sp, #24 + 800bd10: f001 fcb0 bl 800d674 + uint32_t count, loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + 800bd14: f7fb f9ea bl 80070ec + + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800bd18: 6deb ldr r3, [r5, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800bd1a: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800bd1c: 2b00 cmp r3, #0 + 800bd1e: d067 beq.n 800bdf0 + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) && + 800bd20: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800bd24: d167 bne.n 800bdf6 + 800bd26: 69af ldr r7, [r5, #24] + 800bd28: 2f01 cmp r7, #1 + 800bd2a: d164 bne.n 800bdf6 + (hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE)) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + 800bd2c: 6828 ldr r0, [r5, #0] + 800bd2e: 2300 movs r3, #0 + 800bd30: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800bd32: 4631 mov r1, r6 + 800bd34: f001 f920 bl 800cf78 + + if (errorstate != HAL_SD_ERROR_NONE) + 800bd38: 4604 mov r4, r0 + 800bd3a: 2800 cmp r0, #0 + 800bd3c: d13e bne.n 800bdbc + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800bd3e: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800bd42: e9cd 3600 strd r3, r6, [sp] + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800bd46: e9cd 0704 strd r0, r7, [sp, #16] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800bd4a: 2660 movs r6, #96 ; 0x60 + 800bd4c: 2302 movs r3, #2 + + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800bd4e: 6828 ldr r0, [r5, #0] + 800bd50: 4669 mov r1, sp + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800bd52: e9cd 6302 strd r6, r3, [sp, #8] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800bd56: f001 f833 bl 800cdc0 + 800bd5a: 2800 cmp r0, #0 + 800bd5c: d14d bne.n 800bdfa + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SDMMC_SDR104_SWITCH_PATTERN); + 800bd5e: 492a ldr r1, [pc, #168] ; (800be08 ) + 800bd60: 6828 ldr r0, [r5, #0] + 800bd62: f001 fa74 bl 800d24e + if(errorstate != HAL_SD_ERROR_NONE) + 800bd66: 4604 mov r4, r0 + 800bd68: bb40 cbnz r0, 800bdbc + uint32_t count, loop = 0 ; + 800bd6a: 4607 mov r7, r0 + { + return errorstate; + } + + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800bd6c: f240 592a movw r9, #1322 ; 0x52a + 800bd70: 682b ldr r3, [r5, #0] + 800bd72: 6b5e ldr r6, [r3, #52] ; 0x34 + 800bd74: ea16 0609 ands.w r6, r6, r9 + 800bd78: d005 beq.n 800bd86 + hsd->State= HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800bd7a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800bd7c: 0711 lsls r1, r2, #28 + 800bd7e: d521 bpl.n 800bdc4 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800bd80: 2208 movs r2, #8 + 800bd82: 639a str r2, [r3, #56] ; 0x38 + + return errorstate; + 800bd84: e01a b.n 800bdbc + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800bd86: 6b5b ldr r3, [r3, #52] ; 0x34 + 800bd88: 0418 lsls r0, r3, #16 + 800bd8a: d50b bpl.n 800bda4 + 800bd8c: ab06 add r3, sp, #24 + 800bd8e: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800bd92: 6828 ldr r0, [r5, #0] + 800bd94: f000 ffd8 bl 800cd48 + for (count = 0U; count < 8U; count++) + 800bd98: 3601 adds r6, #1 + 800bd9a: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800bd9c: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800bda0: d1f7 bne.n 800bd92 + loop ++; + 800bda2: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800bda4: f7fb f9a2 bl 80070ec + 800bda8: eba0 0008 sub.w r0, r0, r8 + 800bdac: 3001 adds r0, #1 + 800bdae: d1df bne.n 800bd70 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800bdb0: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + hsd->State= HAL_SD_STATE_READY; + 800bdb4: 2301 movs r3, #1 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800bdb6: 63ac str r4, [r5, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800bdb8: f885 3034 strb.w r3, [r5, #52] ; 0x34 +#endif /* (DLYB_SDMMC1) || (DLYB_SDMMC2) */ + } + } + + return errorstate; +} + 800bdbc: 4620 mov r0, r4 + 800bdbe: b016 add sp, #88 ; 0x58 + 800bdc0: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800bdc4: 6b5a ldr r2, [r3, #52] ; 0x34 + 800bdc6: 0792 lsls r2, r2, #30 + 800bdc8: d502 bpl.n 800bdd0 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800bdca: 2402 movs r4, #2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bdcc: 639c str r4, [r3, #56] ; 0x38 + return errorstate; + 800bdce: e7f5 b.n 800bdbc + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800bdd0: 6b5c ldr r4, [r3, #52] ; 0x34 + 800bdd2: f014 0420 ands.w r4, r4, #32 + 800bdd6: d001 beq.n 800bddc + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bdd8: 2420 movs r4, #32 + 800bdda: e7f7 b.n 800bdcc + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800bddc: 4a0b ldr r2, [pc, #44] ; (800be0c ) + 800bdde: 639a str r2, [r3, #56] ; 0x38 + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800bde0: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800bde4: 079b lsls r3, r3, #30 + 800bde6: d50b bpl.n 800be00 + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800bde8: 2001 movs r0, #1 + 800bdea: f7fb f9ef bl 80071cc + 800bdee: e7e5 b.n 800bdbc + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800bdf0: f04f 6480 mov.w r4, #67108864 ; 0x4000000 + 800bdf4: e7e2 b.n 800bdbc + uint32_t errorstate = HAL_SD_ERROR_NONE; + 800bdf6: 2400 movs r4, #0 + 800bdf8: e7e0 b.n 800bdbc + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + 800bdfa: f44f 3480 mov.w r4, #65536 ; 0x10000 + 800bdfe: e7dd b.n 800bdbc + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + 800be00: f04f 5480 mov.w r4, #268435456 ; 0x10000000 + 800be04: e7da b.n 800bdbc + 800be06: bf00 nop + 800be08: 80ff1f03 .word 0x80ff1f03 + 800be0c: 18000f3a .word 0x18000f3a + +0800be10 : +} + 800be10: 4770 bx lr + +0800be12 : + 800be12: 4770 bx lr + +0800be14 : +{ + 800be14: b510 push {r4, lr} + if(hsd == NULL) + 800be16: 4604 mov r4, r0 + 800be18: b198 cbz r0, 800be42 + hsd->State = HAL_SD_STATE_BUSY; + 800be1a: 2303 movs r3, #3 + 800be1c: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800be20: 6983 ldr r3, [r0, #24] + 800be22: 2b01 cmp r3, #1 + 800be24: d102 bne.n 800be2c + HAL_SDEx_DriveTransceiver_1_8V_Callback(RESET); + 800be26: 2000 movs r0, #0 + 800be28: f7fb f9d0 bl 80071cc + (void)SDMMC_PowerState_OFF(hsd->Instance); + 800be2c: 6820 ldr r0, [r4, #0] + 800be2e: f000 ffa3 bl 800cd78 + HAL_SD_MspDeInit(hsd); + 800be32: 4620 mov r0, r4 + 800be34: f7ff ffed bl 800be12 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800be38: 2000 movs r0, #0 + 800be3a: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_RESET; + 800be3c: f884 0034 strb.w r0, [r4, #52] ; 0x34 +} + 800be40: bd10 pop {r4, pc} + return HAL_ERROR; + 800be42: 2001 movs r0, #1 + 800be44: e7fc b.n 800be40 + ... + +0800be48 : +{ + 800be48: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800be4c: b087 sub sp, #28 + 800be4e: 4604 mov r4, r0 + 800be50: 460e mov r6, r1 + 800be52: 4692 mov sl, r2 + 800be54: 461f mov r7, r3 + uint32_t tickstart = HAL_GetTick(); + 800be56: f7fb f949 bl 80070ec + 800be5a: 4681 mov r9, r0 + if(NULL == pData) + 800be5c: b936 cbnz r6, 800be6c + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800be5e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800be60: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800be64: 63a3 str r3, [r4, #56] ; 0x38 + return HAL_ERROR; + 800be66: f04f 0801 mov.w r8, #1 + 800be6a: e011 b.n 800be90 + if(hsd->State == HAL_SD_STATE_READY) + 800be6c: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800be70: 2b01 cmp r3, #1 + 800be72: fa5f f883 uxtb.w r8, r3 + 800be76: f040 80c3 bne.w 800c000 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800be7a: 6d62 ldr r2, [r4, #84] ; 0x54 + 800be7c: eb0a 0307 add.w r3, sl, r7 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800be80: 2100 movs r1, #0 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800be82: 4293 cmp r3, r2 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800be84: 63a1 str r1, [r4, #56] ; 0x38 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800be86: d907 bls.n 800be98 + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + 800be88: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800be8a: f043 7300 orr.w r3, r3, #33554432 ; 0x2000000 + 800be8e: 63a3 str r3, [r4, #56] ; 0x38 +} + 800be90: 4640 mov r0, r8 + 800be92: b007 add sp, #28 + 800be94: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + hsd->State = HAL_SD_STATE_BUSY; + 800be98: 2303 movs r3, #3 + 800be9a: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800be9e: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->Instance->DCTRL = 0U; + 800bea0: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800bea2: 2b01 cmp r3, #1 + config.DataTimeOut = SDMMC_DATATIMEOUT; + 800bea4: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800bea8: 9300 str r3, [sp, #0] + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800beaa: ea4f 2347 mov.w r3, r7, lsl #9 + 800beae: 9301 str r3, [sp, #4] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800beb0: f04f 0502 mov.w r5, #2 + 800beb4: f04f 0390 mov.w r3, #144 ; 0x90 + 800beb8: e9cd 3502 strd r3, r5, [sp, #8] + hsd->Instance->DCTRL = 0U; + 800bebc: 62c1 str r1, [r0, #44] ; 0x2c + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800bebe: f04f 0300 mov.w r3, #0 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bec2: 4669 mov r1, sp + config.DPSM = SDMMC_DPSM_DISABLE; + 800bec4: e9cd 3304 strd r3, r3, [sp, #16] + add *= 512U; + 800bec8: bf18 it ne + 800beca: ea4f 2a4a movne.w sl, sl, lsl #9 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bece: f000 ff77 bl 800cdc0 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800bed2: 6820 ldr r0, [r4, #0] + 800bed4: 68c3 ldr r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800bed6: 2f01 cmp r7, #1 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800bed8: f043 0340 orr.w r3, r3, #64 ; 0x40 + 800bedc: 60c3 str r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800bede: d910 bls.n 800bf02 + hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; + 800bee0: 6325 str r5, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + 800bee2: 4651 mov r1, sl + 800bee4: f001 f87a bl 800cfdc + if(errorstate != HAL_SD_ERROR_NONE) + 800bee8: b188 cbz r0, 800bf0e + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800beea: 6823 ldr r3, [r4, #0] + 800beec: 4a46 ldr r2, [pc, #280] ; (800c008 ) + 800beee: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800bef0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800bef2: 4318 orrs r0, r3 + 800bef4: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800bef6: 2301 movs r3, #1 + 800bef8: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800befc: 2300 movs r3, #0 + 800befe: 6323 str r3, [r4, #48] ; 0x30 + return HAL_ERROR; + 800bf00: e7c6 b.n 800be90 + hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK; + 800bf02: 2301 movs r3, #1 + 800bf04: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); + 800bf06: 4651 mov r1, sl + 800bf08: f001 f84f bl 800cfaa + 800bf0c: e7ec b.n 800bee8 + dataremaining = config.DataLength; + 800bf0e: 9d01 ldr r5, [sp, #4] + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800bf10: 6820 ldr r0, [r4, #0] + 800bf12: 6b43 ldr r3, [r0, #52] ; 0x34 + 800bf14: f413 7f95 tst.w r3, #298 ; 0x12a + 800bf18: d01b beq.n 800bf52 + __SDMMC_CMDTRANS_DISABLE( hsd->Instance); + 800bf1a: 68c3 ldr r3, [r0, #12] + 800bf1c: f023 0340 bic.w r3, r3, #64 ; 0x40 + 800bf20: 60c3 str r3, [r0, #12] + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + 800bf22: 6b43 ldr r3, [r0, #52] ; 0x34 + 800bf24: 05db lsls r3, r3, #23 + 800bf26: d508 bpl.n 800bf3a + 800bf28: 2f01 cmp r7, #1 + 800bf2a: d906 bls.n 800bf3a + if(hsd->SdCard.CardType != CARD_SECURED) + 800bf2c: 6be3 ldr r3, [r4, #60] ; 0x3c + 800bf2e: 2b03 cmp r3, #3 + 800bf30: d003 beq.n 800bf3a + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + 800bf32: f001 f91b bl 800d16c + if(errorstate != HAL_SD_ERROR_NONE) + 800bf36: 2800 cmp r0, #0 + 800bf38: d1d7 bne.n 800beea + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800bf3a: 6823 ldr r3, [r4, #0] + 800bf3c: 6b58 ldr r0, [r3, #52] ; 0x34 + 800bf3e: f010 0008 ands.w r0, r0, #8 + 800bf42: d038 beq.n 800bfb6 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800bf44: 4a30 ldr r2, [pc, #192] ; (800c008 ) + 800bf46: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + 800bf48: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800bf4a: f043 0308 orr.w r3, r3, #8 + 800bf4e: 63a3 str r3, [r4, #56] ; 0x38 + 800bf50: e7d1 b.n 800bef6 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U)) + 800bf52: 6b43 ldr r3, [r0, #52] ; 0x34 + 800bf54: 041a lsls r2, r3, #16 + 800bf56: d518 bpl.n 800bf8a + 800bf58: b1bd cbz r5, 800bf8a + 800bf5a: f106 0a04 add.w sl, r6, #4 + 800bf5e: f106 0b24 add.w fp, r6, #36 ; 0x24 + data = SDMMC_ReadFIFO(hsd->Instance); + 800bf62: 6820 ldr r0, [r4, #0] + 800bf64: f000 fef0 bl 800cd48 + *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); + 800bf68: 0a02 lsrs r2, r0, #8 + 800bf6a: f80a 2c03 strb.w r2, [sl, #-3] + *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); + 800bf6e: 0c02 lsrs r2, r0, #16 + 800bf70: f80a 2c02 strb.w r2, [sl, #-2] + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + 800bf74: 0e02 lsrs r2, r0, #24 + *tempbuff = (uint8_t)(data & 0xFFU); + 800bf76: f80a 0c04 strb.w r0, [sl, #-4] + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + 800bf7a: f80a 2c01 strb.w r2, [sl, #-1] + for(count = 0U; count < 8U; count++) + 800bf7e: f10a 0a04 add.w sl, sl, #4 + 800bf82: 45d3 cmp fp, sl + 800bf84: d1ed bne.n 800bf62 + tempbuff++; + 800bf86: 3620 adds r6, #32 + dataremaining--; + 800bf88: 3d20 subs r5, #32 + if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) + 800bf8a: f7fb f8af bl 80070ec + 800bf8e: 9b10 ldr r3, [sp, #64] ; 0x40 + 800bf90: eba0 0009 sub.w r0, r0, r9 + 800bf94: 4298 cmp r0, r3 + 800bf96: d3bb bcc.n 800bf10 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800bf98: 6823 ldr r3, [r4, #0] + 800bf9a: 4a1b ldr r2, [pc, #108] ; (800c008 ) + 800bf9c: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT; + 800bf9e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800bfa0: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 800bfa4: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800bfa6: 2301 movs r3, #1 + 800bfa8: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800bfac: 2300 movs r3, #0 + 800bfae: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800bfb0: f04f 0803 mov.w r8, #3 + 800bfb4: e76c b.n 800be90 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800bfb6: 6b59 ldr r1, [r3, #52] ; 0x34 + 800bfb8: f011 0102 ands.w r1, r1, #2 + 800bfbc: d00a beq.n 800bfd4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800bfbe: 4a12 ldr r2, [pc, #72] ; (800c008 ) + 800bfc0: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + 800bfc2: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800bfc4: f043 0302 orr.w r3, r3, #2 + 800bfc8: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800bfca: 2301 movs r3, #1 + 800bfcc: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800bfd0: 6320 str r0, [r4, #48] ; 0x30 + return HAL_ERROR; + 800bfd2: e75d b.n 800be90 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800bfd4: 6b5a ldr r2, [r3, #52] ; 0x34 + 800bfd6: f012 0220 ands.w r2, r2, #32 + 800bfda: d00a beq.n 800bff2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800bfdc: 4a0a ldr r2, [pc, #40] ; (800c008 ) + 800bfde: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; + 800bfe0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800bfe2: f043 0320 orr.w r3, r3, #32 + 800bfe6: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800bfe8: 2301 movs r3, #1 + 800bfea: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800bfee: 6321 str r1, [r4, #48] ; 0x30 + return HAL_ERROR; + 800bff0: e74e b.n 800be90 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800bff2: 4906 ldr r1, [pc, #24] ; (800c00c ) + 800bff4: 6399 str r1, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800bff6: 2301 movs r3, #1 + 800bff8: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800bffc: 4690 mov r8, r2 + 800bffe: e747 b.n 800be90 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c000: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c002: f043 5300 orr.w r3, r3, #536870912 ; 0x20000000 + 800c006: e72d b.n 800be64 + 800c008: 1fe00fff .word 0x1fe00fff + 800c00c: 18000f3a .word 0x18000f3a + +0800c010 : +{ + 800c010: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800c014: b089 sub sp, #36 ; 0x24 + 800c016: 4604 mov r4, r0 + 800c018: 460d mov r5, r1 + 800c01a: 4692 mov sl, r2 + 800c01c: 461f mov r7, r3 + uint32_t tickstart = HAL_GetTick(); + 800c01e: f7fb f865 bl 80070ec + 800c022: 4681 mov r9, r0 + if(NULL == pData) + 800c024: b935 cbnz r5, 800c034 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800c026: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c028: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c02c: 63a3 str r3, [r4, #56] ; 0x38 + return HAL_ERROR; + 800c02e: f04f 0801 mov.w r8, #1 + 800c032: e011 b.n 800c058 + if(hsd->State == HAL_SD_STATE_READY) + 800c034: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800c038: 2b01 cmp r3, #1 + 800c03a: fa5f f883 uxtb.w r8, r3 + 800c03e: f040 80b4 bne.w 800c1aa + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c042: 6d62 ldr r2, [r4, #84] ; 0x54 + 800c044: eb0a 0307 add.w r3, sl, r7 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c048: 2100 movs r1, #0 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c04a: 4293 cmp r3, r2 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c04c: 63a1 str r1, [r4, #56] ; 0x38 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c04e: d907 bls.n 800c060 + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + 800c050: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c052: f043 7300 orr.w r3, r3, #33554432 ; 0x2000000 + 800c056: 63a3 str r3, [r4, #56] ; 0x38 +} + 800c058: 4640 mov r0, r8 + 800c05a: b009 add sp, #36 ; 0x24 + 800c05c: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + hsd->State = HAL_SD_STATE_BUSY; + 800c060: 2303 movs r3, #3 + 800c062: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c066: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->Instance->DCTRL = 0U; + 800c068: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c06a: 2b01 cmp r3, #1 + config.DataTimeOut = SDMMC_DATATIMEOUT; + 800c06c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800c070: 9302 str r3, [sp, #8] + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800c072: ea4f 2347 mov.w r3, r7, lsl #9 + hsd->Instance->DCTRL = 0U; + 800c076: 62c1 str r1, [r0, #44] ; 0x2c + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800c078: 9303 str r3, [sp, #12] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + 800c07a: f04f 0190 mov.w r1, #144 ; 0x90 + 800c07e: f04f 0300 mov.w r3, #0 + 800c082: e9cd 1304 strd r1, r3, [sp, #16] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c086: a902 add r1, sp, #8 + config.DPSM = SDMMC_DPSM_DISABLE; + 800c088: e9cd 3306 strd r3, r3, [sp, #24] + add *= 512U; + 800c08c: bf18 it ne + 800c08e: ea4f 2a4a movne.w sl, sl, lsl #9 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c092: f000 fe95 bl 800cdc0 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c096: 6820 ldr r0, [r4, #0] + 800c098: 68c3 ldr r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c09a: 2f01 cmp r7, #1 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c09c: f043 0340 orr.w r3, r3, #64 ; 0x40 + 800c0a0: 60c3 str r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c0a2: d911 bls.n 800c0c8 + hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK; + 800c0a4: 2320 movs r3, #32 + 800c0a6: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + 800c0a8: 4651 mov r1, sl + 800c0aa: f000 ffc9 bl 800d040 + if(errorstate != HAL_SD_ERROR_NONE) + 800c0ae: b188 cbz r0, 800c0d4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c0b0: 6823 ldr r3, [r4, #0] + 800c0b2: 4a40 ldr r2, [pc, #256] ; (800c1b4 ) + 800c0b4: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c0b6: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c0b8: 4318 orrs r0, r3 + 800c0ba: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c0bc: 2301 movs r3, #1 + 800c0be: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c0c2: 2300 movs r3, #0 + 800c0c4: 6323 str r3, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c0c6: e7c7 b.n 800c058 + hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK; + 800c0c8: 2310 movs r3, #16 + 800c0ca: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); + 800c0cc: 4651 mov r1, sl + 800c0ce: f000 ff9e bl 800d00e + 800c0d2: e7ec b.n 800c0ae + dataremaining = config.DataLength; + 800c0d4: 9e03 ldr r6, [sp, #12] + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800c0d6: 6820 ldr r0, [r4, #0] + 800c0d8: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c0da: f413 7f8d tst.w r3, #282 ; 0x11a + 800c0de: d01b beq.n 800c118 + __SDMMC_CMDTRANS_DISABLE( hsd->Instance); + 800c0e0: 68c3 ldr r3, [r0, #12] + 800c0e2: f023 0340 bic.w r3, r3, #64 ; 0x40 + 800c0e6: 60c3 str r3, [r0, #12] + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + 800c0e8: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c0ea: 05db lsls r3, r3, #23 + 800c0ec: d508 bpl.n 800c100 + 800c0ee: 2f01 cmp r7, #1 + 800c0f0: d906 bls.n 800c100 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c0f2: 6be3 ldr r3, [r4, #60] ; 0x3c + 800c0f4: 2b03 cmp r3, #3 + 800c0f6: d003 beq.n 800c100 + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + 800c0f8: f001 f838 bl 800d16c + if(errorstate != HAL_SD_ERROR_NONE) + 800c0fc: 2800 cmp r0, #0 + 800c0fe: d1d7 bne.n 800c0b0 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c100: 6823 ldr r3, [r4, #0] + 800c102: 6b58 ldr r0, [r3, #52] ; 0x34 + 800c104: f010 0008 ands.w r0, r0, #8 + 800c108: d02a beq.n 800c160 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c10a: 4a2a ldr r2, [pc, #168] ; (800c1b4 ) + 800c10c: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + 800c10e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c110: f043 0308 orr.w r3, r3, #8 + 800c114: 63a3 str r3, [r4, #56] ; 0x38 + 800c116: e7d1 b.n 800c0bc + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U)) + 800c118: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c11a: 045a lsls r2, r3, #17 + 800c11c: d50c bpl.n 800c138 + 800c11e: b15e cbz r6, 800c138 + 800c120: f105 0b20 add.w fp, r5, #32 + data |= ((uint32_t)(*tempbuff) << 24U); + 800c124: f855 3b04 ldr.w r3, [r5], #4 + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + 800c128: 6820 ldr r0, [r4, #0] + data |= ((uint32_t)(*tempbuff) << 24U); + 800c12a: 9301 str r3, [sp, #4] + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + 800c12c: a901 add r1, sp, #4 + 800c12e: f000 fe0e bl 800cd4e + for(count = 0U; count < 8U; count++) + 800c132: 45ab cmp fp, r5 + 800c134: d1f6 bne.n 800c124 + dataremaining--; + 800c136: 3e20 subs r6, #32 + if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) + 800c138: f7fa ffd8 bl 80070ec + 800c13c: 9b12 ldr r3, [sp, #72] ; 0x48 + 800c13e: eba0 0009 sub.w r0, r0, r9 + 800c142: 4298 cmp r0, r3 + 800c144: d3c7 bcc.n 800c0d6 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c146: 6823 ldr r3, [r4, #0] + 800c148: 4a1a ldr r2, [pc, #104] ; (800c1b4 ) + 800c14a: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c14c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c14e: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c150: 2301 movs r3, #1 + 800c152: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c156: 2300 movs r3, #0 + 800c158: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800c15a: f04f 0803 mov.w r8, #3 + 800c15e: e77b b.n 800c058 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c160: 6b59 ldr r1, [r3, #52] ; 0x34 + 800c162: f011 0102 ands.w r1, r1, #2 + 800c166: d00a beq.n 800c17e + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c168: 4a12 ldr r2, [pc, #72] ; (800c1b4 ) + 800c16a: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + 800c16c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c16e: f043 0302 orr.w r3, r3, #2 + 800c172: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c174: 2301 movs r3, #1 + 800c176: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c17a: 6320 str r0, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c17c: e76c b.n 800c058 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR)) + 800c17e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c180: f012 0210 ands.w r2, r2, #16 + 800c184: d00a beq.n 800c19c + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c186: 4a0b ldr r2, [pc, #44] ; (800c1b4 ) + 800c188: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; + 800c18a: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c18c: f043 0310 orr.w r3, r3, #16 + 800c190: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c192: 2301 movs r3, #1 + 800c194: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c198: 6321 str r1, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c19a: e75d b.n 800c058 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c19c: 4906 ldr r1, [pc, #24] ; (800c1b8 ) + 800c19e: 6399 str r1, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c1a0: 2301 movs r3, #1 + 800c1a2: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800c1a6: 4690 mov r8, r2 + 800c1a8: e756 b.n 800c058 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c1aa: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c1ac: f043 5300 orr.w r3, r3, #536870912 ; 0x20000000 + 800c1b0: e73c b.n 800c02c + 800c1b2: bf00 nop + 800c1b4: 1fe00fff .word 0x1fe00fff + 800c1b8: 18000f3a .word 0x18000f3a + +0800c1bc : + return hsd->State; + 800c1bc: f890 0034 ldrb.w r0, [r0, #52] ; 0x34 +} + 800c1c0: 4770 bx lr + +0800c1c2 : + return hsd->ErrorCode; + 800c1c2: 6b80 ldr r0, [r0, #56] ; 0x38 +} + 800c1c4: 4770 bx lr + +0800c1c6 : + 800c1c6: 4770 bx lr + +0800c1c8 : + 800c1c8: 4770 bx lr + +0800c1ca : + 800c1ca: 4770 bx lr + +0800c1cc : + 800c1cc: 4770 bx lr + ... + +0800c1d0 : + pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U); + 800c1d0: 6e03 ldr r3, [r0, #96] ; 0x60 + 800c1d2: 0f9a lsrs r2, r3, #30 + 800c1d4: 700a strb r2, [r1, #0] + pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U); + 800c1d6: f3c3 6283 ubfx r2, r3, #26, #4 + 800c1da: 704a strb r2, [r1, #1] + pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U); + 800c1dc: f3c3 6201 ubfx r2, r3, #24, #2 + 800c1e0: 708a strb r2, [r1, #2] + pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U); + 800c1e2: f3c3 4207 ubfx r2, r3, #16, #8 + 800c1e6: 70ca strb r2, [r1, #3] + pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); + 800c1e8: f3c3 2207 ubfx r2, r3, #8, #8 + pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); + 800c1ec: b2db uxtb r3, r3 + pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); + 800c1ee: 710a strb r2, [r1, #4] + pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); + 800c1f0: 714b strb r3, [r1, #5] + pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U); + 800c1f2: 6e43 ldr r3, [r0, #100] ; 0x64 + 800c1f4: 0d1a lsrs r2, r3, #20 + 800c1f6: 80ca strh r2, [r1, #6] + pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U); + 800c1f8: f3c3 4203 ubfx r2, r3, #16, #4 + 800c1fc: 720a strb r2, [r1, #8] + pCSD->PartBlockRead = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U); + 800c1fe: f3c3 32c0 ubfx r2, r3, #15, #1 + 800c202: 724a strb r2, [r1, #9] + pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U); + 800c204: f3c3 3280 ubfx r2, r3, #14, #1 + 800c208: 728a strb r2, [r1, #10] + pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U); + 800c20a: f3c3 3240 ubfx r2, r3, #13, #1 + 800c20e: 72ca strb r2, [r1, #11] + pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U); + 800c210: f3c3 3200 ubfx r2, r3, #12, #1 + 800c214: 730a strb r2, [r1, #12] + pCSD->Reserved2 = 0U; /*!< Reserved */ + 800c216: 2200 movs r2, #0 + 800c218: 734a strb r2, [r1, #13] + if(hsd->SdCard.CardType == CARD_SDSC) + 800c21a: 6bc2 ldr r2, [r0, #60] ; 0x3c +{ + 800c21c: b510 push {r4, lr} + if(hsd->SdCard.CardType == CARD_SDSC) + 800c21e: 2a00 cmp r2, #0 + 800c220: d16c bne.n 800c2fc + pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U)); + 800c222: 6e82 ldr r2, [r0, #104] ; 0x68 + 800c224: f640 74fc movw r4, #4092 ; 0xffc + 800c228: ea04 0383 and.w r3, r4, r3, lsl #2 + 800c22c: ea43 7392 orr.w r3, r3, r2, lsr #30 + 800c230: 610b str r3, [r1, #16] + pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U); + 800c232: f3c2 63c2 ubfx r3, r2, #27, #3 + 800c236: 750b strb r3, [r1, #20] + pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U); + 800c238: f3c2 6302 ubfx r3, r2, #24, #3 + 800c23c: 754b strb r3, [r1, #21] + pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U); + 800c23e: f3c2 5342 ubfx r3, r2, #21, #3 + 800c242: 758b strb r3, [r1, #22] + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); + 800c244: f3c2 4382 ubfx r3, r2, #18, #3 + pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); + 800c248: f3c2 32c2 ubfx r2, r2, #15, #3 + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); + 800c24c: 75cb strb r3, [r1, #23] + pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); + 800c24e: 760a strb r2, [r1, #24] + hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + 800c250: 690b ldr r3, [r1, #16] + hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + 800c252: 7e0a ldrb r2, [r1, #24] + 800c254: f002 0207 and.w r2, r2, #7 + hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + 800c258: 3301 adds r3, #1 + hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + 800c25a: 3202 adds r2, #2 + 800c25c: fa03 f202 lsl.w r2, r3, r2 + 800c260: 64c2 str r2, [r0, #76] ; 0x4c + hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); + 800c262: 7a0b ldrb r3, [r1, #8] + 800c264: f003 040f and.w r4, r3, #15 + 800c268: 2301 movs r3, #1 + 800c26a: 40a3 lsls r3, r4 + 800c26c: 6503 str r3, [r0, #80] ; 0x50 + hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U); + 800c26e: 0a5b lsrs r3, r3, #9 + 800c270: 4353 muls r3, r2 + 800c272: 6543 str r3, [r0, #84] ; 0x54 + hsd->SdCard.LogBlockSize = 512U; + 800c274: f44f 7300 mov.w r3, #512 ; 0x200 + hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize; + 800c278: 6583 str r3, [r0, #88] ; 0x58 + pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U); + 800c27a: 6e83 ldr r3, [r0, #104] ; 0x68 + 800c27c: f3c3 3280 ubfx r2, r3, #14, #1 + 800c280: 764a strb r2, [r1, #25] + pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); + 800c282: f3c3 12c6 ubfx r2, r3, #7, #7 + pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); + 800c286: f003 037f and.w r3, r3, #127 ; 0x7f + pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); + 800c28a: 768a strb r2, [r1, #26] + pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); + 800c28c: 76cb strb r3, [r1, #27] + pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U); + 800c28e: 6ec3 ldr r3, [r0, #108] ; 0x6c + 800c290: 0fda lsrs r2, r3, #31 + 800c292: 770a strb r2, [r1, #28] + pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U); + 800c294: f3c3 7241 ubfx r2, r3, #29, #2 + 800c298: 774a strb r2, [r1, #29] + pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U); + 800c29a: f3c3 6282 ubfx r2, r3, #26, #3 + 800c29e: 778a strb r2, [r1, #30] + pCSD->MaxWrBlockLen= (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U); + 800c2a0: f3c3 5283 ubfx r2, r3, #22, #4 + 800c2a4: 77ca strb r2, [r1, #31] + pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U); + 800c2a6: f3c3 5240 ubfx r2, r3, #21, #1 + 800c2aa: f881 2020 strb.w r2, [r1, #32] + pCSD->Reserved3 = 0; + 800c2ae: 2000 movs r0, #0 + pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); + 800c2b0: f3c3 4200 ubfx r2, r3, #16, #1 + pCSD->Reserved3 = 0; + 800c2b4: f881 0021 strb.w r0, [r1, #33] ; 0x21 + pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); + 800c2b8: f881 2022 strb.w r2, [r1, #34] ; 0x22 + pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U); + 800c2bc: f3c3 32c0 ubfx r2, r3, #15, #1 + 800c2c0: f881 2023 strb.w r2, [r1, #35] ; 0x23 + pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U); + 800c2c4: f3c3 3280 ubfx r2, r3, #14, #1 + 800c2c8: f881 2024 strb.w r2, [r1, #36] ; 0x24 + pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U); + 800c2cc: f3c3 3240 ubfx r2, r3, #13, #1 + 800c2d0: f881 2025 strb.w r2, [r1, #37] ; 0x25 + pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U); + 800c2d4: f3c3 3200 ubfx r2, r3, #12, #1 + 800c2d8: f881 2026 strb.w r2, [r1, #38] ; 0x26 + pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U); + 800c2dc: f3c3 2281 ubfx r2, r3, #10, #2 + 800c2e0: f881 2027 strb.w r2, [r1, #39] ; 0x27 + pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); + 800c2e4: f3c3 2201 ubfx r2, r3, #8, #2 + pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); + 800c2e8: f3c3 0346 ubfx r3, r3, #1, #7 + pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); + 800c2ec: f881 2028 strb.w r2, [r1, #40] ; 0x28 + pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); + 800c2f0: f881 3029 strb.w r3, [r1, #41] ; 0x29 + pCSD->Reserved4 = 1; + 800c2f4: 2301 movs r3, #1 + 800c2f6: f881 302a strb.w r3, [r1, #42] ; 0x2a +} + 800c2fa: bd10 pop {r4, pc} + else if(hsd->SdCard.CardType == CARD_SDHC_SDXC) + 800c2fc: 2a01 cmp r2, #1 + 800c2fe: d10f bne.n 800c320 + pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U)); + 800c300: f8b0 206a ldrh.w r2, [r0, #106] ; 0x6a + 800c304: 041b lsls r3, r3, #16 + 800c306: f403 137c and.w r3, r3, #4128768 ; 0x3f0000 + 800c30a: 4313 orrs r3, r2 + 800c30c: 610b str r3, [r1, #16] + hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U); + 800c30e: 690b ldr r3, [r1, #16] + 800c310: 3301 adds r3, #1 + 800c312: 029b lsls r3, r3, #10 + 800c314: 64c3 str r3, [r0, #76] ; 0x4c + hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr; + 800c316: 6543 str r3, [r0, #84] ; 0x54 + hsd->SdCard.BlockSize = 512U; + 800c318: f44f 7300 mov.w r3, #512 ; 0x200 + 800c31c: 6503 str r3, [r0, #80] ; 0x50 + 800c31e: e7ab b.n 800c278 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c320: 6803 ldr r3, [r0, #0] + 800c322: 4a05 ldr r2, [pc, #20] ; (800c338 ) + 800c324: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c326: 6b83 ldr r3, [r0, #56] ; 0x38 + 800c328: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800c32c: 6383 str r3, [r0, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c32e: 2301 movs r3, #1 + 800c330: f880 3034 strb.w r3, [r0, #52] ; 0x34 + return HAL_ERROR; + 800c334: 4618 mov r0, r3 + 800c336: e7e0 b.n 800c2fa + 800c338: 1fe00fff .word 0x1fe00fff + +0800c33c : +{ + 800c33c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + 800c340: 2300 movs r3, #0 +{ + 800c342: b099 sub sp, #100 ; 0x64 + 800c344: 4604 mov r4, r0 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800c346: f44f 2000 mov.w r0, #524288 ; 0x80000 + Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + 800c34a: e9cd 3307 strd r3, r3, [sp, #28] + Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + 800c34e: e9cd 3309 strd r3, r3, [sp, #36] ; 0x24 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800c352: f7fd fb2d bl 80099b0 + if (sdmmc_clk == 0U) + 800c356: 4605 mov r5, r0 + 800c358: b948 cbnz r0, 800c36e + hsd->State = HAL_SD_STATE_READY; + 800c35a: 2501 movs r5, #1 + hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + 800c35c: f04f 6300 mov.w r3, #134217728 ; 0x8000000 + hsd->State = HAL_SD_STATE_READY; + 800c360: f884 5034 strb.w r5, [r4, #52] ; 0x34 + hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + 800c364: 63a3 str r3, [r4, #56] ; 0x38 +} + 800c366: 4628 mov r0, r5 + 800c368: b019 add sp, #100 ; 0x64 + 800c36a: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + Init.Transceiver = hsd->Init.Transceiver; + 800c36e: 69a3 ldr r3, [r4, #24] + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c370: 6827 ldr r7, [r4, #0] + Init.Transceiver = hsd->Init.Transceiver; + 800c372: 930c str r3, [sp, #48] ; 0x30 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c374: 2b01 cmp r3, #1 + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c376: bf08 it eq + 800c378: 683b ldreq r3, [r7, #0] + Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ); + 800c37a: 4e99 ldr r6, [pc, #612] ; (800c5e0 ) + 800c37c: fbb0 f6f6 udiv r6, r0, r6 + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c380: bf04 itt eq + 800c382: f043 0310 orreq.w r3, r3, #16 + 800c386: 603b streq r3, [r7, #0] + status = SDMMC_Init(hsd->Instance, Init); + 800c388: 960b str r6, [sp, #44] ; 0x2c + 800c38a: ab0a add r3, sp, #40 ; 0x28 + 800c38c: e893 0007 ldmia.w r3, {r0, r1, r2} + 800c390: e88d 0007 stmia.w sp, {r0, r1, r2} + 800c394: ab07 add r3, sp, #28 + 800c396: cb0e ldmia r3, {r1, r2, r3} + 800c398: 4638 mov r0, r7 + 800c39a: f000 fcbb bl 800cd14 + if(status != HAL_OK) + 800c39e: b108 cbz r0, 800c3a4 + return HAL_ERROR; + 800c3a0: 2501 movs r5, #1 + 800c3a2: e7e0 b.n 800c366 + status = SDMMC_PowerState_ON(hsd->Instance); + 800c3a4: 6820 ldr r0, [r4, #0] + 800c3a6: f000 fcd7 bl 800cd58 + if(status != HAL_OK) + 800c3aa: 4607 mov r7, r0 + 800c3ac: 2800 cmp r0, #0 + 800c3ae: d1f7 bne.n 800c3a0 + sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv); + 800c3b0: 0076 lsls r6, r6, #1 + HAL_Delay(1U+ (74U*1000U/(sdmmc_clk))); + 800c3b2: 488c ldr r0, [pc, #560] ; (800c5e4 ) + sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv); + 800c3b4: fbb5 f5f6 udiv r5, r5, r6 + HAL_Delay(1U+ (74U*1000U/(sdmmc_clk))); + 800c3b8: fbb0 f0f5 udiv r0, r0, r5 + 800c3bc: 3001 adds r0, #1 + 800c3be: f7f7 faa8 bl 8003912 + __IO uint32_t count = 0U; + 800c3c2: 9706 str r7, [sp, #24] + uint32_t tickstart = HAL_GetTick(); + 800c3c4: f7fa fe92 bl 80070ec + 800c3c8: 4606 mov r6, r0 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c3ca: 6820 ldr r0, [r4, #0] + 800c3cc: f000 fd18 bl 800ce00 + if(errorstate != HAL_SD_ERROR_NONE) + 800c3d0: 4605 mov r5, r0 + 800c3d2: b940 cbnz r0, 800c3e6 + errorstate = SDMMC_CmdOperCond(hsd->Instance); + 800c3d4: 6820 ldr r0, [r4, #0] + 800c3d6: f001 f8fd bl 800d5d4 + if(errorstate != HAL_SD_ERROR_NONE) + 800c3da: b158 cbz r0, 800c3f4 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c3dc: 6820 ldr r0, [r4, #0] + hsd->SdCard.CardVersion = CARD_V1_X; + 800c3de: 6425 str r5, [r4, #64] ; 0x40 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c3e0: f000 fd0e bl 800ce00 + if(errorstate != HAL_SD_ERROR_NONE) + 800c3e4: b180 cbz r0, 800c408 + hsd->State = HAL_SD_STATE_READY; + 800c3e6: 2501 movs r5, #1 + 800c3e8: f884 5034 strb.w r5, [r4, #52] ; 0x34 + hsd->ErrorCode |= errorstate; + 800c3ec: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c3ee: 4318 orrs r0, r3 + 800c3f0: 63a0 str r0, [r4, #56] ; 0x38 + return HAL_ERROR; + 800c3f2: e7b8 b.n 800c366 + hsd->SdCard.CardVersion = CARD_V2_X; + 800c3f4: 2301 movs r3, #1 + 800c3f6: 6423 str r3, [r4, #64] ; 0x40 + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c3f8: 6820 ldr r0, [r4, #0] + 800c3fa: 2100 movs r1, #0 + 800c3fc: f000 fef5 bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c400: b128 cbz r0, 800c40e + return HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c402: f04f 5080 mov.w r0, #268435456 ; 0x10000000 + 800c406: e7ee b.n 800c3e6 + if( hsd->SdCard.CardVersion == CARD_V2_X) + 800c408: 6c23 ldr r3, [r4, #64] ; 0x40 + 800c40a: 2b01 cmp r3, #1 + 800c40c: d0f4 beq.n 800c3f8 + errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); + 800c40e: f8df 91dc ldr.w r9, [pc, #476] ; 800c5ec +{ + 800c412: 2700 movs r7, #0 + while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) + 800c414: f64f 78fe movw r8, #65534 ; 0xfffe + 800c418: 9b06 ldr r3, [sp, #24] + 800c41a: 4543 cmp r3, r8 + 800c41c: d800 bhi.n 800c420 + 800c41e: b12f cbz r7, 800c42c + if(count >= SDMMC_MAX_VOLT_TRIAL) + 800c420: 9b06 ldr r3, [sp, #24] + 800c422: 4543 cmp r3, r8 + 800c424: d918 bls.n 800c458 + return HAL_SD_ERROR_INVALID_VOLTRANGE; + 800c426: f04f 7080 mov.w r0, #16777216 ; 0x1000000 + 800c42a: e7dc b.n 800c3e6 + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c42c: 6820 ldr r0, [r4, #0] + 800c42e: 4639 mov r1, r7 + 800c430: f000 fedb bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c434: 2800 cmp r0, #0 + 800c436: d1d6 bne.n 800c3e6 + errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); + 800c438: 6820 ldr r0, [r4, #0] + 800c43a: 4649 mov r1, r9 + 800c43c: f001 f816 bl 800d46c + if(errorstate != HAL_SD_ERROR_NONE) + 800c440: 2800 cmp r0, #0 + 800c442: d1de bne.n 800c402 + response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c444: 4639 mov r1, r7 + 800c446: 6820 ldr r0, [r4, #0] + 800c448: f000 fcb7 bl 800cdba + count++; + 800c44c: 9b06 ldr r3, [sp, #24] + 800c44e: 3301 adds r3, #1 + response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c450: 4605 mov r5, r0 + validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); + 800c452: 0fc7 lsrs r7, r0, #31 + count++; + 800c454: 9306 str r3, [sp, #24] + 800c456: e7df b.n 800c418 + if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ + 800c458: f015 4380 ands.w r3, r5, #1073741824 ; 0x40000000 + 800c45c: d04b beq.n 800c4f6 + hsd->SdCard.CardType = CARD_SDHC_SDXC; + 800c45e: 2301 movs r3, #1 + 800c460: 63e3 str r3, [r4, #60] ; 0x3c + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c462: 69a3 ldr r3, [r4, #24] + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c464: 6820 ldr r0, [r4, #0] + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c466: 2b01 cmp r3, #1 + 800c468: d12d bne.n 800c4c6 + if((response & SD_SWITCH_1_8V_CAPACITY) == SD_SWITCH_1_8V_CAPACITY) + 800c46a: 01ef lsls r7, r5, #7 + 800c46c: d52b bpl.n 800c4c6 + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + 800c46e: f44f 7300 mov.w r3, #512 ; 0x200 + 800c472: 65e3 str r3, [r4, #92] ; 0x5c + hsd->Instance->POWER |= SDMMC_POWER_VSWITCHEN; + 800c474: 6803 ldr r3, [r0, #0] + 800c476: f043 0308 orr.w r3, r3, #8 + 800c47a: 6003 str r3, [r0, #0] + errorstate = SDMMC_CmdVoltageSwitch(hsd->Instance); + 800c47c: f000 ff4e bl 800d31c + if(errorstate != HAL_SD_ERROR_NONE) + 800c480: 2800 cmp r0, #0 + 800c482: d1b0 bne.n 800c3e6 + while(( hsd->Instance->STA & SDMMC_FLAG_CKSTOP) != SDMMC_FLAG_CKSTOP) + 800c484: 6823 ldr r3, [r4, #0] + 800c486: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c488: 0155 lsls r5, r2, #5 + 800c48a: d526 bpl.n 800c4da + hsd->Instance->ICR = SDMMC_FLAG_CKSTOP; + 800c48c: f04f 6280 mov.w r2, #67108864 ; 0x4000000 + 800c490: 639a str r2, [r3, #56] ; 0x38 + if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) != SDMMC_FLAG_BUSYD0) + 800c492: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c494: 02d8 lsls r0, r3, #11 + 800c496: d5b4 bpl.n 800c402 + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800c498: 2001 movs r0, #1 + 800c49a: f7fa fe97 bl 80071cc + hsd->Instance->POWER |= SDMMC_POWER_VSWITCH; + 800c49e: 6822 ldr r2, [r4, #0] + 800c4a0: 6813 ldr r3, [r2, #0] + 800c4a2: f043 0304 orr.w r3, r3, #4 + 800c4a6: 6013 str r3, [r2, #0] + while(( hsd->Instance->STA & SDMMC_FLAG_VSWEND) != SDMMC_FLAG_VSWEND) + 800c4a8: 6823 ldr r3, [r4, #0] + 800c4aa: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c4ac: 0191 lsls r1, r2, #6 + 800c4ae: d51c bpl.n 800c4ea + hsd->Instance->ICR = SDMMC_FLAG_VSWEND; + 800c4b0: f04f 7200 mov.w r2, #33554432 ; 0x2000000 + 800c4b4: 639a str r2, [r3, #56] ; 0x38 + if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) == SDMMC_FLAG_BUSYD0) + 800c4b6: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c4b8: 02d2 lsls r2, r2, #11 + 800c4ba: d4b4 bmi.n 800c426 + hsd->Instance->POWER = 0x13U; + 800c4bc: 2213 movs r2, #19 + 800c4be: 601a str r2, [r3, #0] + hsd->Instance->ICR = 0xFFFFFFFFU; + 800c4c0: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800c4c4: 639a str r2, [r3, #56] ; 0x38 + uint16_t sd_rca = 1U; + 800c4c6: 2301 movs r3, #1 + if(SDMMC_GetPowerState(hsd->Instance) == 0U) + 800c4c8: 6820 ldr r0, [r4, #0] + uint16_t sd_rca = 1U; + 800c4ca: f8ad 3016 strh.w r3, [sp, #22] + if(SDMMC_GetPowerState(hsd->Instance) == 0U) + 800c4ce: f000 fc59 bl 800cd84 + 800c4d2: b990 cbnz r0, 800c4fa + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800c4d4: f04f 6080 mov.w r0, #67108864 ; 0x4000000 + 800c4d8: e785 b.n 800c3e6 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c4da: f7fa fe07 bl 80070ec + 800c4de: 1b80 subs r0, r0, r6 + 800c4e0: 3001 adds r0, #1 + 800c4e2: d1cf bne.n 800c484 + return HAL_SD_ERROR_TIMEOUT; + 800c4e4: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800c4e8: e77d b.n 800c3e6 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c4ea: f7fa fdff bl 80070ec + 800c4ee: 1b80 subs r0, r0, r6 + 800c4f0: 3001 adds r0, #1 + 800c4f2: d1d9 bne.n 800c4a8 + 800c4f4: e7f6 b.n 800c4e4 + hsd->SdCard.CardType = CARD_SDSC; + 800c4f6: 63e3 str r3, [r4, #60] ; 0x3c + if(errorstate != HAL_SD_ERROR_NONE) + 800c4f8: e7e5 b.n 800c4c6 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c4fa: 6be3 ldr r3, [r4, #60] ; 0x3c + 800c4fc: 2b03 cmp r3, #3 + 800c4fe: d045 beq.n 800c58c + errorstate = SDMMC_CmdSendCID(hsd->Instance); + 800c500: 6820 ldr r0, [r4, #0] + 800c502: f000 ff65 bl 800d3d0 + if(errorstate != HAL_SD_ERROR_NONE) + 800c506: 2800 cmp r0, #0 + 800c508: f47f af6d bne.w 800c3e6 + hsd->CID[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c50c: 4601 mov r1, r0 + 800c50e: 6820 ldr r0, [r4, #0] + 800c510: f000 fc53 bl 800cdba + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c514: 2104 movs r1, #4 + hsd->CID[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c516: 6720 str r0, [r4, #112] ; 0x70 + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c518: 6820 ldr r0, [r4, #0] + 800c51a: f000 fc4e bl 800cdba + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c51e: 2108 movs r1, #8 + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c520: 6760 str r0, [r4, #116] ; 0x74 + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c522: 6820 ldr r0, [r4, #0] + 800c524: f000 fc49 bl 800cdba + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c528: 210c movs r1, #12 + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c52a: 67a0 str r0, [r4, #120] ; 0x78 + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c52c: 6820 ldr r0, [r4, #0] + 800c52e: f000 fc44 bl 800cdba + if(hsd->SdCard.CardType != CARD_SECURED) + 800c532: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c534: 67e0 str r0, [r4, #124] ; 0x7c + if(hsd->SdCard.CardType != CARD_SECURED) + 800c536: 2b03 cmp r3, #3 + 800c538: d028 beq.n 800c58c + errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca); + 800c53a: 6820 ldr r0, [r4, #0] + 800c53c: f10d 0116 add.w r1, sp, #22 + 800c540: f001 f804 bl 800d54c + if(errorstate != HAL_SD_ERROR_NONE) + 800c544: 2800 cmp r0, #0 + 800c546: f47f af4e bne.w 800c3e6 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c54a: 6be3 ldr r3, [r4, #60] ; 0x3c + errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c54c: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SECURED) + 800c54e: 2b03 cmp r3, #3 + 800c550: d01c beq.n 800c58c + hsd->SdCard.RelCardAdd = sd_rca; + 800c552: f8bd 1016 ldrh.w r1, [sp, #22] + 800c556: 64a1 str r1, [r4, #72] ; 0x48 + errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c558: 0409 lsls r1, r1, #16 + 800c55a: f000 ff4f bl 800d3fc + if(errorstate != HAL_SD_ERROR_NONE) + 800c55e: 2800 cmp r0, #0 + 800c560: f47f af41 bne.w 800c3e6 + hsd->CSD[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c564: 4601 mov r1, r0 + 800c566: 6820 ldr r0, [r4, #0] + 800c568: f000 fc27 bl 800cdba + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c56c: 2104 movs r1, #4 + hsd->CSD[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c56e: 6620 str r0, [r4, #96] ; 0x60 + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c570: 6820 ldr r0, [r4, #0] + 800c572: f000 fc22 bl 800cdba + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c576: 2108 movs r1, #8 + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c578: 6660 str r0, [r4, #100] ; 0x64 + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c57a: 6820 ldr r0, [r4, #0] + 800c57c: f000 fc1d bl 800cdba + hsd->CSD[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c580: 210c movs r1, #12 + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c582: 66a0 str r0, [r4, #104] ; 0x68 + hsd->CSD[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c584: 6820 ldr r0, [r4, #0] + 800c586: f000 fc18 bl 800cdba + 800c58a: 66e0 str r0, [r4, #108] ; 0x6c + hsd->SdCard.Class = (SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2) >> 20U); + 800c58c: 2104 movs r1, #4 + 800c58e: 6820 ldr r0, [r4, #0] + 800c590: f000 fc13 bl 800cdba + 800c594: 0d00 lsrs r0, r0, #20 + 800c596: 6460 str r0, [r4, #68] ; 0x44 + if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK) + 800c598: a90d add r1, sp, #52 ; 0x34 + 800c59a: 4620 mov r0, r4 + 800c59c: f7ff fe18 bl 800c1d0 + 800c5a0: 4605 mov r5, r0 + 800c5a2: 2800 cmp r0, #0 + 800c5a4: f47f af2d bne.w 800c402 + errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U)); + 800c5a8: 6ca2 ldr r2, [r4, #72] ; 0x48 + 800c5aa: 4603 mov r3, r0 + 800c5ac: 0412 lsls r2, r2, #16 + 800c5ae: 6820 ldr r0, [r4, #0] + 800c5b0: f000 fe02 bl 800d1b8 + if(errorstate != HAL_SD_ERROR_NONE) + 800c5b4: 2800 cmp r0, #0 + 800c5b6: f47f af16 bne.w 800c3e6 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800c5ba: 6820 ldr r0, [r4, #0] + 800c5bc: f44f 7100 mov.w r1, #512 ; 0x200 + 800c5c0: f000 fcda bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800c5c4: 2800 cmp r0, #0 + 800c5c6: f43f aece beq.w 800c366 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c5ca: 6823 ldr r3, [r4, #0] + 800c5cc: 4a06 ldr r2, [pc, #24] ; (800c5e8 ) + 800c5ce: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c5d0: 6ba3 ldr r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c5d2: 2501 movs r5, #1 + hsd->ErrorCode |= errorstate; + 800c5d4: 4318 orrs r0, r3 + 800c5d6: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c5d8: f884 5034 strb.w r5, [r4, #52] ; 0x34 + return HAL_ERROR; + 800c5dc: e6c3 b.n 800c366 + 800c5de: bf00 nop + 800c5e0: 000c3500 .word 0x000c3500 + 800c5e4: 00012110 .word 0x00012110 + 800c5e8: 1fe00fff .word 0x1fe00fff + 800c5ec: c1100000 .word 0xc1100000 + +0800c5f0 : +{ + 800c5f0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800c5f4: b096 sub sp, #88 ; 0x58 + 800c5f6: 4604 mov r4, r0 + 800c5f8: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800c5fa: f7fa fd77 bl 80070ec + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c5fe: 2100 movs r1, #0 + uint32_t tickstart = HAL_GetTick(); + 800c600: 4606 mov r6, r0 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c602: 6820 ldr r0, [r4, #0] + 800c604: f000 fbd9 bl 800cdba + 800c608: 0183 lsls r3, r0, #6 + 800c60a: d50b bpl.n 800c624 + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + 800c60c: f44f 6000 mov.w r0, #2048 ; 0x800 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c610: 6823 ldr r3, [r4, #0] + 800c612: 4a54 ldr r2, [pc, #336] ; (800c764 ) + 800c614: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c616: 6ba3 ldr r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c618: 2501 movs r5, #1 + hsd->ErrorCode |= errorstate; + 800c61a: 4318 orrs r0, r3 + 800c61c: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c61e: f884 5034 strb.w r5, [r4, #52] ; 0x34 + status = HAL_ERROR; + 800c622: e08a b.n 800c73a + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800c624: 6820 ldr r0, [r4, #0] + 800c626: 2140 movs r1, #64 ; 0x40 + 800c628: f000 fca6 bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800c62c: b110 cbz r0, 800c634 + hsd->ErrorCode |= HAL_SD_ERROR_NONE; + 800c62e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c630: 63a3 str r3, [r4, #56] ; 0x38 + return errorstate; + 800c632: e7ed b.n 800c610 + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c634: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800c636: 6820 ldr r0, [r4, #0] + 800c638: 0409 lsls r1, r1, #16 + 800c63a: f000 fdd6 bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c63e: 2800 cmp r0, #0 + 800c640: d1f5 bne.n 800c62e + config.DataLength = 64U; + 800c642: 2340 movs r3, #64 ; 0x40 + 800c644: f04f 37ff mov.w r7, #4294967295 ; 0xffffffff + 800c648: e9cd 7300 strd r7, r3, [sp] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800c64c: f04f 0c60 mov.w ip, #96 ; 0x60 + 800c650: 2302 movs r3, #2 + 800c652: e9cd c302 strd ip, r3, [sp, #8] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800c656: 9004 str r0, [sp, #16] + config.DPSM = SDMMC_DPSM_ENABLE; + 800c658: 2301 movs r3, #1 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c65a: 6820 ldr r0, [r4, #0] + config.DPSM = SDMMC_DPSM_ENABLE; + 800c65c: 9305 str r3, [sp, #20] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c65e: 4669 mov r1, sp + 800c660: f000 fbae bl 800cdc0 + errorstate = SDMMC_CmdStatusRegister(hsd->Instance); + 800c664: 6820 ldr r0, [r4, #0] + 800c666: f000 fe40 bl 800d2ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c66a: 2800 cmp r0, #0 + 800c66c: d1df bne.n 800c62e + uint32_t *pData = pSDstatus; + 800c66e: af06 add r7, sp, #24 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800c670: 6823 ldr r3, [r4, #0] + 800c672: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c674: f412 7f95 tst.w r2, #298 ; 0x12a + 800c678: d00a beq.n 800c690 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c67a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c67c: 0711 lsls r1, r2, #28 + 800c67e: d46f bmi.n 800c760 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c680: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c682: 0792 lsls r2, r2, #30 + 800c684: d46a bmi.n 800c75c + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800c686: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c688: 069b lsls r3, r3, #26 + 800c68a: d51e bpl.n 800c6ca + return HAL_SD_ERROR_RX_OVERRUN; + 800c68c: 2020 movs r0, #32 + 800c68e: e7bf b.n 800c610 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800c690: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c692: 0418 lsls r0, r3, #16 + 800c694: d508 bpl.n 800c6a8 + 800c696: f107 0820 add.w r8, r7, #32 + *pData = SDMMC_ReadFIFO(hsd->Instance); + 800c69a: 6820 ldr r0, [r4, #0] + 800c69c: f000 fb54 bl 800cd48 + 800c6a0: f847 0b04 str.w r0, [r7], #4 + for(count = 0U; count < 8U; count++) + 800c6a4: 45b8 cmp r8, r7 + 800c6a6: d1f8 bne.n 800c69a + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c6a8: f7fa fd20 bl 80070ec + 800c6ac: 1b80 subs r0, r0, r6 + 800c6ae: 3001 adds r0, #1 + 800c6b0: d1de bne.n 800c670 + return HAL_SD_ERROR_TIMEOUT; + 800c6b2: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + if(errorstate != HAL_SD_ERROR_NONE) + 800c6b6: e7ab b.n 800c610 + *pData = SDMMC_ReadFIFO(hsd->Instance); + 800c6b8: f000 fb46 bl 800cd48 + 800c6bc: f847 0b04 str.w r0, [r7], #4 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c6c0: f7fa fd14 bl 80070ec + 800c6c4: 1b80 subs r0, r0, r6 + 800c6c6: 3001 adds r0, #1 + 800c6c8: d0f3 beq.n 800c6b2 + while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DPSMACT))) + 800c6ca: 6820 ldr r0, [r4, #0] + 800c6cc: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c6ce: f413 5380 ands.w r3, r3, #4096 ; 0x1000 + 800c6d2: d1f1 bne.n 800c6b8 + pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); + 800c6d4: 9906 ldr r1, [sp, #24] + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c6d6: 4a24 ldr r2, [pc, #144] ; (800c768 ) + 800c6d8: 6382 str r2, [r0, #56] ; 0x38 + pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); + 800c6da: f3c1 1281 ubfx r2, r1, #6, #2 + 800c6de: 702a strb r2, [r5, #0] + pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U); + 800c6e0: f3c1 1240 ubfx r2, r1, #5, #1 + 800c6e4: 706a strb r2, [r5, #1] + pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U)); + 800c6e6: 0a0a lsrs r2, r1, #8 + 800c6e8: f022 02ff bic.w r2, r2, #255 ; 0xff + 800c6ec: ea42 6211 orr.w r2, r2, r1, lsr #24 + 800c6f0: b292 uxth r2, r2 + 800c6f2: 806a strh r2, [r5, #2] + pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U) | ((sd_status[1] & 0xFF00U) << 8U) | + 800c6f4: 9a07 ldr r2, [sp, #28] + 800c6f6: ba12 rev r2, r2 + 800c6f8: 606a str r2, [r5, #4] + pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU); + 800c6fa: 9a08 ldr r2, [sp, #32] + 800c6fc: b2d1 uxtb r1, r2 + 800c6fe: 7229 strb r1, [r5, #8] + pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U); + 800c700: f3c2 2107 ubfx r1, r2, #8, #8 + 800c704: 7269 strb r1, [r5, #9] + pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U); + 800c706: f3c2 5103 ubfx r1, r2, #20, #4 + 800c70a: 72a9 strb r1, [r5, #10] + pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU)); + 800c70c: 9909 ldr r1, [sp, #36] ; 0x24 + 800c70e: 0c12 lsrs r2, r2, #16 + 800c710: b2c8 uxtb r0, r1 + 800c712: f022 02ff bic.w r2, r2, #255 ; 0xff + 800c716: 4302 orrs r2, r0 + 800c718: 81aa strh r2, [r5, #12] + pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U); + 800c71a: f3c1 2285 ubfx r2, r1, #10, #6 + 800c71e: 73aa strb r2, [r5, #14] + pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U); + 800c720: f3c1 2201 ubfx r2, r1, #8, #2 + 800c724: 73ea strb r2, [r5, #15] + pStatus->UhsSpeedGrade = (uint8_t)((sd_status[3] & 0x00F0U) >> 4U); + 800c726: f3c1 1203 ubfx r2, r1, #4, #4 + 800c72a: 742a strb r2, [r5, #16] + pStatus->UhsAllocationUnitSize = (uint8_t)(sd_status[3] & 0x000FU) ; + 800c72c: f001 010f and.w r1, r1, #15 + pStatus->VideoSpeedClass = (uint8_t)((sd_status[4] & 0xFF000000U) >> 24U); + 800c730: f89d 202b ldrb.w r2, [sp, #43] ; 0x2b + pStatus->UhsAllocationUnitSize = (uint8_t)(sd_status[3] & 0x000FU) ; + 800c734: 7469 strb r1, [r5, #17] + pStatus->VideoSpeedClass = (uint8_t)((sd_status[4] & 0xFF000000U) >> 24U); + 800c736: 74aa strb r2, [r5, #18] + HAL_StatusTypeDef status = HAL_OK; + 800c738: 461d mov r5, r3 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800c73a: 6820 ldr r0, [r4, #0] + 800c73c: f44f 7100 mov.w r1, #512 ; 0x200 + 800c740: f000 fc1a bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800c744: b130 cbz r0, 800c754 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c746: 6823 ldr r3, [r4, #0] + 800c748: 4a06 ldr r2, [pc, #24] ; (800c764 ) + 800c74a: 639a str r2, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c74c: 2501 movs r5, #1 + hsd->ErrorCode = errorstate; + 800c74e: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c750: f884 5034 strb.w r5, [r4, #52] ; 0x34 +} + 800c754: 4628 mov r0, r5 + 800c756: b016 add sp, #88 ; 0x58 + 800c758: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + return HAL_SD_ERROR_DATA_CRC_FAIL; + 800c75c: 2002 movs r0, #2 + 800c75e: e757 b.n 800c610 + return HAL_SD_ERROR_DATA_TIMEOUT; + 800c760: 2008 movs r0, #8 + 800c762: e755 b.n 800c610 + 800c764: 1fe00fff .word 0x1fe00fff + 800c768: 18000f3a .word 0x18000f3a + +0800c76c : + pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType); + 800c76c: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800c76e: 600b str r3, [r1, #0] + pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion); + 800c770: 6c03 ldr r3, [r0, #64] ; 0x40 + 800c772: 604b str r3, [r1, #4] + pCardInfo->Class = (uint32_t)(hsd->SdCard.Class); + 800c774: 6c43 ldr r3, [r0, #68] ; 0x44 + 800c776: 608b str r3, [r1, #8] + pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd); + 800c778: 6c83 ldr r3, [r0, #72] ; 0x48 + 800c77a: 60cb str r3, [r1, #12] + pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr); + 800c77c: 6cc3 ldr r3, [r0, #76] ; 0x4c + 800c77e: 610b str r3, [r1, #16] + pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize); + 800c780: 6d03 ldr r3, [r0, #80] ; 0x50 + 800c782: 614b str r3, [r1, #20] + pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr); + 800c784: 6d43 ldr r3, [r0, #84] ; 0x54 + 800c786: 618b str r3, [r1, #24] + pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize); + 800c788: 6d83 ldr r3, [r0, #88] ; 0x58 + 800c78a: 61cb str r3, [r1, #28] +} + 800c78c: 2000 movs r0, #0 + 800c78e: 4770 bx lr + +0800c790 : +{ + 800c790: b530 push {r4, r5, lr} + hsd->State = HAL_SD_STATE_BUSY; + 800c792: 2303 movs r3, #3 + 800c794: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c798: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800c79a: 2b03 cmp r3, #3 +{ + 800c79c: b08b sub sp, #44 ; 0x2c + 800c79e: 4604 mov r4, r0 + 800c7a0: 460d mov r5, r1 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c7a2: d002 beq.n 800c7aa + if(WideMode == SDMMC_BUS_WIDE_8B) + 800c7a4: f5b1 4f00 cmp.w r1, #32768 ; 0x8000 + 800c7a8: d103 bne.n 800c7b2 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c7aa: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c7ac: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800c7b0: e049 b.n 800c846 + else if(WideMode == SDMMC_BUS_WIDE_4B) + 800c7b2: f5b1 4f80 cmp.w r1, #16384 ; 0x4000 + 800c7b6: d123 bne.n 800c800 + uint32_t scr[2U] = {0UL, 0UL}; + 800c7b8: 2100 movs r1, #0 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c7ba: 6800 ldr r0, [r0, #0] + uint32_t scr[2U] = {0UL, 0UL}; + 800c7bc: e9cd 1104 strd r1, r1, [sp, #16] + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c7c0: f000 fafb bl 800cdba + 800c7c4: 0180 lsls r0, r0, #6 + 800c7c6: d435 bmi.n 800c834 + errorstate = SD_FindSCR(hsd, scr); + 800c7c8: a904 add r1, sp, #16 + 800c7ca: 4620 mov r0, r4 + 800c7cc: f7ff fa32 bl 800bc34 + if(errorstate != HAL_SD_ERROR_NONE) + 800c7d0: b960 cbnz r0, 800c7ec + if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO) + 800c7d2: 9b05 ldr r3, [sp, #20] + 800c7d4: 0359 lsls r1, r3, #13 + 800c7d6: d530 bpl.n 800c83a + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c7d8: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800c7da: 6820 ldr r0, [r4, #0] + 800c7dc: 0409 lsls r1, r1, #16 + 800c7de: f000 fd04 bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c7e2: b918 cbnz r0, 800c7ec + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U); + 800c7e4: 2102 movs r1, #2 + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U); + 800c7e6: 6820 ldr r0, [r4, #0] + 800c7e8: f000 fd18 bl 800d21c + hsd->ErrorCode |= errorstate; + 800c7ec: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c7ee: 4318 orrs r0, r3 + 800c7f0: 63a0 str r0, [r4, #56] ; 0x38 + if(hsd->ErrorCode != HAL_SD_ERROR_NONE) + 800c7f2: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c7f4: b34b cbz r3, 800c84a + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c7f6: 6823 ldr r3, [r4, #0] + 800c7f8: 4a42 ldr r2, [pc, #264] ; (800c904 ) + 800c7fa: 639a str r2, [r3, #56] ; 0x38 + status = HAL_ERROR; + 800c7fc: 2501 movs r5, #1 + 800c7fe: e054 b.n 800c8aa + else if(WideMode == SDMMC_BUS_WIDE_1B) + 800c800: b9f1 cbnz r1, 800c840 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c802: 6800 ldr r0, [r0, #0] + uint32_t scr[2U] = {0UL, 0UL}; + 800c804: e9cd 1104 strd r1, r1, [sp, #16] + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c808: f000 fad7 bl 800cdba + 800c80c: 0182 lsls r2, r0, #6 + 800c80e: d411 bmi.n 800c834 + errorstate = SD_FindSCR(hsd, scr); + 800c810: a904 add r1, sp, #16 + 800c812: 4620 mov r0, r4 + 800c814: f7ff fa0e bl 800bc34 + if(errorstate != HAL_SD_ERROR_NONE) + 800c818: 2800 cmp r0, #0 + 800c81a: d1e7 bne.n 800c7ec + if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO) + 800c81c: 9b05 ldr r3, [sp, #20] + 800c81e: 03db lsls r3, r3, #15 + 800c820: d50b bpl.n 800c83a + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c822: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800c824: 6820 ldr r0, [r4, #0] + 800c826: 0409 lsls r1, r1, #16 + 800c828: f000 fcdf bl 800d1ea + if(errorstate != HAL_SD_ERROR_NONE) + 800c82c: 2800 cmp r0, #0 + 800c82e: d1dd bne.n 800c7ec + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U); + 800c830: 4601 mov r1, r0 + 800c832: e7d8 b.n 800c7e6 + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + 800c834: f44f 6000 mov.w r0, #2048 ; 0x800 + 800c838: e7d8 b.n 800c7ec + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800c83a: f04f 6080 mov.w r0, #67108864 ; 0x4000000 + 800c83e: e7d5 b.n 800c7ec + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800c840: 6b83 ldr r3, [r0, #56] ; 0x38 + 800c842: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c846: 63a3 str r3, [r4, #56] ; 0x38 + 800c848: e7d3 b.n 800c7f2 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800c84a: f44f 2000 mov.w r0, #524288 ; 0x80000 + 800c84e: f7fd f8af bl 80099b0 + if (sdmmc_clk != 0U) + 800c852: 2800 cmp r0, #0 + 800c854: d051 beq.n 800c8fa + Init.ClockEdge = hsd->Init.ClockEdge; + 800c856: 6863 ldr r3, [r4, #4] + 800c858: 9304 str r3, [sp, #16] + Init.ClockPowerSave = hsd->Init.ClockPowerSave; + 800c85a: 68a3 ldr r3, [r4, #8] + if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) + 800c85c: 492a ldr r1, [pc, #168] ; (800c908 ) + 800c85e: fbb0 f2f1 udiv r2, r0, r1 + Init.BusWide = WideMode; + 800c862: e9cd 3505 strd r3, r5, [sp, #20] + Init.HardwareFlowControl = hsd->Init.HardwareFlowControl; + 800c866: 6923 ldr r3, [r4, #16] + 800c868: 9307 str r3, [sp, #28] + if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) + 800c86a: 6963 ldr r3, [r4, #20] + 800c86c: 4293 cmp r3, r2 + 800c86e: d301 bcc.n 800c874 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800c870: 9308 str r3, [sp, #32] + 800c872: e00d b.n 800c890 + else if (hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) + 800c874: 6de5 ldr r5, [r4, #92] ; 0x5c + 800c876: f5b5 7f00 cmp.w r5, #512 ; 0x200 + 800c87a: d0f9 beq.n 800c870 + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800c87c: f5b5 7f80 cmp.w r5, #256 ; 0x100 + 800c880: d12e bne.n 800c8e0 + if (hsd->Init.ClockDiv == 0U) + 800c882: bb3b cbnz r3, 800c8d4 + if (sdmmc_clk > SD_HIGH_SPEED_FREQ) + 800c884: 4288 cmp r0, r1 + 800c886: d923 bls.n 800c8d0 + Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); + 800c888: 4b20 ldr r3, [pc, #128] ; (800c90c ) + 800c88a: fbb0 f0f3 udiv r0, r0, r3 + 800c88e: 9008 str r0, [sp, #32] + Init.Transceiver = hsd->Init.Transceiver; + 800c890: 69a3 ldr r3, [r4, #24] + 800c892: 9309 str r3, [sp, #36] ; 0x24 + (void)SDMMC_Init(hsd->Instance, Init); + 800c894: ab0a add r3, sp, #40 ; 0x28 + 800c896: e913 0007 ldmdb r3, {r0, r1, r2} + 800c89a: e88d 0007 stmia.w sp, {r0, r1, r2} + 800c89e: ab04 add r3, sp, #16 + 800c8a0: cb0e ldmia r3, {r1, r2, r3} + 800c8a2: 6820 ldr r0, [r4, #0] + 800c8a4: f000 fa36 bl 800cd14 + HAL_StatusTypeDef status = HAL_OK; + 800c8a8: 2500 movs r5, #0 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800c8aa: 6820 ldr r0, [r4, #0] + 800c8ac: f44f 7100 mov.w r1, #512 ; 0x200 + 800c8b0: f000 fb62 bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800c8b4: b130 cbz r0, 800c8c4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c8b6: 6823 ldr r3, [r4, #0] + 800c8b8: 4a12 ldr r2, [pc, #72] ; (800c904 ) + 800c8ba: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c8bc: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c8be: 4318 orrs r0, r3 + 800c8c0: 63a0 str r0, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800c8c2: 2501 movs r5, #1 + hsd->State = HAL_SD_STATE_READY; + 800c8c4: 2301 movs r3, #1 +} + 800c8c6: 4628 mov r0, r5 + hsd->State = HAL_SD_STATE_READY; + 800c8c8: f884 3034 strb.w r3, [r4, #52] ; 0x34 +} + 800c8cc: b00b add sp, #44 ; 0x2c + 800c8ce: bd30 pop {r4, r5, pc} + Init.ClockDiv = hsd->Init.ClockDiv; + 800c8d0: 2300 movs r3, #0 + 800c8d2: e7cd b.n 800c870 + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ) + 800c8d4: 005a lsls r2, r3, #1 + 800c8d6: fbb0 f2f2 udiv r2, r0, r2 + 800c8da: 428a cmp r2, r1 + 800c8dc: d9c8 bls.n 800c870 + 800c8de: e7d3 b.n 800c888 + if (hsd->Init.ClockDiv == 0U) + 800c8e0: 490b ldr r1, [pc, #44] ; (800c910 ) + 800c8e2: b91b cbnz r3, 800c8ec + if (sdmmc_clk > SD_NORMAL_SPEED_FREQ) + 800c8e4: 4288 cmp r0, r1 + 800c8e6: d9f3 bls.n 800c8d0 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800c8e8: 9208 str r2, [sp, #32] + 800c8ea: e7d1 b.n 800c890 + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ) + 800c8ec: 005d lsls r5, r3, #1 + 800c8ee: fbb0 f0f5 udiv r0, r0, r5 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800c8f2: 4288 cmp r0, r1 + 800c8f4: bf88 it hi + 800c8f6: 4613 movhi r3, r2 + 800c8f8: e7ba b.n 800c870 + hsd->ErrorCode |= SDMMC_ERROR_INVALID_PARAMETER; + 800c8fa: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c8fc: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + 800c900: 63a3 str r3, [r4, #56] ; 0x38 + 800c902: e77b b.n 800c7fc + 800c904: 1fe00fff .word 0x1fe00fff + 800c908: 02faf080 .word 0x02faf080 + 800c90c: 05f5e100 .word 0x05f5e100 + 800c910: 017d7840 .word 0x017d7840 + +0800c914 : + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c914: 6c81 ldr r1, [r0, #72] ; 0x48 +{ + 800c916: b510 push {r4, lr} + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c918: 0409 lsls r1, r1, #16 +{ + 800c91a: 4604 mov r4, r0 + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c91c: 6800 ldr r0, [r0, #0] + 800c91e: f000 fccb bl 800d2b8 + if(errorstate != HAL_SD_ERROR_NONE) + 800c922: 4601 mov r1, r0 + 800c924: b928 cbnz r0, 800c932 + *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c926: 6820 ldr r0, [r4, #0] + 800c928: f000 fa47 bl 800cdba +} + 800c92c: f3c0 2043 ubfx r0, r0, #9, #4 + 800c930: bd10 pop {r4, pc} + hsd->ErrorCode |= errorstate; + 800c932: 6ba0 ldr r0, [r4, #56] ; 0x38 + 800c934: 4308 orrs r0, r1 + 800c936: 63a0 str r0, [r4, #56] ; 0x38 + uint32_t resp1 = 0; + 800c938: 2000 movs r0, #0 + 800c93a: e7f7 b.n 800c92c + +0800c93c : +{ + 800c93c: b570 push {r4, r5, r6, lr} + if(hsd == NULL) + 800c93e: 4604 mov r4, r0 +{ + 800c940: b086 sub sp, #24 + if(hsd == NULL) + 800c942: b918 cbnz r0, 800c94c + return HAL_ERROR; + 800c944: 2501 movs r5, #1 +} + 800c946: 4628 mov r0, r5 + 800c948: b006 add sp, #24 + 800c94a: bd70 pop {r4, r5, r6, pc} + if(hsd->State == HAL_SD_STATE_RESET) + 800c94c: f890 3034 ldrb.w r3, [r0, #52] ; 0x34 + 800c950: f003 02ff and.w r2, r3, #255 ; 0xff + 800c954: b913 cbnz r3, 800c95c + hsd->Lock = HAL_UNLOCKED; + 800c956: 7702 strb r2, [r0, #28] + HAL_SD_MspInit(hsd); + 800c958: f7ff fa5a bl 800be10 + hsd->State = HAL_SD_STATE_BUSY; + 800c95c: 2303 movs r3, #3 + 800c95e: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if (HAL_SD_InitCard(hsd) != HAL_OK) + 800c962: 4620 mov r0, r4 + 800c964: f7ff fcea bl 800c33c + 800c968: 2800 cmp r0, #0 + 800c96a: d1eb bne.n 800c944 + if( HAL_SD_GetCardStatus(hsd, &CardStatus) != HAL_OK) + 800c96c: a901 add r1, sp, #4 + 800c96e: 4620 mov r0, r4 + 800c970: f7ff fe3e bl 800c5f0 + 800c974: 2800 cmp r0, #0 + 800c976: d1e5 bne.n 800c944 + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800c978: 6be1 ldr r1, [r4, #60] ; 0x3c + speedgrade = CardStatus.UhsSpeedGrade; + 800c97a: f89d 2014 ldrb.w r2, [sp, #20] + unitsize = CardStatus.UhsAllocationUnitSize; + 800c97e: f89d 3015 ldrb.w r3, [sp, #21] + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800c982: 2901 cmp r1, #1 + speedgrade = CardStatus.UhsSpeedGrade; + 800c984: b2d2 uxtb r2, r2 + unitsize = CardStatus.UhsAllocationUnitSize; + 800c986: b2db uxtb r3, r3 + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800c988: d11c bne.n 800c9c4 + 800c98a: 4313 orrs r3, r2 + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + 800c98c: bf14 ite ne + 800c98e: f44f 7300 movne.w r3, #512 ; 0x200 + hsd->SdCard.CardSpeed = CARD_HIGH_SPEED; + 800c992: f44f 7380 moveq.w r3, #256 ; 0x100 + 800c996: 65e3 str r3, [r4, #92] ; 0x5c + if(HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK) + 800c998: 68e1 ldr r1, [r4, #12] + 800c99a: 4620 mov r0, r4 + 800c99c: f7ff fef8 bl 800c790 + 800c9a0: 4605 mov r5, r0 + 800c9a2: 2800 cmp r0, #0 + 800c9a4: d1ce bne.n 800c944 + tickstart = HAL_GetTick(); + 800c9a6: f7fa fba1 bl 80070ec + 800c9aa: 4606 mov r6, r0 + while((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + 800c9ac: 4620 mov r0, r4 + 800c9ae: f7ff ffb1 bl 800c914 + 800c9b2: 2804 cmp r0, #4 + 800c9b4: d108 bne.n 800c9c8 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c9b6: 2300 movs r3, #0 + 800c9b8: 63a3 str r3, [r4, #56] ; 0x38 + hsd->Context = SD_CONTEXT_NONE; + 800c9ba: 6323 str r3, [r4, #48] ; 0x30 + hsd->State = HAL_SD_STATE_READY; + 800c9bc: 2301 movs r3, #1 + 800c9be: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800c9c2: e7c0 b.n 800c946 + hsd->SdCard.CardSpeed = CARD_NORMAL_SPEED; + 800c9c4: 65e0 str r0, [r4, #92] ; 0x5c + 800c9c6: e7e7 b.n 800c998 + if((HAL_GetTick()-tickstart) >= SDMMC_DATATIMEOUT) + 800c9c8: f7fa fb90 bl 80070ec + 800c9cc: 1b80 subs r0, r0, r6 + 800c9ce: 3001 adds r0, #1 + 800c9d0: d1ec bne.n 800c9ac + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800c9d2: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800c9d6: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800c9d8: 2301 movs r3, #1 + 800c9da: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c9de: 2300 movs r3, #0 + 800c9e0: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800c9e2: 2503 movs r5, #3 + 800c9e4: e7af b.n 800c946 + ... + +0800c9e8 : +{ + 800c9e8: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + uint32_t SD_hs[16] = {0}; + 800c9ec: 2640 movs r6, #64 ; 0x40 +{ + 800c9ee: b096 sub sp, #88 ; 0x58 + 800c9f0: 4605 mov r5, r0 + uint32_t SD_hs[16] = {0}; + 800c9f2: 4632 mov r2, r6 + 800c9f4: 2100 movs r1, #0 + 800c9f6: a806 add r0, sp, #24 + 800c9f8: f000 fe3c bl 800d674 + uint32_t Timeout = HAL_GetTick(); + 800c9fc: f7fa fb76 bl 80070ec + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800ca00: 6deb ldr r3, [r5, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800ca02: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800ca04: 2b00 cmp r3, #0 + 800ca06: d066 beq.n 800cad6 + if(hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800ca08: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800ca0c: d004 beq.n 800ca18 + uint32_t errorstate = HAL_SD_ERROR_NONE; + 800ca0e: 2400 movs r4, #0 +} + 800ca10: 4620 mov r0, r4 + 800ca12: b016 add sp, #88 ; 0x58 + 800ca14: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hsd->Instance->DCTRL = 0; + 800ca18: 6828 ldr r0, [r5, #0] + 800ca1a: 2300 movs r3, #0 + 800ca1c: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800ca1e: 4631 mov r1, r6 + 800ca20: f000 faaa bl 800cf78 + if (errorstate != HAL_SD_ERROR_NONE) + 800ca24: 4604 mov r4, r0 + 800ca26: 2800 cmp r0, #0 + 800ca28: d1f2 bne.n 800ca10 + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800ca2a: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800ca2e: e9cd 3600 strd r3, r6, [sp] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800ca32: 2260 movs r2, #96 ; 0x60 + 800ca34: 2302 movs r3, #2 + 800ca36: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800ca3a: 9004 str r0, [sp, #16] + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800ca3c: 2301 movs r3, #1 + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800ca3e: 6828 ldr r0, [r5, #0] + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800ca40: 9305 str r3, [sp, #20] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800ca42: 4669 mov r1, sp + 800ca44: f000 f9bc bl 800cdc0 + 800ca48: 2800 cmp r0, #0 + 800ca4a: d147 bne.n 800cadc + errorstate = SDMMC_CmdSwitch(hsd->Instance,SDMMC_SDR25_SWITCH_PATTERN); + 800ca4c: 4925 ldr r1, [pc, #148] ; (800cae4 ) + 800ca4e: 6828 ldr r0, [r5, #0] + 800ca50: f000 fbfd bl 800d24e + if(errorstate != HAL_SD_ERROR_NONE) + 800ca54: 4604 mov r4, r0 + 800ca56: 2800 cmp r0, #0 + 800ca58: d1da bne.n 800ca10 + uint32_t count, loop = 0 ; + 800ca5a: 4607 mov r7, r0 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800ca5c: f240 592a movw r9, #1322 ; 0x52a + 800ca60: 682b ldr r3, [r5, #0] + 800ca62: 6b5e ldr r6, [r3, #52] ; 0x34 + 800ca64: ea16 0609 ands.w r6, r6, r9 + 800ca68: d005 beq.n 800ca76 + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800ca6a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800ca6c: 0710 lsls r0, r2, #28 + 800ca6e: d51e bpl.n 800caae + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800ca70: 2208 movs r2, #8 + 800ca72: 639a str r2, [r3, #56] ; 0x38 + return errorstate; + 800ca74: e7cc b.n 800ca10 + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800ca76: 6b5b ldr r3, [r3, #52] ; 0x34 + 800ca78: 041b lsls r3, r3, #16 + 800ca7a: d50b bpl.n 800ca94 + 800ca7c: ab06 add r3, sp, #24 + 800ca7e: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800ca82: 6828 ldr r0, [r5, #0] + 800ca84: f000 f960 bl 800cd48 + for (count = 0U; count < 8U; count++) + 800ca88: 3601 adds r6, #1 + 800ca8a: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800ca8c: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800ca90: d1f7 bne.n 800ca82 + loop ++; + 800ca92: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800ca94: f7fa fb2a bl 80070ec + 800ca98: eba0 0008 sub.w r0, r0, r8 + 800ca9c: 3001 adds r0, #1 + 800ca9e: d1df bne.n 800ca60 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800caa0: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + hsd->State= HAL_SD_STATE_READY; + 800caa4: 2301 movs r3, #1 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800caa6: 63ac str r4, [r5, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800caa8: f885 3034 strb.w r3, [r5, #52] ; 0x34 + return HAL_SD_ERROR_TIMEOUT; + 800caac: e7b0 b.n 800ca10 + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800caae: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cab0: 0791 lsls r1, r2, #30 + 800cab2: d502 bpl.n 800caba + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800cab4: 2402 movs r4, #2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cab6: 639c str r4, [r3, #56] ; 0x38 + return errorstate; + 800cab8: e7aa b.n 800ca10 + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800caba: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cabc: 0692 lsls r2, r2, #26 + 800cabe: d501 bpl.n 800cac4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cac0: 2420 movs r4, #32 + 800cac2: e7f8 b.n 800cab6 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800cac4: 4a08 ldr r2, [pc, #32] ; (800cae8 ) + 800cac6: 639a str r2, [r3, #56] ; 0x38 + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800cac8: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800cacc: 079b lsls r3, r3, #30 + 800cace: d49e bmi.n 800ca0e + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + 800cad0: f04f 5480 mov.w r4, #268435456 ; 0x10000000 + 800cad4: e79c b.n 800ca10 + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800cad6: f04f 6480 mov.w r4, #67108864 ; 0x4000000 + 800cada: e799 b.n 800ca10 + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + 800cadc: f44f 3480 mov.w r4, #65536 ; 0x10000 + 800cae0: e796 b.n 800ca10 + 800cae2: bf00 nop + 800cae4: 80ffff01 .word 0x80ffff01 + 800cae8: 18000f3a .word 0x18000f3a + +0800caec : +{ + 800caec: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + hsd->State = HAL_SD_STATE_BUSY; + 800caf0: 2303 movs r3, #3 + 800caf2: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800caf6: 6983 ldr r3, [r0, #24] + 800caf8: 2b01 cmp r3, #1 +{ + 800cafa: b096 sub sp, #88 ; 0x58 + 800cafc: 4604 mov r4, r0 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800cafe: f040 80cf bne.w 800cca0 + switch (SpeedMode) + 800cb02: 2904 cmp r1, #4 + 800cb04: f200 80eb bhi.w 800ccde + 800cb08: e8df f011 tbh [pc, r1, lsl #1] + 800cb0c: 00150005 .word 0x00150005 + 800cb10: 001e00dc .word 0x001e00dc + 800cb14: 0031 .short 0x0031 + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cb16: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800cb18: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cb1c: d002 beq.n 800cb24 + 800cb1e: 6bc2 ldr r2, [r0, #60] ; 0x3c + 800cb20: 2a01 cmp r2, #1 + 800cb22: d10a bne.n 800cb3a + hsd->Instance->CLKCR |= 0x00100000U; + 800cb24: 6822 ldr r2, [r4, #0] + 800cb26: 6853 ldr r3, [r2, #4] + 800cb28: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800cb2c: 6053 str r3, [r2, #4] + if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800cb2e: 4620 mov r0, r4 + 800cb30: f7ff f8e6 bl 800bd00 + 800cb34: b920 cbnz r0, 800cb40 + switch (SpeedMode) + 800cb36: 2500 movs r5, #0 + 800cb38: e063 b.n 800cc02 + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800cb3a: f5b3 7f80 cmp.w r3, #256 ; 0x100 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800cb3e: d1fa bne.n 800cb36 + if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800cb40: 4620 mov r0, r4 + 800cb42: f7ff ff51 bl 800c9e8 + 800cb46: e00f b.n 800cb68 + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cb48: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800cb4a: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cb4e: d003 beq.n 800cb58 + 800cb50: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800cb52: 2b01 cmp r3, #1 + 800cb54: f040 8089 bne.w 800cc6a + hsd->Instance->CLKCR |= 0x00100000U; + 800cb58: 6822 ldr r2, [r4, #0] + 800cb5a: 6853 ldr r3, [r2, #4] + 800cb5c: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800cb60: 6053 str r3, [r2, #4] + if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800cb62: 4620 mov r0, r4 + 800cb64: f7ff f8cc bl 800bd00 + if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800cb68: 2800 cmp r0, #0 + 800cb6a: d0e4 beq.n 800cb36 + 800cb6c: e07d b.n 800cc6a + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cb6e: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800cb70: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cb74: d002 beq.n 800cb7c + 800cb76: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800cb78: 2b01 cmp r3, #1 + 800cb7a: d176 bne.n 800cc6a + hsd->Instance->CLKCR |= 0x00100000U; + 800cb7c: 6822 ldr r2, [r4, #0] + 800cb7e: 6853 ldr r3, [r2, #4] + */ +static uint32_t SD_DDR_Mode(SD_HandleTypeDef *hsd) +{ + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + 800cb80: 2540 movs r5, #64 ; 0x40 + hsd->Instance->CLKCR |= 0x00100000U; + 800cb82: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800cb86: 6053 str r3, [r2, #4] + uint32_t SD_hs[16] = {0}; + 800cb88: 2100 movs r1, #0 + 800cb8a: 462a mov r2, r5 + 800cb8c: a806 add r0, sp, #24 + 800cb8e: f000 fd71 bl 800d674 + uint32_t count, loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + 800cb92: f7fa faab bl 80070ec + + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800cb96: 6de3 ldr r3, [r4, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800cb98: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800cb9a: 2b00 cmp r3, #0 + 800cb9c: d065 beq.n 800cc6a + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) && + 800cb9e: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cba2: d1c8 bne.n 800cb36 + 800cba4: 69a6 ldr r6, [r4, #24] + 800cba6: 2e01 cmp r6, #1 + 800cba8: d1c5 bne.n 800cb36 + (hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE)) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + 800cbaa: 6820 ldr r0, [r4, #0] + 800cbac: 2300 movs r3, #0 + 800cbae: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800cbb0: 4629 mov r1, r5 + 800cbb2: f000 f9e1 bl 800cf78 + + if (errorstate != HAL_SD_ERROR_NONE) + 800cbb6: 2800 cmp r0, #0 + 800cbb8: d157 bne.n 800cc6a + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800cbba: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800cbbe: e9cd 3500 strd r3, r5, [sp] + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800cbc2: e9cd 0604 strd r0, r6, [sp, #16] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800cbc6: 2260 movs r2, #96 ; 0x60 + 800cbc8: 2302 movs r3, #2 + + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800cbca: 6820 ldr r0, [r4, #0] + 800cbcc: 4669 mov r1, sp + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800cbce: e9cd 2302 strd r2, r3, [sp, #8] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800cbd2: f000 f8f5 bl 800cdc0 + 800cbd6: 4605 mov r5, r0 + 800cbd8: 2800 cmp r0, #0 + 800cbda: d146 bne.n 800cc6a + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SDMMC_DDR50_SWITCH_PATTERN); + 800cbdc: 494a ldr r1, [pc, #296] ; (800cd08 ) + 800cbde: 6820 ldr r0, [r4, #0] + 800cbe0: f000 fb35 bl 800d24e + if(errorstate != HAL_SD_ERROR_NONE) + 800cbe4: 4607 mov r7, r0 + 800cbe6: 2800 cmp r0, #0 + 800cbe8: d13f bne.n 800cc6a + { + return errorstate; + } + + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800cbea: f240 592a movw r9, #1322 ; 0x52a + 800cbee: 6823 ldr r3, [r4, #0] + 800cbf0: 6b5e ldr r6, [r3, #52] ; 0x34 + 800cbf2: ea16 0609 ands.w r6, r6, r9 + 800cbf6: d01d beq.n 800cc34 + hsd->State= HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800cbf8: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cbfa: 0710 lsls r0, r2, #28 + 800cbfc: d53b bpl.n 800cc76 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800cbfe: 2208 movs r2, #8 + 800cc00: 639a str r2, [r3, #56] ; 0x38 + tickstart = HAL_GetTick(); + 800cc02: f7fa fa73 bl 80070ec + 800cc06: 4606 mov r6, r0 + while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + 800cc08: 4620 mov r0, r4 + 800cc0a: f7ff fe83 bl 800c914 + 800cc0e: 2804 cmp r0, #4 + 800cc10: d169 bne.n 800cce6 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800cc12: 6820 ldr r0, [r4, #0] + 800cc14: f44f 7100 mov.w r1, #512 ; 0x200 + 800cc18: f000 f9ae bl 800cf78 + if(errorstate != HAL_SD_ERROR_NONE) + 800cc1c: b130 cbz r0, 800cc2c + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800cc1e: 6823 ldr r3, [r4, #0] + 800cc20: 4a3a ldr r2, [pc, #232] ; (800cd0c ) + 800cc22: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800cc24: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cc26: 4318 orrs r0, r3 + 800cc28: 63a0 str r0, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800cc2a: 2501 movs r5, #1 + hsd->State = HAL_SD_STATE_READY; + 800cc2c: 2301 movs r3, #1 + 800cc2e: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return status; + 800cc32: e064 b.n 800ccfe + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800cc34: 6b5b ldr r3, [r3, #52] ; 0x34 + 800cc36: 041b lsls r3, r3, #16 + 800cc38: d50b bpl.n 800cc52 + 800cc3a: ab06 add r3, sp, #24 + 800cc3c: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cc40: 6820 ldr r0, [r4, #0] + 800cc42: f000 f881 bl 800cd48 + for (count = 0U; count < 8U; count++) + 800cc46: 3601 adds r6, #1 + 800cc48: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cc4a: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800cc4e: d1f7 bne.n 800cc40 + loop ++; + 800cc50: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800cc52: f7fa fa4b bl 80070ec + 800cc56: eba0 0008 sub.w r0, r0, r8 + 800cc5a: 3001 adds r0, #1 + 800cc5c: d1c7 bne.n 800cbee + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800cc5e: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800cc62: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800cc64: 2301 movs r3, #1 + 800cc66: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800cc6a: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cc6c: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800cc70: 63a3 str r3, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800cc72: 2501 movs r5, #1 + break; + 800cc74: e7c5 b.n 800cc02 + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800cc76: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cc78: 0791 lsls r1, r2, #30 + 800cc7a: d502 bpl.n 800cc82 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800cc7c: 2202 movs r2, #2 + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cc7e: 639a str r2, [r3, #56] ; 0x38 + + errorstate = SDMMC_ERROR_RX_OVERRUN; + + return errorstate; + 800cc80: e7f3 b.n 800cc6a + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800cc82: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cc84: 0692 lsls r2, r2, #26 + 800cc86: d501 bpl.n 800cc8c + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cc88: 2220 movs r2, #32 + 800cc8a: e7f8 b.n 800cc7e + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800cc8c: 4a20 ldr r2, [pc, #128] ; (800cd10 ) + 800cc8e: 639a str r2, [r3, #56] ; 0x38 + + /* Test if the switch mode is ok */ + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800cc90: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800cc94: 079b lsls r3, r3, #30 + 800cc96: d5e8 bpl.n 800cc6a + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->DriveTransceiver_1_8V_Callback(SET); +#else + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800cc98: 2001 movs r0, #1 + 800cc9a: f7fa fa97 bl 80071cc + 800cc9e: e7b0 b.n 800cc02 + switch (SpeedMode) + 800cca0: 2901 cmp r1, #1 + 800cca2: f43f af48 beq.w 800cb36 + 800cca6: 2902 cmp r1, #2 + 800cca8: d00c beq.n 800ccc4 + 800ccaa: b9c1 cbnz r1, 800ccde + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800ccac: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800ccae: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ccb2: f43f af45 beq.w 800cb40 + 800ccb6: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800ccba: f43f af41 beq.w 800cb40 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800ccbe: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800ccc0: 2b01 cmp r3, #1 + 800ccc2: e73c b.n 800cb3e + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800ccc4: 6de3 ldr r3, [r4, #92] ; 0x5c + 800ccc6: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ccca: f43f af39 beq.w 800cb40 + 800ccce: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800ccd2: f43f af35 beq.w 800cb40 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800ccd6: 6be3 ldr r3, [r4, #60] ; 0x3c + 800ccd8: 2b01 cmp r3, #1 + 800ccda: d1c6 bne.n 800cc6a + 800ccdc: e730 b.n 800cb40 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800ccde: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cce0: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + 800cce4: e7c4 b.n 800cc70 + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800cce6: f7fa fa01 bl 80070ec + 800ccea: 1b80 subs r0, r0, r6 + 800ccec: 3001 adds r0, #1 + 800ccee: d18b bne.n 800cc08 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800ccf0: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800ccf4: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800ccf6: 2301 movs r3, #1 + 800ccf8: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_TIMEOUT; + 800ccfc: 2503 movs r5, #3 +} + 800ccfe: 4628 mov r0, r5 + 800cd00: b016 add sp, #88 ; 0x58 + 800cd02: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 800cd06: bf00 nop + 800cd08: 80ffff04 .word 0x80ffff04 + 800cd0c: 1fe00fff .word 0x1fe00fff + 800cd10: 18000f3a .word 0x18000f3a + +0800cd14 : + * @param SDMMCx Pointer to SDMMC register base + * @param Init SDMMC initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init) +{ + 800cd14: b084 sub sp, #16 + 800cd16: b510 push {r4, lr} + 800cd18: ac03 add r4, sp, #12 + 800cd1a: e884 000e stmia.w r4, {r1, r2, r3} + + /* Set SDMMC configuration parameters */ +#if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) + tmpreg |= Init.ClockBypass; +#endif + tmpreg |= (Init.ClockEdge |\ + 800cd1e: 9b03 ldr r3, [sp, #12] + Init.HardwareFlowControl |\ + Init.ClockDiv + ); + + /* Write to SDMMC CLKCR */ + MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + 800cd20: 6841 ldr r1, [r0, #4] + tmpreg |= (Init.ClockEdge |\ + 800cd22: 4313 orrs r3, r2 + Init.ClockPowerSave |\ + 800cd24: 9a05 ldr r2, [sp, #20] + 800cd26: 4313 orrs r3, r2 + Init.BusWide |\ + 800cd28: 9a06 ldr r2, [sp, #24] + 800cd2a: 4313 orrs r3, r2 + Init.HardwareFlowControl |\ + 800cd2c: 9a07 ldr r2, [sp, #28] + + return HAL_OK; +} + 800cd2e: e8bd 4010 ldmia.w sp!, {r4, lr} + Init.HardwareFlowControl |\ + 800cd32: 4313 orrs r3, r2 + MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + 800cd34: 4a03 ldr r2, [pc, #12] ; (800cd44 ) + 800cd36: 400a ands r2, r1 + 800cd38: 4313 orrs r3, r2 + 800cd3a: 6043 str r3, [r0, #4] +} + 800cd3c: b004 add sp, #16 + 800cd3e: 2000 movs r0, #0 + 800cd40: 4770 bx lr + 800cd42: bf00 nop + 800cd44: ffc02c00 .word 0xffc02c00 + +0800cd48 : + * @retval HAL status + */ +uint32_t SDMMC_ReadFIFO(SDMMC_TypeDef *SDMMCx) +{ + /* Read data from Rx FIFO */ + return (SDMMCx->FIFO); + 800cd48: f8d0 0080 ldr.w r0, [r0, #128] ; 0x80 +} + 800cd4c: 4770 bx lr + +0800cd4e : + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData) +{ + /* Write data to FIFO */ + SDMMCx->FIFO = *pWriteData; + 800cd4e: 680b ldr r3, [r1, #0] + 800cd50: f8c0 3080 str.w r3, [r0, #128] ; 0x80 + + return HAL_OK; +} + 800cd54: 2000 movs r0, #0 + 800cd56: 4770 bx lr + +0800cd58 : + * @brief Set SDMMC Power state to ON. + * @param SDMMCx Pointer to SDMMC register base + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx) +{ + 800cd58: b508 push {r3, lr} + /* Set power state to ON */ +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL; + 800cd5a: 6803 ldr r3, [r0, #0] + 800cd5c: f043 0303 orr.w r3, r3, #3 + 800cd60: 6003 str r3, [r0, #0] + SDMMCx->POWER = SDMMC_POWER_PWRCTRL; +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + /* 1ms: required power up waiting time before starting the SD initialization + sequence */ + HAL_Delay(2); + 800cd62: 2002 movs r0, #2 + 800cd64: f7f6 fdd5 bl 8003912 + + return HAL_OK; +} + 800cd68: 2000 movs r0, #0 + 800cd6a: bd08 pop {r3, pc} + +0800cd6c : + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to Power Cycle*/ + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL_1; + 800cd6c: 6803 ldr r3, [r0, #0] + 800cd6e: f043 0302 orr.w r3, r3, #2 + 800cd72: 6003 str r3, [r0, #0] + + return HAL_OK; +} + 800cd74: 2000 movs r0, #0 + 800cd76: 4770 bx lr + +0800cd78 : + */ +HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to OFF */ +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + SDMMCx->POWER &= ~(SDMMC_POWER_PWRCTRL); + 800cd78: 6803 ldr r3, [r0, #0] + 800cd7a: f023 0303 bic.w r3, r3, #3 + 800cd7e: 6003 str r3, [r0, #0] +#else + SDMMCx->POWER = (uint32_t)0x00000000; +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + return HAL_OK; +} + 800cd80: 2000 movs r0, #0 + 800cd82: 4770 bx lr + +0800cd84 : + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDMMC_GetPowerState(SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL); + 800cd84: 6800 ldr r0, [r0, #0] +} + 800cd86: f000 0003 and.w r0, r0, #3 + 800cd8a: 4770 bx lr + +0800cd8c : + assert_param(IS_SDMMC_RESPONSE(Command->Response)); + assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt)); + assert_param(IS_SDMMC_CPSM(Command->CPSM)); + + /* Set the SDMMC Argument value */ + SDMMCx->ARG = Command->Argument; + 800cd8c: 680b ldr r3, [r1, #0] +{ + 800cd8e: b510 push {r4, lr} + SDMMCx->ARG = Command->Argument; + 800cd90: 6083 str r3, [r0, #8] + + /* Set SDMMC command parameters */ + tmpreg |= (uint32_t)(Command->CmdIndex |\ + 800cd92: e9d1 3201 ldrd r3, r2, [r1, #4] + 800cd96: 4313 orrs r3, r2 + Command->Response |\ + 800cd98: 68ca ldr r2, [r1, #12] + Command->WaitForInterrupt |\ + Command->CPSM); + + /* Write to SDMMC CMD register */ + MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg); + 800cd9a: 68c4 ldr r4, [r0, #12] + Command->Response |\ + 800cd9c: 4313 orrs r3, r2 + Command->WaitForInterrupt |\ + 800cd9e: 690a ldr r2, [r1, #16] + 800cda0: 4313 orrs r3, r2 + MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg); + 800cda2: 4a03 ldr r2, [pc, #12] ; (800cdb0 ) + 800cda4: 4022 ands r2, r4 + 800cda6: 4313 orrs r3, r2 + 800cda8: 60c3 str r3, [r0, #12] + + return HAL_OK; +} + 800cdaa: 2000 movs r0, #0 + 800cdac: bd10 pop {r4, pc} + 800cdae: bf00 nop + 800cdb0: fffee0c0 .word 0xfffee0c0 + +0800cdb4 : + * @param SDMMCx Pointer to SDMMC register base + * @retval Command index of the last command response received + */ +uint8_t SDMMC_GetCommandResponse(SDMMC_TypeDef *SDMMCx) +{ + return (uint8_t)(SDMMCx->RESPCMD); + 800cdb4: 6900 ldr r0, [r0, #16] +} + 800cdb6: b2c0 uxtb r0, r0 + 800cdb8: 4770 bx lr + +0800cdba : + + /* Check the parameters */ + assert_param(IS_SDMMC_RESP(Response)); + + /* Get the response */ + tmp = (uint32_t)(&(SDMMCx->RESP1)) + Response; + 800cdba: 3014 adds r0, #20 + + return (*(__IO uint32_t *) tmp); + 800cdbc: 5840 ldr r0, [r0, r1] +} + 800cdbe: 4770 bx lr + +0800cdc0 : + assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir)); + assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode)); + assert_param(IS_SDMMC_DPSM(Data->DPSM)); + + /* Set the SDMMC Data TimeOut value */ + SDMMCx->DTIMER = Data->DataTimeOut; + 800cdc0: 680b ldr r3, [r1, #0] +{ + 800cdc2: b510 push {r4, lr} + SDMMCx->DTIMER = Data->DataTimeOut; + 800cdc4: 6243 str r3, [r0, #36] ; 0x24 + + /* Set the SDMMC DataLength value */ + SDMMCx->DLEN = Data->DataLength; + 800cdc6: 684b ldr r3, [r1, #4] + 800cdc8: 6283 str r3, [r0, #40] ; 0x28 + + /* Set the SDMMC data configuration parameters */ + tmpreg |= (uint32_t)(Data->DataBlockSize |\ + 800cdca: e9d1 3402 ldrd r3, r4, [r1, #8] + 800cdce: 4323 orrs r3, r4 + Data->TransferDir |\ + 800cdd0: 690c ldr r4, [r1, #16] + Data->TransferMode |\ + Data->DPSM); + + /* Write to SDMMC DCTRL */ + MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + 800cdd2: 6ac2 ldr r2, [r0, #44] ; 0x2c + Data->TransferMode |\ + 800cdd4: 6949 ldr r1, [r1, #20] + Data->TransferDir |\ + 800cdd6: 4323 orrs r3, r4 + Data->TransferMode |\ + 800cdd8: 430b orrs r3, r1 + MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + 800cdda: f022 02ff bic.w r2, r2, #255 ; 0xff + 800cdde: 4313 orrs r3, r2 + 800cde0: 62c3 str r3, [r0, #44] ; 0x2c + + return HAL_OK; + +} + 800cde2: 2000 movs r0, #0 + 800cde4: bd10 pop {r4, pc} + +0800cde6 : + * @param SDMMCx Pointer to SDMMC register base + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDMMC_GetDataCounter(SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->DCOUNT); + 800cde6: 6b00 ldr r0, [r0, #48] ; 0x30 +} + 800cde8: 4770 bx lr + +0800cdea : + 800cdea: f8d0 0080 ldr.w r0, [r0, #128] ; 0x80 + 800cdee: 4770 bx lr + +0800cdf0 : +{ + /* Check the parameters */ + assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode)); + + /* Set SDMMC read wait mode */ + MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode); + 800cdf0: 6ac3 ldr r3, [r0, #44] ; 0x2c + 800cdf2: f423 6380 bic.w r3, r3, #1024 ; 0x400 + 800cdf6: 4319 orrs r1, r3 + 800cdf8: 62c1 str r1, [r0, #44] ; 0x2c + + return HAL_OK; +} + 800cdfa: 2000 movs r0, #0 + 800cdfc: 4770 bx lr + ... + +0800ce00 : + * @brief Send the Go Idle State command and check the response. + * @param SDMMCx Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx) +{ + 800ce00: b510 push {r4, lr} + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = 0U; + 800ce02: 2300 movs r3, #0 +{ + 800ce04: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE; + 800ce06: e9cd 3301 strd r3, r3, [sp, #4] + sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800ce0a: e9cd 3303 strd r3, r3, [sp, #12] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800ce0e: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800ce10: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800ce14: 9305 str r3, [sp, #20] +{ + 800ce16: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800ce18: f7ff ffb8 bl 800cd8c + */ +static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx) +{ + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800ce1c: 4b0a ldr r3, [pc, #40] ; (800ce48 ) + 800ce1e: f44f 52fa mov.w r2, #8000 ; 0x1f40 + 800ce22: 681b ldr r3, [r3, #0] + 800ce24: fbb3 f3f2 udiv r3, r3, r2 + 800ce28: f241 3288 movw r2, #5000 ; 0x1388 + 800ce2c: 4353 muls r3, r2 + + do + { + if (count-- == 0U) + 800ce2e: 3b01 subs r3, #1 + 800ce30: d307 bcc.n 800ce42 + { + return SDMMC_ERROR_TIMEOUT; + } + + }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT)); + 800ce32: 6b62 ldr r2, [r4, #52] ; 0x34 + 800ce34: 0612 lsls r2, r2, #24 + 800ce36: d5fa bpl.n 800ce2e + + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800ce38: 4b04 ldr r3, [pc, #16] ; (800ce4c ) + 800ce3a: 63a3 str r3, [r4, #56] ; 0x38 + + return SDMMC_ERROR_NONE; + 800ce3c: 2000 movs r0, #0 +} + 800ce3e: b006 add sp, #24 + 800ce40: bd10 pop {r4, pc} + return SDMMC_ERROR_TIMEOUT; + 800ce42: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + return errorstate; + 800ce46: e7fa b.n 800ce3e + 800ce48: 2009e2a8 .word 0x2009e2a8 + 800ce4c: 002000c5 .word 0x002000c5 + +0800ce50 : + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800ce50: 4b45 ldr r3, [pc, #276] ; (800cf68 ) +{ + 800ce52: b510 push {r4, lr} + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800ce54: 681b ldr r3, [r3, #0] +{ + 800ce56: 4604 mov r4, r0 + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800ce58: f44f 50fa mov.w r0, #8000 ; 0x1f40 + 800ce5c: fbb3 f3f0 udiv r3, r3, r0 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_BUSYD0END)) == 0U) || + 800ce60: 4842 ldr r0, [pc, #264] ; (800cf6c ) + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800ce62: 435a muls r2, r3 + if (count-- == 0U) + 800ce64: 2a00 cmp r2, #0 + 800ce66: d048 beq.n 800cefa + sta_reg = SDMMCx->STA; + 800ce68: 6b63 ldr r3, [r4, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800ce6a: 4203 tst r3, r0 + 800ce6c: d007 beq.n 800ce7e + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_BUSYD0END)) == 0U) || + 800ce6e: 049b lsls r3, r3, #18 + 800ce70: d405 bmi.n 800ce7e + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800ce72: 6b63 ldr r3, [r4, #52] ; 0x34 + 800ce74: 0758 lsls r0, r3, #29 + 800ce76: d504 bpl.n 800ce82 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800ce78: 2004 movs r0, #4 + 800ce7a: 63a0 str r0, [r4, #56] ; 0x38 +} + 800ce7c: bd10 pop {r4, pc} + 800ce7e: 3a01 subs r2, #1 + 800ce80: e7f0 b.n 800ce64 + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800ce82: 6b60 ldr r0, [r4, #52] ; 0x34 + 800ce84: f010 0001 ands.w r0, r0, #1 + 800ce88: d002 beq.n 800ce90 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800ce8a: 2301 movs r3, #1 + 800ce8c: 63a3 str r3, [r4, #56] ; 0x38 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800ce8e: e7f5 b.n 800ce7c + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800ce90: 4b37 ldr r3, [pc, #220] ; (800cf70 ) + 800ce92: 63a3 str r3, [r4, #56] ; 0x38 + return (uint8_t)(SDMMCx->RESPCMD); + 800ce94: 6923 ldr r3, [r4, #16] + if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + 800ce96: b2db uxtb r3, r3 + 800ce98: 4299 cmp r1, r3 + 800ce9a: d131 bne.n 800cf00 + return (*(__IO uint32_t *) tmp); + 800ce9c: 6963 ldr r3, [r4, #20] + if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO) + 800ce9e: 4835 ldr r0, [pc, #212] ; (800cf74 ) + 800cea0: 4018 ands r0, r3 + 800cea2: 2800 cmp r0, #0 + 800cea4: d0ea beq.n 800ce7c + else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE) + 800cea6: 2b00 cmp r3, #0 + 800cea8: db2c blt.n 800cf04 + else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED) + 800ceaa: 005a lsls r2, r3, #1 + 800ceac: d42d bmi.n 800cf0a + else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR) + 800ceae: 009c lsls r4, r3, #2 + 800ceb0: d42d bmi.n 800cf0e + else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR) + 800ceb2: 00d9 lsls r1, r3, #3 + 800ceb4: d42d bmi.n 800cf12 + else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM) + 800ceb6: 011a lsls r2, r3, #4 + 800ceb8: d42e bmi.n 800cf18 + else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION) + 800ceba: 015c lsls r4, r3, #5 + 800cebc: d42f bmi.n 800cf1e + else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED) + 800cebe: 01d9 lsls r1, r3, #7 + 800cec0: d430 bmi.n 800cf24 + else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED) + 800cec2: 021a lsls r2, r3, #8 + 800cec4: d431 bmi.n 800cf2a + else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD) + 800cec6: 025c lsls r4, r3, #9 + 800cec8: d432 bmi.n 800cf30 + else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED) + 800ceca: 0299 lsls r1, r3, #10 + 800cecc: d433 bmi.n 800cf36 + else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR) + 800cece: 02da lsls r2, r3, #11 + 800ced0: d434 bmi.n 800cf3c + else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN) + 800ced2: 035c lsls r4, r3, #13 + 800ced4: d435 bmi.n 800cf42 + else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN) + 800ced6: 0399 lsls r1, r3, #14 + 800ced8: d436 bmi.n 800cf48 + else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE) + 800ceda: 03da lsls r2, r3, #15 + 800cedc: d437 bmi.n 800cf4e + else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP) + 800cede: 041c lsls r4, r3, #16 + 800cee0: d438 bmi.n 800cf54 + else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED) + 800cee2: 0459 lsls r1, r3, #17 + 800cee4: d439 bmi.n 800cf5a + else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET) + 800cee6: 049a lsls r2, r3, #18 + 800cee8: d43a bmi.n 800cf60 + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + 800ceea: f013 0f08 tst.w r3, #8 + 800ceee: bf14 ite ne + 800cef0: f44f 0000 movne.w r0, #8388608 ; 0x800000 + 800cef4: f44f 3080 moveq.w r0, #65536 ; 0x10000 + 800cef8: e7c0 b.n 800ce7c + return SDMMC_ERROR_TIMEOUT; + 800cefa: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800cefe: e7bd b.n 800ce7c + return SDMMC_ERROR_CMD_CRC_FAIL; + 800cf00: 2001 movs r0, #1 + 800cf02: e7bb b.n 800ce7c + return SDMMC_ERROR_ADDR_OUT_OF_RANGE; + 800cf04: f04f 7000 mov.w r0, #33554432 ; 0x2000000 + 800cf08: e7b8 b.n 800ce7c + return SDMMC_ERROR_ADDR_MISALIGNED; + 800cf0a: 2040 movs r0, #64 ; 0x40 + 800cf0c: e7b6 b.n 800ce7c + return SDMMC_ERROR_BLOCK_LEN_ERR; + 800cf0e: 2080 movs r0, #128 ; 0x80 + 800cf10: e7b4 b.n 800ce7c + return SDMMC_ERROR_ERASE_SEQ_ERR; + 800cf12: f44f 7080 mov.w r0, #256 ; 0x100 + 800cf16: e7b1 b.n 800ce7c + return SDMMC_ERROR_BAD_ERASE_PARAM; + 800cf18: f44f 7000 mov.w r0, #512 ; 0x200 + 800cf1c: e7ae b.n 800ce7c + return SDMMC_ERROR_WRITE_PROT_VIOLATION; + 800cf1e: f44f 6080 mov.w r0, #1024 ; 0x400 + 800cf22: e7ab b.n 800ce7c + return SDMMC_ERROR_LOCK_UNLOCK_FAILED; + 800cf24: f44f 6000 mov.w r0, #2048 ; 0x800 + 800cf28: e7a8 b.n 800ce7c + return SDMMC_ERROR_COM_CRC_FAILED; + 800cf2a: f44f 5080 mov.w r0, #4096 ; 0x1000 + 800cf2e: e7a5 b.n 800ce7c + return SDMMC_ERROR_ILLEGAL_CMD; + 800cf30: f44f 5000 mov.w r0, #8192 ; 0x2000 + 800cf34: e7a2 b.n 800ce7c + return SDMMC_ERROR_CARD_ECC_FAILED; + 800cf36: f44f 4080 mov.w r0, #16384 ; 0x4000 + 800cf3a: e79f b.n 800ce7c + return SDMMC_ERROR_CC_ERR; + 800cf3c: f44f 4000 mov.w r0, #32768 ; 0x8000 + 800cf40: e79c b.n 800ce7c + return SDMMC_ERROR_STREAM_READ_UNDERRUN; + 800cf42: f44f 3000 mov.w r0, #131072 ; 0x20000 + 800cf46: e799 b.n 800ce7c + return SDMMC_ERROR_STREAM_WRITE_OVERRUN; + 800cf48: f44f 2080 mov.w r0, #262144 ; 0x40000 + 800cf4c: e796 b.n 800ce7c + return SDMMC_ERROR_CID_CSD_OVERWRITE; + 800cf4e: f44f 2000 mov.w r0, #524288 ; 0x80000 + 800cf52: e793 b.n 800ce7c + return SDMMC_ERROR_WP_ERASE_SKIP; + 800cf54: f44f 1080 mov.w r0, #1048576 ; 0x100000 + 800cf58: e790 b.n 800ce7c + return SDMMC_ERROR_CARD_ECC_DISABLED; + 800cf5a: f44f 1000 mov.w r0, #2097152 ; 0x200000 + 800cf5e: e78d b.n 800ce7c + return SDMMC_ERROR_ERASE_RESET; + 800cf60: f44f 0080 mov.w r0, #4194304 ; 0x400000 + 800cf64: e78a b.n 800ce7c + 800cf66: bf00 nop + 800cf68: 2009e2a8 .word 0x2009e2a8 + 800cf6c: 00200045 .word 0x00200045 + 800cf70: 002000c5 .word 0x002000c5 + 800cf74: fdffe008 .word 0xfdffe008 + +0800cf78 : +{ + 800cf78: b530 push {r4, r5, lr} + 800cf7a: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800cf7c: 2510 movs r5, #16 + 800cf7e: f44f 7380 mov.w r3, #256 ; 0x100 + 800cf82: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800cf86: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cf88: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)BlockSize; + 800cf8c: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cf8e: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cf90: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cf92: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cf96: f7ff fef9 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT); + 800cf9a: f241 3288 movw r2, #5000 ; 0x1388 + 800cf9e: 4629 mov r1, r5 + 800cfa0: 4620 mov r0, r4 + 800cfa2: f7ff ff55 bl 800ce50 +} + 800cfa6: b007 add sp, #28 + 800cfa8: bd30 pop {r4, r5, pc} + +0800cfaa : +{ + 800cfaa: b530 push {r4, r5, lr} + 800cfac: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800cfae: 2511 movs r5, #17 + 800cfb0: f44f 7380 mov.w r3, #256 ; 0x100 + 800cfb4: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800cfb8: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cfba: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + 800cfbe: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cfc0: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cfc2: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cfc4: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cfc8: f7ff fee0 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + 800cfcc: f241 3288 movw r2, #5000 ; 0x1388 + 800cfd0: 4629 mov r1, r5 + 800cfd2: 4620 mov r0, r4 + 800cfd4: f7ff ff3c bl 800ce50 +} + 800cfd8: b007 add sp, #28 + 800cfda: bd30 pop {r4, r5, pc} + +0800cfdc : +{ + 800cfdc: b530 push {r4, r5, lr} + 800cfde: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800cfe0: 2512 movs r5, #18 + 800cfe2: f44f 7380 mov.w r3, #256 ; 0x100 + 800cfe6: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800cfea: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cfec: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + 800cff0: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cff2: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cff4: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800cff6: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800cffa: f7ff fec7 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT); + 800cffe: f241 3288 movw r2, #5000 ; 0x1388 + 800d002: 4629 mov r1, r5 + 800d004: 4620 mov r0, r4 + 800d006: f7ff ff23 bl 800ce50 +} + 800d00a: b007 add sp, #28 + 800d00c: bd30 pop {r4, r5, pc} + +0800d00e : +{ + 800d00e: b530 push {r4, r5, lr} + 800d010: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d012: 2518 movs r5, #24 + 800d014: f44f 7380 mov.w r3, #256 ; 0x100 + 800d018: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d01c: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d01e: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + 800d022: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d024: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d026: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d028: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d02c: f7ff feae bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + 800d030: f241 3288 movw r2, #5000 ; 0x1388 + 800d034: 4629 mov r1, r5 + 800d036: 4620 mov r0, r4 + 800d038: f7ff ff0a bl 800ce50 +} + 800d03c: b007 add sp, #28 + 800d03e: bd30 pop {r4, r5, pc} + +0800d040 : +{ + 800d040: b530 push {r4, r5, lr} + 800d042: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d044: 2519 movs r5, #25 + 800d046: f44f 7380 mov.w r3, #256 ; 0x100 + 800d04a: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d04e: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d050: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + 800d054: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d056: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d058: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d05a: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d05e: f7ff fe95 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT); + 800d062: f241 3288 movw r2, #5000 ; 0x1388 + 800d066: 4629 mov r1, r5 + 800d068: 4620 mov r0, r4 + 800d06a: f7ff fef1 bl 800ce50 +} + 800d06e: b007 add sp, #28 + 800d070: bd30 pop {r4, r5, pc} + +0800d072 : +{ + 800d072: b530 push {r4, r5, lr} + 800d074: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d076: 2520 movs r5, #32 + 800d078: f44f 7380 mov.w r3, #256 ; 0x100 + 800d07c: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d080: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d082: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + 800d086: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d088: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d08a: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d08c: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d090: f7ff fe7c bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + 800d094: f241 3288 movw r2, #5000 ; 0x1388 + 800d098: 4629 mov r1, r5 + 800d09a: 4620 mov r0, r4 + 800d09c: f7ff fed8 bl 800ce50 +} + 800d0a0: b007 add sp, #28 + 800d0a2: bd30 pop {r4, r5, pc} + +0800d0a4 : +{ + 800d0a4: b530 push {r4, r5, lr} + 800d0a6: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d0a8: 2521 movs r5, #33 ; 0x21 + 800d0aa: f44f 7380 mov.w r3, #256 ; 0x100 + 800d0ae: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d0b2: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0b4: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + 800d0b8: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0ba: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0bc: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0be: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0c2: f7ff fe63 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + 800d0c6: f241 3288 movw r2, #5000 ; 0x1388 + 800d0ca: 4629 mov r1, r5 + 800d0cc: 4620 mov r0, r4 + 800d0ce: f7ff febf bl 800ce50 +} + 800d0d2: b007 add sp, #28 + 800d0d4: bd30 pop {r4, r5, pc} + +0800d0d6 : +{ + 800d0d6: b530 push {r4, r5, lr} + 800d0d8: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d0da: 2523 movs r5, #35 ; 0x23 + 800d0dc: f44f 7380 mov.w r3, #256 ; 0x100 + 800d0e0: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d0e4: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0e6: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + 800d0ea: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0ec: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0ee: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0f0: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0f4: f7ff fe4a bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + 800d0f8: f241 3288 movw r2, #5000 ; 0x1388 + 800d0fc: 4629 mov r1, r5 + 800d0fe: 4620 mov r0, r4 + 800d100: f7ff fea6 bl 800ce50 +} + 800d104: b007 add sp, #28 + 800d106: bd30 pop {r4, r5, pc} + +0800d108 : +{ + 800d108: b530 push {r4, r5, lr} + 800d10a: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d10c: 2524 movs r5, #36 ; 0x24 + 800d10e: f44f 7380 mov.w r3, #256 ; 0x100 + 800d112: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d116: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d118: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + 800d11c: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d11e: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d120: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d122: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d126: f7ff fe31 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + 800d12a: f241 3288 movw r2, #5000 ; 0x1388 + 800d12e: 4629 mov r1, r5 + 800d130: 4620 mov r0, r4 + 800d132: f7ff fe8d bl 800ce50 +} + 800d136: b007 add sp, #28 + 800d138: bd30 pop {r4, r5, pc} + +0800d13a : +{ + 800d13a: b530 push {r4, r5, lr} + 800d13c: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d13e: 2526 movs r5, #38 ; 0x26 + 800d140: f44f 7380 mov.w r3, #256 ; 0x100 + 800d144: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d148: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d14a: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = EraseType; + 800d14e: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d150: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d152: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d154: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d158: f7ff fe18 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT); + 800d15c: f24f 6218 movw r2, #63000 ; 0xf618 + 800d160: 4629 mov r1, r5 + 800d162: 4620 mov r0, r4 + 800d164: f7ff fe74 bl 800ce50 +} + 800d168: b007 add sp, #28 + 800d16a: bd30 pop {r4, r5, pc} + +0800d16c : +{ + 800d16c: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d16e: 2300 movs r3, #0 +{ + 800d170: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d172: 250c movs r5, #12 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d174: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d178: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d17c: e9cd 3501 strd r3, r5, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d180: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d184: 9305 str r3, [sp, #20] + __SDMMC_CMDSTOP_ENABLE(SDMMCx); + 800d186: 68c3 ldr r3, [r0, #12] + 800d188: f043 0380 orr.w r3, r3, #128 ; 0x80 + 800d18c: 60c3 str r3, [r0, #12] + __SDMMC_CMDTRANS_DISABLE(SDMMCx); + 800d18e: 68c3 ldr r3, [r0, #12] + 800d190: f023 0340 bic.w r3, r3, #64 ; 0x40 +{ + 800d194: 4604 mov r4, r0 + __SDMMC_CMDTRANS_DISABLE(SDMMCx); + 800d196: 60c3 str r3, [r0, #12] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d198: a901 add r1, sp, #4 + 800d19a: f7ff fdf7 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, SDMMC_STOPTRANSFERTIMEOUT); + 800d19e: 4a05 ldr r2, [pc, #20] ; (800d1b4 ) + 800d1a0: 4629 mov r1, r5 + 800d1a2: 4620 mov r0, r4 + 800d1a4: f7ff fe54 bl 800ce50 + __SDMMC_CMDSTOP_DISABLE(SDMMCx); + 800d1a8: 68e3 ldr r3, [r4, #12] + 800d1aa: f023 0380 bic.w r3, r3, #128 ; 0x80 + 800d1ae: 60e3 str r3, [r4, #12] +} + 800d1b0: b007 add sp, #28 + 800d1b2: bd30 pop {r4, r5, pc} + 800d1b4: 05f5e100 .word 0x05f5e100 + +0800d1b8 : +{ + 800d1b8: b530 push {r4, r5, lr} + 800d1ba: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d1bc: 2507 movs r5, #7 + 800d1be: f44f 7380 mov.w r3, #256 ; 0x100 + 800d1c2: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d1c6: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d1c8: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)Addr; + 800d1cc: 9201 str r2, [sp, #4] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d1ce: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d1d0: 2200 movs r2, #0 + 800d1d2: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d1d6: f7ff fdd9 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT); + 800d1da: f241 3288 movw r2, #5000 ; 0x1388 + 800d1de: 4629 mov r1, r5 + 800d1e0: 4620 mov r0, r4 + 800d1e2: f7ff fe35 bl 800ce50 +} + 800d1e6: b007 add sp, #28 + 800d1e8: bd30 pop {r4, r5, pc} + +0800d1ea : +{ + 800d1ea: b530 push {r4, r5, lr} + 800d1ec: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d1ee: 2537 movs r5, #55 ; 0x37 + 800d1f0: f44f 7380 mov.w r3, #256 ; 0x100 + 800d1f4: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d1f8: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d1fa: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)Argument; + 800d1fe: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d200: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d202: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d204: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d208: f7ff fdc0 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT); + 800d20c: f241 3288 movw r2, #5000 ; 0x1388 + 800d210: 4629 mov r1, r5 + 800d212: 4620 mov r0, r4 + 800d214: f7ff fe1c bl 800ce50 +} + 800d218: b007 add sp, #28 + 800d21a: bd30 pop {r4, r5, pc} + +0800d21c : +{ + 800d21c: b530 push {r4, r5, lr} + 800d21e: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d220: 2506 movs r5, #6 + 800d222: f44f 7380 mov.w r3, #256 ; 0x100 + 800d226: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d22a: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d22c: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)BusWidth; + 800d230: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d232: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d234: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d236: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d23a: f7ff fda7 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT); + 800d23e: f241 3288 movw r2, #5000 ; 0x1388 + 800d242: 4629 mov r1, r5 + 800d244: 4620 mov r0, r4 + 800d246: f7ff fe03 bl 800ce50 +} + 800d24a: b007 add sp, #28 + 800d24c: bd30 pop {r4, r5, pc} + +0800d24e : + 800d24e: f7ff bfe5 b.w 800d21c + +0800d252 : +{ + 800d252: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d254: 2300 movs r3, #0 +{ + 800d256: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d258: 2533 movs r5, #51 ; 0x33 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d25a: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d25e: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d262: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d266: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d268: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d26c: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d26e: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d270: f7ff fd8c bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT); + 800d274: f241 3288 movw r2, #5000 ; 0x1388 + 800d278: 4629 mov r1, r5 + 800d27a: 4620 mov r0, r4 + 800d27c: f7ff fde8 bl 800ce50 +} + 800d280: b007 add sp, #28 + 800d282: bd30 pop {r4, r5, pc} + +0800d284 : +{ + 800d284: b530 push {r4, r5, lr} + 800d286: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d288: 2503 movs r5, #3 + sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U); + 800d28a: 0409 lsls r1, r1, #16 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d28c: f44f 7380 mov.w r3, #256 ; 0x100 + 800d290: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d294: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d296: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U); + 800d29a: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d29c: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d29e: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2a0: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2a4: f7ff fd72 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_REL_ADDR, SDMMC_CMDTIMEOUT); + 800d2a8: f241 3288 movw r2, #5000 ; 0x1388 + 800d2ac: 4629 mov r1, r5 + 800d2ae: 4620 mov r0, r4 + 800d2b0: f7ff fdce bl 800ce50 +} + 800d2b4: b007 add sp, #28 + 800d2b6: bd30 pop {r4, r5, pc} + +0800d2b8 : +{ + 800d2b8: b530 push {r4, r5, lr} + 800d2ba: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d2bc: 250d movs r5, #13 + 800d2be: f44f 7380 mov.w r3, #256 ; 0x100 + 800d2c2: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d2c6: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2c8: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = Argument; + 800d2cc: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2ce: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2d0: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2d2: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2d6: f7ff fd59 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT); + 800d2da: f241 3288 movw r2, #5000 ; 0x1388 + 800d2de: 4629 mov r1, r5 + 800d2e0: 4620 mov r0, r4 + 800d2e2: f7ff fdb5 bl 800ce50 +} + 800d2e6: b007 add sp, #28 + 800d2e8: bd30 pop {r4, r5, pc} + +0800d2ea : +{ + 800d2ea: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d2ec: 2300 movs r3, #0 +{ + 800d2ee: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d2f0: 250d movs r5, #13 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d2f2: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d2f6: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d2fa: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d2fe: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d300: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d304: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d306: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d308: f7ff fd40 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT); + 800d30c: f241 3288 movw r2, #5000 ; 0x1388 + 800d310: 4629 mov r1, r5 + 800d312: 4620 mov r0, r4 + 800d314: f7ff fd9c bl 800ce50 +} + 800d318: b007 add sp, #28 + 800d31a: bd30 pop {r4, r5, pc} + +0800d31c : +{ + 800d31c: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d31e: 2300 movs r3, #0 +{ + 800d320: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d322: 250b movs r5, #11 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d324: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d328: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d32c: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d330: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d332: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d336: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d338: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d33a: f7ff fd27 bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_VOLTAGE_SWITCH, SDMMC_CMDTIMEOUT); + 800d33e: f241 3288 movw r2, #5000 ; 0x1388 + 800d342: 4629 mov r1, r5 + 800d344: 4620 mov r0, r4 + 800d346: f7ff fd83 bl 800ce50 +} + 800d34a: b007 add sp, #28 + 800d34c: bd30 pop {r4, r5, pc} + +0800d34e : +{ + 800d34e: b530 push {r4, r5, lr} + 800d350: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d352: 2508 movs r5, #8 + 800d354: f44f 7380 mov.w r3, #256 ; 0x100 + 800d358: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d35c: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d35e: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = Argument; + 800d362: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d364: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d366: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d368: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d36c: f7ff fd0e bl 800cd8c + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SEND_EXT_CSD,SDMMC_CMDTIMEOUT); + 800d370: f241 3288 movw r2, #5000 ; 0x1388 + 800d374: 4629 mov r1, r5 + 800d376: 4620 mov r0, r4 + 800d378: f7ff fd6a bl 800ce50 +} + 800d37c: b007 add sp, #28 + 800d37e: bd30 pop {r4, r5, pc} + +0800d380 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d380: 4b11 ldr r3, [pc, #68] ; (800d3c8 ) + 800d382: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d386: 681b ldr r3, [r3, #0] + 800d388: fbb3 f3f1 udiv r3, r3, r1 + 800d38c: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d390: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d392: 434b muls r3, r1 + if (count-- == 0U) + 800d394: 3b01 subs r3, #1 + 800d396: d313 bcc.n 800d3c0 + sta_reg = SDMMCx->STA; + 800d398: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d39a: f011 0f45 tst.w r1, #69 ; 0x45 + 800d39e: d0f9 beq.n 800d394 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d3a0: 0489 lsls r1, r1, #18 + 800d3a2: d4f7 bmi.n 800d394 + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d3a4: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d3a6: 075b lsls r3, r3, #29 + 800d3a8: d502 bpl.n 800d3b0 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d3aa: 2004 movs r0, #4 + 800d3ac: 6390 str r0, [r2, #56] ; 0x38 + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + 800d3ae: 4770 bx lr + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d3b0: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d3b2: f010 0001 ands.w r0, r0, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d3b6: bf0c ite eq + 800d3b8: 4b04 ldreq r3, [pc, #16] ; (800d3cc ) + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d3ba: 2301 movne r3, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d3bc: 6393 str r3, [r2, #56] ; 0x38 + return SDMMC_ERROR_NONE; + 800d3be: 4770 bx lr + return SDMMC_ERROR_TIMEOUT; + 800d3c0: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d3c4: 4770 bx lr + 800d3c6: bf00 nop + 800d3c8: 2009e2a8 .word 0x2009e2a8 + 800d3cc: 002000c5 .word 0x002000c5 + +0800d3d0 : +{ + 800d3d0: b510 push {r4, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID; + 800d3d2: 2300 movs r3, #0 +{ + 800d3d4: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID; + 800d3d6: 2202 movs r2, #2 + 800d3d8: e9cd 3201 strd r3, r2, [sp, #4] + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + 800d3dc: f44f 7240 mov.w r2, #768 ; 0x300 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d3e0: e9cd 2303 strd r2, r3, [sp, #12] +{ + 800d3e4: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3e6: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3ea: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3ec: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3ee: f7ff fccd bl 800cd8c + errorstate = SDMMC_GetCmdResp2(SDMMCx); + 800d3f2: 4620 mov r0, r4 + 800d3f4: f7ff ffc4 bl 800d380 +} + 800d3f8: b006 add sp, #24 + 800d3fa: bd10 pop {r4, pc} + +0800d3fc : +{ + 800d3fc: b510 push {r4, lr} + 800d3fe: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + 800d400: 2209 movs r2, #9 + 800d402: f44f 7340 mov.w r3, #768 ; 0x300 + 800d406: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d40a: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d40c: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d410: 2100 movs r1, #0 + 800d412: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d416: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d418: a901 add r1, sp, #4 + 800d41a: f7ff fcb7 bl 800cd8c + errorstate = SDMMC_GetCmdResp2(SDMMCx); + 800d41e: 4620 mov r0, r4 + 800d420: f7ff ffae bl 800d380 +} + 800d424: b006 add sp, #24 + 800d426: bd10 pop {r4, pc} + +0800d428 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d428: 4b0e ldr r3, [pc, #56] ; (800d464 ) + 800d42a: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d42e: 681b ldr r3, [r3, #0] + 800d430: fbb3 f3f1 udiv r3, r3, r1 + 800d434: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d438: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d43a: 434b muls r3, r1 + if (count-- == 0U) + 800d43c: 3b01 subs r3, #1 + 800d43e: d30e bcc.n 800d45e + sta_reg = SDMMCx->STA; + 800d440: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d442: f011 0f45 tst.w r1, #69 ; 0x45 + 800d446: d0f9 beq.n 800d43c + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d448: 0489 lsls r1, r1, #18 + 800d44a: d4f7 bmi.n 800d43c + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d44c: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d44e: f010 0004 ands.w r0, r0, #4 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d452: bf15 itete ne + 800d454: 2004 movne r0, #4 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d456: 4b04 ldreq r3, [pc, #16] ; (800d468 ) + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d458: 6390 strne r0, [r2, #56] ; 0x38 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d45a: 6393 streq r3, [r2, #56] ; 0x38 + return SDMMC_ERROR_NONE; + 800d45c: 4770 bx lr + return SDMMC_ERROR_TIMEOUT; + 800d45e: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d462: 4770 bx lr + 800d464: 2009e2a8 .word 0x2009e2a8 + 800d468: 002000c5 .word 0x002000c5 + +0800d46c : +{ + 800d46c: b510 push {r4, lr} + 800d46e: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d470: 2229 movs r2, #41 ; 0x29 + 800d472: f44f 7380 mov.w r3, #256 ; 0x100 + 800d476: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d47a: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d47c: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d480: 2100 movs r1, #0 + 800d482: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d486: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d488: a901 add r1, sp, #4 + 800d48a: f7ff fc7f bl 800cd8c + errorstate = SDMMC_GetCmdResp3(SDMMCx); + 800d48e: 4620 mov r0, r4 + 800d490: f7ff ffca bl 800d428 +} + 800d494: b006 add sp, #24 + 800d496: bd10 pop {r4, pc} + +0800d498 : +{ + 800d498: b510 push {r4, lr} + 800d49a: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d49c: 2201 movs r2, #1 + 800d49e: f44f 7380 mov.w r3, #256 ; 0x100 + 800d4a2: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d4a6: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4a8: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d4ac: 2100 movs r1, #0 + 800d4ae: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d4b2: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d4b4: a901 add r1, sp, #4 + 800d4b6: f7ff fc69 bl 800cd8c + errorstate = SDMMC_GetCmdResp3(SDMMCx); + 800d4ba: 4620 mov r0, r4 + 800d4bc: f7ff ffb4 bl 800d428 +} + 800d4c0: b006 add sp, #24 + 800d4c2: bd10 pop {r4, pc} + +0800d4c4 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d4c4: 4b1f ldr r3, [pc, #124] ; (800d544 ) +{ + 800d4c6: b510 push {r4, lr} + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d4c8: 681b ldr r3, [r3, #0] +{ + 800d4ca: 4604 mov r4, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d4cc: f44f 50fa mov.w r0, #8000 ; 0x1f40 + 800d4d0: fbb3 f3f0 udiv r3, r3, r0 + 800d4d4: f241 3088 movw r0, #5000 ; 0x1388 + 800d4d8: 4343 muls r3, r0 + if (count-- == 0U) + 800d4da: 3b01 subs r3, #1 + 800d4dc: d329 bcc.n 800d532 + sta_reg = SDMMCx->STA; + 800d4de: 6b60 ldr r0, [r4, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d4e0: f010 0f45 tst.w r0, #69 ; 0x45 + 800d4e4: d0f9 beq.n 800d4da + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d4e6: 0480 lsls r0, r0, #18 + 800d4e8: d4f7 bmi.n 800d4da + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d4ea: 6b63 ldr r3, [r4, #52] ; 0x34 + 800d4ec: 0758 lsls r0, r3, #29 + 800d4ee: d502 bpl.n 800d4f6 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d4f0: 2004 movs r0, #4 + 800d4f2: 63a0 str r0, [r4, #56] ; 0x38 +} + 800d4f4: bd10 pop {r4, pc} + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d4f6: 6b60 ldr r0, [r4, #52] ; 0x34 + 800d4f8: f010 0001 ands.w r0, r0, #1 + 800d4fc: d002 beq.n 800d504 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d4fe: 2301 movs r3, #1 + 800d500: 63a3 str r3, [r4, #56] ; 0x38 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d502: e7f7 b.n 800d4f4 + return (uint8_t)(SDMMCx->RESPCMD); + 800d504: 6923 ldr r3, [r4, #16] + if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + 800d506: b2db uxtb r3, r3 + 800d508: 4299 cmp r1, r3 + 800d50a: d115 bne.n 800d538 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d50c: 4b0e ldr r3, [pc, #56] ; (800d548 ) + 800d50e: 63a3 str r3, [r4, #56] ; 0x38 + return (*(__IO uint32_t *) tmp); + 800d510: 6963 ldr r3, [r4, #20] + if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO) + 800d512: f413 4060 ands.w r0, r3, #57344 ; 0xe000 + 800d516: d102 bne.n 800d51e + *pRCA = (uint16_t) (response_r1 >> 16); + 800d518: 0c1b lsrs r3, r3, #16 + 800d51a: 8013 strh r3, [r2, #0] + return SDMMC_ERROR_NONE; + 800d51c: e7ea b.n 800d4f4 + else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD) + 800d51e: 045a lsls r2, r3, #17 + 800d520: d40c bmi.n 800d53c + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + 800d522: f413 4f00 tst.w r3, #32768 ; 0x8000 + 800d526: bf14 ite ne + 800d528: f44f 5080 movne.w r0, #4096 ; 0x1000 + 800d52c: f44f 3080 moveq.w r0, #65536 ; 0x10000 + 800d530: e7e0 b.n 800d4f4 + return SDMMC_ERROR_TIMEOUT; + 800d532: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800d536: e7dd b.n 800d4f4 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d538: 2001 movs r0, #1 + 800d53a: e7db b.n 800d4f4 + return SDMMC_ERROR_ILLEGAL_CMD; + 800d53c: f44f 5000 mov.w r0, #8192 ; 0x2000 + 800d540: e7d8 b.n 800d4f4 + 800d542: bf00 nop + 800d544: 2009e2a8 .word 0x2009e2a8 + 800d548: 002000c5 .word 0x002000c5 + +0800d54c : +{ + 800d54c: b530 push {r4, r5, lr} + 800d54e: b089 sub sp, #36 ; 0x24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d550: 2300 movs r3, #0 +{ + 800d552: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d554: 2503 movs r5, #3 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d556: f44f 7180 mov.w r1, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d55a: e9cd 1305 strd r1, r3, [sp, #20] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d55e: e9cd 3503 strd r3, r5, [sp, #12] +{ + 800d562: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d564: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d568: a903 add r1, sp, #12 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d56a: 9307 str r3, [sp, #28] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d56c: f7ff fc0e bl 800cd8c + errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA); + 800d570: 9a01 ldr r2, [sp, #4] + 800d572: 4629 mov r1, r5 + 800d574: 4620 mov r0, r4 + 800d576: f7ff ffa5 bl 800d4c4 +} + 800d57a: b009 add sp, #36 ; 0x24 + 800d57c: bd30 pop {r4, r5, pc} + ... + +0800d580 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d580: 4b13 ldr r3, [pc, #76] ; (800d5d0 ) + 800d582: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d586: 681b ldr r3, [r3, #0] + 800d588: fbb3 f3f1 udiv r3, r3, r1 + 800d58c: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d590: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d592: 434b muls r3, r1 + if (count-- == 0U) + 800d594: 3b01 subs r3, #1 + 800d596: d317 bcc.n 800d5c8 + sta_reg = SDMMCx->STA; + 800d598: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d59a: f011 0f45 tst.w r1, #69 ; 0x45 + 800d59e: d0f9 beq.n 800d594 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d5a0: 0488 lsls r0, r1, #18 + 800d5a2: d4f7 bmi.n 800d594 + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d5a4: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d5a6: 0759 lsls r1, r3, #29 + 800d5a8: d502 bpl.n 800d5b0 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d5aa: 2004 movs r0, #4 + 800d5ac: 6390 str r0, [r2, #56] ; 0x38 + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + 800d5ae: 4770 bx lr + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d5b0: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d5b2: f010 0001 ands.w r0, r0, #1 + 800d5b6: d002 beq.n 800d5be + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d5b8: 2301 movs r3, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND); + 800d5ba: 6393 str r3, [r2, #56] ; 0x38 + 800d5bc: 4770 bx lr + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND)) + 800d5be: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d5c0: 065b lsls r3, r3, #25 + 800d5c2: d503 bpl.n 800d5cc + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND); + 800d5c4: 2340 movs r3, #64 ; 0x40 + 800d5c6: e7f8 b.n 800d5ba + return SDMMC_ERROR_TIMEOUT; + 800d5c8: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d5cc: 4770 bx lr + 800d5ce: bf00 nop + 800d5d0: 2009e2a8 .word 0x2009e2a8 + +0800d5d4 : +{ + 800d5d4: b510 push {r4, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + 800d5d6: f44f 72d5 mov.w r2, #426 ; 0x1aa +{ + 800d5da: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + 800d5dc: 2308 movs r3, #8 + 800d5de: e9cd 2301 strd r2, r3, [sp, #4] + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d5e2: f44f 7180 mov.w r1, #256 ; 0x100 + 800d5e6: 2300 movs r3, #0 + 800d5e8: e9cd 1303 strd r1, r3, [sp, #12] +{ + 800d5ec: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5ee: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5f2: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5f4: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5f6: f7ff fbc9 bl 800cd8c + errorstate = SDMMC_GetCmdResp7(SDMMCx); + 800d5fa: 4620 mov r0, r4 + 800d5fc: f7ff ffc0 bl 800d580 +} + 800d600: b006 add sp, #24 + 800d602: bd10 pop {r4, pc} + +0800d604 : + 800d604: b510 push {r4, lr} + 800d606: 3901 subs r1, #1 + 800d608: 4402 add r2, r0 + 800d60a: 4290 cmp r0, r2 + 800d60c: d101 bne.n 800d612 + 800d60e: 2000 movs r0, #0 + 800d610: e005 b.n 800d61e + 800d612: 7803 ldrb r3, [r0, #0] + 800d614: f811 4f01 ldrb.w r4, [r1, #1]! + 800d618: 42a3 cmp r3, r4 + 800d61a: d001 beq.n 800d620 + 800d61c: 1b18 subs r0, r3, r4 + 800d61e: bd10 pop {r4, pc} + 800d620: 3001 adds r0, #1 + 800d622: e7f2 b.n 800d60a + +0800d624 : + 800d624: 440a add r2, r1 + 800d626: 4291 cmp r1, r2 + 800d628: f100 33ff add.w r3, r0, #4294967295 ; 0xffffffff + 800d62c: d100 bne.n 800d630 + 800d62e: 4770 bx lr + 800d630: b510 push {r4, lr} + 800d632: f811 4b01 ldrb.w r4, [r1], #1 + 800d636: f803 4f01 strb.w r4, [r3, #1]! + 800d63a: 4291 cmp r1, r2 + 800d63c: d1f9 bne.n 800d632 + 800d63e: bd10 pop {r4, pc} + +0800d640 : + 800d640: 4288 cmp r0, r1 + 800d642: b510 push {r4, lr} + 800d644: eb01 0402 add.w r4, r1, r2 + 800d648: d902 bls.n 800d650 + 800d64a: 4284 cmp r4, r0 + 800d64c: 4623 mov r3, r4 + 800d64e: d807 bhi.n 800d660 + 800d650: 1e43 subs r3, r0, #1 + 800d652: 42a1 cmp r1, r4 + 800d654: d008 beq.n 800d668 + 800d656: f811 2b01 ldrb.w r2, [r1], #1 + 800d65a: f803 2f01 strb.w r2, [r3, #1]! + 800d65e: e7f8 b.n 800d652 + 800d660: 4402 add r2, r0 + 800d662: 4601 mov r1, r0 + 800d664: 428a cmp r2, r1 + 800d666: d100 bne.n 800d66a + 800d668: bd10 pop {r4, pc} + 800d66a: f813 4d01 ldrb.w r4, [r3, #-1]! + 800d66e: f802 4d01 strb.w r4, [r2, #-1]! + 800d672: e7f7 b.n 800d664 + +0800d674 : + 800d674: 4402 add r2, r0 + 800d676: 4603 mov r3, r0 + 800d678: 4293 cmp r3, r2 + 800d67a: d100 bne.n 800d67e + 800d67c: 4770 bx lr + 800d67e: f803 1b01 strb.w r1, [r3], #1 + 800d682: e7f9 b.n 800d678 + +0800d684 : + 800d684: 46ec mov ip, sp + 800d686: e8a0 5ff0 stmia.w r0!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} + 800d68a: f04f 0000 mov.w r0, #0 + 800d68e: 4770 bx lr + +0800d690 : + 800d690: e8b0 5ff0 ldmia.w r0!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} + 800d694: 46e5 mov sp, ip + 800d696: 0008 movs r0, r1 + 800d698: bf08 it eq + 800d69a: 2001 moveq r0, #1 + 800d69c: 4770 bx lr + 800d69e: bf00 nop + +0800d6a0 : + 800d6a0: 4603 mov r3, r0 + 800d6a2: f811 2b01 ldrb.w r2, [r1], #1 + 800d6a6: f803 2b01 strb.w r2, [r3], #1 + 800d6aa: 2a00 cmp r2, #0 + 800d6ac: d1f9 bne.n 800d6a2 + 800d6ae: 4770 bx lr + +0800d6b0 : + 800d6b0: b510 push {r4, lr} + 800d6b2: 460b mov r3, r1 + 800d6b4: b162 cbz r2, 800d6d0 + 800d6b6: 3a01 subs r2, #1 + 800d6b8: d008 beq.n 800d6cc + 800d6ba: f813 4b01 ldrb.w r4, [r3], #1 + 800d6be: f800 4b01 strb.w r4, [r0], #1 + 800d6c2: 2c00 cmp r4, #0 + 800d6c4: d1f7 bne.n 800d6b6 + 800d6c6: 1a58 subs r0, r3, r1 + 800d6c8: 3801 subs r0, #1 + 800d6ca: bd10 pop {r4, pc} + 800d6cc: 2200 movs r2, #0 + 800d6ce: 7002 strb r2, [r0, #0] + 800d6d0: f813 2b01 ldrb.w r2, [r3], #1 + 800d6d4: 2a00 cmp r2, #0 + 800d6d6: d1fb bne.n 800d6d0 + 800d6d8: e7f5 b.n 800d6c6 + +0800d6da : + 800d6da: 4603 mov r3, r0 + 800d6dc: f813 2b01 ldrb.w r2, [r3], #1 + 800d6e0: 2a00 cmp r2, #0 + 800d6e2: d1fb bne.n 800d6dc + 800d6e4: 1a18 subs r0, r3, r0 + 800d6e6: 3801 subs r0, #1 + 800d6e8: 4770 bx lr + 800d6ea: 0000 movs r0, r0 + 800d6ec: 0000 movs r0, r0 + ... + +0800d6f0 <__flash_burn_veneer>: + 800d6f0: f85f f000 ldr.w pc, [pc] ; 800d6f4 <__flash_burn_veneer+0x4> + 800d6f4: 2009e001 .word 0x2009e001 + +0800d6f8 <__flash_page_erase_veneer>: + 800d6f8: f85f f000 ldr.w pc, [pc] ; 800d6fc <__flash_page_erase_veneer+0x4> + 800d6fc: 2009e08d .word 0x2009e08d + 800d700: 6f636e69 .word 0x6f636e69 + 800d704: 006e .short 0x006e + 800d706: 6944 .short 0x6944 + 800d708: 44203a65 .word 0x44203a65 + 800d70c: 44005546 .word 0x44005546 + 800d710: 203a6569 .word 0x203a6569 + 800d714: 6e776f44 .word 0x6e776f44 + 800d718: 64617267 .word 0x64617267 + 800d71c: 69440065 .word 0x69440065 + 800d720: 42203a65 .word 0x42203a65 + 800d724: 6b6e616c .word 0x6b6e616c + 800d728: 00687369 .word 0x00687369 + 800d72c: 3a656944 .word 0x3a656944 + 800d730: 69724220 .word 0x69724220 + 800d734: 42006b63 .word 0x42006b63 + 800d738: 32746f6f .word 0x32746f6f + 800d73c: 00554644 .word 0x00554644 + 800d740: 43455441 .word 0x43455441 + 800d744: 38303643 .word 0x38303643 + 800d748: 53440a42 .word 0x53440a42 + 800d74c: 33433832 .word 0x33433832 + 800d750: 4c004236 .word 0x4c004236 + 800d754: 0052 .short 0x0052 + 800d756: 6e65 .short 0x6e65 + 800d758: 5f726574 .word 0x5f726574 + 800d75c: 28756664 .word 0x28756664 + 800d760: 0029 .short 0x0029 + 800d762: 0a0d .short 0x0a0d + 800d764: 346b4d0a .word 0x346b4d0a + 800d768: 6f6f4220 .word 0x6f6f4220 + 800d76c: 616f6c74 .word 0x616f6c74 + 800d770: 3a726564 .word 0x3a726564 + 800d774: 463e0020 .word 0x463e0020 + 800d778: 57455249 .word 0x57455249 + 800d77c: 454c4c41 .word 0x454c4c41 + 800d780: 70003c44 .word 0x70003c44 + 800d784: 2d726961 .word 0x2d726961 + 800d788: 63697262 .word 0x63697262 + 800d78c: 0064656b .word 0x0064656b + 800d790: 69726556 .word 0x69726556 + 800d794: 203a7966 .word 0x203a7966 + 800d798: 00000000 .word 0x00000000 + 800d79c: 00000150 .word 0x00000150 + 800d7a0: 00000001 .word 0x00000001 + 800d7a4: 00000000 .word 0x00000000 + 800d7a8: 00000001 .word 0x00000001 + 800d7ac: 00000000 .word 0x00000000 + +0800d7b0 : + 800d7b0: 0700262e ff000707 .&....../ + +0800d7b9 : + 800d7b9: 227f0021 !..".. + +0800d7bf : + 800d7bf: 400020ae c83fa8a1 12da00d3 f1d980d5 . .@..?......... + 800d7cf: ff8130db 148da6a4 .0....... + +0800d7d8 : + 800d7d8: 227f0021 !..".. + +0800d7de : + 800d7de: 007f007f 0034007f 000d8081 000d8081 ......4......... + 800d7ee: 00628081 01030183 0183000b 000b0103 ..b............. + 800d7fe: 01030183 007f007f 0034007f ..........4.. + +0800d80b : + 800d80b: 007f007f 002b007f 8803f881 0000f085 ......+......... + 800d81b: 400380c0 00008086 03d84040 04808100 ...@....@@...... + 800d82b: 00808a40 800000f8 80000040 80834004 @.......@....@.. + 800d83b: 40038000 50f88082 041f8100 000f8310 ...@...P........ + 800d84b: 8100091f 8100031f 8a10040f 021f0008 ................ + 800d85b: 10080403 12040f00 0f001383 08821003 ................ + 800d86b: 7f007f1f 2b007f00 .......+.. + +0800d875 : + 800d875: 0037007f 40c08086 03303060 05188190 ..7....@`00..... + 800d885: 08188510 68e0f018 f8808b00 38e1071c .......h.......8 + 800d895: 0103060c 82000b01 006820ff 0e7fc182 ......... h..... + 800d8a5: 80808700 0e3860c0 85006907 04060301 .....`8..i...... + 800d8b5: 82020406 02030606 01030383 f881005e ............^... + 800d8c5: 08868804 40400000 820003d8 400380c0 ......@@.......@ + 800d8d5: c000808a 40804040 04c00080 00c08300 ....@@.@........ + 800d8e5: 84400400 80c00080 80834003 40048000 ..@......@.....@ + 800d8f5: 08008087 30488808 1f810043 1f810009 ......H0C....... + 800d905: 1f810003 1f8f0006 00070000 100f001f ................ + 800d915: 0f100f08 11030e00 001f0984 8100061f ................ + 800d925: 8412040f 1b000013 0026007f ..........&.. + +0800d932 : + 800d932: 002c007f 00888003 98f09000 1640d0a0 ..,...........@. + 800d942: 80808400 180330e0 18031081 80e03084 .....0.......0.. + 800d952: 89004380 0c18f0c0 191373e6 89010519 .C.......s...... + 800d962: 07030100 000039ef 92001501 f9ede702 .....9.......... + 800d972: 783818c8 78381838 f9c81838 0042e7ed ..8x8.8x8.....B. + 800d982: e03d0f85 000a0180 70c08085 0017023f ..=........p?... + 800d992: 07fcf883 7e870304 640464fc 03047efc .......~.d.d.~.. + 800d9a2: f0fc0783 01840043 06020301 03028306 ....C........... + 800d9b2: 82001b01 06060703 06030781 06060781 ................ + 800d9c2: 2e030782 03f88100 e0108408 40040000 ...............@ + 800d9d2: c0008084 83400380 03800080 c0808440 ......@.....@... + 800d9e2: 40048000 c0008084 81400380 81000380 ...@......@..... + 800d9f2: 81000bf8 830804f0 04c00030 00c08300 ........0....... + 800da02: 84400480 f0400080 00834003 40048000 ..@...@..@.....@ + 800da12: c0008088 40804040 81000380 81001bf8 ....@@.@........ + 800da22: 8410031f 0e000708 09841103 041f001f ................ + 800da32: 001f8300 84880347 0f007f84 13831204 ....G........... + 800da42: 00081f00 000b1b81 10040f81 0f000c83 ................ + 800da52: 08841003 0409001f 000c8412 10030f00 ................ + 800da62: 0f000883 0f881004 00001f00 031f0007 ................ + 800da72: 7f1b8100 00001000 ........ + +0800da7a : + 800da7a: 0035007f 00f0f095 6060c080 10103030 ..5.......``00.. + 800da8a: 10101818 60603030 006b80c0 0c040f04 ....00``..k..... + 800da9a: ff820003 840007ff e0fc0f03 c083006c ............l... + 800daaa: 00058080 0603018c 80800006 0f3c70c0 .............p<. + 800daba: 8e006d01 03030101 06060202 03030202 .m.............. + 800daca: 00570101 0803f881 00e01084 83400480 ..W...........@. + 800dada: 04c00080 00c08400 400380c0 80008083 ...........@.... + 800daea: 80854003 80c000c0 80834003 40040000 .@.......@.....@ + 800dafa: 80008083 80844003 048000f8 00808740 .....@......@... + 800db0a: 48880808 81003c30 8410031f 0f000708 ...H0<.......... + 800db1a: 0f8a1004 08100f00 000f100f 8300041f ................ + 800db2a: 0347001f 7f848488 00061f00 11030e81 ..G............. + 800db3a: 001f0984 8410030f 0f001f08 13841204 ................ + 800db4a: 7f1b0000 00002200 .....".. + +0800db52 : + 800db52: 007f007f 0036007f 90fc9089 0090fc90 ......6......... + 800db62: 4203fc40 f000048b 00c00000 fc4000f0 @..B..........@. + 800db72: 04814203 03840066 03030000 05078100 .B..f........... + 800db82: 04038900 03040302 7f070000 7f007f00 ................ + 800db92: 00003900 .9.. + +0800db96 : + 800db96: 0035007f c0078081 00064081 6f808082 ..5......@.....o + 800dba6: ffff8200 c0070006 c7c3c189 f0f8dcce ................ + 800dbb6: 0068c0e0 06ff7f82 068081c0 70608800 ..h...........`p + 800dbc6: 070e1c38 007f0103 f8810050 80810006 8.......P....... + 800dbd6: 80834004 40038000 00c08084 83400480 .@.....@......@. + 800dbe6: 04c00080 00c08400 4003f040 f8810009 ........@..@.... + 800dbf6: 10840803 048000e0 00808440 400380c0 ........@......@ + 800dc06: 80008083 80814004 1f810034 00821005 .....@..4....... + 800dc16: 8310040f 0347000f 7f848488 10040f00 ......G......... + 800dc26: 0f000f83 08851003 0f00001f 08811003 ................ + 800dc36: 1f810008 08841003 040f0007 000f8310 ................ + 800dc46: 8300041f 040f001f 7f138112 00001b00 ................ + +0800dc56 : + 800dc56: 007f007f 0043007f 0c30c083 01060073 ......C...0.s... + 800dc66: 0c300084 06000403 7f007f01 39007f00 ..0............9 + ... + +0800dc78 : + 800dc78: 0031007f c0e06084 85001080 f030e0e0 ..1..`........0. + 800dc88: 863008f0 6020f0f0 004f80c0 c189c00c ..0... `..O..... + 800dc98: dccec7c3 c0e0f0f8 ff8f0009 0f0f00ff ................ + 800dca8: cc8c0c0c cccc4ccc 00030f8f feff0183 .....L.......... + 800dcb8: 808a0057 3870e0c0 03070e1c 82000a01 W.....p8........ + 800dcc8: 0004ffff 301f0689 30302030 0004061f .......00 00.... + 800dcd8: 57ffff82 01018200 01820012 82031101 ...W............ + 800dce8: 00410101 f8080889 00000808 400380c0 ..A............@ + 800dcf8: 80008083 80834004 40048000 c0008084 .....@.....@.... + 800dd08: 84400380 f0400080 00094003 0804f081 ..@...@..@...... + 800dd18: 00003083 80844004 0380c000 00808340 .0...@......@... + 800dd28: 82400380 0034f880 1f101088 00001010 ..@...4......... + 800dd38: 8300041f 0409001f 000c8312 8312040f ................ + 800dd48: 071f0013 030f8100 08088110 040f8100 ................ + 800dd58: 000c8310 8411030e 1f001f09 0f810006 ................ + 800dd68: 08821003 1b007f1f .......... + +0800dd72 : + 800dd72: 002c007f 00888003 98f09000 1640d0a0 ..,...........@. + 800dd82: 80808400 180330e0 18031081 80e03084 .....0.......0.. + 800dd92: 89004380 0c18f0c0 191373e6 89010519 .C.......s...... + 800dda2: 07030100 000039ef 92001501 f9ede702 .....9.......... + 800ddb2: 783818c8 78381838 f9c81838 0042e7ed ..8x8.8x8.....B. + 800ddc2: e03d0f85 000a0180 70c08085 0017023f ..=........p?... + 800ddd2: 07fcf883 7e870304 640464fc 03047efc .......~.d.d.~.. + 800dde2: f0fc0783 01840043 06020301 03028306 ....C........... + 800ddf2: 82001b01 06060703 06030781 06060781 ................ + 800de02: 2b030782 03f88100 e0108408 40040000 ...+...........@ + 800de12: c0008084 83400380 03800080 c0808440 ......@.....@... + 800de22: 40048000 c0008084 81400380 81000380 ...@......@..... + 800de32: 81000bf8 830804f0 04000030 00808340 ........0...@... + 800de42: 840004c0 f04000c0 00034003 d8404083 ......@..@...@@. + 800de52: 80810003 80844004 0380c000 03808140 .....@......@... + 800de62: 14f88100 031f8100 07088410 11030e00 ................ + 800de72: 001f0984 8300041f 0347001f 7f848488 ..........G..... + 800de82: 12040f00 1f001383 1b810008 0f81000b ................ + 800de92: 0c831004 11030e00 001f0984 8510030f ................ + 800dea2: 00001f08 8110030f 81000408 8100031f ................ + 800deb2: 8310040f 041f000f 031f8100 7f1b8100 ................ + 800dec2: 00000c00 .... + +0800dec6 : + 800dec6: 007f007f 002f007f 0804f881 8000f083 ....../......... + 800ded6: 80844004 0380c000 00808440 0005f800 .@......@....... + 800dee6: 0004c081 8000c083 80824003 880057c0 .........@...W.. + 800def6: 0503011f 0f001009 13841204 03047f00 ................ + 800df06: 00078408 10030f00 0f000083 08841003 ................ + 800df16: 0347001f 7f848288 007f007f 002e007f ..G............. + ... + +0800df27 : + 800df27: 0035007f 04808082 60c08300 83180530 ..5........`0... + 800df37: 04c07030 6b808100 ff018600 070606fe 0p.....k........ + 800df47: e6810604 07860604 fffe0607 03006901 .............i.. + 800df57: bf078401 000580e0 0005ff81 bfe08084 ................ + 800df67: 69010307 07068300 89010303 06060203 ...i............ + 800df77: 02020607 83010303 62060703 04f88100 ...........b.... + 800df87: 00f88900 0830c000 060000f8 70008980 ......0........p + 800df97: 08088888 04f80010 00088688 f8102040 ............@ .. + 800dfa7: 0f810059 0f831004 02030300 00021f83 Y............... + 800dfb7: 00890406 11101008 1f000e11 00041005 ................ + 800dfc7: 007f1f81 ....... + +0800dfce : + 800dfce: 0035007f 04808082 60c08300 83180530 ..5........`0... + 800dfde: 04c07030 6b808100 ff018600 070606fe 0p.....k........ + 800dfee: e6810604 07860604 fffe0607 03006901 .............i.. + 800dffe: bf078401 000580e0 0005ff81 bfe08084 ................ + 800e00e: 69010307 07068300 89010303 06060203 ...i............ + 800e01e: 02020607 83010303 62060703 04f88100 ...........b.... + 800e02e: 00f88300 824804f8 80060088 88700089 ......H.......p. + 800e03e: 10080888 8804f800 30000883 88820803 ...........0.... + 800e04e: 81005770 8310040f 0408000f 000f8210 pW.............. + 800e05e: 00890406 11101008 1f000e11 00871005 ................ + 800e06e: 11121418 007f1010 ........,.. + +0800e079 : + 800e079: 0028007f 2060c085 18061030 60301085 ..(...` 0.....0` + 800e089: 000f80c0 30e0e085 3008f0f0 20f0f086 .......0...0... + 800e099: 4c80c060 fffc8300 82000e01 000eff03 `..L............ + 800e0a9: 00ffff8f 0c0c0f0f 4ccccc8c 0f8fcccc ...........L.... + 800e0b9: 01830003 004bfeff 0c060389 20303018 ......K......00 + 800e0c9: 20036020 18103089 e0713f1e 000b80c0 `. .0...?q..... + 800e0d9: 04ffff82 1f068900 30203030 04061f30 ........00 00... + 800e0e9: ffff8200 0184005e 09060703 01018200 ....^........... + 800e0f9: 01820311 88003c01 08888870 80001008 .....<..p....... + 800e109: 80834004 40040000 c0008084 83400380 .@.....@......@. + 800e119: 04800080 00808440 400380f8 00008086 ....@......@.... + 800e129: 03d84040 80c08200 80834003 40038000 @@.......@.....@ + 800e139: 42c08082 10088800 0e111110 12040f00 ...B............ + 800e149: 0e001383 09841103 061f001f 040f8100 ................ + 800e159: 00088310 8100041f 8100041f 8100031f ................ + 800e169: 8300041f 0347001f 7f848788 38100000 ......G........8 + 800e179: 83000410 04103810 38108300 19007f10 .....8.....8.... + ... + +0800e18b : + 800e18b: 0035007f 0e80c082 6a800600 ffff8200 ..5........j.... + 800e19b: 80900005 603060c0 63c080c0 30181c37 .....`0`...c7..0 + 800e1ab: 691e3f20 ffff8800 ceccc0c0 c005c1c7 ?.i............ + 800e1bb: c009c181 007f8081 f8810056 f8840004 ........V....... + 800e1cb: 0380c000 00808340 85400380 c000c080 ....@.....@..... + 800e1db: 83400380 04000080 00808340 87400380 ..@.....@.....@. + 800e1eb: 0000f880 03d84040 80c08200 80834003 ....@@.......@.. + 800e1fb: 40038000 42c08082 040f8100 000f8410 ...@...B........ + 800e20b: 0803047f 47000783 84848803 061f007f .......G........ + 800e21b: 030e8100 1f098411 10030f00 041f0882 ................ + 800e22b: 031f8100 041f8100 001f8300 82880347 ............G... + 800e23b: 007f7f84 ....".. + +0800e242 : + 800e242: 0038007f 60c08085 10033020 1018188a ..8....` 0...... + 800e252: 60303010 6b80c060 fce08400 00070107 .00``..k........ + 800e262: 07ffff82 0f038400 0068e0fc 380f0187 ..........h....8 + 800e272: 8080c060 018c0005 00060703 70c08080 `..............p + 800e282: 6d010f3c 01018e00 02020303 02020606 <..m............ + 800e292: 01010303 f881005a f8830004 40048000 ....Z..........@ + 800e2a2: c0008084 86400380 40000080 0004d840 ......@....@@... + 800e2b2: 0803f081 c0001083 c0860004 40400000 ..............@@ + 800e2c2: 820003d8 400380c0 80008083 80824003 .......@.....@.. + 800e2d2: 880042c0 18180601 0f000106 13831204 .B.............. + 800e2e2: 00091f00 00031f81 031f0182 00008301 ................ + 800e2f2: 82880347 00047f84 00031f81 00041f81 G............... + 800e302: 47001f83 84828803 22007f7f ...G.......".. + +0800e310 : + 800e310: 0038007f 60c08084 82000420 0004f8f8 ..8....` ....... + 800e320: c0606084 84006b80 0307fce0 ff820007 .``..k.......... + 800e330: 840007ff e0fc0f03 01870068 c060380f ........h....8`. + 800e340: 000a8080 c0808087 010f3c70 018e006d ........p<..m... + 800e350: 02030301 02060602 01030302 88005701 .............W.. + 800e360: 08888870 80001008 80834004 40048000 p........@.....@ + 800e370: 80008083 80824003 810008f8 860004f8 .....@.......... + 800e380: 400000f8 0003d840 0380c082 00808340 ...@@.......@... + 800e390: 83400480 03800080 f8808240 0888003b ..@.....@...;... + 800e3a0: 11111010 040f000e 00138312 8312040f ................ + 800e3b0: 030f0013 1f088210 07860008 18070718 ................ + 800e3c0: 81000407 8200031f 0803047f 0f000783 ................ + 800e3d0: 13831204 10030f00 7f1f0882 00001e00 ................ + 800e3e0: 65737361 64007472 676e776f 65646172 assert.downgrade + 800e3f0: 67697300 69616620 6f6e006c 72696620 .sig fail.no fir + 800e400: 7261776d 61460065 726f7463 6f622079 mware.Factory bo + 800e410: 5700746f 3a4e5241 64655220 67696c20 ot.WARN: Red lig + 800e420: 57007468 3a4e5241 736e5520 656e6769 ht.WARN: Unsigne + 800e430: 69662064 61776d72 47006572 20646f6f d firmware.Good + 800e440: 6d726966 65726177 726f6300 74707572 firmware.corrupt + 800e450: 72696620 7261776d firmware. + +0800e45a : + 800e45a: 2641cbb4 f36ce1f7 71b4f28f 0123fb1d ..A&..l....q..#. + 800e46a: 66d6760d 6ca38aa7 f6f9539b 0518587b .v.f...l.S..{X.. + 800e47a: e93b0b58 b89fc431 113c0444 470f0896 X.;.1...D.<....G + 800e48a: 37ed2581 4a9e237a 3818b7af da0438ba .%.7z#.J...8.8.. + 800e49a: 1dc8a2d6 df5e811c 6d290ca6 8d8f57b8 ......^...)m.W.. + 800e4aa: 9269295e c178d1ce 31d7207b b596a17b ^)i...x.{ .1{... + 800e4ba: 0c1bef3d c31a79aa c8c45845 ffeb2d8a =....y..EX...-.. + 800e4ca: 01829bfe bc5e5f87 4fe5a596 9ffe68c7 ....._^....O.h.. + 800e4da: 0166ef42 95cfc456 38f0b5f4 c5261164 B.f.V......8d.&. + 800e4ea: 66c13999 14120632 689c254c bad38c35 .9.f2...L%.h5... + 800e4fa: 8cde7824 6cdfab52 7809bfb8 3a63bb03 $x..R..l...x..c: + 800e50a: 0ed90111 8f737aa4 7f3b18bf c87b0af0 .....zs...;...{. + 800e51a: 56546067 c5ec0c82 0882bc1d ef39c116 g`TV..........9. + 800e52a: 32babff5 e35fce7c d7621e74 4cc5fce9 ...2|._.t.b....L + 800e53a: 8d11e88a 13c2adc3 2a4f2992 a4f8d2ea .........)O*.... + 800e54a: fe7cd5c4 3b450512 07598954 88d7d6da ..|...E;T.Y..... + 800e55a: 37cfb143 1f897cd2 f3acfe5b 95fc33ba C..7.|..[....3.. + 800e56a: dde7d981 14ef9525 bb97efdd a7d8f333 ....%.......3... + 800e57a: 977a2b34 73aab3ba 32419de7 17a1fcd8 4+z....s..A2.... + 800e58a: fe0bb566 89214063 8e7b92c9 590bdf72 f...c@!...{.r..Y + 800e59a: 76dc5cd0 30dd3016 56f180c2 61a85c26 .\.v.0.0...V&\.a + 800e5aa: 69694fd7 3d57b8e5 582ae235 c69acedd .Oii..W=5.*X.... + 800e5ba: 2b1ca945 8efc010c 13513fbf 137c7e80 E..+.....?Q..~|. + 800e5ca: 5e4b4fd5 d59b4c9b e0d81d9e 2246c0ad .OK^.L........F" + 800e5da: 20314553 666e6f63 66206769 006c6961 SE1 config fail. + 800e5ea: 6c706572 72206775 69757165 00646572 replug required. + 800e5fa: 72726f63 20747075 72696170 63657320 corrupt pair sec + 800e60a: 75636d00 6c756620 7562006c 66206e72 .mcu full.burn f + 800e61a: 3a6c6961 76210020 64696c61 6162003f ail: .!valid?.ba + 800e62a: 61762064 66003f6c 20747361 63697262 d val?.fast bric + 800e63a: 2e2e2e6b 64200020 00656e6f 79706f43 k... . done.Copy + 800e64a: 68676972 30322074 202d3831 43207962 right 2018- by C + 800e65a: 6b6e696f 20657469 2e636e49 206f6e00 oinkite Inc..no + 800e66a: 00726573 66206b77 0016006c 01410800 ser.wk fl.....A. + ... + 800e686: 000000ee 006100e1 218f0000 438f808f ......a....!...C + 800e696: 430080af 20834300 43c343c3 43c343c3 ...C.C. .C.C.C.C + 800e6a6: 43c343c3 0000438f ffffffff 00000000 .C.C.C.......... + 800e6b6: ffffffff 00000000 00000000 000000f0 ................ + ... + 800e6ce: 00001502 003c0000 01bc005c 01bc01fc ......<.\....... + 800e6de: 01dc01dc 03dc03d1 03dc03dc 03dc03dc ................ + 800e6ee: 01dc03dc 0001003c 00120000 00000000 ....<........... + 800e6fe: 00010000 00080000 02000000 00020000 ................ + 800e70e: 00000000 00010000 00070000 .............. + +0800e71c : + 800e71c: 0d0c0b09 .... + +0800e720 : + 800e720: 2e322e33 69742031 323d656d 30353230 3.2.1 time=20250 + 800e730: 2e353134 39303930 67203533 6d3d7469 415.090935 git=m + 800e740: 65747361 64614072 63326663 0d006538 aster@adcf2c8e.. + 800e750: .. + +0800e752 : + 800e752: 33323130 37363534 62613938 66656463 0123456789abcdef + 800e762: 41525350 6166204d 50006c69 203a5253 PSRAM fail.PSR: + 800e772: 6164616e 52535000 6321203a 6b636568 nada.PSR: !check + 800e782: 52535000 6576203a 6f697372 fc00006e .PSR: version... + 800e792: 00020000 00000000 00030000 000a0000 ................ + 800e7a2: 00080000 00100000 6f6c0000 7220676e ..........long r + 800e7b2: 20646165 6c696166 55464400 72617020 ead fail.DFU par + 800e7c2: 66206573 006c6961 646f6f67 72696620 se fail.good fir + 800e7d2: 7261776d 72770065 20676e6f 6c726f77 mware.wrong worl + 800e7e2: 64730064 64726163 6165735f 3a686372 d.sdcard_search: + 800e7f2: 64730020 64726163 6f72705f 203a6562 .sdcard_probe: + 800e802: 696e6900 61662074 73006c69 64656570 .init fail.speed + 800e812: 64697700 73620065 3f657a69 006b6f00 .wide.bsize?.ok. + 800e822: 6c696166 61657220 66440064 00655375 fail read.DfuSe. + 800e832: 6e756f66 20402064 63655200 7265766f found @ .Recover + 800e842: 6f6d2079 002e6564 1f000000 00020000 y mode.......... + 800e852: 00010000 00030000 000c0000 00040000 ................ + 800e862: 00020000 00010000 00030000 000c0000 ................ + ... + +0800e874 : + 800e874: 01002008 fffffc2f fffffffe ffffffff . ../........... + 800e884: ffffffff ffffffff ffffffff ffffffff ................ + 800e894: ffffffff d0364141 bfd25e8c af48a03b ....AA6..^..;.H. + 800e8a4: baaedce6 fffffffe ffffffff ffffffff ................ + 800e8b4: ffffffff 16f81798 59f2815b 2dce28d9 ........[..Y.(.- + 800e8c4: 029bfcdb ce870b07 55a06295 f9dcbbac .........b.U.... + 800e8d4: 79be667e fb10d4b8 9c47d08f a6855419 ~f.y......G..T.. + 800e8e4: fd17b448 0e1108a8 5da4fbfc 26a3c465 H..........]e..& + 800e8f4: 483ada77 00000007 00000000 00000000 w.:H............ + ... + 800e918: 0800663d 08005ec1 08006097 08005cad =f...^...`...\.. + +0800e928 : + 800e928: 01002008 ffffffff ffffffff ffffffff . .............. + ... + 800e944: 00000001 ffffffff fc632551 f3b9cac2 ........Q%c..... + 800e954: a7179e84 bce6faad ffffffff ffffffff ................ + 800e964: 00000000 ffffffff d898c296 f4a13945 ............E9.. + 800e974: 2deb33a0 77037d81 63a440f2 f8bce6e5 .3.-.}.w.@.c.... + 800e984: e12c4247 6b17d1f2 37bf51f5 cbb64068 GB,....k.Q.7h@.. + 800e994: 6b315ece 2bce3357 7c0f9e16 8ee7eb4a .^1kW3.+...|J... + 800e9a4: fe1a7f9b 4fe342e2 27d2604b 3bce3c3e .....B.OK`.'><.; + 800e9b4: cc53b0f6 651d06b0 769886bc b3ebbd55 ..S....e...vU... + 800e9c4: aa3a93e7 5ac635d8 08006785 08005ec1 ..:..5.Z.g...^.. + 800e9d4: 0800672b 08005d29 +g..)].. + +0800e9dc : + ... + 800e9e4: 04030201 09080706 ........ + +0800e9ec : + 800e9ec: 00000000 04030201 ........ + +0800e9f4 : + 800e9f4: 000186a0 00030d40 00061a80 000c3500 ....@........5.. + 800ea04: 000f4240 001e8480 003d0900 007a1200 @B........=...z. + 800ea14: 00f42400 016e3600 01e84800 02dc6c00 .$...6n..H...l.. + 800ea24: 20727463 3f746573 00702100 00006000 ctr set?.!p..`.. + 800ea34: 00000012 00000000 00000003 00000004 ................ + +0800ea44 : + 800ea44: 00008000 .... + +Disassembly of section .relocate: + +2009e000 : +{ +2009e000: b530 push {r4, r5, lr} + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e002: 4920 ldr r1, [pc, #128] ; (2009e084 ) +2009e004: 690c ldr r4, [r1, #16] +2009e006: 03e5 lsls r5, r4, #15 +2009e008: d4fc bmi.n 2009e004 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e00a: 690d ldr r5, [r1, #16] + if(error) { +2009e00c: 4c1e ldr r4, [pc, #120] ; (2009e088 ) +2009e00e: 4225 tst r5, r4 +2009e010: d104 bne.n 2009e01c + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e012: 690c ldr r4, [r1, #16] +2009e014: 07e4 lsls r4, r4, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e016: bf44 itt mi +2009e018: 2401 movmi r4, #1 +2009e01a: 610c strmi r4, [r1, #16] + FLASH->SR = FLASH->SR & FLASH_FLAG_SR_ERRORS; +2009e01c: 4919 ldr r1, [pc, #100] ; (2009e084 ) +2009e01e: 4d1a ldr r5, [pc, #104] ; (2009e088 ) +2009e020: 690c ldr r4, [r1, #16] +2009e022: 402c ands r4, r5 +2009e024: 610c str r4, [r1, #16] + __HAL_FLASH_DATA_CACHE_DISABLE(); +2009e026: 680c ldr r4, [r1, #0] +2009e028: f424 6480 bic.w r4, r4, #1024 ; 0x400 +2009e02c: 600c str r4, [r1, #0] + CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB)); // added +2009e02e: 694c ldr r4, [r1, #20] +2009e030: f424 64ff bic.w r4, r4, #2040 ; 0x7f8 +2009e034: f024 0407 bic.w r4, r4, #7 +2009e038: 614c str r4, [r1, #20] + SET_BIT(FLASH->CR, FLASH_CR_PG); +2009e03a: 694c ldr r4, [r1, #20] +2009e03c: f044 0401 orr.w r4, r4, #1 +2009e040: 614c str r4, [r1, #20] + *(__IO uint32_t *)(address) = (uint32_t)val; +2009e042: 6002 str r2, [r0, #0] + __ASM volatile ("isb 0xF":::"memory"); +2009e044: f3bf 8f6f isb sy + *(__IO uint32_t *)(address+4) = (uint32_t)(val >> 32); +2009e048: 6043 str r3, [r0, #4] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e04a: 690b ldr r3, [r1, #16] +2009e04c: 03da lsls r2, r3, #15 +2009e04e: d4fc bmi.n 2009e04a + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e050: 6908 ldr r0, [r1, #16] + if(error) { +2009e052: 4028 ands r0, r5 +2009e054: d104 bne.n 2009e060 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e056: 690b ldr r3, [r1, #16] +2009e058: 07db lsls r3, r3, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e05a: bf44 itt mi +2009e05c: 2301 movmi r3, #1 +2009e05e: 610b strmi r3, [r1, #16] + CLEAR_BIT(FLASH->CR, FLASH_CR_PG); +2009e060: 4b08 ldr r3, [pc, #32] ; (2009e084 ) +2009e062: 695a ldr r2, [r3, #20] +2009e064: f022 0201 bic.w r2, r2, #1 +2009e068: 615a str r2, [r3, #20] + __HAL_FLASH_DATA_CACHE_RESET(); +2009e06a: 681a ldr r2, [r3, #0] +2009e06c: f442 5280 orr.w r2, r2, #4096 ; 0x1000 +2009e070: 601a str r2, [r3, #0] +2009e072: 681a ldr r2, [r3, #0] +2009e074: f422 5280 bic.w r2, r2, #4096 ; 0x1000 +2009e078: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); +2009e07a: 681a ldr r2, [r3, #0] +2009e07c: f442 6280 orr.w r2, r2, #1024 ; 0x400 +2009e080: 601a str r2, [r3, #0] +} +2009e082: bd30 pop {r4, r5, pc} +2009e084: 40022000 .word 0x40022000 +2009e088: 0002c3fa .word 0x0002c3fa + +2009e08c : + if(page_num < ((BL_FLASH_SIZE + BL_NVROM_SIZE) / FLASH_ERASE_SIZE)) { +2009e08c: 4b2d ldr r3, [pc, #180] ; (2009e144 ) +2009e08e: 4003 ands r3, r0 +{ +2009e090: b510 push {r4, lr} + if(page_num < ((BL_FLASH_SIZE + BL_NVROM_SIZE) / FLASH_ERASE_SIZE)) { +2009e092: 2b00 cmp r3, #0 +2009e094: d054 beq.n 2009e140 + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e096: 4b2c ldr r3, [pc, #176] ; (2009e148 ) + page_num &= 0xff; +2009e098: f3c0 3207 ubfx r2, r0, #12, #8 + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e09c: 6919 ldr r1, [r3, #16] +2009e09e: 03c9 lsls r1, r1, #15 +2009e0a0: d4fc bmi.n 2009e09c + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e0a2: 691c ldr r4, [r3, #16] + if(error) { +2009e0a4: 4929 ldr r1, [pc, #164] ; (2009e14c ) +2009e0a6: 420c tst r4, r1 +2009e0a8: d104 bne.n 2009e0b4 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e0aa: 6919 ldr r1, [r3, #16] +2009e0ac: 07cc lsls r4, r1, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e0ae: bf44 itt mi +2009e0b0: 2101 movmi r1, #1 +2009e0b2: 6119 strmi r1, [r3, #16] + FLASH->SR = FLASH->SR & 0xffff; +2009e0b4: 4b24 ldr r3, [pc, #144] ; (2009e148 ) +2009e0b6: 6919 ldr r1, [r3, #16] +2009e0b8: b289 uxth r1, r1 +2009e0ba: 6119 str r1, [r3, #16] + __HAL_FLASH_DATA_CACHE_DISABLE(); +2009e0bc: 6819 ldr r1, [r3, #0] +2009e0be: f421 6180 bic.w r1, r1, #1024 ; 0x400 +2009e0c2: 6019 str r1, [r3, #0] + SET_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0c4: 6959 ldr r1, [r3, #20] + if(bank2) { +2009e0c6: f010 6ffe tst.w r0, #133169152 ; 0x7f00000 + SET_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0ca: bf14 ite ne +2009e0cc: f441 6100 orrne.w r1, r1, #2048 ; 0x800 + CLEAR_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0d0: f421 6100 biceq.w r1, r1, #2048 ; 0x800 +2009e0d4: 6159 str r1, [r3, #20] + MODIFY_REG(FLASH->CR, FLASH_CR_PNB, (page_num << POSITION_VAL(FLASH_CR_PNB))); +2009e0d6: 6959 ldr r1, [r3, #20] + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +2009e0d8: f44f 63ff mov.w r3, #2040 ; 0x7f8 +2009e0dc: f421 61ff bic.w r1, r1, #2040 ; 0x7f8 +2009e0e0: fa93 f3a3 rbit r3, r3 + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +2009e0e4: fab3 f383 clz r3, r3 +2009e0e8: 409a lsls r2, r3 +2009e0ea: 4b17 ldr r3, [pc, #92] ; (2009e148 ) +2009e0ec: 430a orrs r2, r1 +2009e0ee: 615a str r2, [r3, #20] + SET_BIT(FLASH->CR, FLASH_CR_PER); +2009e0f0: 695a ldr r2, [r3, #20] +2009e0f2: f042 0202 orr.w r2, r2, #2 +2009e0f6: 615a str r2, [r3, #20] + SET_BIT(FLASH->CR, FLASH_CR_STRT); +2009e0f8: 695a ldr r2, [r3, #20] +2009e0fa: f442 3280 orr.w r2, r2, #65536 ; 0x10000 +2009e0fe: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e100: 691a ldr r2, [r3, #16] +2009e102: 03d1 lsls r1, r2, #15 +2009e104: d4fc bmi.n 2009e100 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e106: 6918 ldr r0, [r3, #16] +2009e108: 4a10 ldr r2, [pc, #64] ; (2009e14c ) + if(error) { +2009e10a: 4010 ands r0, r2 +2009e10c: d104 bne.n 2009e118 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e10e: 691a ldr r2, [r3, #16] +2009e110: 07d2 lsls r2, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e112: bf44 itt mi +2009e114: 2201 movmi r2, #1 +2009e116: 611a strmi r2, [r3, #16] + CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB)); +2009e118: 4b0b ldr r3, [pc, #44] ; (2009e148 ) +2009e11a: 695a ldr r2, [r3, #20] +2009e11c: f422 62ff bic.w r2, r2, #2040 ; 0x7f8 +2009e120: f022 0202 bic.w r2, r2, #2 +2009e124: 615a str r2, [r3, #20] + __HAL_FLASH_DATA_CACHE_RESET(); +2009e126: 681a ldr r2, [r3, #0] +2009e128: f442 5280 orr.w r2, r2, #4096 ; 0x1000 +2009e12c: 601a str r2, [r3, #0] +2009e12e: 681a ldr r2, [r3, #0] +2009e130: f422 5280 bic.w r2, r2, #4096 ; 0x1000 +2009e134: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); +2009e136: 681a ldr r2, [r3, #0] +2009e138: f442 6280 orr.w r2, r2, #1024 ; 0x400 +2009e13c: 601a str r2, [r3, #0] +} +2009e13e: bd10 pop {r4, pc} + return 1; +2009e140: 2001 movs r0, #1 +2009e142: e7fc b.n 2009e13e +2009e144: 07fe0000 .word 0x07fe0000 +2009e148: 40022000 .word 0x40022000 +2009e14c: 0002c3fa .word 0x0002c3fa diff --git a/stm32/q1-bootloader/releases/1.1.0.txt b/stm32/q1-bootloader/releases/1.1.0.txt new file mode 100644 index 00000000..ffb133b9 --- /dev/null +++ b/stm32/q1-bootloader/releases/1.1.0.txt @@ -0,0 +1,4 @@ +f85eb3fcc2bbaa3056ef1efb5f5de94c1527eea17c21e21f0fb4fcd6a988c8b6 bootloader.dfu +62aaa45a663e9765125f1bd9d36bd498c402a94b0fd7dfc3c9cdb771c8f2384b bootloader.bin +e16d7e6a6f7379327799e3add8948a8c903f0f8b8429084b7731fd73b60d9274 bootloader.lss +1.1.0 time=20250415.093631 git=master@28926acd diff --git a/stm32/q1-bootloader/releases/1.1.0/bootloader.bin b/stm32/q1-bootloader/releases/1.1.0/bootloader.bin new file mode 100644 index 0000000000000000000000000000000000000000..aeb9b20cd4e23e8dfb5649e733163145a9169f59 GIT binary patch literal 114688 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
SVM!KvXIO73gr))q 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: + 8000000: 200a0000 .word 0x200a0000 + 8000004: 080000b5 .word 0x080000b5 + 8000008: 0800001d .word 0x0800001d + 800000c: 0800001f .word 0x0800001f + 8000010: 08000021 .word 0x08000021 + 8000014: 08000023 .word 0x08000023 + 8000018: 08000025 .word 0x08000025 + +0800001c : + 800001c: be01 bkpt 0x0001 + +0800001e : + 800001e: be02 bkpt 0x0002 + +08000020 : + 8000020: be03 bkpt 0x0003 + +08000022 : + 8000022: be04 bkpt 0x0004 + +08000024 : + 8000024: be05 bkpt 0x0005 + 8000026: e7fe b.n 8000026 + +08000028 : + ... + 8000040: 08000305 .word 0x08000305 + +08000044 : + 8000044: 00000200 .word 0x00000200 + ... + 8000060: 20296328 .word 0x20296328 + 8000064: 79706f43 .word 0x79706f43 + 8000068: 68676972 .word 0x68676972 + 800006c: 30322074 .word 0x30322074 + 8000070: 322d3831 .word 0x322d3831 + 8000074: 20323230 .word 0x20323230 + 8000078: 43207962 .word 0x43207962 + 800007c: 6b6e696f .word 0x6b6e696f + 8000080: 20657469 .word 0x20657469 + 8000084: 2e636e49 .word 0x2e636e49 + 8000088: 0a200a20 .word 0x0a200a20 + 800008c: 73696854 .word 0x73696854 + 8000090: 61707320 .word 0x61707320 + 8000094: 66206563 .word 0x66206563 + 8000098: 7220726f .word 0x7220726f + 800009c: 21746e65 .word 0x21746e65 + 80000a0: 73754a20 .word 0x73754a20 + 80000a4: 42312074 .word 0x42312074 + 80000a8: 792f4354 .word 0x792f4354 + 80000ac: 2e726165 .word 0x2e726165 + 80000b0: 0a200a20 .word 0x0a200a20 + +080000b4 : + 80000b4: f000 f816 bl 80000e4 + 80000b8: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 80000bc: f04f 0100 mov.w r1, #0 + 80000c0: f04f 0200 mov.w r2, #0 + 80000c4: f04f 0300 mov.w r3, #0 + 80000c8: f000 f91c bl 8000304 + 80000cc: f248 0120 movw r1, #32800 ; 0x8020 + 80000d0: ea4f 3101 mov.w r1, r1, lsl #12 + 80000d4: 6808 ldr r0, [r1, #0] + 80000d6: 4685 mov sp, r0 + 80000d8: f04f 0001 mov.w r0, #1 + 80000dc: f8d1 e004 ldr.w lr, [r1, #4] + 80000e0: 4770 bx lr + ... + +080000e4 : + void +firewall_setup(void) +{ + // This is critical: without the clock enabled to "SYSCFG" we + // can't tell the FW is enabled or not! Enabling it would also not work + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000e4: 4b1b ldr r3, [pc, #108] ; (8000154 ) +{ + 80000e6: b500 push {lr} + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000e8: 6e1a ldr r2, [r3, #96] ; 0x60 + 80000ea: f042 0201 orr.w r2, r2, #1 + 80000ee: 661a str r2, [r3, #96] ; 0x60 + 80000f0: 6e1b ldr r3, [r3, #96] ; 0x60 +{ + 80000f2: b08b sub sp, #44 ; 0x2c + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80000f4: f003 0301 and.w r3, r3, #1 + 80000f8: 9300 str r3, [sp, #0] + 80000fa: 9b00 ldr r3, [sp, #0] + + if(__HAL_FIREWALL_IS_ENABLED()) { + 80000fc: 4b16 ldr r3, [pc, #88] ; (8000158 ) + 80000fe: 685b ldr r3, [r3, #4] + 8000100: 07db lsls r3, r3, #31 + 8000102: d524 bpl.n 800014e + // REMINDERS: + // - cannot debug anything in boot loader w/ firewall enabled (no readback, no bkpt) + // - when RDP=2, this protection still important or else python can read pairing secret + // - in factory mode (RDP!=2), it's nice to have this disabled so we can debug still + // - could look at RDP level here, but it would be harder to completely reset the bag number! + if(check_all_ones_raw(rom_secrets->bag_number, sizeof(rom_secrets->bag_number))) { + 8000104: 4815 ldr r0, [pc, #84] ; (800015c ) + 8000106: 2120 movs r1, #32 + 8000108: f002 fb74 bl 80027f4 + 800010c: b9f8 cbnz r0, 800014e + // for debug builds, never enable firewall + return; +#endif + + extern int firewall_starts; // see startup.S ... aligned@256 (0x08000300) + uint32_t start = (uint32_t)&firewall_starts; + 800010e: 4b14 ldr r3, [pc, #80] ; (8000160 ) + uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE); + 8000110: 4a14 ldr r2, [pc, #80] ; (8000164 ) + // but sensitive stuff is still there (which would allow bypass) + // - so it's important to enable option bytes to set write-protect flash of entire bootloader + // - to disable debug and complete protection, must enable write-protect "level 2" (RDP=2) + // + + FIREWALL_InitTypeDef init = { + 8000112: 9302 str r3, [sp, #8] + uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE); + 8000114: 1ad3 subs r3, r2, r3 + FIREWALL_InitTypeDef init = { + 8000116: e9cd 3203 strd r3, r2, [sp, #12] + 800011a: f44f 4380 mov.w r3, #16384 ; 0x4000 + 800011e: e9cd 3005 strd r3, r0, [sp, #20] + 8000122: e9cd 0007 strd r0, r0, [sp, #28] + 8000126: 9009 str r0, [sp, #36] ; 0x24 + .VDataSegmentLength = 0, + .VolatileDataExecution = 0, + .VolatileDataShared = 0, + }; + + int rv = HAL_FIREWALL_Config((FIREWALL_InitTypeDef *)&init); + 8000128: a802 add r0, sp, #8 + 800012a: f000 f821 bl 8000170 + if(rv) { + 800012e: b110 cbz r0, 8000136 + INCONSISTENT("fw"); + 8000130: 480d ldr r0, [pc, #52] ; (8000168 ) + 8000132: f000 fc81 bl 8000a38 + } + + __HAL_FIREWALL_PREARM_DISABLE(); + 8000136: 4b0d ldr r3, [pc, #52] ; (800016c ) + 8000138: 6a1a ldr r2, [r3, #32] + 800013a: f022 0201 bic.w r2, r2, #1 + 800013e: 621a str r2, [r3, #32] + 8000140: 6a1b ldr r3, [r3, #32] + 8000142: f003 0301 and.w r3, r3, #1 + 8000146: 9301 str r3, [sp, #4] + 8000148: 9b01 ldr r3, [sp, #4] + HAL_FIREWALL_EnableFirewall(); + 800014a: f000 f88b bl 8000264 +} + 800014e: b00b add sp, #44 ; 0x2c + 8000150: f85d fb04 ldr.w pc, [sp], #4 + 8000154: 40021000 .word 0x40021000 + 8000158: 40010000 .word 0x40010000 + 800015c: 0801c050 .word 0x0801c050 + 8000160: 08000300 .word 0x08000300 + 8000164: 0801c000 .word 0x0801c000 + 8000168: 0800d9a0 .word 0x0800d9a0 + 800016c: 40011c00 .word 0x40011c00 + +08000170 : + * @param fw_init: Firewall initialization structure + * @note The API returns HAL_ERROR if the Firewall is already enabled. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init) +{ + 8000170: b573 push {r0, r1, r4, r5, r6, lr} + /* Check the Firewall initialization structure allocation */ + if(fw_init == NULL) + 8000172: b910 cbnz r0, 800017a + { + return HAL_ERROR; + 8000174: 2001 movs r0, #1 + /* Set Firewall Configuration Register VDE and VDS bits + (volatile data execution and shared configuration) */ + MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared); + + return HAL_OK; +} + 8000176: b002 add sp, #8 + 8000178: bd70 pop {r4, r5, r6, pc} + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 800017a: 4b19 ldr r3, [pc, #100] ; (80001e0 ) + 800017c: 6e1a ldr r2, [r3, #96] ; 0x60 + 800017e: f042 0280 orr.w r2, r2, #128 ; 0x80 + 8000182: 661a str r2, [r3, #96] ; 0x60 + 8000184: 6e1b ldr r3, [r3, #96] ; 0x60 + 8000186: f003 0380 and.w r3, r3, #128 ; 0x80 + 800018a: 9301 str r3, [sp, #4] + 800018c: 9b01 ldr r3, [sp, #4] + if (__HAL_FIREWALL_IS_ENABLED() != RESET) + 800018e: 4b15 ldr r3, [pc, #84] ; (80001e4 ) + 8000190: 685b ldr r3, [r3, #4] + 8000192: 07db lsls r3, r3, #31 + 8000194: d5ee bpl.n 8000174 + if (fw_init->CodeSegmentLength != 0U) + 8000196: 6841 ldr r1, [r0, #4] + if (fw_init->NonVDataSegmentLength < 0x100U) + 8000198: 68c2 ldr r2, [r0, #12] + if (fw_init->CodeSegmentLength != 0U) + 800019a: b109 cbz r1, 80001a0 + if (fw_init->NonVDataSegmentLength < 0x100U) + 800019c: 2aff cmp r2, #255 ; 0xff + 800019e: d9e9 bls.n 8000174 + WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress)); + 80001a0: 6803 ldr r3, [r0, #0] + 80001a2: 4e11 ldr r6, [pc, #68] ; (80001e8 ) + if (fw_init->VDataSegmentLength != 0U) + 80001a4: 6944 ldr r4, [r0, #20] + WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress)); + 80001a6: ea03 0506 and.w r5, r3, r6 + 80001aa: 4b10 ldr r3, [pc, #64] ; (80001ec ) + 80001ac: 601d str r5, [r3, #0] + WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength)); + 80001ae: 4d10 ldr r5, [pc, #64] ; (80001f0 ) + 80001b0: 4029 ands r1, r5 + 80001b2: 6059 str r1, [r3, #4] + WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress)); + 80001b4: 6881 ldr r1, [r0, #8] + WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength)); + 80001b6: 402a ands r2, r5 + WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress)); + 80001b8: 4031 ands r1, r6 + 80001ba: 6099 str r1, [r3, #8] + WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength)); + 80001bc: 60da str r2, [r3, #12] + WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress)); + 80001be: 6901 ldr r1, [r0, #16] + 80001c0: 4a0c ldr r2, [pc, #48] ; (80001f4 ) + 80001c2: 4011 ands r1, r2 + WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength)); + 80001c4: 4022 ands r2, r4 + WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress)); + 80001c6: 6119 str r1, [r3, #16] + WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength)); + 80001c8: 615a str r2, [r3, #20] + MODIFY_REG(FIREWALL->CR, FW_CR_VDS|FW_CR_VDE, fw_init->VolatileDataExecution|fw_init->VolatileDataShared); + 80001ca: e9d0 2006 ldrd r2, r0, [r0, #24] + 80001ce: 6a19 ldr r1, [r3, #32] + 80001d0: 4302 orrs r2, r0 + 80001d2: f021 0106 bic.w r1, r1, #6 + 80001d6: 430a orrs r2, r1 + 80001d8: 621a str r2, [r3, #32] + return HAL_OK; + 80001da: 2000 movs r0, #0 + 80001dc: e7cb b.n 8000176 + 80001de: bf00 nop + 80001e0: 40021000 .word 0x40021000 + 80001e4: 40010000 .word 0x40010000 + 80001e8: 00ffff00 .word 0x00ffff00 + 80001ec: 40011c00 .word 0x40011c00 + 80001f0: 003fff00 .word 0x003fff00 + 80001f4: 0003ffc0 .word 0x0003ffc0 + +080001f8 : +void HAL_FIREWALL_GetConfig(FIREWALL_InitTypeDef * fw_config) +{ + + /* Enable Firewall clock, in case no Firewall configuration has been carried + out up to this point */ + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 80001f8: 4b15 ldr r3, [pc, #84] ; (8000250 ) + 80001fa: 6e1a ldr r2, [r3, #96] ; 0x60 +{ + 80001fc: b573 push {r0, r1, r4, r5, r6, lr} + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 80001fe: f042 0280 orr.w r2, r2, #128 ; 0x80 + 8000202: 661a str r2, [r3, #96] ; 0x60 + 8000204: 6e1b ldr r3, [r3, #96] ; 0x60 + + /* Retrieve code segment protection setting */ + fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD); + 8000206: 4e13 ldr r6, [pc, #76] ; (8000254 ) + fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG); + 8000208: 4d13 ldr r5, [pc, #76] ; (8000258 ) + __HAL_RCC_FIREWALL_CLK_ENABLE(); + 800020a: f003 0380 and.w r3, r3, #128 ; 0x80 + 800020e: 9301 str r3, [sp, #4] + 8000210: 9b01 ldr r3, [sp, #4] + fw_config->CodeSegmentStartAddress = (READ_REG(FIREWALL->CSSA) & FW_CSSA_ADD); + 8000212: 4b12 ldr r3, [pc, #72] ; (800025c ) + 8000214: 681a ldr r2, [r3, #0] + 8000216: 4032 ands r2, r6 + 8000218: 6002 str r2, [r0, #0] + fw_config->CodeSegmentLength = (READ_REG(FIREWALL->CSL) & FW_CSL_LENG); + 800021a: 685c ldr r4, [r3, #4] + 800021c: 402c ands r4, r5 + 800021e: 6044 str r4, [r0, #4] + + /* Retrieve non volatile data segment protection setting */ + fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD); + 8000220: 6899 ldr r1, [r3, #8] + fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG); + + /* Retrieve volatile data segment protection setting */ + fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD); + 8000222: 4c0f ldr r4, [pc, #60] ; (8000260 ) + fw_config->NonVDataSegmentStartAddress = (READ_REG(FIREWALL->NVDSSA) & FW_NVDSSA_ADD); + 8000224: 4031 ands r1, r6 + 8000226: 6081 str r1, [r0, #8] + fw_config->NonVDataSegmentLength = (READ_REG(FIREWALL->NVDSL) & FW_NVDSL_LENG); + 8000228: 68da ldr r2, [r3, #12] + 800022a: 402a ands r2, r5 + 800022c: 60c2 str r2, [r0, #12] + fw_config->VDataSegmentStartAddress = (READ_REG(FIREWALL->VDSSA) & FW_VDSSA_ADD); + 800022e: 6919 ldr r1, [r3, #16] + 8000230: 4021 ands r1, r4 + 8000232: 6101 str r1, [r0, #16] + fw_config->VDataSegmentLength = (READ_REG(FIREWALL->VDSL) & FW_VDSL_LENG); + 8000234: 695a ldr r2, [r3, #20] + 8000236: 4022 ands r2, r4 + 8000238: 6142 str r2, [r0, #20] + + /* Retrieve volatile data execution setting */ + fw_config->VolatileDataExecution = (READ_REG(FIREWALL->CR) & FW_CR_VDE); + 800023a: 6a1a ldr r2, [r3, #32] + 800023c: f002 0204 and.w r2, r2, #4 + 8000240: 6182 str r2, [r0, #24] + + /* Retrieve volatile data shared setting */ + fw_config->VolatileDataShared = (READ_REG(FIREWALL->CR) & FW_CR_VDS); + 8000242: 6a1b ldr r3, [r3, #32] + 8000244: f003 0302 and.w r3, r3, #2 + 8000248: 61c3 str r3, [r0, #28] + + return; +} + 800024a: b002 add sp, #8 + 800024c: bd70 pop {r4, r5, r6, pc} + 800024e: bf00 nop + 8000250: 40021000 .word 0x40021000 + 8000254: 00ffff00 .word 0x00ffff00 + 8000258: 003fff00 .word 0x003fff00 + 800025c: 40011c00 .word 0x40011c00 + 8000260: 0003ffc0 .word 0x0003ffc0 + +08000264 : + * @retval None + */ +void HAL_FIREWALL_EnableFirewall(void) +{ + /* Clears FWDIS bit of SYSCFG CFGR1 register */ + CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_FWDIS); + 8000264: 4a02 ldr r2, [pc, #8] ; (8000270 ) + 8000266: 6853 ldr r3, [r2, #4] + 8000268: f023 0301 bic.w r3, r3, #1 + 800026c: 6053 str r3, [r2, #4] + +} + 800026e: 4770 bx lr + 8000270: 40010000 .word 0x40010000 + +08000274 : + * @retval None + */ +void HAL_FIREWALL_EnablePreArmFlag(void) +{ + /* Set FPA bit */ + SET_BIT(FIREWALL->CR, FW_CR_FPA); + 8000274: 4a02 ldr r2, [pc, #8] ; (8000280 ) + 8000276: 6a13 ldr r3, [r2, #32] + 8000278: f043 0301 orr.w r3, r3, #1 + 800027c: 6213 str r3, [r2, #32] +} + 800027e: 4770 bx lr + 8000280: 40011c00 .word 0x40011c00 + +08000284 : + * @retval None + */ +void HAL_FIREWALL_DisablePreArmFlag(void) +{ + /* Clear FPA bit */ + CLEAR_BIT(FIREWALL->CR, FW_CR_FPA); + 8000284: 4a02 ldr r2, [pc, #8] ; (8000290 ) + 8000286: 6a13 ldr r3, [r2, #32] + 8000288: f023 0301 bic.w r3, r3, #1 + 800028c: 6213 str r3, [r2, #32] +} + 800028e: 4770 bx lr + 8000290: 40011c00 .word 0x40011c00 + ... + +08000300 <_firewall_start>: + 8000300: 0f193a11 .word 0x0f193a11 + +08000304 : + 8000304: f24e 0900 movw r9, #57344 ; 0xe000 + 8000308: f2c2 0909 movt r9, #8201 ; 0x2009 + 800030c: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 8000310: 44ca add sl, r9 + +08000312 : + 8000312: f849 ab04 str.w sl, [r9], #4 + 8000316: 45d1 cmp r9, sl + 8000318: d1fb bne.n 8000312 + 800031a: 46ea mov sl, sp + 800031c: 46cd mov sp, r9 + 800031e: e92d 4400 stmdb sp!, {sl, lr} + +08000322 : + 8000322: f000 f841 bl 80003a8 + 8000326: e8bd 4400 ldmia.w sp!, {sl, lr} + 800032a: 46d5 mov sp, sl + 800032c: f24e 0900 movw r9, #57344 ; 0xe000 + 8000330: f2c2 0909 movt r9, #8201 ; 0x2009 + 8000334: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 8000338: 44ca add sl, r9 + +0800033a : + 800033a: f849 0b04 str.w r0, [r9], #4 + 800033e: 45d1 cmp r9, sl + 8000340: d1fb bne.n 800033a + 8000342: 4770 bx lr + +08000344 <__NVIC_SystemReset>: + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); + 8000344: f3bf 8f4f dsb sy +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8000348: 4905 ldr r1, [pc, #20] ; (8000360 <__NVIC_SystemReset+0x1c>) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 800034a: 4b06 ldr r3, [pc, #24] ; (8000364 <__NVIC_SystemReset+0x20>) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 800034c: 68ca ldr r2, [r1, #12] + 800034e: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8000352: 4313 orrs r3, r2 + 8000354: 60cb str r3, [r1, #12] + 8000356: f3bf 8f4f dsb sy + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + 800035a: bf00 nop + for(;;) /* wait until reset */ + 800035c: e7fd b.n 800035a <__NVIC_SystemReset+0x16> + 800035e: bf00 nop + 8000360: e000ed00 .word 0xe000ed00 + 8000364: 05fa0004 .word 0x05fa0004 + +08000368 : +good_addr(const uint8_t *b, int minlen, int len, bool readonly) +{ + uint32_t x = (uint32_t)b; + + if(minlen) { + if(!b) return EFAULT; // gave no buffer + 8000368: b198 cbz r0, 8000392 + if(len < minlen) return ERANGE; // too small + 800036a: 4291 cmp r1, r2 + 800036c: dc13 bgt.n 8000396 + } + + if((x >= SRAM1_BASE) && ((x+len) <= BL_SRAM_BASE)) { + 800036e: f1b0 5f00 cmp.w r0, #536870912 ; 0x20000000 + 8000372: d303 bcc.n 800037c + 8000374: 490b ldr r1, [pc, #44] ; (80003a4 ) + 8000376: 4402 add r2, r0 + 8000378: 428a cmp r2, r1 + 800037a: d90e bls.n 800039a + // ok: it's inside the SRAM areas, up to where we start + return 0; + } + + if(!readonly) { + 800037c: b17b cbz r3, 800039e + return EPERM; + } + + if((x >= FIRMWARE_START) && (x - FIRMWARE_START) < FW_MAX_LENGTH_MK4) { + 800037e: f100 4077 add.w r0, r0, #4143972352 ; 0xf7000000 + 8000382: f500 007e add.w r0, r0, #16646144 ; 0xfe0000 + // inside flash of main firmware (happens for QSTR's) + return 0; + } + + return EACCES; + 8000386: f5b0 1ff0 cmp.w r0, #1966080 ; 0x1e0000 + 800038a: bf34 ite cc + 800038c: 2000 movcc r0, #0 + 800038e: 200d movcs r0, #13 + 8000390: 4770 bx lr + if(!b) return EFAULT; // gave no buffer + 8000392: 200e movs r0, #14 + 8000394: 4770 bx lr + if(len < minlen) return ERANGE; // too small + 8000396: 2022 movs r0, #34 ; 0x22 + 8000398: 4770 bx lr + return 0; + 800039a: 2000 movs r0, #0 + 800039c: 4770 bx lr + return EPERM; + 800039e: 2001 movs r0, #1 +} + 80003a0: 4770 bx lr + 80003a2: bf00 nop + 80003a4: 2009e000 .word 0x2009e000 + +080003a8 : +// + __attribute__ ((used)) + int +firewall_dispatch(int method_num, uint8_t *buf_io, int len_in, + uint32_t arg2, uint32_t incoming_sp, uint32_t incoming_lr) +{ + 80003a8: b570 push {r4, r5, r6, lr} + 80003aa: b09e sub sp, #120 ; 0x78 + 80003ac: 460d mov r5, r1 + 80003ae: 9c23 ldr r4, [sp, #140] ; 0x8c + 80003b0: 9301 str r3, [sp, #4] + __ASM volatile ("cpsid i" : : : "memory"); + 80003b2: b672 cpsid i + // in case the caller didn't already, but would just lead to a crash anyway + __disable_irq(); + + // "1=any code executed outside the protected segment will close the Firewall" + // "0=.. will reset the processor" + __HAL_FIREWALL_PREARM_DISABLE(); + 80003b4: 4ba9 ldr r3, [pc, #676] ; (800065c ) + 80003b6: 6a19 ldr r1, [r3, #32] + 80003b8: f021 0101 bic.w r1, r1, #1 + 80003bc: 6219 str r1, [r3, #32] + 80003be: 6a1b ldr r3, [r3, #32] + 80003c0: f003 0301 and.w r3, r3, #1 + 80003c4: 9302 str r3, [sp, #8] + // using read/write in place. + // - use arg2 use when a simple number is needed; never a pointer! + // - mpy may provide a pointer to flash if we give it a qstr or small value, and if + // we're reading only, that's fine. + + if(len_in > 1024) { // arbitrary max, increase as needed + 80003c6: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + __HAL_FIREWALL_PREARM_DISABLE(); + 80003ca: 9b02 ldr r3, [sp, #8] + if(len_in > 1024) { // arbitrary max, increase as needed + 80003cc: f300 82ec bgt.w 80009a8 + + // Use these macros +#define REQUIRE_IN_ONLY(x) if((rv = good_addr(buf_io, (x), len_in, true))) { goto fail; } +#define REQUIRE_OUT(x) if((rv = good_addr(buf_io, (x), len_in, false))) { goto fail; } + + switch(method_num) { + 80003d0: 3001 adds r0, #1 + 80003d2: 281b cmp r0, #27 + 80003d4: f200 81c0 bhi.w 8000758 + 80003d8: e8df f010 tbh [pc, r0, lsl #1] + 80003dc: 001c02f4 .word 0x001c02f4 + 80003e0: 007f0033 .word 0x007f0033 + 80003e4: 00da00bc .word 0x00da00bc + 80003e8: 01fd00fb .word 0x01fd00fb + 80003ec: 01be01be .word 0x01be01be + 80003f0: 01be01be .word 0x01be01be + 80003f4: 010301be .word 0x010301be + 80003f8: 01be01be .word 0x01be01be + 80003fc: 012d010e .word 0x012d010e + 8000400: 0171015e .word 0x0171015e + 8000404: 020101b5 .word 0x020101b5 + 8000408: 02690210 .word 0x02690210 + 800040c: 02c002ac .word 0x02c002ac + 8000410: 02d802c8 .word 0x02d802c8 + case 0: { + REQUIRE_OUT(64); + 8000414: 2300 movs r3, #0 + 8000416: 2140 movs r1, #64 ; 0x40 + 8000418: 4628 mov r0, r5 + 800041a: 9200 str r2, [sp, #0] + 800041c: f7ff ffa4 bl 8000368 + 8000420: 4604 mov r4, r0 + 8000422: bb48 cbnz r0, 8000478 + + // Return my version string + memset(buf_io, 0, len_in); + 8000424: 4601 mov r1, r0 + 8000426: 9a00 ldr r2, [sp, #0] + 8000428: 4628 mov r0, r5 + 800042a: f00d fa7b bl 800d924 + strlcpy((char *)buf_io, version_string, len_in); + 800042e: 9a00 ldr r2, [sp, #0] + 8000430: 498b ldr r1, [pc, #556] ; (8000660 ) + 8000432: 4628 mov r0, r5 + 8000434: f00d fa8c bl 800d950 + + rv = strlen(version_string); + 8000438: 4889 ldr r0, [pc, #548] ; (8000660 ) + 800043a: f00d fa9e bl 800d97a + ae_setup(); + ae_keep_alive(); + switch(arg2) { + default: + case 0: // read state + rv = ae_get_gpio(); + 800043e: 4604 mov r4, r0 + break; + 8000440: e01a b.n 8000478 + REQUIRE_OUT(32); + 8000442: 2300 movs r3, #0 + 8000444: 2120 movs r1, #32 + 8000446: 4628 mov r0, r5 + 8000448: f7ff ff8e bl 8000368 + 800044c: 4604 mov r4, r0 + 800044e: b998 cbnz r0, 8000478 + sha256_init(&ctx); + 8000450: a80b add r0, sp, #44 ; 0x2c + 8000452: f005 f993 bl 800577c + sha256_update(&ctx, (void *)&arg2, 4); + 8000456: 2204 movs r2, #4 + 8000458: eb0d 0102 add.w r1, sp, r2 + 800045c: a80b add r0, sp, #44 ; 0x2c + 800045e: f005 f99b bl 8005798 + sha256_update(&ctx, (void *)BL_FLASH_BASE, BL_FLASH_SIZE); + 8000462: f04f 6100 mov.w r1, #134217728 ; 0x8000000 + 8000466: a80b add r0, sp, #44 ; 0x2c + 8000468: f44f 32e0 mov.w r2, #114688 ; 0x1c000 + 800046c: f005 f994 bl 8005798 + sha256_final(&ctx, buf_io); + 8000470: 4629 mov r1, r5 + 8000472: a80b add r0, sp, #44 ; 0x2c + 8000474: f005 f9d6 bl 8005824 + +fail: + + // Precaution: we don't want to leave SE1 authorized for any specific keys, + // perhaps due to an error path we didn't see. Always reset the chip. + ae_reset_chip(); + 8000478: f002 fb5c bl 8002b34 + + // Unlikely it matters, but clear flash memory cache. + __HAL_FLASH_DATA_CACHE_DISABLE(); + 800047c: 4b79 ldr r3, [pc, #484] ; (8000664 ) + 800047e: 681a ldr r2, [r3, #0] + 8000480: f422 6280 bic.w r2, r2, #1024 ; 0x400 + 8000484: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_RESET(); + 8000486: 681a ldr r2, [r3, #0] + 8000488: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800048c: 601a str r2, [r3, #0] + 800048e: 681a ldr r2, [r3, #0] + 8000490: f422 5280 bic.w r2, r2, #4096 ; 0x1000 + 8000494: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); + 8000496: 681a ldr r2, [r3, #0] + 8000498: f442 6280 orr.w r2, r2, #1024 ; 0x400 + 800049c: 601a str r2, [r3, #0] + + // .. and instruction memory (flash cache too?) + __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); + 800049e: 681a ldr r2, [r3, #0] + 80004a0: f422 7200 bic.w r2, r2, #512 ; 0x200 + 80004a4: 601a str r2, [r3, #0] + __HAL_FLASH_INSTRUCTION_CACHE_RESET(); + 80004a6: 681a ldr r2, [r3, #0] + 80004a8: f442 6200 orr.w r2, r2, #2048 ; 0x800 + 80004ac: 601a str r2, [r3, #0] + 80004ae: 681a ldr r2, [r3, #0] + 80004b0: f422 6200 bic.w r2, r2, #2048 ; 0x800 + 80004b4: 601a str r2, [r3, #0] + __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); + 80004b6: 681a ldr r2, [r3, #0] + 80004b8: f442 7200 orr.w r2, r2, #512 ; 0x200 + 80004bc: 601a str r2, [r3, #0] + + // authorize return from firewall into user's code + __HAL_FIREWALL_PREARM_ENABLE(); + 80004be: f5a3 3382 sub.w r3, r3, #66560 ; 0x10400 + + return rv; +} + 80004c2: 4620 mov r0, r4 + __HAL_FIREWALL_PREARM_ENABLE(); + 80004c4: 6a1a ldr r2, [r3, #32] + 80004c6: f042 0201 orr.w r2, r2, #1 + 80004ca: 621a str r2, [r3, #32] + 80004cc: 6a1b ldr r3, [r3, #32] + 80004ce: f003 0301 and.w r3, r3, #1 + 80004d2: 930b str r3, [sp, #44] ; 0x2c + 80004d4: 9b0b ldr r3, [sp, #44] ; 0x2c +} + 80004d6: b01e add sp, #120 ; 0x78 + 80004d8: bd70 pop {r4, r5, r6, pc} +// Write bag number (probably a string) +void flash_save_bag_number(const uint8_t new_number[32]); + +// Are we operating in level2? +static inline bool flash_is_security_level2(void) { + rng_delay(); + 80004da: f002 fa15 bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 80004de: 4b61 ldr r3, [pc, #388] ; (8000664 ) + 80004e0: 6a1b ldr r3, [r3, #32] + 80004e2: b2db uxtb r3, r3 + 80004e4: f1a3 02cc sub.w r2, r3, #204 ; 0xcc + 80004e8: 4255 negs r5, r2 + 80004ea: 4155 adcs r5, r2 + switch(arg2) { + 80004ec: 9a01 ldr r2, [sp, #4] + 80004ee: 2a02 cmp r2, #2 + 80004f0: d01c beq.n 800052c + 80004f2: 2a03 cmp r2, #3 + 80004f4: d01f beq.n 8000536 + 80004f6: 2a01 cmp r2, #1 + 80004f8: d013 beq.n 8000522 + if(secure) { + 80004fa: 2bcc cmp r3, #204 ; 0xcc + 80004fc: f000 8221 beq.w 8000942 + puts("Die: DFU"); + 8000500: 4859 ldr r0, [pc, #356] ; (8000668 ) + scr = screen_upgrading; // was screen_dfu, but limited audience + 8000502: 4c5a ldr r4, [pc, #360] ; (800066c ) + puts("Die: DFU"); + 8000504: f004 fdb0 bl 8005068 + bool secure = flash_is_security_level2(); + 8000508: 2500 movs r5, #0 + oled_setup(); + 800050a: f000 fc33 bl 8000d74 + oled_show(scr); + 800050e: 4620 mov r0, r4 + 8000510: f000 fdb0 bl 8001074 + wipe_all_sram(); + 8000514: f000 fa70 bl 80009f8 + psram_wipe(); + 8000518: f004 fece bl 80052b8 + if(secure) { + 800051c: b18d cbz r5, 8000542 + LOCKUP_FOREVER(); + 800051e: f003 fbab bl 8003c78 + puts("Die: Downgrade"); + 8000522: 4853 ldr r0, [pc, #332] ; (8000670 ) + scr = screen_downgrade; + 8000524: 4c53 ldr r4, [pc, #332] ; (8000674 ) + puts("Die: Downgrade"); + 8000526: f004 fd9f bl 8005068 + break; + 800052a: e7ee b.n 800050a + puts("Die: Blankish"); + 800052c: 4852 ldr r0, [pc, #328] ; (8000678 ) + scr = screen_blankish; + 800052e: 4c53 ldr r4, [pc, #332] ; (800067c ) + puts("Die: Blankish"); + 8000530: f004 fd9a bl 8005068 + break; + 8000534: e7e9 b.n 800050a + puts("Die: Brick"); + 8000536: 4852 ldr r0, [pc, #328] ; (8000680 ) + scr = screen_brick; + 8000538: 4c52 ldr r4, [pc, #328] ; (8000684 ) + puts("Die: Brick"); + 800053a: f004 fd95 bl 8005068 + secure = true; // no point going into DFU, if even possible + 800053e: 2501 movs r5, #1 + break; + 8000540: e7e3 b.n 800050a + memcpy(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)); + 8000542: 4951 ldr r1, [pc, #324] ; (8000688 ) + 8000544: 4a51 ldr r2, [pc, #324] ; (800068c ) + 8000546: 6808 ldr r0, [r1, #0] + 8000548: 6849 ldr r1, [r1, #4] + 800054a: 4613 mov r3, r2 + 800054c: c303 stmia r3!, {r0, r1} + dfu_flag->screen = scr; + 800054e: 6094 str r4, [r2, #8] + NVIC_SystemReset(); + 8000550: f7ff fef8 bl 8000344 <__NVIC_SystemReset> + switch(arg2) { + 8000554: 9b01 ldr r3, [sp, #4] + 8000556: 2b02 cmp r3, #2 + 8000558: d002 beq.n 8000560 + 800055a: 2b03 cmp r3, #3 + 800055c: d016 beq.n 800058c + 800055e: b913 cbnz r3, 8000566 + oled_show(screen_logout); + 8000560: 484b ldr r0, [pc, #300] ; (8000690 ) + oled_show(screen_poweroff); + 8000562: f000 fd87 bl 8001074 + wipe_all_sram(); + 8000566: f000 fa47 bl 80009f8 + psram_wipe(); + 800056a: f004 fea5 bl 80052b8 + if(arg2 == 3) { + 800056e: 9b01 ldr r3, [sp, #4] + 8000570: 2b03 cmp r3, #3 + 8000572: d104 bne.n 800057e + delay_ms(100); + 8000574: 2064 movs r0, #100 ; 0x64 + 8000576: f003 fa85 bl 8003a84 + turn_power_off(); + 800057a: f003 fb71 bl 8003c60 + if(arg2 == 2) { + 800057e: 9b01 ldr r3, [sp, #4] + 8000580: 2b02 cmp r3, #2 + 8000582: d1cc bne.n 800051e + delay_ms(100); + 8000584: 2064 movs r0, #100 ; 0x64 + 8000586: f003 fa7d bl 8003a84 + 800058a: e7e1 b.n 8000550 + oled_show(screen_poweroff); + 800058c: 4841 ldr r0, [pc, #260] ; (8000694 ) + 800058e: e7e8 b.n 8000562 + ae_setup(); + 8000590: f002 fade bl 8002b50 + ae_keep_alive(); + 8000594: f002 fb0e bl 8002bb4 + switch(arg2) { + 8000598: 9b01 ldr r3, [sp, #4] + 800059a: 2b02 cmp r3, #2 + 800059c: d00a beq.n 80005b4 + 800059e: 2b03 cmp r3, #3 + 80005a0: d00a beq.n 80005b8 + 80005a2: 2b01 cmp r3, #1 + 80005a4: d002 beq.n 80005ac + rv = ae_get_gpio(); + 80005a6: f003 f883 bl 80036b0 + 80005aa: e748 b.n 800043e + rv = ae_set_gpio(0); + 80005ac: 2000 movs r0, #0 + rv = ae_set_gpio(1); + 80005ae: f003 f851 bl 8003654 + 80005b2: e744 b.n 800043e + 80005b4: 2001 movs r0, #1 + 80005b6: e7fa b.n 80005ae + checksum_flash(fw_digest, world_digest, 0); + 80005b8: 2200 movs r2, #0 + 80005ba: a90b add r1, sp, #44 ; 0x2c + 80005bc: a803 add r0, sp, #12 + 80005be: f001 fb2d bl 8001c1c + rv = ae_set_gpio_secure(world_digest); + 80005c2: a80b add r0, sp, #44 ; 0x2c + 80005c4: f003 f85c bl 8003680 + 80005c8: 4604 mov r4, r0 + oled_show(screen_blankish); + 80005ca: 482c ldr r0, [pc, #176] ; (800067c ) + 80005cc: f000 fd52 bl 8001074 + break; + 80005d0: e752 b.n 8000478 + ae_setup(); + 80005d2: f002 fabd bl 8002b50 + rv = (ae_pair_unlock() != 0); + 80005d6: f002 fcb1 bl 8002f3c + 80005da: 1e04 subs r4, r0, #0 + 80005dc: bf18 it ne + 80005de: 2401 movne r4, #1 + break; + 80005e0: e74a b.n 8000478 + REQUIRE_OUT(1); + 80005e2: 2300 movs r3, #0 + 80005e4: 2101 movs r1, #1 + 80005e6: 4628 mov r0, r5 + 80005e8: f7ff febe bl 8000368 + 80005ec: 4604 mov r4, r0 + 80005ee: 2800 cmp r0, #0 + 80005f0: f47f af42 bne.w 8000478 + buf_io[0] = 0; // NOT SUPPORTED on Mk4 + 80005f4: 7028 strb r0, [r5, #0] + break; + 80005f6: e73f b.n 8000478 + if(len_in != 4 && len_in != 32 && len_in != 72) { + 80005f8: 2a04 cmp r2, #4 + 80005fa: d004 beq.n 8000606 + 80005fc: 2a20 cmp r2, #32 + 80005fe: d002 beq.n 8000606 + 8000600: 2a48 cmp r2, #72 ; 0x48 + 8000602: f040 81d1 bne.w 80009a8 + REQUIRE_OUT(4); + 8000606: 2300 movs r3, #0 + 8000608: 2104 movs r1, #4 + 800060a: 4628 mov r0, r5 + 800060c: 9200 str r2, [sp, #0] + 800060e: f7ff feab bl 8000368 + 8000612: 4604 mov r4, r0 + 8000614: 2800 cmp r0, #0 + 8000616: f47f af2f bne.w 8000478 + ae_setup(); + 800061a: f002 fa99 bl 8002b50 + if(ae_read_data_slot(arg2 & 0xf, buf_io, len_in)) { + 800061e: 9801 ldr r0, [sp, #4] + 8000620: 9a00 ldr r2, [sp, #0] + 8000622: 4629 mov r1, r5 + 8000624: f000 000f and.w r0, r0, #15 + 8000628: f002 ffce bl 80035c8 + if(rv) { + 800062c: 2800 cmp r0, #0 + 800062e: f000 80d2 beq.w 80007d6 + rv = EIO; + 8000632: 2405 movs r4, #5 + 8000634: e720 b.n 8000478 + REQUIRE_OUT(MAX_PIN_LEN); + 8000636: 2300 movs r3, #0 + 8000638: 2120 movs r1, #32 + 800063a: 4628 mov r0, r5 + 800063c: f7ff fe94 bl 8000368 + 8000640: 4604 mov r4, r0 + 8000642: 2800 cmp r0, #0 + 8000644: f47f af18 bne.w 8000478 + if((arg2 < 1) || (arg2 > MAX_PIN_LEN)) { + 8000648: 9901 ldr r1, [sp, #4] + 800064a: 1e4b subs r3, r1, #1 + 800064c: 2b1f cmp r3, #31 + 800064e: f200 81ab bhi.w 80009a8 + if(pin_prefix_words((char *)buf_io, arg2, (uint32_t *)buf_io)) { + 8000652: 462a mov r2, r5 + 8000654: 4628 mov r0, r5 + 8000656: f003 fdb1 bl 80041bc + 800065a: e7e7 b.n 800062c + 800065c: 40011c00 .word 0x40011c00 + 8000660: 0801079c .word 0x0801079c + 8000664: 40022000 .word 0x40022000 + 8000668: 0800d9a6 .word 0x0800d9a6 + 800066c: 0800ff35 .word 0x0800ff35 + 8000670: 0800d9af .word 0x0800d9af + 8000674: 0800e2f2 .word 0x0800e2f2 + 8000678: 0800d9be .word 0x0800d9be + 800067c: 0800da48 .word 0x0800da48 + 8000680: 0800d9cc .word 0x0800d9cc + 8000684: 0800da61 .word 0x0800da61 + 8000688: 0800d9d7 .word 0x0800d9d7 + 800068c: 20008000 .word 0x20008000 + 8000690: 0800e5f8 .word 0x0800e5f8 + 8000694: 0800e759 .word 0x0800e759 + REQUIRE_OUT(32); + 8000698: 2300 movs r3, #0 + 800069a: 2120 movs r1, #32 + 800069c: 4628 mov r0, r5 + 800069e: f7ff fe63 bl 8000368 + 80006a2: 4604 mov r4, r0 + 80006a4: 2800 cmp r0, #0 + 80006a6: f47f aee7 bne.w 8000478 + memset(buf_io, 0x55, 32); // to help show errors + 80006aa: 2220 movs r2, #32 + 80006ac: 2155 movs r1, #85 ; 0x55 + 80006ae: 4628 mov r0, r5 + 80006b0: f00d f938 bl 800d924 + rng_buffer(buf_io, 32); + 80006b4: 2120 movs r1, #32 + 80006b6: 4628 mov r0, r5 + 80006b8: f002 f910 bl 80028dc + break; + 80006bc: e6dc b.n 8000478 + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2); + 80006be: 2300 movs r3, #0 + 80006c0: f44f 718c mov.w r1, #280 ; 0x118 + 80006c4: 4628 mov r0, r5 + 80006c6: 9200 str r2, [sp, #0] + 80006c8: f7ff fe4e bl 8000368 + 80006cc: 4604 mov r4, r0 + 80006ce: 2800 cmp r0, #0 + 80006d0: f47f aed2 bne.w 8000478 + switch(arg2) { + 80006d4: e9dd 2300 ldrd r2, r3, [sp] + 80006d8: 2b08 cmp r3, #8 + 80006da: d83d bhi.n 8000758 + 80006dc: e8df f003 tbb [pc, r3] + 80006e0: 110d0905 .word 0x110d0905 + 80006e4: 221d1915 .word 0x221d1915 + 80006e8: 26 .byte 0x26 + 80006e9: 00 .byte 0x00 + rv = pin_setup_attempt(args); + 80006ea: 4628 mov r0, r5 + 80006ec: f003 fd84 bl 80041f8 + 80006f0: e6a5 b.n 800043e + rv = pin_delay(args); + 80006f2: 4628 mov r0, r5 + 80006f4: f003 fdee bl 80042d4 + 80006f8: e6a1 b.n 800043e + rv = pin_login_attempt(args); + 80006fa: 4628 mov r0, r5 + 80006fc: f003 fdec bl 80042d8 + 8000700: e69d b.n 800043e + rv = pin_change(args); + 8000702: 4628 mov r0, r5 + 8000704: f003 fef6 bl 80044f4 + 8000708: e699 b.n 800043e + rv = pin_fetch_secret(args); + 800070a: 4628 mov r0, r5 + 800070c: f003 ffaa bl 8004664 + 8000710: e695 b.n 800043e + rv = pin_firmware_greenlight(args); + 8000712: 4628 mov r0, r5 + 8000714: f004 f966 bl 80049e4 + 8000718: e691 b.n 800043e + rv = pin_long_secret(args, NULL); + 800071a: 2100 movs r1, #0 + rv = pin_long_secret(args, &buf_io[PIN_ATTEMPT_SIZE_V2]); + 800071c: 4628 mov r0, r5 + 800071e: f004 f8a3 bl 8004868 + 8000722: e68c b.n 800043e + rv = pin_firmware_upgrade(args); + 8000724: 4628 mov r0, r5 + 8000726: f004 f99d bl 8004a64 + 800072a: e688 b.n 800043e + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2 + AE_LONG_SECRET_LEN); + 800072c: 2300 movs r3, #0 + 800072e: f44f 712e mov.w r1, #696 ; 0x2b8 + 8000732: 4628 mov r0, r5 + 8000734: f7ff fe18 bl 8000368 + 8000738: 4604 mov r4, r0 + 800073a: 2800 cmp r0, #0 + 800073c: f47f ae9c bne.w 8000478 + rv = pin_long_secret(args, &buf_io[PIN_ATTEMPT_SIZE_V2]); + 8000740: f505 718c add.w r1, r5, #280 ; 0x118 + 8000744: e7ea b.n 800071c + switch(arg2) { + 8000746: 9b01 ldr r3, [sp, #4] + 8000748: 2b64 cmp r3, #100 ; 0x64 + 800074a: d041 beq.n 80007d0 + 800074c: d806 bhi.n 800075c + 800074e: 2b01 cmp r3, #1 + 8000750: d01e beq.n 8000790 + 8000752: 2b02 cmp r3, #2 + 8000754: d028 beq.n 80007a8 + 8000756: b13b cbz r3, 8000768 + 8000758: 2402 movs r4, #2 + 800075a: e68d b.n 8000478 + 800075c: 2b65 cmp r3, #101 ; 0x65 + 800075e: d03c beq.n 80007da + 8000760: 2b66 cmp r3, #102 ; 0x66 + 8000762: d1f9 bne.n 8000758 + flash_lockdown_hard(OB_RDP_LEVEL_2); // No change possible after this. + 8000764: 20cc movs r0, #204 ; 0xcc + 8000766: e034 b.n 80007d2 + REQUIRE_OUT(32); + 8000768: 2120 movs r1, #32 + 800076a: 4628 mov r0, r5 + 800076c: f7ff fdfc bl 8000368 + 8000770: 4604 mov r4, r0 + 8000772: 2800 cmp r0, #0 + 8000774: f47f ae80 bne.w 8000478 + memcpy(buf_io, rom_secrets->bag_number, 32); + 8000778: 4a99 ldr r2, [pc, #612] ; (80009e0 ) + 800077a: 4e9a ldr r6, [pc, #616] ; (80009e4 ) + 800077c: 4613 mov r3, r2 + 800077e: cb03 ldmia r3!, {r0, r1} + 8000780: 42b3 cmp r3, r6 + 8000782: 6028 str r0, [r5, #0] + 8000784: 6069 str r1, [r5, #4] + 8000786: 461a mov r2, r3 + 8000788: f105 0508 add.w r5, r5, #8 + 800078c: d1f6 bne.n 800077c + 800078e: e673 b.n 8000478 + REQUIRE_IN_ONLY(32); + 8000790: 2120 movs r1, #32 + 8000792: 4628 mov r0, r5 + 8000794: f7ff fde8 bl 8000368 + 8000798: 4604 mov r4, r0 + 800079a: 2800 cmp r0, #0 + 800079c: f47f ae6c bne.w 8000478 + flash_save_bag_number(buf_io); + 80007a0: 4628 mov r0, r5 + 80007a2: f001 fd7f bl 80022a4 + break; + 80007a6: e667 b.n 8000478 + REQUIRE_OUT(1); + 80007a8: 2300 movs r3, #0 + 80007aa: 2101 movs r1, #1 + 80007ac: 4628 mov r0, r5 + 80007ae: f7ff fddb bl 8000368 + 80007b2: 4604 mov r4, r0 + 80007b4: 2800 cmp r0, #0 + 80007b6: f47f ae5f bne.w 8000478 + rng_delay(); + 80007ba: f002 f8a5 bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 80007be: 4b8a ldr r3, [pc, #552] ; (80009e8 ) + 80007c0: 6a1b ldr r3, [r3, #32] + 80007c2: b2db uxtb r3, r3 + buf_io[0] = (flash_is_security_level2() ? 2 : 0xff); + 80007c4: 2bcc cmp r3, #204 ; 0xcc + 80007c6: bf0c ite eq + 80007c8: 2302 moveq r3, #2 + 80007ca: 23ff movne r3, #255 ; 0xff + buf_io[0] = 8; + 80007cc: 702b strb r3, [r5, #0] + break; + 80007ce: e653 b.n 8000478 + flash_lockdown_hard(OB_RDP_LEVEL_0); // wipes contents of flash (1->0) + 80007d0: 20aa movs r0, #170 ; 0xaa + flash_lockdown_hard(OB_RDP_LEVEL_2); // No change possible after this. + 80007d2: f001 fe9f bl 8002514 + int rv = 0; + 80007d6: 2400 movs r4, #0 + break; + 80007d8: e64e b.n 8000478 + flash_lockdown_hard(OB_RDP_LEVEL_1); // Can only do 0->1 (experiments) + 80007da: 20bb movs r0, #187 ; 0xbb + 80007dc: e7f9 b.n 80007d2 + REQUIRE_OUT(128); + 80007de: 2300 movs r3, #0 + 80007e0: 2180 movs r1, #128 ; 0x80 + 80007e2: 4628 mov r0, r5 + 80007e4: f7ff fdc0 bl 8000368 + 80007e8: 4604 mov r4, r0 + 80007ea: 2800 cmp r0, #0 + 80007ec: f47f ae44 bne.w 8000478 + ae_setup(); + 80007f0: f002 f9ae bl 8002b50 + rv = ae_config_read(buf_io); + 80007f4: 4628 mov r0, r5 + 80007f6: f002 ffac bl 8003752 + 80007fa: e717 b.n 800062c + switch(arg2) { + 80007fc: 9b01 ldr r3, [sp, #4] + 80007fe: 2b03 cmp r3, #3 + 8000800: d8aa bhi.n 8000758 + 8000802: e8df f003 tbb [pc, r3] + 8000806: 0f02 .short 0x0f02 + 8000808: 441d .short 0x441d + REQUIRE_OUT(8); + 800080a: 2300 movs r3, #0 + 800080c: 2108 movs r1, #8 + 800080e: 4628 mov r0, r5 + 8000810: f7ff fdaa bl 8000368 + 8000814: 4604 mov r4, r0 + 8000816: 2800 cmp r0, #0 + 8000818: f47f ae2e bne.w 8000478 + get_min_version(buf_io); + 800081c: 4628 mov r0, r5 + 800081e: f001 fa8d bl 8001d3c + break; + 8000822: e629 b.n 8000478 + REQUIRE_IN_ONLY(8); + 8000824: 2301 movs r3, #1 + 8000826: 2108 movs r1, #8 + 8000828: 4628 mov r0, r5 + 800082a: f7ff fd9d bl 8000368 + 800082e: 4604 mov r4, r0 + 8000830: 2800 cmp r0, #0 + 8000832: f47f ae21 bne.w 8000478 + rv = check_is_downgrade(buf_io, NULL); + 8000836: 4601 mov r1, r0 + 8000838: 4628 mov r0, r5 + 800083a: f001 fa9f bl 8001d7c + 800083e: e5fe b.n 800043e + REQUIRE_IN_ONLY(8); + 8000840: 2301 movs r3, #1 + 8000842: 2108 movs r1, #8 + 8000844: 4628 mov r0, r5 + 8000846: f7ff fd8f bl 8000368 + 800084a: 4604 mov r4, r0 + 800084c: 2800 cmp r0, #0 + 800084e: f47f ae13 bne.w 8000478 + if(buf_io[0] < 0x10 || buf_io[0] >= 0x40) { + 8000852: 782b ldrb r3, [r5, #0] + 8000854: 3b10 subs r3, #16 + rv = ERANGE; + 8000856: 2b2f cmp r3, #47 ; 0x2f + } if(check_is_downgrade(buf_io, NULL)) { + 8000858: 4601 mov r1, r0 + 800085a: 4628 mov r0, r5 + rv = ERANGE; + 800085c: bf88 it hi + 800085e: 2422 movhi r4, #34 ; 0x22 + } if(check_is_downgrade(buf_io, NULL)) { + 8000860: f001 fa8c bl 8001d7c + 8000864: 2800 cmp r0, #0 + 8000866: f040 80b9 bne.w 80009dc + get_min_version(min); + 800086a: a80b add r0, sp, #44 ; 0x2c + 800086c: f001 fa66 bl 8001d3c + if(memcmp(min, buf_io, 8) == 0) { + 8000870: 2208 movs r2, #8 + 8000872: 4629 mov r1, r5 + 8000874: a80b add r0, sp, #44 ; 0x2c + 8000876: f00d f837 bl 800d8e8 + 800087a: 2800 cmp r0, #0 + 800087c: f000 80ae beq.w 80009dc + if(record_highwater_version(buf_io)) { + 8000880: 4628 mov r0, r5 + 8000882: f001 fe61 bl 8002548 + rv = ENOMEM; + 8000886: 2800 cmp r0, #0 + 8000888: bf18 it ne + 800088a: 240c movne r4, #12 + 800088c: e5f4 b.n 8000478 + REQUIRE_OUT(4); + 800088e: 2300 movs r3, #0 + 8000890: 2104 movs r1, #4 + 8000892: 4628 mov r0, r5 + 8000894: f7ff fd68 bl 8000368 + 8000898: 4604 mov r4, r0 + 800089a: 2800 cmp r0, #0 + 800089c: f47f adec bne.w 8000478 + ae_setup(); + 80008a0: f002 f956 bl 8002b50 + rv = ae_get_counter((uint32_t *)buf_io, 0) ? EIO: 0; + 80008a4: 4621 mov r1, r4 + 80008a6: 4628 mov r0, r5 + 80008a8: f002 fd43 bl 8003332 + 80008ac: e6be b.n 800062c + REQUIRE_OUT(PIN_ATTEMPT_SIZE_V2 + sizeof(trick_slot_t)); + 80008ae: 2300 movs r3, #0 + 80008b0: f44f 71cc mov.w r1, #408 ; 0x198 + 80008b4: 4628 mov r0, r5 + 80008b6: f7ff fd57 bl 8000368 + 80008ba: 4604 mov r4, r0 + 80008bc: 2800 cmp r0, #0 + 80008be: f47f addb bne.w 8000478 + rv = pin_check_logged_in(args, &trick_mode); + 80008c2: a90b add r1, sp, #44 ; 0x2c + 80008c4: 4628 mov r0, r5 + 80008c6: f003 fde3 bl 8004490 + if(rv) goto fail; + 80008ca: 4604 mov r4, r0 + 80008cc: 2800 cmp r0, #0 + 80008ce: f47f add3 bne.w 8000478 + if(trick_mode) { + 80008d2: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 80008d6: b10b cbz r3, 80008dc + mcu_key_clear(NULL); + 80008d8: f001 fe84 bl 80025e4 + switch(arg2) { + 80008dc: 9b01 ldr r3, [sp, #4] + 80008de: 2b01 cmp r3, #1 + trick_slot_t *slot = (trick_slot_t *)(&buf_io[PIN_ATTEMPT_SIZE_V2]); + 80008e0: f505 728c add.w r2, r5, #280 ; 0x118 + switch(arg2) { + 80008e4: d00c beq.n 8000900 + 80008e6: 2b02 cmp r3, #2 + 80008e8: d01b beq.n 8000922 + 80008ea: 2b00 cmp r3, #0 + 80008ec: f47f af34 bne.w 8000758 + if(!trick_mode) { + 80008f0: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 80008f4: 2b00 cmp r3, #0 + 80008f6: f47f adbf bne.w 8000478 + se2_clear_tricks(); + 80008fa: f007 fb9f bl 800803c + 80008fe: e5bb b.n 8000478 + if(trick_mode) { + 8000900: f89d 102c ldrb.w r1, [sp, #44] ; 0x2c + 8000904: 2900 cmp r1, #0 + 8000906: f47f af27 bne.w 8000758 + if(slot->pin_len > 16) { + 800090a: f8d5 1170 ldr.w r1, [r5, #368] ; 0x170 + 800090e: 2910 cmp r1, #16 + 8000910: dc4a bgt.n 80009a8 + if(se2_test_trick_pin(slot->pin, slot->pin_len, slot, true)) { + 8000912: f505 70b0 add.w r0, r5, #352 ; 0x160 + 8000916: f007 fbf7 bl 8008108 + 800091a: 2800 cmp r0, #0 + 800091c: f47f adac bne.w 8000478 + 8000920: e71a b.n 8000758 + if(!trick_mode) { + 8000922: f89d 302c ldrb.w r3, [sp, #44] ; 0x2c + 8000926: 2b00 cmp r3, #0 + 8000928: f47f ada6 bne.w 8000478 + rv = se2_save_trick(slot); + 800092c: 4610 mov r0, r2 + 800092e: f007 fd05 bl 800833c + 8000932: e584 b.n 800043e + if(arg2 == 0xBeef) { + 8000934: 9b01 ldr r3, [sp, #4] + 8000936: f64b 62ef movw r2, #48879 ; 0xbeef + 800093a: 4293 cmp r3, r2 + 800093c: d103 bne.n 8000946 + fast_wipe(); + 800093e: f001 ff43 bl 80027c8 + rv = EPERM; + 8000942: 2401 movs r4, #1 + 8000944: e598 b.n 8000478 + } else if(arg2 == 0xDead) { + 8000946: f64d 62ad movw r2, #57005 ; 0xdead + 800094a: 4293 cmp r3, r2 + 800094c: d1f9 bne.n 8000942 + mcu_key_clear(NULL); + 800094e: 2000 movs r0, #0 + 8000950: f001 fe48 bl 80025e4 + oled_show(screen_wiped); + 8000954: 4825 ldr r0, [pc, #148] ; (80009ec ) + 8000956: f000 fb8d bl 8001074 + 800095a: e5e0 b.n 800051e + if(arg2 == 0xDead) fast_brick(); + 800095c: 9a01 ldr r2, [sp, #4] + 800095e: f64d 63ad movw r3, #57005 ; 0xdead + 8000962: 429a cmp r2, r3 + 8000964: d1ed bne.n 8000942 + 8000966: f001 ff01 bl 800276c + 800096a: e7ea b.n 8000942 + REQUIRE_OUT(8); + 800096c: 2300 movs r3, #0 + 800096e: 2108 movs r1, #8 + 8000970: 4628 mov r0, r5 + 8000972: f7ff fcf9 bl 8000368 + 8000976: 4604 mov r4, r0 + 8000978: 2800 cmp r0, #0 + 800097a: f47f ad7d bne.w 8000478 + mcu_key_usage(avail, consumed, total); + 800097e: f105 0208 add.w r2, r5, #8 + 8000982: 1d29 adds r1, r5, #4 + 8000984: 4628 mov r0, r5 + 8000986: f001 fe5b bl 8002640 + break; + 800098a: e575 b.n 8000478 + REQUIRE_OUT(33); + 800098c: 2300 movs r3, #0 + 800098e: 2121 movs r1, #33 ; 0x21 + 8000990: 4628 mov r0, r5 + 8000992: f7ff fce9 bl 8000368 + 8000996: 4604 mov r4, r0 + 8000998: 2800 cmp r0, #0 + 800099a: f47f ad6d bne.w 8000478 + switch(arg2) { + 800099e: 9b01 ldr r3, [sp, #4] + 80009a0: 2b01 cmp r3, #1 + 80009a2: d003 beq.n 80009ac + 80009a4: 2b02 cmp r3, #2 + 80009a6: d008 beq.n 80009ba + rv = ERANGE; + 80009a8: 2422 movs r4, #34 ; 0x22 + 80009aa: e565 b.n 8000478 + ae_setup(); + 80009ac: f002 f8d0 bl 8002b50 + ae_secure_random(&buf_io[1]); + 80009b0: 1c68 adds r0, r5, #1 + 80009b2: f002 fc35 bl 8003220 + buf_io[0] = 32; + 80009b6: 2320 movs r3, #32 + 80009b8: e708 b.n 80007cc + se2_read_rng(&buf_io[1]); + 80009ba: 1c68 adds r0, r5, #1 + 80009bc: f007 fea2 bl 8008704 + buf_io[0] = 8; + 80009c0: 2308 movs r3, #8 + 80009c2: e703 b.n 80007cc + if(incoming_lr <= BL_FLASH_BASE || incoming_lr >= (uint32_t)&firewall_starts) { + 80009c4: f1b4 6f00 cmp.w r4, #134217728 ; 0x8000000 + 80009c8: d902 bls.n 80009d0 + 80009ca: 4b09 ldr r3, [pc, #36] ; (80009f0 ) + 80009cc: 429c cmp r4, r3 + 80009ce: d302 bcc.n 80009d6 + fatal_error("LR"); + 80009d0: 4808 ldr r0, [pc, #32] ; (80009f4 ) + 80009d2: f000 f831 bl 8000a38 + system_startup(); + 80009d6: f000 f88d bl 8000af4 + break; + 80009da: e6fc b.n 80007d6 + rv = EAGAIN; + 80009dc: 240b movs r4, #11 + 80009de: e54b b.n 8000478 + 80009e0: 0801c050 .word 0x0801c050 + 80009e4: 0801c070 .word 0x0801c070 + 80009e8: 40022000 .word 0x40022000 + 80009ec: 08010174 .word 0x08010174 + 80009f0: 08000300 .word 0x08000300 + 80009f4: 0800d9e0 .word 0x0800d9e0 + +080009f8 : +// + static inline void +memset4(uint32_t *dest, uint32_t value, uint32_t byte_len) +{ + for(; byte_len; byte_len-=4, dest++) { + *dest = value; + 80009f8: 4a0a ldr r2, [pc, #40] ; (8000a24 ) + for(; byte_len; byte_len-=4, dest++) { + 80009fa: 490b ldr r1, [pc, #44] ; (8000a28 ) + +// wipe_all_sram() +// + void +wipe_all_sram(void) +{ + 80009fc: f04f 5300 mov.w r3, #536870912 ; 0x20000000 + *dest = value; + 8000a00: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a04: 428b cmp r3, r1 + 8000a06: d1fb bne.n 8000a00 + 8000a08: 4908 ldr r1, [pc, #32] ; (8000a2c ) + 8000a0a: f04f 5380 mov.w r3, #268435456 ; 0x10000000 + *dest = value; + 8000a0e: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a12: 428b cmp r3, r1 + 8000a14: d1fb bne.n 8000a0e + 8000a16: 4b06 ldr r3, [pc, #24] ; (8000a30 ) + 8000a18: 4906 ldr r1, [pc, #24] ; (8000a34 ) + *dest = value; + 8000a1a: f843 2b04 str.w r2, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 8000a1e: 428b cmp r3, r1 + 8000a20: d1fb bne.n 8000a1a + STATIC_ASSERT((SRAM3_BASE + SRAM3_SIZE) - BL_SRAM_BASE == 8192); + + memset4((void *)SRAM1_BASE, noise, SRAM1_SIZE_MAX); + memset4((void *)SRAM2_BASE, noise, SRAM2_SIZE); + memset4((void *)SRAM3_BASE, noise, SRAM3_SIZE - (BL_SRAM_BASE - SRAM3_BASE)); +} + 8000a22: 4770 bx lr + 8000a24: deadbeef .word 0xdeadbeef + 8000a28: 20030000 .word 0x20030000 + 8000a2c: 10010000 .word 0x10010000 + 8000a30: 20040000 .word 0x20040000 + 8000a34: 20042000 .word 0x20042000 + +08000a38 : + +// fatal_error(const char *msg) +// + void __attribute__((noreturn)) +fatal_error(const char *msgvoid) +{ + 8000a38: b508 push {r3, lr} + oled_setup(); + 8000a3a: f000 f99b bl 8000d74 + oled_show(screen_fatal); + 8000a3e: 4802 ldr r0, [pc, #8] ; (8000a48 ) + 8000a40: f000 fb18 bl 8001074 + BREAKPOINT; +#endif + + // Maybe should do a reset after a delay, like with + // the watchdog timer or something. + LOCKUP_FOREVER(); + 8000a44: f003 f918 bl 8003c78 + 8000a48: 0800e58d .word 0x0800e58d + +08000a4c : + +// fatal_mitm() +// + void __attribute__((noreturn)) +fatal_mitm(void) +{ + 8000a4c: b508 push {r3, lr} + oled_setup(); + 8000a4e: f000 f991 bl 8000d74 + oled_show(screen_mitm); + 8000a52: 4803 ldr r0, [pc, #12] ; (8000a60 ) + 8000a54: f000 fb0e bl 8001074 + +#ifdef RELEASE + wipe_all_sram(); + 8000a58: f7ff ffce bl 80009f8 +#endif + + LOCKUP_FOREVER(); + 8000a5c: f003 f90c bl 8003c78 + 8000a60: 0800e717 .word 0x0800e717 + +08000a64 : + +// enter_dfu() +// + void __attribute__((noreturn)) +enter_dfu(void) +{ + 8000a64: b507 push {r0, r1, r2, lr} + puts("enter_dfu()"); + 8000a66: 481f ldr r0, [pc, #124] ; (8000ae4 ) + 8000a68: f004 fafe bl 8005068 + + // clear the green light, if set + ae_setup(); + 8000a6c: f002 f870 bl 8002b50 + ae_set_gpio(0); + 8000a70: 2000 movs r0, #0 + 8000a72: f002 fdef bl 8003654 + + // Reset huge parts of the chip + __HAL_RCC_APB1_FORCE_RESET(); + 8000a76: 4b1c ldr r3, [pc, #112] ; (8000ae8 ) + 8000a78: f04f 31ff mov.w r1, #4294967295 ; 0xffffffff + __HAL_RCC_APB1_RELEASE_RESET(); + 8000a7c: 2200 movs r2, #0 + __HAL_RCC_APB1_FORCE_RESET(); + 8000a7e: 6399 str r1, [r3, #56] ; 0x38 + 8000a80: 63d9 str r1, [r3, #60] ; 0x3c + __HAL_RCC_APB1_RELEASE_RESET(); + 8000a82: 639a str r2, [r3, #56] ; 0x38 + 8000a84: 63da str r2, [r3, #60] ; 0x3c + + __HAL_RCC_APB2_FORCE_RESET(); + 8000a86: 6419 str r1, [r3, #64] ; 0x40 + __HAL_RCC_APB2_RELEASE_RESET(); + 8000a88: 641a str r2, [r3, #64] ; 0x40 + + __HAL_RCC_AHB1_FORCE_RESET(); + 8000a8a: 6299 str r1, [r3, #40] ; 0x28 + __HAL_RCC_AHB1_RELEASE_RESET(); + 8000a8c: 629a str r2, [r3, #40] ; 0x28 + // But not this; it borks things. + __HAL_RCC_AHB2_FORCE_RESET(); + __HAL_RCC_AHB2_RELEASE_RESET(); +#endif + + __HAL_RCC_AHB3_FORCE_RESET(); + 8000a8e: 6319 str r1, [r3, #48] ; 0x30 + __HAL_RCC_AHB3_RELEASE_RESET(); + 8000a90: 631a str r2, [r3, #48] ; 0x30 + + __HAL_FIREWALL_PREARM_ENABLE(); + 8000a92: f5a3 4374 sub.w r3, r3, #62464 ; 0xf400 + 8000a96: 6a1a ldr r2, [r3, #32] + 8000a98: f042 0201 orr.w r2, r2, #1 + 8000a9c: 621a str r2, [r3, #32] + 8000a9e: 6a1b ldr r3, [r3, #32] + 8000aa0: f003 0301 and.w r3, r3, #1 + 8000aa4: 9301 str r3, [sp, #4] + 8000aa6: 9b01 ldr r3, [sp, #4] + + // Wipe all of memory SRAM, just in case + // there is some way to trick us into DFU + // after sensitive content in place. + wipe_all_sram(); + 8000aa8: f7ff ffa6 bl 80009f8 + rng_delay(); + 8000aac: f001 ff2c bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000ab0: 4b0e ldr r3, [pc, #56] ; (8000aec ) + 8000ab2: 6a1b ldr r3, [r3, #32] + 8000ab4: b2db uxtb r3, r3 + + if(flash_is_security_level2()) { + 8000ab6: 2bcc cmp r3, #204 ; 0xcc + 8000ab8: d101 bne.n 8000abe + // cannot do DFU in RDP=2, so just die. Helps to preserve screen + LOCKUP_FOREVER(); + 8000aba: f003 f8dd bl 8003c78 + } + + // Reset clocks. + HAL_RCC_DeInit(); + 8000abe: f007 ff5f bl 8008980 + + // move system ROM into 0x0 + __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH(); + 8000ac2: 4a0b ldr r2, [pc, #44] ; (8000af0 ) + 8000ac4: 6813 ldr r3, [r2, #0] + 8000ac6: f023 0307 bic.w r3, r3, #7 + 8000aca: f043 0301 orr.w r3, r3, #1 + 8000ace: 6013 str r3, [r2, #0] + + // need this here?! + asm("nop; nop; nop; nop;"); + 8000ad0: bf00 nop + 8000ad2: bf00 nop + 8000ad4: bf00 nop + 8000ad6: bf00 nop + + // simulate a reset vector + __ASM volatile ("movs r0, #0\n" + 8000ad8: 2000 movs r0, #0 + 8000ada: 6803 ldr r3, [r0, #0] + 8000adc: f383 8808 msr MSP, r3 + 8000ae0: 6843 ldr r3, [r0, #4] + 8000ae2: 4798 blx r3 + "ldr r3, [r0, #4]\n" + "blx r3" + : : : "r0", "r3"); // also SP + + // NOT-REACHED. + __builtin_unreachable(); + 8000ae4: 0800d9e3 .word 0x0800d9e3 + 8000ae8: 40021000 .word 0x40021000 + 8000aec: 40022000 .word 0x40022000 + 8000af0: 40010000 .word 0x40010000 + +08000af4 : +{ + 8000af4: b510 push {r4, lr} + system_init0(); + 8000af6: f001 fa77 bl 8001fe8 + clocks_setup(); + 8000afa: f001 fa97 bl 800202c + rng_setup(); // needs to be super early + 8000afe: f001 fec1 bl 8002884 + rng_delay(); + 8000b02: f001 ff01 bl 8002908 + if(!check_all_ones(rom_secrets->bag_number, sizeof(rom_secrets->bag_number)) + 8000b06: 4838 ldr r0, [pc, #224] ; (8000be8 ) + 8000b08: 2120 movs r1, #32 + 8000b0a: f001 fe7f bl 800280c + 8000b0e: b948 cbnz r0, 8000b24 + rng_delay(); + 8000b10: f001 fefa bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000b14: 4b35 ldr r3, [pc, #212] ; (8000bec ) + 8000b16: 6a1b ldr r3, [r3, #32] + 8000b18: b2db uxtb r3, r3 + && !flash_is_security_level2() + 8000b1a: 2bcc cmp r3, #204 ; 0xcc + 8000b1c: d002 beq.n 8000b24 + flash_lockdown_hard(OB_RDP_LEVEL_2); + 8000b1e: 20cc movs r0, #204 ; 0xcc + 8000b20: f001 fcf8 bl 8002514 + gpio_setup(); + 8000b24: f002 ffbe bl 8003aa4 + uint32_t reset_reason = RCC->CSR; + 8000b28: 4c31 ldr r4, [pc, #196] ; (8000bf0 ) + console_setup(); + 8000b2a: f004 f9c3 bl 8004eb4 + puts2(BOOT_BANNER); + 8000b2e: 4831 ldr r0, [pc, #196] ; (8000bf4 ) + 8000b30: f004 fa0c bl 8004f4c + puts(version_string); + 8000b34: 4830 ldr r0, [pc, #192] ; (8000bf8 ) + 8000b36: f004 fa97 bl 8005068 + uint32_t reset_reason = RCC->CSR; + 8000b3a: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + if(reset_reason & RCC_CSR_FWRSTF) { + 8000b3e: 01db lsls r3, r3, #7 + 8000b40: d502 bpl.n 8000b48 + puts(">FIREWALLED<"); + 8000b42: 482e ldr r0, [pc, #184] ; (8000bfc ) + 8000b44: f004 fa90 bl 8005068 + SET_BIT(RCC->CSR, RCC_CSR_RMVF); + 8000b48: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8000b4c: f443 0300 orr.w r3, r3, #8388608 ; 0x800000 + 8000b50: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + if(memcmp(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)) == 0) { + 8000b54: 4c2a ldr r4, [pc, #168] ; (8000c00 ) + pin_setup0(); + 8000b56: f003 fa9b bl 8004090 + rng_delay(); + 8000b5a: f001 fed5 bl 8002908 + lcd_full_setup(); + 8000b5e: f000 f981 bl 8000e64 + if(memcmp(dfu_flag->magic, REBOOT_TO_DFU, sizeof(dfu_flag->magic)) == 0) { + 8000b62: 4928 ldr r1, [pc, #160] ; (8000c04 ) + 8000b64: 2208 movs r2, #8 + 8000b66: 4620 mov r0, r4 + 8000b68: f00c febe bl 800d8e8 + 8000b6c: b928 cbnz r0, 8000b7a + dfu_flag->magic[0] = 0; + 8000b6e: 7020 strb r0, [r4, #0] + oled_show(dfu_flag->screen); + 8000b70: 68a0 ldr r0, [r4, #8] + 8000b72: f000 fa7f bl 8001074 + enter_dfu(); + 8000b76: f7ff ff75 bl 8000a64 + rng_delay(); + 8000b7a: f001 fec5 bl 8002908 + oled_show_progress(screen_verify, 0); + 8000b7e: 2100 movs r1, #0 + 8000b80: 4821 ldr r0, [pc, #132] ; (8000c08 ) + 8000b82: f000 faf1 bl 8001168 + wipe_all_sram(); + 8000b86: f7ff ff37 bl 80009f8 + ae_setup(); + 8000b8a: f001 ffe1 bl 8002b50 + ae_set_gpio(0); // turn light red + 8000b8e: 2000 movs r0, #0 + 8000b90: f002 fd60 bl 8003654 + se2_setup(); + 8000b94: f007 fa0c bl 8007fb0 + se2_probe(); + 8000b98: f006 ff90 bl 8007abc + flash_setup(); + 8000b9c: f001 fbee bl 800237c + psram_setup(); + 8000ba0: f004 fa9a bl 80050d8 + if(ae_pair_unlock() != 0) { + 8000ba4: f002 f9ca bl 8002f3c + 8000ba8: b138 cbz r0, 8000bba + oled_show(screen_brick); + 8000baa: 4818 ldr r0, [pc, #96] ; (8000c0c ) + 8000bac: f000 fa62 bl 8001074 + puts("pair-bricked"); + 8000bb0: 4817 ldr r0, [pc, #92] ; (8000c10 ) + 8000bb2: f004 fa59 bl 8005068 + LOCKUP_FOREVER(); + 8000bb6: f003 f85f bl 8003c78 + puts2("Verify: "); + 8000bba: 4816 ldr r0, [pc, #88] ; (8000c14 ) + 8000bbc: f004 f9c6 bl 8004f4c + bool main_ok = verify_firmware(); + 8000bc0: f001 f996 bl 8001ef0 + if(main_ok) { + 8000bc4: b120 cbz r0, 8000bd0 +} + 8000bc6: e8bd 4010 ldmia.w sp!, {r4, lr} + oled_show(screen_blankish); + 8000bca: 4813 ldr r0, [pc, #76] ; (8000c18 ) + 8000bcc: f000 ba52 b.w 8001074 + psram_recover_firmware(); + 8000bd0: f004 fbd0 bl 8005374 + rng_delay(); + 8000bd4: f001 fe98 bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8000bd8: 4b04 ldr r3, [pc, #16] ; (8000bec ) + 8000bda: 6a1b ldr r3, [r3, #32] + 8000bdc: b2db uxtb r3, r3 + if(!flash_is_security_level2()) { + 8000bde: 2bcc cmp r3, #204 ; 0xcc + 8000be0: d1c9 bne.n 8000b76 + while(1) sdcard_recovery(); + 8000be2: f004 fd91 bl 8005708 + 8000be6: e7fc b.n 8000be2 + 8000be8: 0801c050 .word 0x0801c050 + 8000bec: 40022000 .word 0x40022000 + 8000bf0: 40021000 .word 0x40021000 + 8000bf4: 0800d9ef .word 0x0800d9ef + 8000bf8: 0801079c .word 0x0801079c + 8000bfc: 0800da02 .word 0x0800da02 + 8000c00: 20008000 .word 0x20008000 + 8000c04: 0800d9d7 .word 0x0800d9d7 + 8000c08: 0801004d .word 0x0801004d + 8000c0c: 0800da61 .word 0x0800da61 + 8000c10: 0800da0f .word 0x0800da0f + 8000c14: 0800da1c .word 0x0800da1c + 8000c18: 0800da48 .word 0x0800da48 + +08000c1c : + +// lcd_write_data() +// + static void +lcd_write_data(int len, const uint8_t *pixels) +{ + 8000c1c: b538 push {r3, r4, r5, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c1e: 2201 movs r2, #1 +{ + 8000c20: 4605 mov r5, r0 + 8000c22: 460c mov r4, r1 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c24: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c28: 2110 movs r1, #16 + 8000c2a: f000 fc5d bl 80014e8 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 1); + 8000c2e: 2201 movs r2, #1 + 8000c30: f44f 7180 mov.w r1, #256 ; 0x100 + 8000c34: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c38: f000 fc56 bl 80014e8 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000c3c: 2200 movs r2, #0 + 8000c3e: 2110 movs r1, #16 + 8000c40: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c44: f000 fc50 bl 80014e8 + HAL_SPI_Transmit(&spi_port, (uint8_t *)buf, len, HAL_MAX_DELAY); + 8000c48: b2aa uxth r2, r5 + 8000c4a: 4621 mov r1, r4 + 8000c4c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8000c50: 4805 ldr r0, [pc, #20] ; (8000c68 ) + 8000c52: f000 fce9 bl 8001628 + + write_bytes(len, pixels); + + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); +} + 8000c56: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000c5a: 2201 movs r2, #1 + 8000c5c: 2110 movs r1, #16 + 8000c5e: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000c62: f000 bc41 b.w 80014e8 + 8000c66: bf00 nop + 8000c68: 2009e158 .word 0x2009e158 + +08000c6c : + +// lcd_write_data1() +// + static void +lcd_write_data1(uint8_t data) +{ + 8000c6c: b507 push {r0, r1, r2, lr} + 8000c6e: f88d 0007 strb.w r0, [sp, #7] + lcd_write_data(1, &data); + 8000c72: f10d 0107 add.w r1, sp, #7 + 8000c76: 2001 movs r0, #1 + 8000c78: f7ff ffd0 bl 8000c1c +} + 8000c7c: b003 add sp, #12 + 8000c7e: f85d fb04 ldr.w pc, [sp], #4 + ... + +08000c84 : +static inline void wait_vsync(void) { + 8000c84: b538 push {r3, r4, r5, lr} + 8000c86: 4c08 ldr r4, [pc, #32] ; (8000ca8 ) + if(HAL_GPIO_ReadPin(GPIOB, TEAR_PIN) != 0) { + 8000c88: 4d08 ldr r5, [pc, #32] ; (8000cac ) + 8000c8a: f44f 6100 mov.w r1, #2048 ; 0x800 + 8000c8e: 4628 mov r0, r5 + 8000c90: f000 fc24 bl 80014dc + 8000c94: b930 cbnz r0, 8000ca4 + for(; timeout; timeout--) { + 8000c96: 3c01 subs r4, #1 + 8000c98: d1f7 bne.n 8000c8a +} + 8000c9a: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + puts("TEAR timeout"); + 8000c9e: 4804 ldr r0, [pc, #16] ; (8000cb0 ) + 8000ca0: f004 b9e2 b.w 8005068 +} + 8000ca4: bd38 pop {r3, r4, r5, pc} + 8000ca6: bf00 nop + 8000ca8: 000f4240 .word 0x000f4240 + 8000cac: 48000400 .word 0x48000400 + 8000cb0: 0800da25 .word 0x0800da25 + +08000cb4 : +{ + 8000cb4: b507 push {r0, r1, r2, lr} + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000cb6: 2201 movs r2, #1 +{ + 8000cb8: f88d 0007 strb.w r0, [sp, #7] + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000cbc: 2110 movs r1, #16 + 8000cbe: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cc2: f000 fc11 bl 80014e8 + HAL_GPIO_WritePin(GPIOA, DC_PIN, 0); + 8000cc6: 2200 movs r2, #0 + 8000cc8: f44f 7180 mov.w r1, #256 ; 0x100 + 8000ccc: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cd0: f000 fc0a bl 80014e8 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 0); + 8000cd4: 2200 movs r2, #0 + 8000cd6: 2110 movs r1, #16 + 8000cd8: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cdc: f000 fc04 bl 80014e8 + HAL_SPI_Transmit(&spi_port, (uint8_t *)buf, len, HAL_MAX_DELAY); + 8000ce0: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8000ce4: f10d 0107 add.w r1, sp, #7 + 8000ce8: 2201 movs r2, #1 + 8000cea: 4806 ldr r0, [pc, #24] ; (8000d04 ) + 8000cec: f000 fc9c bl 8001628 + HAL_GPIO_WritePin(GPIOA, CS_PIN, 1); + 8000cf0: 2201 movs r2, #1 + 8000cf2: 2110 movs r1, #16 + 8000cf4: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000cf8: f000 fbf6 bl 80014e8 +} + 8000cfc: b003 add sp, #12 + 8000cfe: f85d fb04 ldr.w pc, [sp], #4 + 8000d02: bf00 nop + 8000d04: 2009e158 .word 0x2009e158 + +08000d08 : +{ + 8000d08: b537 push {r0, r1, r2, r4, r5, lr} + 8000d0a: 460d mov r5, r1 + 8000d0c: 4614 mov r4, r2 + lcd_write_cmd(cmd); + 8000d0e: f7ff ffd1 bl 8000cb4 + uint8_t d[4] = { (a>>8), a&0xff, (b>>8), b&0xff }; + 8000d12: 0a2b lsrs r3, r5, #8 + 8000d14: f88d 3004 strb.w r3, [sp, #4] + lcd_write_data(4, d); + 8000d18: a901 add r1, sp, #4 + uint8_t d[4] = { (a>>8), a&0xff, (b>>8), b&0xff }; + 8000d1a: 0a23 lsrs r3, r4, #8 + lcd_write_data(4, d); + 8000d1c: 2004 movs r0, #4 + uint8_t d[4] = { (a>>8), a&0xff, (b>>8), b&0xff }; + 8000d1e: f88d 5005 strb.w r5, [sp, #5] + 8000d22: f88d 3006 strb.w r3, [sp, #6] + 8000d26: f88d 4007 strb.w r4, [sp, #7] + lcd_write_data(4, d); + 8000d2a: f7ff ff77 bl 8000c1c +} + 8000d2e: b003 add sp, #12 + 8000d30: bd30 pop {r4, r5, pc} + ... + +08000d34 : +// +// Just setup SPI, do not reset display, etc. +// + void +lcd_spi_setup(void) +{ + 8000d34: b538 push {r3, r4, r5, lr} +#ifndef DISABLE_LCD + // might already be setup + if(spi_port.Instance == SPI1) return; + 8000d36: 4c0d ldr r4, [pc, #52] ; (8000d6c ) + 8000d38: 4d0d ldr r5, [pc, #52] ; (8000d70 ) + 8000d3a: 6823 ldr r3, [r4, #0] + 8000d3c: 42ab cmp r3, r5 + 8000d3e: d014 beq.n 8000d6a + + memset(&spi_port, 0, sizeof(spi_port)); + 8000d40: f104 0008 add.w r0, r4, #8 + 8000d44: 225c movs r2, #92 ; 0x5c + 8000d46: 2100 movs r1, #0 + 8000d48: f00c fdec bl 800d924 + + spi_port.Instance = SPI1; + + // see SPI_InitTypeDef + spi_port.Init.Mode = SPI_MODE_MASTER; + 8000d4c: f44f 7382 mov.w r3, #260 ; 0x104 + 8000d50: 6063 str r3, [r4, #4] + spi_port.Init.Direction = SPI_DIRECTION_2LINES; + spi_port.Init.DataSize = SPI_DATASIZE_8BIT; + 8000d52: f44f 63e0 mov.w r3, #1792 ; 0x700 + 8000d56: 60e3 str r3, [r4, #12] + spi_port.Init.CLKPolarity = SPI_POLARITY_LOW; + spi_port.Init.CLKPhase = SPI_PHASE_1EDGE; + spi_port.Init.NSS = SPI_NSS_SOFT; + 8000d58: f44f 7300 mov.w r3, #512 ; 0x200 + spi_port.Instance = SPI1; + 8000d5c: 6025 str r5, [r4, #0] + spi_port.Init.NSS = SPI_NSS_SOFT; + 8000d5e: 61a3 str r3, [r4, #24] + spi_port.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + spi_port.Init.FirstBit = SPI_FIRSTBIT_MSB; + spi_port.Init.TIMode = SPI_TIMODE_DISABLED; + spi_port.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + + HAL_SPI_Init(&spi_port); + 8000d60: 4620 mov r0, r4 +#endif +} + 8000d62: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + HAL_SPI_Init(&spi_port); + 8000d66: f000 bc01 b.w 800156c +} + 8000d6a: bd38 pop {r3, r4, r5, pc} + 8000d6c: 2009e158 .word 0x2009e158 + 8000d70: 40013000 .word 0x40013000 + +08000d74 : +// +// Ok to call this lots. +// + void +oled_setup(void) +{ + 8000d74: b530 push {r4, r5, lr} + puts("lcd disabled");return; // disable so I can use MCO +#endif + + static uint32_t inited; + + if(inited == 0x238a572F) { + 8000d76: 4b23 ldr r3, [pc, #140] ; (8000e04 ) + 8000d78: 4a23 ldr r2, [pc, #140] ; (8000e08 ) + 8000d7a: 6819 ldr r1, [r3, #0] + 8000d7c: 4291 cmp r1, r2 +{ + 8000d7e: b087 sub sp, #28 + if(inited == 0x238a572F) { + 8000d80: d03e beq.n 8000e00 + return; + } + inited = 0x238a572F; + 8000d82: 601a str r2, [r3, #0] + + // enable some internal clocks + __HAL_RCC_SPI1_CLK_ENABLE(); + 8000d84: 4b21 ldr r3, [pc, #132] ; (8000e0c ) + + // take over from GPU + // - can be issue when coming in via callgate from mpy which might have been showing menu + HAL_GPIO_WritePin(GPIOE, PIN_G_CTRL, 1); // set G_CTRL pin -- we have control + 8000d86: 4822 ldr r0, [pc, #136] ; (8000e10 ) + __HAL_RCC_SPI1_CLK_ENABLE(); + 8000d88: 6e1a ldr r2, [r3, #96] ; 0x60 + + // .. wait for GPU to finish it's work + // - might take 16+ms because waiting for next vsync, etc + for(int i=0; i<100; i++) { + if(HAL_GPIO_ReadPin(GPIOE, PIN_G_BUSY) == 0) break; + 8000d8a: 4d21 ldr r5, [pc, #132] ; (8000e10 ) + __HAL_RCC_SPI1_CLK_ENABLE(); + 8000d8c: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8000d90: 661a str r2, [r3, #96] ; 0x60 + 8000d92: 6e1b ldr r3, [r3, #96] ; 0x60 + 8000d94: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 8000d98: 9300 str r3, [sp, #0] + HAL_GPIO_WritePin(GPIOE, PIN_G_CTRL, 1); // set G_CTRL pin -- we have control + 8000d9a: 2201 movs r2, #1 + 8000d9c: 2120 movs r1, #32 + __HAL_RCC_SPI1_CLK_ENABLE(); + 8000d9e: 9b00 ldr r3, [sp, #0] + HAL_GPIO_WritePin(GPIOE, PIN_G_CTRL, 1); // set G_CTRL pin -- we have control + 8000da0: f000 fba2 bl 80014e8 + 8000da4: 2464 movs r4, #100 ; 0x64 + if(HAL_GPIO_ReadPin(GPIOE, PIN_G_BUSY) == 0) break; + 8000da6: 2104 movs r1, #4 + 8000da8: 4628 mov r0, r5 + 8000daa: f000 fb97 bl 80014dc + 8000dae: b120 cbz r0, 8000dba + delay_ms(1); + 8000db0: 2001 movs r0, #1 + 8000db2: f002 fe67 bl 8003a84 + for(int i=0; i<100; i++) { + 8000db6: 3c01 subs r4, #1 + 8000db8: d1f5 bne.n 8000da6 + } + + // Simple pins + // - must be opendrain to allow GPU to share + GPIO_InitTypeDef setup = { + 8000dba: 4d16 ldr r5, [pc, #88] ; (8000e14 ) + 8000dbc: cd0f ldmia r5!, {r0, r1, r2, r3} + 8000dbe: ac01 add r4, sp, #4 + 8000dc0: c40f stmia r4!, {r0, r1, r2, r3} + 8000dc2: 682b ldr r3, [r5, #0] + 8000dc4: 6023 str r3, [r4, #0] + .Mode = GPIO_MODE_OUTPUT_OD, + .Pull = GPIO_PULLUP, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = 0, + }; + HAL_GPIO_Init(GPIOA, &setup); + 8000dc6: a901 add r1, sp, #4 + 8000dc8: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000dcc: f000 fa12 bl 80011f4 + + // starting values + HAL_GPIO_WritePin(GPIOA, RESET_PIN | CS_PIN | DC_PIN, 1); + 8000dd0: 2201 movs r2, #1 + 8000dd2: f44f 71a8 mov.w r1, #336 ; 0x150 + 8000dd6: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000dda: f000 fb85 bl 80014e8 + + // SPI pins (same but with AF) + setup.Pin = SPI_SCK | SPI_MOSI; + 8000dde: 23a0 movs r3, #160 ; 0xa0 + 8000de0: 9301 str r3, [sp, #4] + setup.Alternate = GPIO_AF5_SPI1; + 8000de2: 2305 movs r3, #5 + 8000de4: 9305 str r3, [sp, #20] + setup.Mode = GPIO_MODE_AF_PP; + 8000de6: 2302 movs r3, #2 + setup.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + HAL_GPIO_Init(GPIOA, &setup); + 8000de8: a901 add r1, sp, #4 + 8000dea: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + setup.Mode = GPIO_MODE_AF_PP; + 8000dee: 9302 str r3, [sp, #8] + setup.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + 8000df0: 2303 movs r3, #3 + 8000df2: 9304 str r3, [sp, #16] + HAL_GPIO_Init(GPIOA, &setup); + 8000df4: f000 f9fe bl 80011f4 + + // config SPI port + lcd_spi_setup(); + 8000df8: f7ff ff9c bl 8000d34 + rng_delay(); + 8000dfc: f001 fd84 bl 8002908 +} + 8000e00: b007 add sp, #28 + 8000e02: bd30 pop {r4, r5, pc} + 8000e04: 2009e150 .word 0x2009e150 + 8000e08: 238a572f .word 0x238a572f + 8000e0c: 40021000 .word 0x40021000 + 8000e10: 48001000 .word 0x48001000 + 8000e14: 0800da34 .word 0x0800da34 + +08000e18 : + +// lcd_fill_solid() +// + void +lcd_fill_solid(uint16_t pattern) +{ + 8000e18: b5b0 push {r4, r5, r7, lr} + // note, MADCTL MV/MX/MY setting causes row vs. col swap here + lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x) + 8000e1a: f240 123f movw r2, #319 ; 0x13f +{ + 8000e1e: af00 add r7, sp, #0 + lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x) + 8000e20: 2100 movs r1, #0 +{ + 8000e22: 4604 mov r4, r0 + lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x) + 8000e24: 202a movs r0, #42 ; 0x2a + 8000e26: f7ff ff6f bl 8000d08 + lcd_write_cmd4(0x2b, 0, LCD_HEIGHT-1); // RASET - Row address set range (y) + 8000e2a: 22ef movs r2, #239 ; 0xef + 8000e2c: 2100 movs r1, #0 + 8000e2e: 202b movs r0, #43 ; 0x2b + 8000e30: f7ff ff6a bl 8000d08 + + lcd_write_cmd(0x2c); // RAMWR - memory write + 8000e34: 202c movs r0, #44 ; 0x2c + 8000e36: f7ff ff3d bl 8000cb4 + + uint16_t row[LCD_WIDTH]; + 8000e3a: f5ad 7d20 sub.w sp, sp, #640 ; 0x280 + 8000e3e: 466d mov r5, sp + for(; byte_len; byte_len-=2, dest++) { + 8000e40: f505 7220 add.w r2, r5, #640 ; 0x280 + uint16_t row[LCD_WIDTH]; + 8000e44: 462b mov r3, r5 + *dest = value; + 8000e46: f823 4b02 strh.w r4, [r3], #2 + for(; byte_len; byte_len-=2, dest++) { + 8000e4a: 429a cmp r2, r3 + 8000e4c: d1fb bne.n 8000e46 + 8000e4e: 24f0 movs r4, #240 ; 0xf0 + memset2(row, pattern, sizeof(row)); + + for(int y=0; y + for(int y=0; y + } +} + 8000e5e: 46bd mov sp, r7 + 8000e60: bdb0 pop {r4, r5, r7, pc} + ... + +08000e64 : +{ + 8000e64: b508 push {r3, lr} + oled_setup(); + 8000e66: f7ff ff85 bl 8000d74 + lcd_write_cmd(0x28); // DISPOFF + 8000e6a: 2028 movs r0, #40 ; 0x28 + 8000e6c: f7ff ff22 bl 8000cb4 + lcd_write_cmd(0x36); // MADCTL: memory addr ctrl, page 215 + 8000e70: 2036 movs r0, #54 ; 0x36 + 8000e72: f7ff ff1f bl 8000cb4 + lcd_write_data1(0x60); // MV=1 => horz mode, first byte=top-left corner, RGB order + 8000e76: 2060 movs r0, #96 ; 0x60 + 8000e78: f7ff fef8 bl 8000c6c + lcd_fill_solid(COL_BLACK); // works only on second+ reboots/resets + 8000e7c: 2000 movs r0, #0 + 8000e7e: f7ff ffcb bl 8000e18 + delay_ms(1); + 8000e82: 2001 movs r0, #1 + 8000e84: f002 fdfe bl 8003a84 + HAL_GPIO_WritePin(GPIOA, RESET_PIN, 0); + 8000e88: 2200 movs r2, #0 + 8000e8a: 2140 movs r1, #64 ; 0x40 + 8000e8c: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000e90: f000 fb2a bl 80014e8 + delay_ms(1); + 8000e94: 2001 movs r0, #1 + 8000e96: f002 fdf5 bl 8003a84 + HAL_GPIO_WritePin(GPIOA, RESET_PIN, 1); + 8000e9a: 2201 movs r2, #1 + 8000e9c: 2140 movs r1, #64 ; 0x40 + 8000e9e: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8000ea2: f000 fb21 bl 80014e8 + delay_ms(120); // 120ms - reset recovery time + 8000ea6: 2078 movs r0, #120 ; 0x78 + 8000ea8: f002 fdec bl 8003a84 + lcd_write_cmd(0x11); // SLPOUT: Sleep Out => turn off sleep mode + 8000eac: 2011 movs r0, #17 + 8000eae: f7ff ff01 bl 8000cb4 + delay_ms(5); // 5ms - wake up time + 8000eb2: 2005 movs r0, #5 + 8000eb4: f002 fde6 bl 8003a84 + lcd_write_cmd(0x36); // MADCTL: memory addr ctrl, page 215 + 8000eb8: 2036 movs r0, #54 ; 0x36 + 8000eba: f7ff fefb bl 8000cb4 + lcd_write_data1(0x60); // MV=1 => horz mode, first byte=top-left corner, RGB order + 8000ebe: 2060 movs r0, #96 ; 0x60 + 8000ec0: f7ff fed4 bl 8000c6c + lcd_write_cmd(0x3a); // COLMOD: pixel format + 8000ec4: 203a movs r0, #58 ; 0x3a + 8000ec6: f7ff fef5 bl 8000cb4 + lcd_write_data1(0x05); // => 16bit/pixel + 8000eca: 2005 movs r0, #5 + 8000ecc: f7ff fece bl 8000c6c + lcd_write_cmd(0xb2); // PORCTRL - porch control + 8000ed0: 20b2 movs r0, #178 ; 0xb2 + 8000ed2: f7ff feef bl 8000cb4 + lcd_write_data1(0x0c); + 8000ed6: 200c movs r0, #12 + 8000ed8: f7ff fec8 bl 8000c6c + lcd_write_data1(0x0c); + 8000edc: 200c movs r0, #12 + 8000ede: f7ff fec5 bl 8000c6c + lcd_write_data1(0x00); + 8000ee2: 2000 movs r0, #0 + 8000ee4: f7ff fec2 bl 8000c6c + lcd_write_data1(0x33); + 8000ee8: 2033 movs r0, #51 ; 0x33 + 8000eea: f7ff febf bl 8000c6c + lcd_write_data1(0x33); + 8000eee: 2033 movs r0, #51 ; 0x33 + 8000ef0: f7ff febc bl 8000c6c + lcd_write_cmd(0xb7); + 8000ef4: 20b7 movs r0, #183 ; 0xb7 + 8000ef6: f7ff fedd bl 8000cb4 + lcd_write_data1(0x35); + 8000efa: 2035 movs r0, #53 ; 0x35 + 8000efc: f7ff feb6 bl 8000c6c + lcd_write_cmd(0xbb); // VCOMS + 8000f00: 20bb movs r0, #187 ; 0xbb + 8000f02: f7ff fed7 bl 8000cb4 + lcd_write_data1(0x25); //35 20 + 8000f06: 2025 movs r0, #37 ; 0x25 + 8000f08: f7ff feb0 bl 8000c6c + lcd_write_cmd(0xc0); // LCM + 8000f0c: 20c0 movs r0, #192 ; 0xc0 + 8000f0e: f7ff fed1 bl 8000cb4 + lcd_write_data1(0x2c); + 8000f12: 202c movs r0, #44 ; 0x2c + 8000f14: f7ff feaa bl 8000c6c + lcd_write_cmd(0xc2); // VDVVRHEN + 8000f18: 20c2 movs r0, #194 ; 0xc2 + 8000f1a: f7ff fecb bl 8000cb4 + lcd_write_data1(0x01); + 8000f1e: 2001 movs r0, #1 + 8000f20: f7ff fea4 bl 8000c6c + lcd_write_cmd(0xc3); // VRHS + 8000f24: 20c3 movs r0, #195 ; 0xc3 + 8000f26: f7ff fec5 bl 8000cb4 + lcd_write_data1(0x13); //0e + 8000f2a: 2013 movs r0, #19 + 8000f2c: f7ff fe9e bl 8000c6c + lcd_write_cmd(0xc4); // VDVSET + 8000f30: 20c4 movs r0, #196 ; 0xc4 + 8000f32: f7ff febf bl 8000cb4 + lcd_write_data1(0x20); + 8000f36: 2020 movs r0, #32 + 8000f38: f7ff fe98 bl 8000c6c + lcd_write_cmd(0xc6); // FRCTR2 + 8000f3c: 20c6 movs r0, #198 ; 0xc6 + 8000f3e: f7ff feb9 bl 8000cb4 + lcd_write_data1(0x0f); + 8000f42: 200f movs r0, #15 + 8000f44: f7ff fe92 bl 8000c6c + lcd_write_cmd(0xd0); // PWCTRL1 + 8000f48: 20d0 movs r0, #208 ; 0xd0 + 8000f4a: f7ff feb3 bl 8000cb4 + lcd_write_data1(0xa4); + 8000f4e: 20a4 movs r0, #164 ; 0xa4 + 8000f50: f7ff fe8c bl 8000c6c + lcd_write_data1(0xa1); + 8000f54: 20a1 movs r0, #161 ; 0xa1 + 8000f56: f7ff fe89 bl 8000c6c + lcd_write_cmd(0xe0); // PVGAMCTRL + 8000f5a: 20e0 movs r0, #224 ; 0xe0 + 8000f5c: f7ff feaa bl 8000cb4 + lcd_write_data1(0xd0); + 8000f60: 20d0 movs r0, #208 ; 0xd0 + 8000f62: f7ff fe83 bl 8000c6c + lcd_write_data1(0x00); + 8000f66: 2000 movs r0, #0 + 8000f68: f7ff fe80 bl 8000c6c + lcd_write_data1(0x03); + 8000f6c: 2003 movs r0, #3 + 8000f6e: f7ff fe7d bl 8000c6c + lcd_write_data1(0x09); + 8000f72: 2009 movs r0, #9 + 8000f74: f7ff fe7a bl 8000c6c + lcd_write_data1(0x13); + 8000f78: 2013 movs r0, #19 + 8000f7a: f7ff fe77 bl 8000c6c + lcd_write_data1(0x1c); + 8000f7e: 201c movs r0, #28 + 8000f80: f7ff fe74 bl 8000c6c + lcd_write_data1(0x3a); + 8000f84: 203a movs r0, #58 ; 0x3a + 8000f86: f7ff fe71 bl 8000c6c + lcd_write_data1(0x55); + 8000f8a: 2055 movs r0, #85 ; 0x55 + 8000f8c: f7ff fe6e bl 8000c6c + lcd_write_data1(0x48); + 8000f90: 2048 movs r0, #72 ; 0x48 + 8000f92: f7ff fe6b bl 8000c6c + lcd_write_data1(0x18); + 8000f96: 2018 movs r0, #24 + 8000f98: f7ff fe68 bl 8000c6c + lcd_write_data1(0x12); + 8000f9c: 2012 movs r0, #18 + 8000f9e: f7ff fe65 bl 8000c6c + lcd_write_data1(0x0e); + 8000fa2: 200e movs r0, #14 + 8000fa4: f7ff fe62 bl 8000c6c + lcd_write_data1(0x19); + 8000fa8: 2019 movs r0, #25 + 8000faa: f7ff fe5f bl 8000c6c + lcd_write_data1(0x1e); + 8000fae: 201e movs r0, #30 + 8000fb0: f7ff fe5c bl 8000c6c + lcd_write_cmd(0xe1); // NVGAMCTRL + 8000fb4: 20e1 movs r0, #225 ; 0xe1 + 8000fb6: f7ff fe7d bl 8000cb4 + lcd_write_data1(0xd0); + 8000fba: 20d0 movs r0, #208 ; 0xd0 + 8000fbc: f7ff fe56 bl 8000c6c + lcd_write_data1(0x00); + 8000fc0: 2000 movs r0, #0 + 8000fc2: f7ff fe53 bl 8000c6c + lcd_write_data1(0x03); + 8000fc6: 2003 movs r0, #3 + 8000fc8: f7ff fe50 bl 8000c6c + lcd_write_data1(0x09); + 8000fcc: 2009 movs r0, #9 + 8000fce: f7ff fe4d bl 8000c6c + lcd_write_data1(0x05); + 8000fd2: 2005 movs r0, #5 + 8000fd4: f7ff fe4a bl 8000c6c + lcd_write_data1(0x25); + 8000fd8: 2025 movs r0, #37 ; 0x25 + 8000fda: f7ff fe47 bl 8000c6c + lcd_write_data1(0x3a); + 8000fde: 203a movs r0, #58 ; 0x3a + 8000fe0: f7ff fe44 bl 8000c6c + lcd_write_data1(0x55); + 8000fe4: 2055 movs r0, #85 ; 0x55 + 8000fe6: f7ff fe41 bl 8000c6c + lcd_write_data1(0x50); + 8000fea: 2050 movs r0, #80 ; 0x50 + 8000fec: f7ff fe3e bl 8000c6c + lcd_write_data1(0x3d); + 8000ff0: 203d movs r0, #61 ; 0x3d + 8000ff2: f7ff fe3b bl 8000c6c + lcd_write_data1(0x1c); + 8000ff6: 201c movs r0, #28 + 8000ff8: f7ff fe38 bl 8000c6c + lcd_write_data1(0x1d); + 8000ffc: 201d movs r0, #29 + 8000ffe: f7ff fe35 bl 8000c6c + lcd_write_data1(0x1d); + 8001002: 201d movs r0, #29 + 8001004: f7ff fe32 bl 8000c6c + lcd_write_data1(0x1e); + 8001008: 201e movs r0, #30 + 800100a: f7ff fe2f bl 8000c6c + lcd_write_cmd(0x35); // TEON - Tear signal on + 800100e: 2035 movs r0, #53 ; 0x35 + 8001010: f7ff fe50 bl 8000cb4 + lcd_write_data1(0x0); + 8001014: 2000 movs r0, #0 + 8001016: f7ff fe29 bl 8000c6c + lcd_fill_solid(COL_BLACK); + 800101a: 2000 movs r0, #0 + 800101c: f7ff fefc bl 8000e18 + lcd_write_cmd(0x21); // INVON + 8001020: 2021 movs r0, #33 ; 0x21 + 8001022: f7ff fe47 bl 8000cb4 + lcd_write_cmd(0x29); // DISPON + 8001026: 2029 movs r0, #41 ; 0x29 + 8001028: f7ff fe44 bl 8000cb4 + delay_ms(50); + 800102c: 2032 movs r0, #50 ; 0x32 + 800102e: f002 fd29 bl 8003a84 + last_screen = NULL; + 8001032: 4b02 ldr r3, [pc, #8] ; (800103c ) + 8001034: 2200 movs r2, #0 + 8001036: 601a str r2, [r3, #0] +} + 8001038: bd08 pop {r3, pc} + 800103a: bf00 nop + 800103c: 2009e154 .word 0x2009e154 + +08001040 : + +// lcd_write_rows() +// + void +lcd_write_rows(int y, int num_rows, uint16_t *pixels) +{ + 8001040: b570 push {r4, r5, r6, lr} + 8001042: 4606 mov r6, r0 + 8001044: 460c mov r4, r1 + 8001046: 4615 mov r5, r2 + lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x) + 8001048: 2100 movs r1, #0 + 800104a: f240 123f movw r2, #319 ; 0x13f + 800104e: 202a movs r0, #42 ; 0x2a + 8001050: f7ff fe5a bl 8000d08 + lcd_write_cmd4(0x2b, y, LCD_HEIGHT-1); // RASET - Row address set range (y) + 8001054: b2b1 uxth r1, r6 + 8001056: 22ef movs r2, #239 ; 0xef + 8001058: 202b movs r0, #43 ; 0x2b + 800105a: f7ff fe55 bl 8000d08 + + lcd_write_cmd(0x2c); // RAMWR - memory write + 800105e: 202c movs r0, #44 ; 0x2c + 8001060: f7ff fe28 bl 8000cb4 + + lcd_write_data(num_rows * 2 * LCD_WIDTH, (uint8_t *)pixels); + 8001064: f44f 7020 mov.w r0, #640 ; 0x280 + 8001068: 4629 mov r1, r5 + 800106a: 4360 muls r0, r4 +} + 800106c: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + lcd_write_data(num_rows * 2 * LCD_WIDTH, (uint8_t *)pixels); + 8001070: f7ff bdd4 b.w 8000c1c + +08001074 : +// +// Perform simple RLE decompression, and pixel expansion. +// + void +oled_show(const uint8_t *pixels) +{ + 8001074: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8001078: f5ad 6d07 sub.w sp, sp, #2160 ; 0x870 + 800107c: af00 add r7, sp, #0 + 800107e: 4606 mov r6, r0 + oled_setup(); + 8001080: f7ff fe78 bl 8000d74 + + // we are NOT fast enough to send entire screen during the + // vblanking time, so either we show torn stuff, or we flash display off a little + wait_vsync(); + 8001084: f7ff fdfe bl 8000c84 + lcd_write_cmd(0x28); // DISPOFF + 8001088: 2028 movs r0, #40 ; 0x28 + 800108a: f7ff fe13 bl 8000cb4 + + // always full update: minus part we aren't saving "TOP_CROP" at top edge + lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x) + 800108e: f240 123f movw r2, #319 ; 0x13f + 8001092: 2100 movs r1, #0 + 8001094: 202a movs r0, #42 ; 0x2a + 8001096: f7ff fe37 bl 8000d08 + // RASET - Row address set range (y) + lcd_write_cmd4(0x2b, SCREEN_TOP_CROP, LCD_HEIGHT-1); + 800109a: 22ef movs r2, #239 ; 0xef + 800109c: 210f movs r1, #15 + 800109e: 202b movs r0, #43 ; 0x2b + 80010a0: f7ff fe32 bl 8000d08 + lcd_write_cmd(0x2c); // RAMWR - memory write + 80010a4: 202c movs r0, #44 ; 0x2c + 80010a6: f7ff fe05 bl 8000cb4 + + uint8_t buf[127]; + uint16_t expand[sizeof(buf)*8]; + const uint8_t *p = pixels; + + uint16_t blk_row[LCD_WIDTH]; + 80010aa: f5ad 7d20 sub.w sp, sp, #640 ; 0x280 + 80010ae: 46e8 mov r8, sp + *dest = value; + 80010b0: f44f 7220 mov.w r2, #640 ; 0x280 + 80010b4: 2100 movs r1, #0 + 80010b6: 4640 mov r0, r8 + 80010b8: f00c fc34 bl 800d924 + const uint8_t *p = pixels; + 80010bc: 4634 mov r4, r6 + memset2(blk_row, COL_BLACK, sizeof(blk_row)); + + while(1) { + uint8_t hdr = *(p++); + 80010be: 7823 ldrb r3, [r4, #0] + if(!hdr) break; // end marker + 80010c0: 2b00 cmp r3, #0 + 80010c2: d042 beq.n 800114a + + uint8_t len = hdr & 0x7f; + if(hdr & 0x80) { + 80010c4: 061a lsls r2, r3, #24 + uint8_t len = hdr & 0x7f; + 80010c6: f003 057f and.w r5, r3, #127 ; 0x7f + if(hdr & 0x80) { + 80010ca: d514 bpl.n 80010f6 + uint8_t hdr = *(p++); + 80010cc: 3401 adds r4, #1 + // random bytes follow + memcpy(buf, p, len); + 80010ce: 4621 mov r1, r4 + 80010d0: 462a mov r2, r5 + 80010d2: 4638 mov r0, r7 + 80010d4: f00c fc18 bl 800d908 + p += len; + 80010d8: 442c add r4, r5 + p++; + } + + // expand 'len' packed monochrome into BGR565 16-bit data: buf => expand + uint16_t *out = expand; + for(int i=0; i>= 1, out++) { + if(packed & mask) { + *out = COL_FOREGROUND; + } else { + *out = COL_BLACK; + 80010e2: f246 0cfd movw ip, #24829 ; 0x60fd + for(int i=0; i + } + } + } + lcd_write_data(len*8*2, (uint8_t *)expand); + 80010ea: f107 0180 add.w r1, r7, #128 ; 0x80 + 80010ee: 0128 lsls r0, r5, #4 + 80010f0: f7ff fd94 bl 8000c1c + 80010f4: e7e3 b.n 80010be + } else if(hdr == 0x7f) { + 80010f6: 2b7f cmp r3, #127 ; 0x7f + for(int i=0; i + for(int i=0; i + lcd_write_data(2 * LCD_WIDTH, (uint8_t *)blk_row); + 8001106: 4641 mov r1, r8 + 8001108: f44f 7020 mov.w r0, #640 ; 0x280 + 800110c: f7ff fd86 bl 8000c1c + for(int i=0; i + 8001116: e7d2 b.n 80010be + memset(buf, *p, len); + 8001118: 462a mov r2, r5 + 800111a: 4649 mov r1, r9 + 800111c: 4638 mov r0, r7 + 800111e: f00c fc01 bl 800d924 + p++; + 8001122: e7da b.n 80010da + uint8_t packed = buf[i]; + 8001124: f810 ab01 ldrb.w sl, [r0], #1 + for(uint8_t mask = 0x80; mask; mask >>= 1, out++) { + 8001128: 2180 movs r1, #128 ; 0x80 + 800112a: f103 0e10 add.w lr, r3, #16 + *out = COL_BLACK; + 800112e: ea1a 0f01 tst.w sl, r1 + 8001132: bf14 ite ne + 8001134: 46e1 movne r9, ip + 8001136: f04f 0900 moveq.w r9, #0 + 800113a: f823 9b02 strh.w r9, [r3], #2 + for(uint8_t mask = 0x80; mask; mask >>= 1, out++) { + 800113e: 4573 cmp r3, lr + 8001140: ea4f 0151 mov.w r1, r1, lsr #1 + 8001144: d1f3 bne.n 800112e + for(int i=0; i + } + + lcd_write_cmd(0x29); // DISPON + 800114a: 2029 movs r0, #41 ; 0x29 + 800114c: f7ff fdb2 bl 8000cb4 + + last_screen = pixels; + 8001150: 4b04 ldr r3, [pc, #16] ; (8001164 ) + 8001152: 601e str r6, [r3, #0] + rng_delay(); + 8001154: f001 fbd8 bl 8002908 +} + 8001158: f507 6707 add.w r7, r7, #2160 ; 0x870 + 800115c: 46bd mov sp, r7 + 800115e: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 8001162: bf00 nop + 8001164: 2009e154 .word 0x2009e154 + +08001168 : +// +// Perform simple RLE decompression, and add a bar on final screen line. +// + void +oled_show_progress(const uint8_t *pixels, int progress) +{ + 8001168: b5b0 push {r4, r5, r7, lr} + 800116a: af00 add r7, sp, #0 + 800116c: 4605 mov r5, r0 + 800116e: 460c mov r4, r1 + oled_setup(); + 8001170: f7ff fe00 bl 8000d74 + + if(last_screen != pixels) { + 8001174: 4b1d ldr r3, [pc, #116] ; (80011ec ) + 8001176: 681b ldr r3, [r3, #0] + 8001178: 42ab cmp r3, r5 + 800117a: d002 beq.n 8001182 + oled_show(pixels); + 800117c: 4628 mov r0, r5 + 800117e: f7ff ff79 bl 8001074 + } + + uint32_t p_count = LCD_WIDTH * 10 * progress / 1000; + 8001182: f44f 6148 mov.w r1, #3200 ; 0xc80 + 8001186: 4361 muls r1, r4 + 8001188: f44f 737a mov.w r3, #1000 ; 0x3e8 + 800118c: fb91 f1f3 sdiv r1, r1, r3 + if(p_count > LCD_WIDTH) p_count = LCD_WIDTH-1; + 8001190: f240 133f movw r3, #319 ; 0x13f + 8001194: f5b1 7fa0 cmp.w r1, #320 ; 0x140 + 8001198: bf88 it hi + 800119a: 4619 movhi r1, r3 + if(p_count < 0) p_count = 0; + + // draw just the progress bar + uint16_t row[LCD_WIDTH]; + 800119c: f5ad 7d20 sub.w sp, sp, #640 ; 0x280 + 80011a0: 466c mov r4, sp + memset2(row, COL_FOREGROUND, 2*p_count); + 80011a2: 004a lsls r2, r1, #1 + 80011a4: b293 uxth r3, r2 + for(; byte_len; byte_len-=2, dest++) { + 80011a6: 4620 mov r0, r4 + *dest = value; + 80011a8: f246 05fd movw r5, #24829 ; 0x60fd + for(; byte_len; byte_len-=2, dest++) { + 80011ac: b9a3 cbnz r3, 80011d8 + memset2(&row[p_count], COL_BLACK, 2*(LCD_WIDTH-p_count)); + 80011ae: f5c1 71a0 rsb r1, r1, #320 ; 0x140 + 80011b2: 4422 add r2, r4 + 80011b4: 0049 lsls r1, r1, #1 + for(; byte_len; byte_len-=2, dest++) { + 80011b6: b289 uxth r1, r1 + 80011b8: b999 cbnz r1, 80011e2 + + wait_vsync(); + 80011ba: f7ff fd63 bl 8000c84 + 80011be: 25eb movs r5, #235 ; 0xeb + + for(int i=0; i + for(int i=0; i + } + + rng_delay(); + 80011d0: f001 fb9a bl 8002908 +} + 80011d4: 46bd mov sp, r7 + 80011d6: bdb0 pop {r4, r5, r7, pc} + for(; byte_len; byte_len-=2, dest++) { + 80011d8: 3b02 subs r3, #2 + *dest = value; + 80011da: f820 5b02 strh.w r5, [r0], #2 + for(; byte_len; byte_len-=2, dest++) { + 80011de: b29b uxth r3, r3 + 80011e0: e7e4 b.n 80011ac + *dest = value; + 80011e2: f822 3b02 strh.w r3, [r2], #2 + for(; byte_len; byte_len-=2, dest++) { + 80011e6: 3902 subs r1, #2 + 80011e8: e7e5 b.n 80011b6 + 80011ea: bf00 nop + 80011ec: 2009e154 .word 0x2009e154 + +080011f0 : +// + void +oled_factory_busy(void) +{ + // not implemented: would need to talk to GPU for this +} + 80011f0: 4770 bx lr + ... + +080011f4 : + * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains + * the configuration information for the specified GPIO peripheral. + * @retval None + */ +void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) +{ + 80011f4: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + /*--------------------- EXTI Mode Configuration ------------------------*/ + /* Configure the External Interrupt or event for the current IO */ + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + { + /* Enable SYSCFG Clock */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80011f8: f8df 81b4 ldr.w r8, [pc, #436] ; 80013b0 + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + SYSCFG->EXTICR[position >> 2] = temp; + + /* Clear EXTI line configuration */ + temp = EXTI->IMR1; + 80011fc: 4c6a ldr r4, [pc, #424] ; (80013a8 ) + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 80011fe: f8df 91b4 ldr.w r9, [pc, #436] ; 80013b4 +{ + 8001202: b085 sub sp, #20 + uint32_t position = 0x00; + 8001204: 2300 movs r3, #0 + while (((GPIO_Init->Pin) >> position) != RESET) + 8001206: 680a ldr r2, [r1, #0] + 8001208: fa32 f503 lsrs.w r5, r2, r3 + 800120c: d102 bne.n 8001214 + } + } + + position++; + } +} + 800120e: b005 add sp, #20 + 8001210: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + iocurrent = (GPIO_Init->Pin) & (1U << position); + 8001214: 2701 movs r7, #1 + 8001216: 409f lsls r7, r3 + if(iocurrent) + 8001218: 403a ands r2, r7 + 800121a: f000 80b4 beq.w 8001386 + if((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) + 800121e: 684d ldr r5, [r1, #4] + 8001220: f025 0a10 bic.w sl, r5, #16 + 8001224: f1ba 0f02 cmp.w sl, #2 + 8001228: d116 bne.n 8001258 + temp = GPIOx->AFR[position >> 3]; + 800122a: ea4f 0ed3 mov.w lr, r3, lsr #3 + 800122e: eb00 0e8e add.w lr, r0, lr, lsl #2 + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 8001232: f003 0b07 and.w fp, r3, #7 + temp = GPIOx->AFR[position >> 3]; + 8001236: f8de 6020 ldr.w r6, [lr, #32] + temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 800123a: ea4f 0b8b mov.w fp, fp, lsl #2 + 800123e: f04f 0c0f mov.w ip, #15 + 8001242: fa0c fc0b lsl.w ip, ip, fp + 8001246: ea26 0c0c bic.w ip, r6, ip + temp |= ((uint32_t)(GPIO_Init->Alternate) << (((uint32_t)position & (uint32_t)0x07) * 4)); + 800124a: 690e ldr r6, [r1, #16] + 800124c: fa06 f60b lsl.w r6, r6, fp + 8001250: ea46 060c orr.w r6, r6, ip + GPIOx->AFR[position >> 3] = temp; + 8001254: f8ce 6020 str.w r6, [lr, #32] + temp = GPIOx->MODER; + 8001258: f8d0 b000 ldr.w fp, [r0] + temp &= ~(GPIO_MODER_MODE0 << (position * 2)); + 800125c: ea4f 0e43 mov.w lr, r3, lsl #1 + 8001260: f04f 0c03 mov.w ip, #3 + 8001264: fa0c fc0e lsl.w ip, ip, lr + 8001268: ea6f 060c mvn.w r6, ip + 800126c: ea2b 0b0c bic.w fp, fp, ip + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + 8001270: f005 0c03 and.w ip, r5, #3 + 8001274: fa0c fc0e lsl.w ip, ip, lr + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 8001278: f10a 3aff add.w sl, sl, #4294967295 ; 0xffffffff + temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2)); + 800127c: ea4c 0c0b orr.w ip, ip, fp + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 8001280: f1ba 0f01 cmp.w sl, #1 + temp &= ~(GPIO_MODER_MODE0 << (position * 2)); + 8001284: 9601 str r6, [sp, #4] + GPIOx->MODER = temp; + 8001286: f8c0 c000 str.w ip, [r0] + if((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) || + 800128a: d815 bhi.n 80012b8 + temp = GPIOx->OSPEEDR; + 800128c: f8d0 c008 ldr.w ip, [r0, #8] + temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2)); + 8001290: ea06 0c0c and.w ip, r6, ip + temp |= (GPIO_Init->Speed << (position * 2)); + 8001294: 68ce ldr r6, [r1, #12] + 8001296: fa06 fa0e lsl.w sl, r6, lr + 800129a: ea4a 0c0c orr.w ip, sl, ip + GPIOx->OSPEEDR = temp; + 800129e: f8c0 c008 str.w ip, [r0, #8] + temp = GPIOx->OTYPER; + 80012a2: f8d0 c004 ldr.w ip, [r0, #4] + temp &= ~(GPIO_OTYPER_OT0 << position) ; + 80012a6: ea2c 0707 bic.w r7, ip, r7 + temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4) << position); + 80012aa: f3c5 1c00 ubfx ip, r5, #4, #1 + 80012ae: fa0c fc03 lsl.w ip, ip, r3 + 80012b2: ea4c 0707 orr.w r7, ip, r7 + GPIOx->OTYPER = temp; + 80012b6: 6047 str r7, [r0, #4] + temp = GPIOx->PUPDR; + 80012b8: 68c7 ldr r7, [r0, #12] + temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2)); + 80012ba: 9e01 ldr r6, [sp, #4] + 80012bc: 4037 ands r7, r6 + temp |= ((GPIO_Init->Pull) << (position * 2)); + 80012be: 688e ldr r6, [r1, #8] + 80012c0: fa06 f60e lsl.w r6, r6, lr + 80012c4: 433e orrs r6, r7 + GPIOx->PUPDR = temp; + 80012c6: 60c6 str r6, [r0, #12] + if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE) + 80012c8: 00ee lsls r6, r5, #3 + 80012ca: d55c bpl.n 8001386 + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80012cc: f8d8 6060 ldr.w r6, [r8, #96] ; 0x60 + 80012d0: f046 0601 orr.w r6, r6, #1 + 80012d4: f8c8 6060 str.w r6, [r8, #96] ; 0x60 + 80012d8: f8d8 6060 ldr.w r6, [r8, #96] ; 0x60 + 80012dc: f023 0703 bic.w r7, r3, #3 + 80012e0: f107 4780 add.w r7, r7, #1073741824 ; 0x40000000 + 80012e4: f006 0601 and.w r6, r6, #1 + 80012e8: f507 3780 add.w r7, r7, #65536 ; 0x10000 + 80012ec: 9603 str r6, [sp, #12] + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 80012ee: f003 0c03 and.w ip, r3, #3 + __HAL_RCC_SYSCFG_CLK_ENABLE(); + 80012f2: 9e03 ldr r6, [sp, #12] + temp = SYSCFG->EXTICR[position >> 2]; + 80012f4: f8d7 a008 ldr.w sl, [r7, #8] + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 80012f8: f04f 0e0f mov.w lr, #15 + 80012fc: ea4f 0c8c mov.w ip, ip, lsl #2 + 8001300: fa0e f60c lsl.w r6, lr, ip + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 8001304: f1b0 4f90 cmp.w r0, #1207959552 ; 0x48000000 + temp &= ~(((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001308: ea2a 0e06 bic.w lr, sl, r6 + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 800130c: d03d beq.n 800138a + 800130e: 4e27 ldr r6, [pc, #156] ; (80013ac ) + 8001310: 42b0 cmp r0, r6 + 8001312: d03c beq.n 800138e + 8001314: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001318: 42b0 cmp r0, r6 + 800131a: d03a beq.n 8001392 + 800131c: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001320: 42b0 cmp r0, r6 + 8001322: d038 beq.n 8001396 + 8001324: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001328: 42b0 cmp r0, r6 + 800132a: d036 beq.n 800139a + 800132c: f506 6680 add.w r6, r6, #1024 ; 0x400 + 8001330: 42b0 cmp r0, r6 + 8001332: d034 beq.n 800139e + 8001334: 4548 cmp r0, r9 + 8001336: d034 beq.n 80013a2 + 8001338: f506 6600 add.w r6, r6, #2048 ; 0x800 + 800133c: 42b0 cmp r0, r6 + 800133e: bf0c ite eq + 8001340: 2607 moveq r6, #7 + 8001342: 2608 movne r6, #8 + 8001344: fa06 f60c lsl.w r6, r6, ip + 8001348: ea46 060e orr.w r6, r6, lr + SYSCFG->EXTICR[position >> 2] = temp; + 800134c: 60be str r6, [r7, #8] + temp = EXTI->IMR1; + 800134e: 6826 ldr r6, [r4, #0] + temp &= ~((uint32_t)iocurrent); + 8001350: 43d7 mvns r7, r2 + if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT) + 8001352: f415 3f80 tst.w r5, #65536 ; 0x10000 + temp &= ~((uint32_t)iocurrent); + 8001356: bf0c ite eq + 8001358: 403e andeq r6, r7 + temp |= iocurrent; + 800135a: 4316 orrne r6, r2 + EXTI->IMR1 = temp; + 800135c: 6026 str r6, [r4, #0] + temp = EXTI->EMR1; + 800135e: 6866 ldr r6, [r4, #4] + if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT) + 8001360: f415 3f00 tst.w r5, #131072 ; 0x20000 + temp &= ~((uint32_t)iocurrent); + 8001364: bf0c ite eq + 8001366: 403e andeq r6, r7 + temp |= iocurrent; + 8001368: 4316 orrne r6, r2 + EXTI->EMR1 = temp; + 800136a: 6066 str r6, [r4, #4] + temp = EXTI->RTSR1; + 800136c: 68a6 ldr r6, [r4, #8] + if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE) + 800136e: f415 1f80 tst.w r5, #1048576 ; 0x100000 + temp &= ~((uint32_t)iocurrent); + 8001372: bf0c ite eq + 8001374: 403e andeq r6, r7 + temp |= iocurrent; + 8001376: 4316 orrne r6, r2 + EXTI->RTSR1 = temp; + 8001378: 60a6 str r6, [r4, #8] + temp = EXTI->FTSR1; + 800137a: 68e6 ldr r6, [r4, #12] + if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE) + 800137c: 02ad lsls r5, r5, #10 + temp &= ~((uint32_t)iocurrent); + 800137e: bf54 ite pl + 8001380: 403e andpl r6, r7 + temp |= iocurrent; + 8001382: 4316 orrmi r6, r2 + EXTI->FTSR1 = temp; + 8001384: 60e6 str r6, [r4, #12] + position++; + 8001386: 3301 adds r3, #1 + 8001388: e73d b.n 8001206 + temp |= (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))); + 800138a: 2600 movs r6, #0 + 800138c: e7da b.n 8001344 + 800138e: 2601 movs r6, #1 + 8001390: e7d8 b.n 8001344 + 8001392: 2602 movs r6, #2 + 8001394: e7d6 b.n 8001344 + 8001396: 2603 movs r6, #3 + 8001398: e7d4 b.n 8001344 + 800139a: 2604 movs r6, #4 + 800139c: e7d2 b.n 8001344 + 800139e: 2605 movs r6, #5 + 80013a0: e7d0 b.n 8001344 + 80013a2: 2606 movs r6, #6 + 80013a4: e7ce b.n 8001344 + 80013a6: bf00 nop + 80013a8: 40010400 .word 0x40010400 + 80013ac: 48000400 .word 0x48000400 + 80013b0: 40021000 .word 0x40021000 + 80013b4: 48001800 .word 0x48001800 + +080013b8 : + * @param GPIO_Pin: specifies the port bit to be written. + * This parameter can be one of GPIO_PIN_x where x can be (0..15). + * @retval None + */ +void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) +{ + 80013b8: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + { + tmp = ((uint32_t)0x0F) << (4 * (position & 0x03)); + SYSCFG->EXTICR[position >> 2] &= ~tmp; + + /* Clear EXTI line configuration */ + EXTI->IMR1 &= ~((uint32_t)iocurrent); + 80013bc: 4c43 ldr r4, [pc, #268] ; (80014cc ) + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 80013be: f8df a114 ldr.w sl, [pc, #276] ; 80014d4 + 80013c2: f8df b114 ldr.w fp, [pc, #276] ; 80014d8 + uint32_t position = 0x00; + 80013c6: 2200 movs r2, #0 + iocurrent = (GPIO_Pin) & (1U << position); + 80013c8: f04f 0901 mov.w r9, #1 + while ((GPIO_Pin >> position) != RESET) + 80013cc: fa31 f302 lsrs.w r3, r1, r2 + 80013d0: d101 bne.n 80013d6 + } + } + + position++; + } +} + 80013d2: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + iocurrent = (GPIO_Pin) & (1U << position); + 80013d6: fa09 f802 lsl.w r8, r9, r2 + if (iocurrent) + 80013da: ea18 0c01 ands.w ip, r8, r1 + 80013de: d064 beq.n 80014aa + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2)); + 80013e0: 6805 ldr r5, [r0, #0] + 80013e2: 2303 movs r3, #3 + 80013e4: 0056 lsls r6, r2, #1 + 80013e6: fa03 f606 lsl.w r6, r3, r6 + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 80013ea: fa22 fe03 lsr.w lr, r2, r3 + GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2)); + 80013ee: 4335 orrs r5, r6 + 80013f0: eb00 0e8e add.w lr, r0, lr, lsl #2 + 80013f4: 6005 str r5, [r0, #0] + GPIOx->AFR[position >> 3] &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ; + 80013f6: f8de 5020 ldr.w r5, [lr, #32] + 80013fa: f002 0707 and.w r7, r2, #7 + 80013fe: 462b mov r3, r5 + 8001400: 00bf lsls r7, r7, #2 + 8001402: 250f movs r5, #15 + 8001404: fa05 f707 lsl.w r7, r5, r7 + 8001408: ea23 0707 bic.w r7, r3, r7 + 800140c: f8ce 7020 str.w r7, [lr, #32] + GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2)); + 8001410: 6887 ldr r7, [r0, #8] + 8001412: ea27 0706 bic.w r7, r7, r6 + 8001416: 6087 str r7, [r0, #8] + GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ; + 8001418: 6847 ldr r7, [r0, #4] + 800141a: ea27 0708 bic.w r7, r7, r8 + 800141e: 6047 str r7, [r0, #4] + GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2)); + 8001420: 68c7 ldr r7, [r0, #12] + 8001422: ea27 0606 bic.w r6, r7, r6 + 8001426: 60c6 str r6, [r0, #12] + tmp = SYSCFG->EXTICR[position >> 2]; + 8001428: f022 0603 bic.w r6, r2, #3 + 800142c: f106 4680 add.w r6, r6, #1073741824 ; 0x40000000 + 8001430: f506 3680 add.w r6, r6, #65536 ; 0x10000 + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001434: f002 0703 and.w r7, r2, #3 + tmp = SYSCFG->EXTICR[position >> 2]; + 8001438: f8d6 e008 ldr.w lr, [r6, #8] + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 800143c: 00bf lsls r7, r7, #2 + 800143e: 40bd lsls r5, r7 + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 8001440: f1b0 4f90 cmp.w r0, #1207959552 ; 0x48000000 + tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03))); + 8001444: ea05 0e0e and.w lr, r5, lr + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 8001448: d031 beq.n 80014ae + 800144a: 4b21 ldr r3, [pc, #132] ; (80014d0 ) + 800144c: 4298 cmp r0, r3 + 800144e: d030 beq.n 80014b2 + 8001450: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001454: 4298 cmp r0, r3 + 8001456: d02e beq.n 80014b6 + 8001458: f503 6380 add.w r3, r3, #1024 ; 0x400 + 800145c: 4298 cmp r0, r3 + 800145e: d02c beq.n 80014ba + 8001460: f503 6380 add.w r3, r3, #1024 ; 0x400 + 8001464: 4298 cmp r0, r3 + 8001466: d02a beq.n 80014be + 8001468: f503 6380 add.w r3, r3, #1024 ; 0x400 + 800146c: 4298 cmp r0, r3 + 800146e: d028 beq.n 80014c2 + 8001470: 4550 cmp r0, sl + 8001472: d028 beq.n 80014c6 + 8001474: 4558 cmp r0, fp + 8001476: bf0c ite eq + 8001478: 2307 moveq r3, #7 + 800147a: 2308 movne r3, #8 + 800147c: 40bb lsls r3, r7 + 800147e: 4573 cmp r3, lr + 8001480: d113 bne.n 80014aa + SYSCFG->EXTICR[position >> 2] &= ~tmp; + 8001482: 68b3 ldr r3, [r6, #8] + 8001484: ea23 0505 bic.w r5, r3, r5 + 8001488: 60b5 str r5, [r6, #8] + EXTI->IMR1 &= ~((uint32_t)iocurrent); + 800148a: 6823 ldr r3, [r4, #0] + 800148c: ea23 030c bic.w r3, r3, ip + 8001490: 6023 str r3, [r4, #0] + EXTI->EMR1 &= ~((uint32_t)iocurrent); + 8001492: 6863 ldr r3, [r4, #4] + 8001494: ea23 030c bic.w r3, r3, ip + 8001498: 6063 str r3, [r4, #4] + EXTI->RTSR1 &= ~((uint32_t)iocurrent); + 800149a: 68a3 ldr r3, [r4, #8] + 800149c: ea23 030c bic.w r3, r3, ip + 80014a0: 60a3 str r3, [r4, #8] + EXTI->FTSR1 &= ~((uint32_t)iocurrent); + 80014a2: 68e3 ldr r3, [r4, #12] + 80014a4: ea23 030c bic.w r3, r3, ip + 80014a8: 60e3 str r3, [r4, #12] + position++; + 80014aa: 3201 adds r2, #1 + 80014ac: e78e b.n 80013cc + if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03)))) + 80014ae: 2300 movs r3, #0 + 80014b0: e7e4 b.n 800147c + 80014b2: 2301 movs r3, #1 + 80014b4: e7e2 b.n 800147c + 80014b6: 2302 movs r3, #2 + 80014b8: e7e0 b.n 800147c + 80014ba: 2303 movs r3, #3 + 80014bc: e7de b.n 800147c + 80014be: 2304 movs r3, #4 + 80014c0: e7dc b.n 800147c + 80014c2: 2305 movs r3, #5 + 80014c4: e7da b.n 800147c + 80014c6: 2306 movs r3, #6 + 80014c8: e7d8 b.n 800147c + 80014ca: bf00 nop + 80014cc: 40010400 .word 0x40010400 + 80014d0: 48000400 .word 0x48000400 + 80014d4: 48001800 .word 0x48001800 + 80014d8: 48001c00 .word 0x48001c00 + +080014dc : + GPIO_PinState bitstatus; + + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + if((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET) + 80014dc: 6903 ldr r3, [r0, #16] + 80014de: 4219 tst r1, r3 + else + { + bitstatus = GPIO_PIN_RESET; + } + return bitstatus; +} + 80014e0: bf14 ite ne + 80014e2: 2001 movne r0, #1 + 80014e4: 2000 moveq r0, #0 + 80014e6: 4770 bx lr + +080014e8 : +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + assert_param(IS_GPIO_PIN_ACTION(PinState)); + + if(PinState != GPIO_PIN_RESET) + 80014e8: b10a cbz r2, 80014ee + { + GPIOx->BSRR = (uint32_t)GPIO_Pin; + 80014ea: 6181 str r1, [r0, #24] + 80014ec: 4770 bx lr + } + else + { + GPIOx->BRR = (uint32_t)GPIO_Pin; + 80014ee: 6281 str r1, [r0, #40] ; 0x28 + } +} + 80014f0: 4770 bx lr + +080014f2 : +void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + /* Check the parameters */ + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + GPIOx->ODR ^= GPIO_Pin; + 80014f2: 6943 ldr r3, [r0, #20] + 80014f4: 4059 eors r1, r3 + 80014f6: 6141 str r1, [r0, #20] +} + 80014f8: 4770 bx lr + +080014fa : + * @param GPIO_Pin: specifies the port bits to be locked. + * This parameter can be any combination of GPIO_Pin_x where x can be (0..15). + * @retval None + */ +HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) +{ + 80014fa: b082 sub sp, #8 + __IO uint32_t tmp = GPIO_LCKR_LCKK; + 80014fc: f44f 3380 mov.w r3, #65536 ; 0x10000 + 8001500: 9301 str r3, [sp, #4] + /* Check the parameters */ + assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); + assert_param(IS_GPIO_PIN(GPIO_Pin)); + + /* Apply lock key write sequence */ + tmp |= GPIO_Pin; + 8001502: 9b01 ldr r3, [sp, #4] + 8001504: 430b orrs r3, r1 + 8001506: 9301 str r3, [sp, #4] + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + 8001508: 9b01 ldr r3, [sp, #4] + 800150a: 61c3 str r3, [r0, #28] + /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ + GPIOx->LCKR = GPIO_Pin; + 800150c: 61c1 str r1, [r0, #28] + /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ + GPIOx->LCKR = tmp; + 800150e: 9b01 ldr r3, [sp, #4] + 8001510: 61c3 str r3, [r0, #28] + /* Read LCKK bit*/ + tmp = GPIOx->LCKR; + 8001512: 69c3 ldr r3, [r0, #28] + 8001514: 9301 str r3, [sp, #4] + + if((GPIOx->LCKR & GPIO_LCKR_LCKK) != RESET) + 8001516: 69c0 ldr r0, [r0, #28] + 8001518: f480 3080 eor.w r0, r0, #65536 ; 0x10000 + } + else + { + return HAL_ERROR; + } +} + 800151c: f3c0 4000 ubfx r0, r0, #16, #1 + 8001520: b002 add sp, #8 + 8001522: 4770 bx lr + +08001524 : + UNUSED(GPIO_Pin); + + /* NOTE: This function should not be modified, when the callback is needed, + the HAL_GPIO_EXTI_Callback could be implemented in the user file + */ +} + 8001524: 4770 bx lr + ... + +08001528 : + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + 8001528: 4a04 ldr r2, [pc, #16] ; (800153c ) + 800152a: 6951 ldr r1, [r2, #20] + 800152c: 4201 tst r1, r0 +{ + 800152e: b508 push {r3, lr} + if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) + 8001530: d002 beq.n 8001538 + __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); + 8001532: 6150 str r0, [r2, #20] + HAL_GPIO_EXTI_Callback(GPIO_Pin); + 8001534: f7ff fff6 bl 8001524 +} + 8001538: bd08 pop {r3, pc} + 800153a: bf00 nop + 800153c: 40010400 .word 0x40010400 + +08001540 : +static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, uint32_t State, + uint32_t Timeout, uint32_t Tickstart) +{ + __IO uint8_t tmpreg; + + while ((hspi->Instance->SR & Fifo) != State) + 8001540: 6803 ldr r3, [r0, #0] +static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) + 8001542: b082 sub sp, #8 + while ((hspi->Instance->SR & Fifo) != State) + 8001544: 689a ldr r2, [r3, #8] + 8001546: f412 5fc0 tst.w r2, #6144 ; 0x1800 + 800154a: d1fb bne.n 8001544 + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, + uint32_t Timeout, uint32_t Tickstart) +{ + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 800154c: 689a ldr r2, [r3, #8] + 800154e: 0612 lsls r2, r2, #24 + 8001550: d4fc bmi.n 800154c + while ((hspi->Instance->SR & Fifo) != State) + 8001552: 6898 ldr r0, [r3, #8] + 8001554: f410 60c0 ands.w r0, r0, #1536 ; 0x600 + 8001558: d101 bne.n 800155e +} + 800155a: b002 add sp, #8 + 800155c: 4770 bx lr + tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); + 800155e: 7b1a ldrb r2, [r3, #12] + 8001560: b2d2 uxtb r2, r2 + 8001562: f88d 2007 strb.w r2, [sp, #7] + UNUSED(tmpreg); + 8001566: f89d 2007 ldrb.w r2, [sp, #7] + 800156a: e7f2 b.n 8001552 + +0800156c : +{ + 800156c: b5f0 push {r4, r5, r6, r7, lr} + if (hspi == NULL) + 800156e: 2800 cmp r0, #0 + 8001570: d054 beq.n 800161c + if (hspi->State == HAL_SPI_STATE_RESET) + 8001572: f890 305d ldrb.w r3, [r0, #93] ; 0x5d + if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) + 8001576: f8d0 c024 ldr.w ip, [r0, #36] ; 0x24 + if (hspi->State == HAL_SPI_STATE_RESET) + 800157a: f003 02ff and.w r2, r3, #255 ; 0xff + 800157e: b90b cbnz r3, 8001584 + hspi->Lock = HAL_UNLOCKED; + 8001580: f880 205c strb.w r2, [r0, #92] ; 0x5c + __HAL_SPI_DISABLE(hspi); + 8001584: 6801 ldr r1, [r0, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 8001586: 68c2 ldr r2, [r0, #12] + hspi->State = HAL_SPI_STATE_BUSY; + 8001588: 2302 movs r3, #2 + 800158a: f880 305d strb.w r3, [r0, #93] ; 0x5d + __HAL_SPI_DISABLE(hspi); + 800158e: 680b ldr r3, [r1, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 8001590: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + __HAL_SPI_DISABLE(hspi); + 8001594: f023 0340 bic.w r3, r3, #64 ; 0x40 + 8001598: 600b str r3, [r1, #0] + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 800159a: f04f 0300 mov.w r3, #0 + 800159e: d83f bhi.n 8001620 + frxth = SPI_RXFIFO_THRESHOLD_QF; + 80015a0: f44f 5580 mov.w r5, #4096 ; 0x1000 + if ((hspi->Init.DataSize != SPI_DATASIZE_16BIT) && (hspi->Init.DataSize != SPI_DATASIZE_8BIT)) + 80015a4: d000 beq.n 80015a8 + hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + 80015a6: 6283 str r3, [r0, #40] ; 0x28 + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE) + 80015a8: 6b03 ldr r3, [r0, #48] ; 0x30 + 80015aa: b92b cbnz r3, 80015b8 + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 80015ac: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + hspi->Init.CRCLength = SPI_CRC_LENGTH_16BIT; + 80015b0: bf8c ite hi + 80015b2: 2302 movhi r3, #2 + hspi->Init.CRCLength = SPI_CRC_LENGTH_8BIT; + 80015b4: 2301 movls r3, #1 + 80015b6: 6303 str r3, [r0, #48] ; 0x30 + WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | + 80015b8: e9d0 3701 ldrd r3, r7, [r0, #4] + 80015bc: 433b orrs r3, r7 + 80015be: 6907 ldr r7, [r0, #16] + 80015c0: 6984 ldr r4, [r0, #24] + 80015c2: 6a86 ldr r6, [r0, #40] ; 0x28 + 80015c4: 433b orrs r3, r7 + 80015c6: 6947 ldr r7, [r0, #20] + 80015c8: 433b orrs r3, r7 + 80015ca: 69c7 ldr r7, [r0, #28] + 80015cc: 433b orrs r3, r7 + 80015ce: 6a07 ldr r7, [r0, #32] + 80015d0: 433b orrs r3, r7 + 80015d2: 4333 orrs r3, r6 + 80015d4: f404 7700 and.w r7, r4, #512 ; 0x200 + 80015d8: 433b orrs r3, r7 + 80015da: 600b str r3, [r1, #0] + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + 80015dc: 6b03 ldr r3, [r0, #48] ; 0x30 + 80015de: 2b02 cmp r3, #2 + hspi->Instance->CR1 |= SPI_CR1_CRCL; + 80015e0: bf02 ittt eq + 80015e2: 680b ldreq r3, [r1, #0] + 80015e4: f443 6300 orreq.w r3, r3, #2048 ; 0x800 + 80015e8: 600b streq r3, [r1, #0] + WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode | + 80015ea: 6b43 ldr r3, [r0, #52] ; 0x34 + 80015ec: ea4c 0202 orr.w r2, ip, r2 + 80015f0: 0c24 lsrs r4, r4, #16 + 80015f2: 431a orrs r2, r3 + 80015f4: f004 0404 and.w r4, r4, #4 + 80015f8: 4322 orrs r2, r4 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80015fa: f5b6 5f00 cmp.w r6, #8192 ; 0x2000 + WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial); + 80015fe: bf08 it eq + 8001600: 6ac3 ldreq r3, [r0, #44] ; 0x2c + WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode | + 8001602: ea45 0502 orr.w r5, r5, r2 + 8001606: 604d str r5, [r1, #4] + hspi->State = HAL_SPI_STATE_READY; + 8001608: f04f 0201 mov.w r2, #1 + WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial); + 800160c: bf08 it eq + 800160e: 610b streq r3, [r1, #16] + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001610: 2300 movs r3, #0 + 8001612: 6603 str r3, [r0, #96] ; 0x60 + hspi->State = HAL_SPI_STATE_READY; + 8001614: f880 205d strb.w r2, [r0, #93] ; 0x5d + return HAL_OK; + 8001618: 4618 mov r0, r3 +} + 800161a: bdf0 pop {r4, r5, r6, r7, pc} + return HAL_ERROR; + 800161c: 2001 movs r0, #1 + 800161e: e7fc b.n 800161a + frxth = SPI_RXFIFO_THRESHOLD_HF; + 8001620: 461d mov r5, r3 + if ((hspi->Init.DataSize != SPI_DATASIZE_16BIT) && (hspi->Init.DataSize != SPI_DATASIZE_8BIT)) + 8001622: f5b2 6f70 cmp.w r2, #3840 ; 0xf00 + 8001626: e7bd b.n 80015a4 + +08001628 : +{ + 8001628: e92d 41f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, lr} + 800162c: 461e mov r6, r3 + __HAL_LOCK(hspi); + 800162e: f890 305c ldrb.w r3, [r0, #92] ; 0x5c + 8001632: 2b01 cmp r3, #1 +{ + 8001634: 4604 mov r4, r0 + 8001636: 460d mov r5, r1 + 8001638: 4690 mov r8, r2 + __HAL_LOCK(hspi); + 800163a: f000 809c beq.w 8001776 + 800163e: 2301 movs r3, #1 + 8001640: f880 305c strb.w r3, [r0, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8001644: f005 feca bl 80073dc + if (hspi->State != HAL_SPI_STATE_READY) + 8001648: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + 800164c: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 800164e: 4607 mov r7, r0 + if (hspi->State != HAL_SPI_STATE_READY) + 8001650: b2d8 uxtb r0, r3 + 8001652: f040 808e bne.w 8001772 + if ((pData == NULL) || (Size == 0U)) + 8001656: 2d00 cmp r5, #0 + 8001658: d07a beq.n 8001750 + 800165a: f1b8 0f00 cmp.w r8, #0 + 800165e: d077 beq.n 8001750 + hspi->State = HAL_SPI_STATE_BUSY_TX; + 8001660: 2303 movs r3, #3 + 8001662: f884 305d strb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001666: 68a3 ldr r3, [r4, #8] + SPI_1LINE_TX(hspi); + 8001668: 6822 ldr r2, [r4, #0] + hspi->pTxBuffPtr = (uint8_t *)pData; + 800166a: 63a5 str r5, [r4, #56] ; 0x38 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 800166c: 2100 movs r1, #0 + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 800166e: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001672: 6621 str r1, [r4, #96] ; 0x60 + hspi->TxXferCount = Size; + 8001674: f8a4 803e strh.w r8, [r4, #62] ; 0x3e + hspi->RxXferCount = 0U; + 8001678: f8a4 1046 strh.w r1, [r4, #70] ; 0x46 + SPI_1LINE_TX(hspi); + 800167c: bf08 it eq + 800167e: 6813 ldreq r3, [r2, #0] + hspi->TxXferSize = Size; + 8001680: f8a4 803c strh.w r8, [r4, #60] ; 0x3c + SPI_1LINE_TX(hspi); + 8001684: bf08 it eq + 8001686: f443 4380 orreq.w r3, r3, #16384 ; 0x4000 + hspi->RxISR = NULL; + 800168a: e9c4 1113 strd r1, r1, [r4, #76] ; 0x4c + hspi->pRxBuffPtr = (uint8_t *)NULL; + 800168e: 6421 str r1, [r4, #64] ; 0x40 + hspi->RxXferSize = 0U; + 8001690: f8a4 1044 strh.w r1, [r4, #68] ; 0x44 + SPI_1LINE_TX(hspi); + 8001694: bf08 it eq + 8001696: 6013 streq r3, [r2, #0] + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001698: 6aa3 ldr r3, [r4, #40] ; 0x28 + 800169a: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 800169e: d107 bne.n 80016b0 + SPI_RESET_CRC(hspi); + 80016a0: 6813 ldr r3, [r2, #0] + 80016a2: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 80016a6: 6013 str r3, [r2, #0] + 80016a8: 6813 ldr r3, [r2, #0] + 80016aa: f443 5300 orr.w r3, r3, #8192 ; 0x2000 + 80016ae: 6013 str r3, [r2, #0] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 80016b0: 6813 ldr r3, [r2, #0] + 80016b2: 0659 lsls r1, r3, #25 + __HAL_SPI_ENABLE(hspi); + 80016b4: bf5e ittt pl + 80016b6: 6813 ldrpl r3, [r2, #0] + 80016b8: f043 0340 orrpl.w r3, r3, #64 ; 0x40 + 80016bc: 6013 strpl r3, [r2, #0] + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) + 80016be: 6863 ldr r3, [r4, #4] + 80016c0: b11b cbz r3, 80016ca + 80016c2: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80016c4: b29b uxth r3, r3 + 80016c6: 2b01 cmp r3, #1 + 80016c8: d110 bne.n 80016ec + if (hspi->TxXferCount > 1U) + 80016ca: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80016cc: b29b uxth r3, r3 + 80016ce: 2b01 cmp r3, #1 + 80016d0: d905 bls.n 80016de + hspi->Instance->DR = *((uint16_t *)pData); + 80016d2: f835 3b02 ldrh.w r3, [r5], #2 + 80016d6: 60d3 str r3, [r2, #12] + hspi->TxXferCount -= 2U; + 80016d8: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80016da: 3b02 subs r3, #2 + 80016dc: e004 b.n 80016e8 + *((__IO uint8_t *)&hspi->Instance->DR) = (*pData++); + 80016de: f815 3b01 ldrb.w r3, [r5], #1 + 80016e2: 7313 strb r3, [r2, #12] + hspi->TxXferCount--; + 80016e4: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80016e6: 3b01 subs r3, #1 + 80016e8: b29b uxth r3, r3 + 80016ea: 87e3 strh r3, [r4, #62] ; 0x3e + while (hspi->TxXferCount > 0U) + 80016ec: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80016ee: b29b uxth r3, r3 + 80016f0: b9e3 cbnz r3, 800172c + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80016f2: 6aa3 ldr r3, [r4, #40] ; 0x28 + 80016f4: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 80016f8: bf01 itttt eq + 80016fa: 6822 ldreq r2, [r4, #0] + 80016fc: 6813 ldreq r3, [r2, #0] + 80016fe: f443 5380 orreq.w r3, r3, #4096 ; 0x1000 + 8001702: 6013 streq r3, [r2, #0] + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + 8001704: 4620 mov r0, r4 + 8001706: f7ff ff1b bl 8001540 + 800170a: b108 cbz r0, 8001710 + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + 800170c: 2320 movs r3, #32 + 800170e: 6623 str r3, [r4, #96] ; 0x60 + if (hspi->Init.Direction == SPI_DIRECTION_2LINES) + 8001710: 68a3 ldr r3, [r4, #8] + 8001712: b933 cbnz r3, 8001722 + __HAL_SPI_CLEAR_OVRFLAG(hspi); + 8001714: 9301 str r3, [sp, #4] + 8001716: 6823 ldr r3, [r4, #0] + 8001718: 68da ldr r2, [r3, #12] + 800171a: 9201 str r2, [sp, #4] + 800171c: 689b ldr r3, [r3, #8] + 800171e: 9301 str r3, [sp, #4] + 8001720: 9b01 ldr r3, [sp, #4] + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 8001722: 6e20 ldr r0, [r4, #96] ; 0x60 + errorcode = HAL_BUSY; + 8001724: 3800 subs r0, #0 + 8001726: bf18 it ne + 8001728: 2001 movne r0, #1 +error: + 800172a: e011 b.n 8001750 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) + 800172c: 6823 ldr r3, [r4, #0] + 800172e: 689a ldr r2, [r3, #8] + 8001730: 0792 lsls r2, r2, #30 + 8001732: d50b bpl.n 800174c + if (hspi->TxXferCount > 1U) + 8001734: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001736: b292 uxth r2, r2 + 8001738: 2a01 cmp r2, #1 + 800173a: d903 bls.n 8001744 + hspi->Instance->DR = *((uint16_t *)pData); + 800173c: f835 2b02 ldrh.w r2, [r5], #2 + 8001740: 60da str r2, [r3, #12] + 8001742: e7c9 b.n 80016d8 + *((__IO uint8_t *)&hspi->Instance->DR) = (*pData++); + 8001744: f815 2b01 ldrb.w r2, [r5], #1 + 8001748: 731a strb r2, [r3, #12] + hspi->TxXferCount--; + 800174a: e7cb b.n 80016e4 + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 800174c: b94e cbnz r6, 8001762 + errorcode = HAL_TIMEOUT; + 800174e: 2003 movs r0, #3 + hspi->State = HAL_SPI_STATE_READY; + 8001750: 2301 movs r3, #1 + 8001752: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 8001756: 2300 movs r3, #0 + 8001758: f884 305c strb.w r3, [r4, #92] ; 0x5c +} + 800175c: b002 add sp, #8 + 800175e: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 8001762: 1c73 adds r3, r6, #1 + 8001764: d0c2 beq.n 80016ec + 8001766: f005 fe39 bl 80073dc + 800176a: 1bc0 subs r0, r0, r7 + 800176c: 42b0 cmp r0, r6 + 800176e: d3bd bcc.n 80016ec + 8001770: e7ed b.n 800174e + errorcode = HAL_BUSY; + 8001772: 2002 movs r0, #2 + 8001774: e7ec b.n 8001750 + __HAL_LOCK(hspi); + 8001776: 2002 movs r0, #2 + 8001778: e7f0 b.n 800175c + +0800177a : + * @param Timeout: Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, + uint32_t Timeout) +{ + 800177a: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + 800177e: 461e mov r6, r3 + uint32_t tmp = 0U, tmp1 = 0U; +#if (USE_SPI_CRC != 0U) + __IO uint16_t tmpreg = 0U; + 8001780: 2300 movs r3, #0 + 8001782: f8ad 3006 strh.w r3, [sp, #6] + + /* Check Direction parameter */ + assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); + + /* Process Locked */ + __HAL_LOCK(hspi); + 8001786: f890 305c ldrb.w r3, [r0, #92] ; 0x5c +{ + 800178a: f8dd 8028 ldr.w r8, [sp, #40] ; 0x28 + __HAL_LOCK(hspi); + 800178e: 2b01 cmp r3, #1 +{ + 8001790: 4604 mov r4, r0 + 8001792: 460d mov r5, r1 + 8001794: 4617 mov r7, r2 + __HAL_LOCK(hspi); + 8001796: f000 8124 beq.w 80019e2 + 800179a: 2301 movs r3, #1 + 800179c: f880 305c strb.w r3, [r0, #92] ; 0x5c + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + 80017a0: f005 fe1c bl 80073dc + + tmp = hspi->State; + 80017a4: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + tmp1 = hspi->Init.Mode; + 80017a8: 6861 ldr r1, [r4, #4] + + if (!((tmp == HAL_SPI_STATE_READY) || \ + 80017aa: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 80017ac: 4681 mov r9, r0 + tmp = hspi->State; + 80017ae: b2da uxtb r2, r3 + if (!((tmp == HAL_SPI_STATE_READY) || \ + 80017b0: d00a beq.n 80017c8 + 80017b2: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 80017b6: f040 8112 bne.w 80019de + ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX)))) + 80017ba: 68a3 ldr r3, [r4, #8] + 80017bc: 2b00 cmp r3, #0 + 80017be: f040 810e bne.w 80019de + 80017c2: 2a04 cmp r2, #4 + 80017c4: f040 810b bne.w 80019de + { + errorcode = HAL_BUSY; + goto error; + } + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + 80017c8: b955 cbnz r5, 80017e0 + { + errorcode = HAL_ERROR; + 80017ca: 2101 movs r1, #1 + { + errorcode = HAL_ERROR; + } + +error : + hspi->State = HAL_SPI_STATE_READY; + 80017cc: 2301 movs r3, #1 + 80017ce: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 80017d2: 2300 movs r3, #0 + 80017d4: f884 305c strb.w r3, [r4, #92] ; 0x5c + return errorcode; +} + 80017d8: 4608 mov r0, r1 + 80017da: b003 add sp, #12 + 80017dc: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) + 80017e0: 2f00 cmp r7, #0 + 80017e2: d0f2 beq.n 80017ca + 80017e4: 2e00 cmp r6, #0 + 80017e6: d0f0 beq.n 80017ca + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + 80017e8: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80017ec: 6aa2 ldr r2, [r4, #40] ; 0x28 + hspi->pRxBuffPtr = (uint8_t *)pRxData; + 80017ee: 6427 str r7, [r4, #64] ; 0x40 + if (hspi->State != HAL_SPI_STATE_BUSY_RX) + 80017f0: 2b04 cmp r3, #4 + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + 80017f2: bf1c itt ne + 80017f4: 2305 movne r3, #5 + 80017f6: f884 305d strbne.w r3, [r4, #93] ; 0x5d + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 80017fa: 2300 movs r3, #0 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 80017fc: f5b2 5f00 cmp.w r2, #8192 ; 0x2000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001800: 6623 str r3, [r4, #96] ; 0x60 + hspi->TxISR = NULL; + 8001802: e9c4 3313 strd r3, r3, [r4, #76] ; 0x4c + hspi->RxXferCount = Size; + 8001806: f8a4 6046 strh.w r6, [r4, #70] ; 0x46 + SPI_RESET_CRC(hspi); + 800180a: 6823 ldr r3, [r4, #0] + hspi->RxXferSize = Size; + 800180c: f8a4 6044 strh.w r6, [r4, #68] ; 0x44 + hspi->pTxBuffPtr = (uint8_t *)pTxData; + 8001810: 63a5 str r5, [r4, #56] ; 0x38 + hspi->TxXferCount = Size; + 8001812: 87e6 strh r6, [r4, #62] ; 0x3e + hspi->TxXferSize = Size; + 8001814: 87a6 strh r6, [r4, #60] ; 0x3c + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001816: d107 bne.n 8001828 + SPI_RESET_CRC(hspi); + 8001818: 681a ldr r2, [r3, #0] + 800181a: f422 5200 bic.w r2, r2, #8192 ; 0x2000 + 800181e: 601a str r2, [r3, #0] + 8001820: 681a ldr r2, [r3, #0] + 8001822: f442 5200 orr.w r2, r2, #8192 ; 0x2000 + 8001826: 601a str r2, [r3, #0] + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount > 1U)) + 8001828: 68e2 ldr r2, [r4, #12] + 800182a: f5b2 6fe0 cmp.w r2, #1792 ; 0x700 + 800182e: d804 bhi.n 800183a + 8001830: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001834: b292 uxth r2, r2 + 8001836: 2a01 cmp r2, #1 + 8001838: d94e bls.n 80018d8 + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 800183a: 685a ldr r2, [r3, #4] + 800183c: f422 5280 bic.w r2, r2, #4096 ; 0x1000 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 8001840: 605a str r2, [r3, #4] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 8001842: 681a ldr r2, [r3, #0] + 8001844: 0650 lsls r0, r2, #25 + __HAL_SPI_ENABLE(hspi); + 8001846: bf5e ittt pl + 8001848: 681a ldrpl r2, [r3, #0] + 800184a: f042 0240 orrpl.w r2, r2, #64 ; 0x40 + 800184e: 601a strpl r2, [r3, #0] + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) + 8001850: b119 cbz r1, 800185a + 8001852: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001854: b292 uxth r2, r2 + 8001856: 2a01 cmp r2, #1 + 8001858: d10a bne.n 8001870 + if (hspi->TxXferCount > 1U) + 800185a: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 800185c: b292 uxth r2, r2 + 800185e: 2a01 cmp r2, #1 + 8001860: d93e bls.n 80018e0 + hspi->Instance->DR = *((uint16_t *)pTxData); + 8001862: f835 2b02 ldrh.w r2, [r5], #2 + 8001866: 60da str r2, [r3, #12] + hspi->TxXferCount -= 2U; + 8001868: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 800186a: 3b02 subs r3, #2 + 800186c: b29b uxth r3, r3 + 800186e: 87e3 strh r3, [r4, #62] ; 0x3e + txallowed = 1U; + 8001870: 2601 movs r6, #1 + while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) + 8001872: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 8001874: b29b uxth r3, r3 + 8001876: 2b00 cmp r3, #0 + 8001878: d138 bne.n 80018ec + 800187a: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 800187e: b29b uxth r3, r3 + 8001880: 2b00 cmp r3, #0 + 8001882: d133 bne.n 80018ec + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001884: 6aa2 ldr r2, [r4, #40] ; 0x28 + if (txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) + 8001886: 6823 ldr r3, [r4, #0] + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001888: f5b2 5f00 cmp.w r2, #8192 ; 0x2000 + 800188c: d10d bne.n 80018aa + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 800188e: 689a ldr r2, [r3, #8] + 8001890: 07d1 lsls r1, r2, #31 + 8001892: d5fc bpl.n 800188e + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + 8001894: 68e2 ldr r2, [r4, #12] + 8001896: f5b2 6f70 cmp.w r2, #3840 ; 0xf00 + 800189a: f040 8092 bne.w 80019c2 + tmpreg = hspi->Instance->DR; + 800189e: 68da ldr r2, [r3, #12] + 80018a0: b292 uxth r2, r2 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80018a2: f8ad 2006 strh.w r2, [sp, #6] + UNUSED(tmpreg); + 80018a6: f8bd 2006 ldrh.w r2, [sp, #6] + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + 80018aa: 6899 ldr r1, [r3, #8] + 80018ac: f011 0110 ands.w r1, r1, #16 + 80018b0: d007 beq.n 80018c2 + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + 80018b2: 6e22 ldr r2, [r4, #96] ; 0x60 + 80018b4: f042 0202 orr.w r2, r2, #2 + 80018b8: 6622 str r2, [r4, #96] ; 0x60 + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + 80018ba: f64f 72ef movw r2, #65519 ; 0xffef + 80018be: 609a str r2, [r3, #8] + errorcode = HAL_ERROR; + 80018c0: 2101 movs r1, #1 + if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) + 80018c2: 4620 mov r0, r4 + 80018c4: f7ff fe3c bl 8001540 + 80018c8: b108 cbz r0, 80018ce + hspi->ErrorCode = HAL_SPI_ERROR_FLAG; + 80018ca: 2320 movs r3, #32 + 80018cc: 6623 str r3, [r4, #96] ; 0x60 + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 80018ce: 6e23 ldr r3, [r4, #96] ; 0x60 + 80018d0: 2b00 cmp r3, #0 + 80018d2: f47f af7a bne.w 80017ca + 80018d6: e779 b.n 80017cc + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 80018d8: 685a ldr r2, [r3, #4] + 80018da: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 80018de: e7af b.n 8001840 + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 80018e0: f815 2b01 ldrb.w r2, [r5], #1 + 80018e4: 731a strb r2, [r3, #12] + hspi->TxXferCount--; + 80018e6: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80018e8: 3b01 subs r3, #1 + 80018ea: e7bf b.n 800186c + if (txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))) + 80018ec: 2e00 cmp r6, #0 + 80018ee: d030 beq.n 8001952 + 80018f0: 8fe3 ldrh r3, [r4, #62] ; 0x3e + 80018f2: b29b uxth r3, r3 + 80018f4: 2b00 cmp r3, #0 + 80018f6: d02c beq.n 8001952 + 80018f8: 6823 ldr r3, [r4, #0] + 80018fa: 689a ldr r2, [r3, #8] + 80018fc: 0792 lsls r2, r2, #30 + 80018fe: d528 bpl.n 8001952 + if (hspi->TxXferCount > 1U) + 8001900: 8fe2 ldrh r2, [r4, #62] ; 0x3e + 8001902: b292 uxth r2, r2 + 8001904: 2a01 cmp r2, #1 + hspi->Instance->DR = *((uint16_t *)pTxData); + 8001906: bf8b itete hi + 8001908: f835 2b02 ldrhhi.w r2, [r5], #2 + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 800190c: f815 2b01 ldrbls.w r2, [r5], #1 + hspi->Instance->DR = *((uint16_t *)pTxData); + 8001910: 60da strhi r2, [r3, #12] + *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++); + 8001912: 731a strbls r2, [r3, #12] + hspi->TxXferCount -= 2U; + 8001914: bf8b itete hi + 8001916: 8fe3 ldrhhi r3, [r4, #62] ; 0x3e + hspi->TxXferCount--; + 8001918: 8fe3 ldrhls r3, [r4, #62] ; 0x3e + hspi->TxXferCount -= 2U; + 800191a: 3b02 subhi r3, #2 + hspi->TxXferCount--; + 800191c: f103 33ff addls.w r3, r3, #4294967295 ; 0xffffffff + 8001920: b29b uxth r3, r3 + 8001922: 87e3 strh r3, [r4, #62] ; 0x3e + if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) + 8001924: 8fe6 ldrh r6, [r4, #62] ; 0x3e + 8001926: b2b6 uxth r6, r6 + 8001928: b996 cbnz r6, 8001950 + 800192a: 6aa3 ldr r3, [r4, #40] ; 0x28 + 800192c: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 8001930: d10f bne.n 8001952 + if (((hspi->Instance->CR1 & SPI_CR1_MSTR) == 0U) && ((hspi->Instance->CR2 & SPI_CR2_NSSP) == SPI_CR2_NSSP)) + 8001932: 6823 ldr r3, [r4, #0] + 8001934: 681a ldr r2, [r3, #0] + 8001936: 0756 lsls r6, r2, #29 + 8001938: d406 bmi.n 8001948 + 800193a: 685a ldr r2, [r3, #4] + 800193c: 0710 lsls r0, r2, #28 + SET_BIT(hspi->Instance->CR1, SPI_CR1_SSM); + 800193e: bf42 ittt mi + 8001940: 681a ldrmi r2, [r3, #0] + 8001942: f442 7200 orrmi.w r2, r2, #512 ; 0x200 + 8001946: 601a strmi r2, [r3, #0] + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 8001948: 681a ldr r2, [r3, #0] + 800194a: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800194e: 601a str r2, [r3, #0] + txallowed = 0U; + 8001950: 2600 movs r6, #0 + if ((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))) + 8001952: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 8001956: b29b uxth r3, r3 + 8001958: b1e3 cbz r3, 8001994 + 800195a: 6821 ldr r1, [r4, #0] + 800195c: 688b ldr r3, [r1, #8] + 800195e: f013 0301 ands.w r3, r3, #1 + 8001962: d017 beq.n 8001994 + if (hspi->RxXferCount > 1U) + 8001964: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001968: b292 uxth r2, r2 + 800196a: 2a01 cmp r2, #1 + 800196c: d91f bls.n 80019ae + *((uint16_t *)pRxData) = hspi->Instance->DR; + 800196e: 68ca ldr r2, [r1, #12] + 8001970: f827 2b02 strh.w r2, [r7], #2 + hspi->RxXferCount -= 2U; + 8001974: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001978: 3a02 subs r2, #2 + 800197a: b292 uxth r2, r2 + 800197c: f8a4 2046 strh.w r2, [r4, #70] ; 0x46 + if (hspi->RxXferCount <= 1U) + 8001980: f8b4 2046 ldrh.w r2, [r4, #70] ; 0x46 + 8001984: b292 uxth r2, r2 + 8001986: 2a01 cmp r2, #1 + 8001988: d803 bhi.n 8001992 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 800198a: 684a ldr r2, [r1, #4] + 800198c: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8001990: 604a str r2, [r1, #4] + txallowed = 1U; + 8001992: 461e mov r6, r3 + if ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout)) + 8001994: f1b8 3fff cmp.w r8, #4294967295 ; 0xffffffff + 8001998: f43f af6b beq.w 8001872 + 800199c: f005 fd1e bl 80073dc + 80019a0: eba0 0009 sub.w r0, r0, r9 + 80019a4: 4540 cmp r0, r8 + 80019a6: f4ff af64 bcc.w 8001872 + errorcode = HAL_TIMEOUT; + 80019aa: 2103 movs r1, #3 + 80019ac: e70e b.n 80017cc + (*(uint8_t *)pRxData++) = *(__IO uint8_t *)&hspi->Instance->DR; + 80019ae: 7b0a ldrb r2, [r1, #12] + 80019b0: f807 2b01 strb.w r2, [r7], #1 + hspi->RxXferCount--; + 80019b4: f8b4 1046 ldrh.w r1, [r4, #70] ; 0x46 + 80019b8: 3901 subs r1, #1 + 80019ba: b289 uxth r1, r1 + 80019bc: f8a4 1046 strh.w r1, [r4, #70] ; 0x46 + 80019c0: e7e7 b.n 8001992 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80019c2: 7b1a ldrb r2, [r3, #12] + 80019c4: f8ad 2006 strh.w r2, [sp, #6] + UNUSED(tmpreg); + 80019c8: f8bd 2006 ldrh.w r2, [sp, #6] + if (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT) + 80019cc: 6b22 ldr r2, [r4, #48] ; 0x30 + 80019ce: 2a02 cmp r2, #2 + 80019d0: f47f af6b bne.w 80018aa + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 80019d4: 689a ldr r2, [r3, #8] + 80019d6: 07d2 lsls r2, r2, #31 + 80019d8: d5fc bpl.n 80019d4 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 80019da: 7b1a ldrb r2, [r3, #12] + 80019dc: e761 b.n 80018a2 + errorcode = HAL_BUSY; + 80019de: 2102 movs r1, #2 + 80019e0: e6f4 b.n 80017cc + __HAL_LOCK(hspi); + 80019e2: 2102 movs r1, #2 + 80019e4: e6f8 b.n 80017d8 + +080019e6 : +{ + 80019e6: e92d 41ff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr} + 80019ea: 461f mov r7, r3 + __IO uint16_t tmpreg = 0U; + 80019ec: 2300 movs r3, #0 + 80019ee: f8ad 300e strh.w r3, [sp, #14] + if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + 80019f2: 6843 ldr r3, [r0, #4] + 80019f4: f5b3 7f82 cmp.w r3, #260 ; 0x104 +{ + 80019f8: 4604 mov r4, r0 + 80019fa: 460e mov r6, r1 + 80019fc: 4615 mov r5, r2 + if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) + 80019fe: d10c bne.n 8001a1a + 8001a00: 6883 ldr r3, [r0, #8] + 8001a02: b953 cbnz r3, 8001a1a + hspi->State = HAL_SPI_STATE_BUSY_RX; + 8001a04: 2304 movs r3, #4 + 8001a06: f880 305d strb.w r3, [r0, #93] ; 0x5d + return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout); + 8001a0a: 4613 mov r3, r2 + 8001a0c: 9700 str r7, [sp, #0] + 8001a0e: 460a mov r2, r1 + 8001a10: f7ff feb3 bl 800177a +} + 8001a14: b004 add sp, #16 + 8001a16: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + __HAL_LOCK(hspi); + 8001a1a: f894 305c ldrb.w r3, [r4, #92] ; 0x5c + 8001a1e: 2b01 cmp r3, #1 + 8001a20: f000 80dd beq.w 8001bde + 8001a24: 2301 movs r3, #1 + 8001a26: f884 305c strb.w r3, [r4, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8001a2a: f005 fcd7 bl 80073dc + if (hspi->State != HAL_SPI_STATE_READY) + 8001a2e: f894 305d ldrb.w r3, [r4, #93] ; 0x5d + 8001a32: 2b01 cmp r3, #1 + tickstart = HAL_GetTick(); + 8001a34: 4680 mov r8, r0 + if (hspi->State != HAL_SPI_STATE_READY) + 8001a36: b2d8 uxtb r0, r3 + 8001a38: f040 80cf bne.w 8001bda + if ((pData == NULL) || (Size == 0U)) + 8001a3c: 2e00 cmp r6, #0 + 8001a3e: f000 8092 beq.w 8001b66 + 8001a42: 2d00 cmp r5, #0 + 8001a44: f000 808f beq.w 8001b66 + hspi->State = HAL_SPI_STATE_BUSY_RX; + 8001a48: 2304 movs r3, #4 + 8001a4a: f884 305d strb.w r3, [r4, #93] ; 0x5d + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001a4e: 6aa3 ldr r3, [r4, #40] ; 0x28 + hspi->RxXferSize = Size; + 8001a50: f8a4 5044 strh.w r5, [r4, #68] ; 0x44 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001a54: 2100 movs r1, #0 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001a56: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + 8001a5a: 6621 str r1, [r4, #96] ; 0x60 + hspi->TxISR = NULL; + 8001a5c: e9c4 1113 strd r1, r1, [r4, #76] ; 0x4c + hspi->RxXferCount = Size; + 8001a60: f8a4 5046 strh.w r5, [r4, #70] ; 0x46 + hspi->pRxBuffPtr = (uint8_t *)pData; + 8001a64: 6426 str r6, [r4, #64] ; 0x40 + SPI_RESET_CRC(hspi); + 8001a66: 6825 ldr r5, [r4, #0] + hspi->pTxBuffPtr = (uint8_t *)NULL; + 8001a68: 63a1 str r1, [r4, #56] ; 0x38 + hspi->TxXferSize = 0U; + 8001a6a: 87a1 strh r1, [r4, #60] ; 0x3c + hspi->TxXferCount = 0U; + 8001a6c: 87e1 strh r1, [r4, #62] ; 0x3e + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001a6e: d10d bne.n 8001a8c + SPI_RESET_CRC(hspi); + 8001a70: 682b ldr r3, [r5, #0] + 8001a72: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 8001a76: 602b str r3, [r5, #0] + 8001a78: 682b ldr r3, [r5, #0] + 8001a7a: f443 5300 orr.w r3, r3, #8192 ; 0x2000 + 8001a7e: 602b str r3, [r5, #0] + hspi->RxXferCount--; + 8001a80: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 8001a84: 3b01 subs r3, #1 + 8001a86: b29b uxth r3, r3 + 8001a88: f8a4 3046 strh.w r3, [r4, #70] ; 0x46 + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 8001a8c: 68e3 ldr r3, [r4, #12] + 8001a8e: f5b3 6fe0 cmp.w r3, #1792 ; 0x700 + CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 8001a92: 686b ldr r3, [r5, #4] + 8001a94: bf8c ite hi + 8001a96: f423 5380 bichi.w r3, r3, #4096 ; 0x1000 + SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); + 8001a9a: f443 5380 orrls.w r3, r3, #4096 ; 0x1000 + 8001a9e: 606b str r3, [r5, #4] + if (hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001aa0: 68a3 ldr r3, [r4, #8] + 8001aa2: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + SPI_1LINE_RX(hspi); + 8001aa6: bf02 ittt eq + 8001aa8: 682b ldreq r3, [r5, #0] + 8001aaa: f423 4380 biceq.w r3, r3, #16384 ; 0x4000 + 8001aae: 602b streq r3, [r5, #0] + if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) + 8001ab0: 682b ldr r3, [r5, #0] + 8001ab2: 0658 lsls r0, r3, #25 + 8001ab4: d403 bmi.n 8001abe + __HAL_SPI_ENABLE(hspi); + 8001ab6: 682b ldr r3, [r5, #0] + 8001ab8: f043 0340 orr.w r3, r3, #64 ; 0x40 + 8001abc: 602b str r3, [r5, #0] + while (hspi->RxXferCount > 0U) + 8001abe: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + 8001ac2: 6822 ldr r2, [r4, #0] + while (hspi->RxXferCount > 0U) + 8001ac4: b29b uxth r3, r3 + 8001ac6: 2b00 cmp r3, #0 + 8001ac8: d13e bne.n 8001b48 + if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) + 8001aca: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8001acc: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 8001ad0: d11c bne.n 8001b0c + SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); + 8001ad2: 6813 ldr r3, [r2, #0] + 8001ad4: f443 5380 orr.w r3, r3, #4096 ; 0x1000 + 8001ad8: 6013 str r3, [r2, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001ada: 6893 ldr r3, [r2, #8] + 8001adc: 07df lsls r7, r3, #31 + 8001ade: d5fc bpl.n 8001ada + if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) + 8001ae0: 68e3 ldr r3, [r4, #12] + 8001ae2: f5b3 6fe0 cmp.w r3, #1792 ; 0x700 + (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 8001ae6: bf95 itete ls + 8001ae8: 7b13 ldrbls r3, [r2, #12] + *((uint16_t *)pData) = hspi->Instance->DR; + 8001aea: 68d3 ldrhi r3, [r2, #12] + (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 8001aec: 7033 strbls r3, [r6, #0] + *((uint16_t *)pData) = hspi->Instance->DR; + 8001aee: 8033 strhhi r3, [r6, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001af0: 6823 ldr r3, [r4, #0] + 8001af2: 689a ldr r2, [r3, #8] + 8001af4: 07d6 lsls r6, r2, #31 + 8001af6: d5fc bpl.n 8001af2 + if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) + 8001af8: 68e1 ldr r1, [r4, #12] + 8001afa: f5b1 6f70 cmp.w r1, #3840 ; 0xf00 + 8001afe: d142 bne.n 8001b86 + tmpreg = hspi->Instance->DR; + 8001b00: 68db ldr r3, [r3, #12] + 8001b02: b29b uxth r3, r3 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 8001b04: f8ad 300e strh.w r3, [sp, #14] + UNUSED(tmpreg); + 8001b08: f8bd 300e ldrh.w r3, [sp, #14] + * @param Tickstart: tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) +{ + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001b0c: 6861 ldr r1, [r4, #4] + 8001b0e: 6823 ldr r3, [r4, #0] + 8001b10: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 8001b14: d10a bne.n 8001b2c + 8001b16: 68a2 ldr r2, [r4, #8] + 8001b18: f5b2 4f00 cmp.w r2, #32768 ; 0x8000 + 8001b1c: d002 beq.n 8001b24 + || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + 8001b1e: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + 8001b22: d103 bne.n 8001b2c + { + /* Disable SPI peripheral */ + __HAL_SPI_DISABLE(hspi); + 8001b24: 681a ldr r2, [r3, #0] + 8001b26: f022 0240 bic.w r2, r2, #64 ; 0x40 + 8001b2a: 601a str r2, [r3, #0] + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001b2c: 689a ldr r2, [r3, #8] + 8001b2e: 0610 lsls r0, r2, #24 + 8001b30: d4fc bmi.n 8001b2c + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } + + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001b32: f5b1 7f82 cmp.w r1, #260 ; 0x104 + 8001b36: d036 beq.n 8001ba6 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) + 8001b38: 689a ldr r2, [r3, #8] + 8001b3a: 06d2 lsls r2, r2, #27 + 8001b3c: d445 bmi.n 8001bca + if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) + 8001b3e: 6e20 ldr r0, [r4, #96] ; 0x60 + errorcode = HAL_BUSY; + 8001b40: 3800 subs r0, #0 + 8001b42: bf18 it ne + 8001b44: 2001 movne r0, #1 +error : + 8001b46: e00e b.n 8001b66 + if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) + 8001b48: 6893 ldr r3, [r2, #8] + 8001b4a: 07d9 lsls r1, r3, #31 + 8001b4c: d509 bpl.n 8001b62 + (* (uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR; + 8001b4e: 7b13 ldrb r3, [r2, #12] + 8001b50: f806 3b01 strb.w r3, [r6], #1 + hspi->RxXferCount--; + 8001b54: f8b4 3046 ldrh.w r3, [r4, #70] ; 0x46 + 8001b58: 3b01 subs r3, #1 + 8001b5a: b29b uxth r3, r3 + 8001b5c: f8a4 3046 strh.w r3, [r4, #70] ; 0x46 + 8001b60: e7ad b.n 8001abe + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 8001b62: b93f cbnz r7, 8001b74 + errorcode = HAL_TIMEOUT; + 8001b64: 2003 movs r0, #3 + hspi->State = HAL_SPI_STATE_READY; + 8001b66: 2301 movs r3, #1 + 8001b68: f884 305d strb.w r3, [r4, #93] ; 0x5d + __HAL_UNLOCK(hspi); + 8001b6c: 2300 movs r3, #0 + 8001b6e: f884 305c strb.w r3, [r4, #92] ; 0x5c + return errorcode; + 8001b72: e74f b.n 8001a14 + if ((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick() - tickstart) >= Timeout))) + 8001b74: 1c7b adds r3, r7, #1 + 8001b76: d0a2 beq.n 8001abe + 8001b78: f005 fc30 bl 80073dc + 8001b7c: eba0 0008 sub.w r0, r0, r8 + 8001b80: 42b8 cmp r0, r7 + 8001b82: d39c bcc.n 8001abe + 8001b84: e7ee b.n 8001b64 + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 8001b86: 7b1a ldrb r2, [r3, #12] + 8001b88: f8ad 200e strh.w r2, [sp, #14] + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + 8001b8c: f5b1 6fe0 cmp.w r1, #1792 ; 0x700 + UNUSED(tmpreg); + 8001b90: f8bd 200e ldrh.w r2, [sp, #14] + if ((hspi->Init.DataSize == SPI_DATASIZE_8BIT) && (hspi->Init.CRCLength == SPI_CRC_LENGTH_16BIT)) + 8001b94: d1ba bne.n 8001b0c + 8001b96: 6b22 ldr r2, [r4, #48] ; 0x30 + 8001b98: 2a02 cmp r2, #2 + 8001b9a: d1b7 bne.n 8001b0c + while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) + 8001b9c: 689a ldr r2, [r3, #8] + 8001b9e: 07d5 lsls r5, r2, #31 + 8001ba0: d5fc bpl.n 8001b9c + tmpreg = *(__IO uint8_t *)&hspi->Instance->DR; + 8001ba2: 7b1b ldrb r3, [r3, #12] + 8001ba4: e7ae b.n 8001b04 + if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) + 8001ba6: 68a2 ldr r2, [r4, #8] + 8001ba8: f5b2 4f00 cmp.w r2, #32768 ; 0x8000 + 8001bac: d002 beq.n 8001bb4 + || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) + 8001bae: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + 8001bb2: d1c1 bne.n 8001b38 + while ((hspi->Instance->SR & Fifo) != State) + 8001bb4: 689a ldr r2, [r3, #8] + 8001bb6: f412 6fc0 tst.w r2, #1536 ; 0x600 + 8001bba: d0bd beq.n 8001b38 + tmpreg = *((__IO uint8_t *)&hspi->Instance->DR); + 8001bbc: 7b1a ldrb r2, [r3, #12] + 8001bbe: b2d2 uxtb r2, r2 + 8001bc0: f88d 200d strb.w r2, [sp, #13] + UNUSED(tmpreg); + 8001bc4: f89d 200d ldrb.w r2, [sp, #13] + 8001bc8: e7f4 b.n 8001bb4 + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); + 8001bca: 6e22 ldr r2, [r4, #96] ; 0x60 + 8001bcc: f042 0202 orr.w r2, r2, #2 + 8001bd0: 6622 str r2, [r4, #96] ; 0x60 + __HAL_SPI_CLEAR_CRCERRFLAG(hspi); + 8001bd2: f64f 72ef movw r2, #65519 ; 0xffef + 8001bd6: 609a str r2, [r3, #8] + 8001bd8: e7b1 b.n 8001b3e + errorcode = HAL_BUSY; + 8001bda: 2002 movs r0, #2 + 8001bdc: e7c3 b.n 8001b66 + __HAL_LOCK(hspi); + 8001bde: 2002 movs r0, #2 + 8001be0: e718 b.n 8001a14 + ... + +08001be4 : + +// checksum_more() +// + static void +checksum_more(SHA256_CTX *ctx, uint32_t *total, const uint8_t *addr, int len) +{ + 8001be4: b5f8 push {r3, r4, r5, r6, r7, lr} + 8001be6: 460c mov r4, r1 + // mk4 has hardware hash engine, and no DFU button + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001be8: 6809 ldr r1, [r1, #0] +{ + 8001bea: 461d mov r5, r3 + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001bec: 2364 movs r3, #100 ; 0x64 +{ + 8001bee: 4617 mov r7, r2 + 8001bf0: 4606 mov r6, r0 + int percent = ((*total) * 100) / TOTAL_CHECKSUM_LEN; + 8001bf2: 4359 muls r1, r3 + puts2("Verify %0x"); + puthex2(percent); + putchar('\n'); +#endif + + oled_show_progress(screen_verify, percent); + 8001bf4: 4807 ldr r0, [pc, #28] ; (8001c14 ) + 8001bf6: 4b08 ldr r3, [pc, #32] ; (8001c18 ) + 8001bf8: fbb1 f1f3 udiv r1, r1, r3 + 8001bfc: f7ff fab4 bl 8001168 + + sha256_update(ctx, addr, len); + 8001c00: 462a mov r2, r5 + 8001c02: 4639 mov r1, r7 + 8001c04: 4630 mov r0, r6 + 8001c06: f003 fdc7 bl 8005798 + *total += len; + 8001c0a: 6823 ldr r3, [r4, #0] + 8001c0c: 442b add r3, r5 + 8001c0e: 6023 str r3, [r4, #0] +} + 8001c10: bdf8 pop {r3, r4, r5, r6, r7, pc} + 8001c12: bf00 nop + 8001c14: 0801004d .word 0x0801004d + 8001c18: 0018541c .word 0x0018541c + +08001c1c : + +// checksum_flash() +// + void +checksum_flash(uint8_t fw_digest[32], uint8_t world_digest[32], uint32_t fw_length) +{ + 8001c1c: b570 push {r4, r5, r6, lr} + 8001c1e: b09c sub sp, #112 ; 0x70 + 8001c20: 4606 mov r6, r0 + 8001c22: 460d mov r5, r1 + 8001c24: 4614 mov r4, r2 + const uint8_t *start = (const uint8_t *)FIRMWARE_START; + + rng_delay(); + 8001c26: f000 fe6f bl 8002908 + + SHA256_CTX ctx; + uint32_t total_len = 0; + 8001c2a: 2300 movs r3, #0 + 8001c2c: 9300 str r3, [sp, #0] + + if(fw_length == 0) { + 8001c2e: 2c00 cmp r4, #0 + 8001c30: d15f bne.n 8001cf2 + uint8_t first[32]; + sha256_init(&ctx); + 8001c32: a809 add r0, sp, #36 ; 0x24 + 8001c34: f003 fda2 bl 800577c + + // use length from header in flash + fw_length = FW_HDR->firmware_length; + 8001c38: 4b36 ldr r3, [pc, #216] ; (8001d14 ) + + // start of firmware (just after we end) to header + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001c3a: 4a37 ldr r2, [pc, #220] ; (8001d18 ) + fw_length = FW_HDR->firmware_length; + 8001c3c: f8d3 4098 ldr.w r4, [r3, #152] ; 0x98 + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001c40: 4669 mov r1, sp + 8001c42: f44f 537f mov.w r3, #16320 ; 0x3fc0 + 8001c46: a809 add r0, sp, #36 ; 0x24 + 8001c48: f7ff ffcc bl 8001be4 + + // from after header to end + checksum_more(&ctx, &total_len, start + FW_HEADER_OFFSET + FW_HEADER_SIZE, + 8001c4c: 4a33 ldr r2, [pc, #204] ; (8001d1c ) + 8001c4e: f5a4 4380 sub.w r3, r4, #16384 ; 0x4000 + 8001c52: 4669 mov r1, sp + 8001c54: a809 add r0, sp, #36 ; 0x24 + 8001c56: f7ff ffc5 bl 8001be4 + fw_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + + sha256_final(&ctx, first); + 8001c5a: a901 add r1, sp, #4 + 8001c5c: a809 add r0, sp, #36 ; 0x24 + 8001c5e: f003 fde1 bl 8005824 + + // double SHA256 + sha256_single(first, sizeof(first), fw_digest); + 8001c62: 4632 mov r2, r6 + 8001c64: 2120 movs r1, #32 + 8001c66: a801 add r0, sp, #4 + 8001c68: f003 fdf0 bl 800584c + // fw_digest should already be populated by caller + total_len = fw_length - 64; + } + + // start over, and get the rest of flash. All of it. + sha256_init(&ctx); + 8001c6c: a809 add r0, sp, #36 ; 0x24 + 8001c6e: f003 fd85 bl 800577c + + // .. and chain in what we have so far + sha256_update(&ctx, fw_digest, 32); + 8001c72: 2220 movs r2, #32 + 8001c74: 4631 mov r1, r6 + 8001c76: a809 add r0, sp, #36 ; 0x24 + 8001c78: f003 fd8e bl 8005798 + + // Bootloader, including pairing secret area, but excluding MCU keys. + const uint8_t *base = (const uint8_t *)BL_FLASH_BASE; + checksum_more(&ctx, &total_len, base, ((uint8_t *)MCU_KEYS)-base); + 8001c7c: f44f 33f0 mov.w r3, #122880 ; 0x1e000 + 8001c80: f04f 6200 mov.w r2, #134217728 ; 0x8000000 + 8001c84: 4669 mov r1, sp + 8001c86: a809 add r0, sp, #36 ; 0x24 + 8001c88: f7ff ffac bl 8001be4 + + // Probably-blank area after firmware, and filesystem area. + // Important: firmware images (fw_length) must be aligned with flash erase unit size (4k). + const uint8_t *fs = start + fw_length; + const uint8_t *last = base + MAIN_FLASH_SIZE; + checksum_more(&ctx, &total_len, fs, last-fs); + 8001c8c: f104 6200 add.w r2, r4, #134217728 ; 0x8000000 + 8001c90: f5c4 13b0 rsb r3, r4, #1441792 ; 0x160000 + 8001c94: f502 3200 add.w r2, r2, #131072 ; 0x20000 + 8001c98: 4669 mov r1, sp + 8001c9a: a809 add r0, sp, #36 ; 0x24 + 8001c9c: f7ff ffa2 bl 8001be4 + + rng_delay(); + 8001ca0: f000 fe32 bl 8002908 + + // OTP area + checksum_more(&ctx, &total_len, (void *)0x1fff7000, 0x400); + 8001ca4: 4a1e ldr r2, [pc, #120] ; (8001d20 ) + 8001ca6: f44f 6380 mov.w r3, #1024 ; 0x400 + 8001caa: 4669 mov r1, sp + 8001cac: a809 add r0, sp, #36 ; 0x24 + 8001cae: f7ff ff99 bl 8001be4 + + // "just in case" ... the option bytes (2 banks) + checksum_more(&ctx, &total_len, (void *)0x1fff7800, 0x28); + 8001cb2: 4a1c ldr r2, [pc, #112] ; (8001d24 ) + 8001cb4: 2328 movs r3, #40 ; 0x28 + 8001cb6: 4669 mov r1, sp + 8001cb8: a809 add r0, sp, #36 ; 0x24 + 8001cba: f7ff ff93 bl 8001be4 + checksum_more(&ctx, &total_len, (void *)0x1ffff800, 0x28); + 8001cbe: 4a1a ldr r2, [pc, #104] ; (8001d28 ) + 8001cc0: 2328 movs r3, #40 ; 0x28 + 8001cc2: 4669 mov r1, sp + 8001cc4: a809 add r0, sp, #36 ; 0x24 + 8001cc6: f7ff ff8d bl 8001be4 + + // System ROM (they say it can't change, but clearly + // implemented as flash cells) + checksum_more(&ctx, &total_len, (void *)0x1fff0000, 0x7000); + 8001cca: 4a18 ldr r2, [pc, #96] ; (8001d2c ) + 8001ccc: f44f 43e0 mov.w r3, #28672 ; 0x7000 + 8001cd0: 4669 mov r1, sp + 8001cd2: a809 add r0, sp, #36 ; 0x24 + 8001cd4: f7ff ff86 bl 8001be4 + + // device serial number, just for kicks + checksum_more(&ctx, &total_len, (void *)0x1fff7590, 12); + 8001cd8: 4a15 ldr r2, [pc, #84] ; (8001d30 ) + 8001cda: 230c movs r3, #12 + 8001cdc: 4669 mov r1, sp + 8001cde: a809 add r0, sp, #36 ; 0x24 + 8001ce0: f7ff ff80 bl 8001be4 + + ASSERT(total_len == TOTAL_CHECKSUM_LEN); + 8001ce4: 4b13 ldr r3, [pc, #76] ; (8001d34 ) + 8001ce6: 9a00 ldr r2, [sp, #0] + 8001ce8: 429a cmp r2, r3 + 8001cea: d006 beq.n 8001cfa + 8001cec: 4812 ldr r0, [pc, #72] ; (8001d38 ) + 8001cee: f7fe fea3 bl 8000a38 + total_len = fw_length - 64; + 8001cf2: f1a4 0340 sub.w r3, r4, #64 ; 0x40 + 8001cf6: 9300 str r3, [sp, #0] + 8001cf8: e7b8 b.n 8001c6c + + sha256_final(&ctx, world_digest); + 8001cfa: 4629 mov r1, r5 + 8001cfc: a809 add r0, sp, #36 ; 0x24 + 8001cfe: f003 fd91 bl 8005824 + + // double SHA256 (a bitcoin fetish) + sha256_single(world_digest, 32, world_digest); + 8001d02: 462a mov r2, r5 + 8001d04: 2120 movs r1, #32 + 8001d06: 4628 mov r0, r5 + 8001d08: f003 fda0 bl 800584c + + rng_delay(); + 8001d0c: f000 fdfc bl 8002908 +} + 8001d10: b01c add sp, #112 ; 0x70 + 8001d12: bd70 pop {r4, r5, r6, pc} + 8001d14: 08023f00 .word 0x08023f00 + 8001d18: 08020000 .word 0x08020000 + 8001d1c: 08024000 .word 0x08024000 + 8001d20: 1fff7000 .word 0x1fff7000 + 8001d24: 1fff7800 .word 0x1fff7800 + 8001d28: 1ffff800 .word 0x1ffff800 + 8001d2c: 1fff0000 .word 0x1fff0000 + 8001d30: 1fff7590 .word 0x1fff7590 + 8001d34: 0018541c .word 0x0018541c + 8001d38: 0801046c .word 0x0801046c + +08001d3c : +// Scan the OTP area and determine what the current min-version (timestamp) +// we can allow. All zeros if any if okay. +// + void +get_min_version(uint8_t min_version[8]) +{ + 8001d3c: b570 push {r4, r5, r6, lr} + 8001d3e: 4604 mov r4, r0 + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + 8001d40: 4d0c ldr r5, [pc, #48] ; (8001d74 ) + + rng_delay(); + memset(min_version, 0, 8); + + for(int i=0; i) + rng_delay(); + 8001d44: f000 fde0 bl 8002908 + memset(min_version, 0, 8); + 8001d48: 2300 movs r3, #0 + 8001d4a: 6023 str r3, [r4, #0] + 8001d4c: 6063 str r3, [r4, #4] + // is it programmed? + if(otp[0] == 0xff) continue; + + // is it a timestamp value? + if(otp[0] >= 0x40) continue; + if(otp[0] < 0x10) continue; + 8001d4e: 782b ldrb r3, [r5, #0] + 8001d50: 3b10 subs r3, #16 + 8001d52: 2b2f cmp r3, #47 ; 0x2f + 8001d54: d80a bhi.n 8001d6c + + if(memcmp(otp, min_version, 8) > 0) { + 8001d56: 4621 mov r1, r4 + 8001d58: 2208 movs r2, #8 + 8001d5a: 4628 mov r0, r5 + 8001d5c: f00b fdc4 bl 800d8e8 + 8001d60: 2800 cmp r0, #0 + memcpy(min_version, otp, 8); + 8001d62: bfc1 itttt gt + 8001d64: 462b movgt r3, r5 + 8001d66: cb03 ldmiagt r3!, {r0, r1} + 8001d68: 6020 strgt r0, [r4, #0] + 8001d6a: 6061 strgt r1, [r4, #4] + for(int i=0; i + } + } +} + 8001d72: bd70 pop {r4, r5, r6, pc} + 8001d74: 1fff7000 .word 0x1fff7000 + 8001d78: 1fff7400 .word 0x1fff7400 + +08001d7c : + +// check_is_downgrade() +// + bool +check_is_downgrade(const uint8_t timestamp[8], const char *version) +{ + 8001d7c: b513 push {r0, r1, r4, lr} + 8001d7e: 4604 mov r4, r0 + } +#endif + + // look at FW_HDR->timestamp and compare to a growing list in main flash OTP + uint8_t min[8]; + get_min_version(min); + 8001d80: 4668 mov r0, sp + 8001d82: f7ff ffdb bl 8001d3c + + return (memcmp(timestamp, min, 8) < 0); + 8001d86: 2208 movs r2, #8 + 8001d88: 4669 mov r1, sp + 8001d8a: 4620 mov r0, r4 + 8001d8c: f00b fdac bl 800d8e8 +} + 8001d90: 0fc0 lsrs r0, r0, #31 + 8001d92: b002 add sp, #8 + 8001d94: bd10 pop {r4, pc} + +08001d96 : + +// warn_fishy_firmware() +// + void +warn_fishy_firmware(const uint8_t *pixels) +{ + 8001d96: b538 push {r3, r4, r5, lr} + 8001d98: 4605 mov r5, r0 + const int wait = 100; +#else + const int wait = 10; +#endif + + for(int i=0; i < wait; i++) { + 8001d9a: 2400 movs r4, #0 + oled_show_progress(pixels, (i*100)/wait); + 8001d9c: 4621 mov r1, r4 + 8001d9e: 4628 mov r0, r5 + 8001da0: f7ff f9e2 bl 8001168 + for(int i=0; i < wait; i++) { + 8001da4: 3401 adds r4, #1 + + delay_ms(250); + 8001da6: 20fa movs r0, #250 ; 0xfa + 8001da8: f001 fe6c bl 8003a84 + for(int i=0; i < wait; i++) { + 8001dac: 2c64 cmp r4, #100 ; 0x64 + 8001dae: d1f5 bne.n 8001d9c + } +} + 8001db0: bd38 pop {r3, r4, r5, pc} + ... + +08001db4 : + +// verify_header() +// + bool +verify_header(const coldcardFirmwareHeader_t *hdr) +{ + 8001db4: b510 push {r4, lr} + 8001db6: 4604 mov r4, r0 + rng_delay(); + 8001db8: f000 fda6 bl 8002908 + + if(hdr->magic_value != FW_HEADER_MAGIC) goto fail; + 8001dbc: 6822 ldr r2, [r4, #0] + 8001dbe: 4b0b ldr r3, [pc, #44] ; (8001dec ) + 8001dc0: 429a cmp r2, r3 + 8001dc2: d110 bne.n 8001de6 + if(hdr->version_string[0] == 0x0) goto fail; + 8001dc4: 7b20 ldrb r0, [r4, #12] + 8001dc6: b168 cbz r0, 8001de4 + if(hdr->timestamp[0] >= 0x40) goto fail; // 22 yr product lifetime + 8001dc8: 7923 ldrb r3, [r4, #4] + 8001dca: 2b3f cmp r3, #63 ; 0x3f + 8001dcc: d80b bhi.n 8001de6 + if(hdr->firmware_length < FW_MIN_LENGTH) goto fail; + 8001dce: 69a3 ldr r3, [r4, #24] + 8001dd0: f5a3 2380 sub.w r3, r3, #262144 ; 0x40000 + 8001dd4: f5b3 1fd0 cmp.w r3, #1703936 ; 0x1a0000 + 8001dd8: d205 bcs.n 8001de6 + if(hdr->firmware_length >= FW_MAX_LENGTH_MK4) goto fail; + if(hdr->pubkey_num >= NUM_KNOWN_PUBKEYS) goto fail; + 8001dda: 6960 ldr r0, [r4, #20] + 8001ddc: 2805 cmp r0, #5 + 8001dde: bf8c ite hi + 8001de0: 2000 movhi r0, #0 + 8001de2: 2001 movls r0, #1 + + return true; +fail: + return false; +} + 8001de4: bd10 pop {r4, pc} + return false; + 8001de6: 2000 movs r0, #0 + 8001de8: e7fc b.n 8001de4 + 8001dea: bf00 nop + 8001dec: cc001234 .word 0xcc001234 + +08001df0 : +// +// Given double-sha256 over the firmware bytes, check the signature. +// + bool +verify_signature(const coldcardFirmwareHeader_t *hdr, const uint8_t fw_check[32]) +{ + 8001df0: b530 push {r4, r5, lr} + // this takes a few ms at least, not fast. + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001df2: 6943 ldr r3, [r0, #20] + 8001df4: 4d0b ldr r5, [pc, #44] ; (8001e24 ) +{ + 8001df6: b085 sub sp, #20 + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001df8: eb05 1583 add.w r5, r5, r3, lsl #6 +{ + 8001dfc: 4604 mov r4, r0 + 8001dfe: 9103 str r1, [sp, #12] + int ok = uECC_verify(approved_pubkeys[hdr->pubkey_num], fw_check, 32, + 8001e00: f004 fee8 bl 8006bd4 + 8001e04: f104 0340 add.w r3, r4, #64 ; 0x40 + 8001e08: 9903 ldr r1, [sp, #12] + 8001e0a: 9000 str r0, [sp, #0] + 8001e0c: 2220 movs r2, #32 + 8001e0e: 4628 mov r0, r5 + 8001e10: f005 f967 bl 80070e2 + 8001e14: 4604 mov r4, r0 + hdr->signature, uECC_secp256k1()); + + //puts(ok ? "Sig ok" : "Sig fail"); + rng_delay(); + 8001e16: f000 fd77 bl 8002908 + + return ok; +} + 8001e1a: 1e20 subs r0, r4, #0 + 8001e1c: bf18 it ne + 8001e1e: 2001 movne r0, #1 + 8001e20: b005 add sp, #20 + 8001e22: bd30 pop {r4, r5, pc} + 8001e24: 080104e6 .word 0x080104e6 + +08001e28 : +// Check hdr, and even signature of protential new firmware in PSRAM. +// Returns checksum needed for 608 +// + bool +verify_firmware_in_ram(const uint8_t *start, uint32_t len, uint8_t world_check[32]) +{ + 8001e28: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + const coldcardFirmwareHeader_t *hdr = (const coldcardFirmwareHeader_t *) + 8001e2c: f500 567e add.w r6, r0, #16256 ; 0x3f80 +{ + 8001e30: b09c sub sp, #112 ; 0x70 + 8001e32: 4605 mov r5, r0 + (start + FW_HEADER_OFFSET); + uint8_t fw_digest[32]; + + // check basics like verison, hw compat, etc + if(!verify_header(hdr)) goto fail; + 8001e34: 4630 mov r0, r6 +{ + 8001e36: 4617 mov r7, r2 + if(!verify_header(hdr)) goto fail; + 8001e38: f7ff ffbc bl 8001db4 + 8001e3c: 4604 mov r4, r0 + 8001e3e: b150 cbz r0, 8001e56 + + if(check_is_downgrade(hdr->timestamp, (const char *)hdr->version_string)) { + 8001e40: f106 010c add.w r1, r6, #12 + 8001e44: 1d30 adds r0, r6, #4 + 8001e46: f7ff ff99 bl 8001d7c + 8001e4a: 4604 mov r4, r0 + 8001e4c: b138 cbz r0, 8001e5e + puts("downgrade"); + 8001e4e: 481e ldr r0, [pc, #120] ; (8001ec8 ) + 8001e50: f003 f90a bl 8005068 + + checksum_flash(fw_digest, world_check, hdr->firmware_length); + + return true; +fail: + return false; + 8001e54: 2400 movs r4, #0 +} + 8001e56: 4620 mov r0, r4 + 8001e58: b01c add sp, #112 ; 0x70 + 8001e5a: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + rng_delay(); + 8001e5e: f000 fd53 bl 8002908 + hdr->firmware_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + 8001e62: f505 5840 add.w r8, r5, #12288 ; 0x3000 + sha256_init(&ctx); + 8001e66: a809 add r0, sp, #36 ; 0x24 + uint32_t total_len = 0; + 8001e68: 9400 str r4, [sp, #0] + sha256_init(&ctx); + 8001e6a: f003 fc87 bl 800577c + checksum_more(&ctx, &total_len, start, FW_HEADER_OFFSET + FW_HEADER_SIZE - 64); + 8001e6e: f44f 537f mov.w r3, #16320 ; 0x3fc0 + 8001e72: 462a mov r2, r5 + 8001e74: 4669 mov r1, sp + 8001e76: a809 add r0, sp, #36 ; 0x24 + 8001e78: f7ff feb4 bl 8001be4 + hdr->firmware_length - (FW_HEADER_OFFSET + FW_HEADER_SIZE)); + 8001e7c: f8d8 3f98 ldr.w r3, [r8, #3992] ; 0xf98 + checksum_more(&ctx, &total_len, start + FW_HEADER_OFFSET + FW_HEADER_SIZE, + 8001e80: f505 4280 add.w r2, r5, #16384 ; 0x4000 + 8001e84: f5a3 4380 sub.w r3, r3, #16384 ; 0x4000 + 8001e88: 4669 mov r1, sp + 8001e8a: a809 add r0, sp, #36 ; 0x24 + 8001e8c: f7ff feaa bl 8001be4 + sha256_final(&ctx, fw_digest); + 8001e90: a901 add r1, sp, #4 + 8001e92: a809 add r0, sp, #36 ; 0x24 + 8001e94: f003 fcc6 bl 8005824 + sha256_single(fw_digest, 32, fw_digest); + 8001e98: aa01 add r2, sp, #4 + 8001e9a: 4610 mov r0, r2 + 8001e9c: 2120 movs r1, #32 + 8001e9e: f003 fcd5 bl 800584c + rng_delay(); + 8001ea2: f000 fd31 bl 8002908 + if(!verify_signature(hdr, fw_digest)) { + 8001ea6: a901 add r1, sp, #4 + 8001ea8: 4630 mov r0, r6 + 8001eaa: f7ff ffa1 bl 8001df0 + 8001eae: 4604 mov r4, r0 + 8001eb0: b918 cbnz r0, 8001eba + puts("sig fail"); + 8001eb2: 4806 ldr r0, [pc, #24] ; (8001ecc ) + 8001eb4: f003 f8d8 bl 8005068 + goto fail; + 8001eb8: e7cd b.n 8001e56 + checksum_flash(fw_digest, world_check, hdr->firmware_length); + 8001eba: f8d8 2f98 ldr.w r2, [r8, #3992] ; 0xf98 + 8001ebe: 4639 mov r1, r7 + 8001ec0: a801 add r0, sp, #4 + 8001ec2: f7ff feab bl 8001c1c + return true; + 8001ec6: e7c6 b.n 8001e56 + 8001ec8: 08010473 .word 0x08010473 + 8001ecc: 0801047d .word 0x0801047d + +08001ed0 : +// - don't set the light at this point. +// - requires bootloader to have been unchanged since world_check recorded (debug issue) +// + bool +verify_world_checksum(const uint8_t world_check[32]) +{ + 8001ed0: b507 push {r0, r1, r2, lr} + 8001ed2: 9001 str r0, [sp, #4] + ae_setup(); + 8001ed4: f000 fe3c bl 8002b50 + ae_pair_unlock(); + 8001ed8: f001 f830 bl 8002f3c + + return (ae_checkmac_hard(KEYNUM_firmware, world_check) == 0); + 8001edc: 9901 ldr r1, [sp, #4] + 8001ede: 200e movs r0, #14 + 8001ee0: f001 f9ba bl 8003258 +} + 8001ee4: fab0 f080 clz r0, r0 + 8001ee8: 0940 lsrs r0, r0, #5 + 8001eea: b003 add sp, #12 + 8001eec: f85d fb04 ldr.w pc, [sp], #4 + +08001ef0 : + +// verify_firmware() +// + bool +verify_firmware(void) +{ + 8001ef0: b570 push {r4, r5, r6, lr} + STATIC_ASSERT(sizeof(coldcardFirmwareHeader_t) == FW_HEADER_SIZE); + + rng_delay(); + + // watch for unprogrammed header. and some + if(FW_HDR->version_string[0] == 0xff) goto blank; + 8001ef2: 4e2a ldr r6, [pc, #168] ; (8001f9c ) +{ + 8001ef4: b090 sub sp, #64 ; 0x40 + rng_delay(); + 8001ef6: f000 fd07 bl 8002908 + if(FW_HDR->version_string[0] == 0xff) goto blank; + 8001efa: f896 308c ldrb.w r3, [r6, #140] ; 0x8c + 8001efe: 2bff cmp r3, #255 ; 0xff + 8001f00: d107 bne.n 8001f12 + puts("corrupt firmware"); + oled_show(screen_corrupt); + return false; + +blank: + puts("no firmware"); + 8001f02: 4827 ldr r0, [pc, #156] ; (8001fa0 ) + puts("corrupt firmware"); + 8001f04: f003 f8b0 bl 8005068 + oled_show(screen_corrupt); + 8001f08: 4826 ldr r0, [pc, #152] ; (8001fa4 ) + 8001f0a: f7ff f8b3 bl 8001074 + return false; + 8001f0e: 2400 movs r4, #0 + 8001f10: e030 b.n 8001f74 + if(!verify_header(FW_HDR)) goto fail; + 8001f12: 4825 ldr r0, [pc, #148] ; (8001fa8 ) + 8001f14: f7ff ff4e bl 8001db4 + 8001f18: 2800 cmp r0, #0 + 8001f1a: d03c beq.n 8001f96 + rng_delay(); + 8001f1c: f000 fcf4 bl 8002908 + checksum_flash(fw_check, world_check, 0); + 8001f20: 2200 movs r2, #0 + 8001f22: a908 add r1, sp, #32 + 8001f24: 4668 mov r0, sp + 8001f26: f7ff fe79 bl 8001c1c + rng_delay(); + 8001f2a: f000 fced bl 8002908 + if(!verify_signature(FW_HDR, fw_check)) goto fail; + 8001f2e: 481e ldr r0, [pc, #120] ; (8001fa8 ) + 8001f30: 4669 mov r1, sp + 8001f32: f7ff ff5d bl 8001df0 + 8001f36: 4604 mov r4, r0 + 8001f38: b368 cbz r0, 8001f96 + int not_green = ae_set_gpio_secure(world_check); + 8001f3a: a808 add r0, sp, #32 + 8001f3c: f001 fba0 bl 8003680 + 8001f40: 4605 mov r5, r0 + rng_delay(); + 8001f42: f000 fce1 bl 8002908 + rng_delay(); + 8001f46: f000 fcdf bl 8002908 + return ((FLASH->OPTR & FLASH_OPTR_RDP_Msk) == 0xCC); + 8001f4a: 4b18 ldr r3, [pc, #96] ; (8001fac ) + 8001f4c: 6a1b ldr r3, [r3, #32] + 8001f4e: b2db uxtb r3, r3 + if(!flash_is_security_level2() && not_green) { + 8001f50: 2bcc cmp r3, #204 ; 0xcc + 8001f52: d008 beq.n 8001f66 + 8001f54: b18d cbz r5, 8001f7a + oled_show_progress(screen_verify, 100); + 8001f56: 4816 ldr r0, [pc, #88] ; (8001fb0 ) + 8001f58: 2164 movs r1, #100 ; 0x64 + 8001f5a: f7ff f905 bl 8001168 + puts("Factory boot"); + 8001f5e: 4815 ldr r0, [pc, #84] ; (8001fb4 ) + puts("Good firmware"); + 8001f60: f003 f882 bl 8005068 + 8001f64: e006 b.n 8001f74 + } else if(not_green) { + 8001f66: b145 cbz r5, 8001f7a + puts("WARN: Red light"); + 8001f68: 4813 ldr r0, [pc, #76] ; (8001fb8 ) + 8001f6a: f003 f87d bl 8005068 + warn_fishy_firmware(screen_red_light); + 8001f6e: 4813 ldr r0, [pc, #76] ; (8001fbc ) + warn_fishy_firmware(screen_devmode); + 8001f70: f7ff ff11 bl 8001d96 + oled_show(screen_corrupt); + + return false; +} + 8001f74: 4620 mov r0, r4 + 8001f76: b010 add sp, #64 ; 0x40 + 8001f78: bd70 pop {r4, r5, r6, pc} + } else if(FW_HDR->pubkey_num == 0) { + 8001f7a: f8d6 3094 ldr.w r3, [r6, #148] ; 0x94 + 8001f7e: b923 cbnz r3, 8001f8a + puts("WARN: Unsigned firmware"); + 8001f80: 480f ldr r0, [pc, #60] ; (8001fc0 ) + 8001f82: f003 f871 bl 8005068 + warn_fishy_firmware(screen_devmode); + 8001f86: 480f ldr r0, [pc, #60] ; (8001fc4 ) + 8001f88: e7f2 b.n 8001f70 + oled_show_progress(screen_verify, 100); + 8001f8a: 4809 ldr r0, [pc, #36] ; (8001fb0 ) + 8001f8c: 2164 movs r1, #100 ; 0x64 + 8001f8e: f7ff f8eb bl 8001168 + puts("Good firmware"); + 8001f92: 480d ldr r0, [pc, #52] ; (8001fc8 ) + 8001f94: e7e4 b.n 8001f60 + puts("corrupt firmware"); + 8001f96: 480d ldr r0, [pc, #52] ; (8001fcc ) + 8001f98: e7b4 b.n 8001f04 + 8001f9a: bf00 nop + 8001f9c: 08023f00 .word 0x08023f00 + 8001fa0: 08010486 .word 0x08010486 + 8001fa4: 0800db0d .word 0x0800db0d + 8001fa8: 08023f80 .word 0x08023f80 + 8001fac: 40022000 .word 0x40022000 + 8001fb0: 0801004d .word 0x0801004d + 8001fb4: 08010492 .word 0x08010492 + 8001fb8: 0801049f .word 0x0801049f + 8001fbc: 0800ec15 .word 0x0800ec15 + 8001fc0: 080104af .word 0x080104af + 8001fc4: 0800ddcf .word 0x0800ddcf + 8001fc8: 080104c7 .word 0x080104c7 + 8001fcc: 080104d5 .word 0x080104d5 + +08001fd0 : + void +systick_setup(void) +{ + const uint32_t ticks = HCLK_FREQUENCY/1000; + + SysTick->LOAD = (ticks - 1); + 8001fd0: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 8001fd4: 4a03 ldr r2, [pc, #12] ; (8001fe4 ) + 8001fd6: 615a str r2, [r3, #20] + SysTick->VAL = 0; + 8001fd8: 2200 movs r2, #0 + 8001fda: 619a str r2, [r3, #24] + SysTick->CTRL = SYSTICK_CLKSOURCE_HCLK | SysTick_CTRL_ENABLE_Msk; + 8001fdc: 2205 movs r2, #5 + 8001fde: 611a str r2, [r3, #16] +} + 8001fe0: 4770 bx lr + 8001fe2: bf00 nop + 8001fe4: 0001d4bf .word 0x0001d4bf + +08001fe8 : + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; +#endif + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ + 8001fe8: 4a0e ldr r2, [pc, #56] ; (8002024 ) + 8001fea: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 8001fee: f443 0370 orr.w r3, r3, #15728640 ; 0xf00000 + 8001ff2: f8c2 3088 str.w r3, [r2, #136] ; 0x88 +#endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + 8001ff6: 4b0c ldr r3, [pc, #48] ; (8002028 ) + 8001ff8: 681a ldr r2, [r3, #0] + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + 8001ffa: 2100 movs r1, #0 + RCC->CR |= RCC_CR_MSION; + 8001ffc: f042 0201 orr.w r2, r2, #1 + 8002000: 601a str r2, [r3, #0] + RCC->CFGR = 0x00000000U; + 8002002: 6099 str r1, [r3, #8] + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + 8002004: 681a ldr r2, [r3, #0] + 8002006: f022 52a8 bic.w r2, r2, #352321536 ; 0x15000000 + 800200a: f422 2210 bic.w r2, r2, #589824 ; 0x90000 + 800200e: 601a str r2, [r3, #0] + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + 8002010: f44f 5280 mov.w r2, #4096 ; 0x1000 + 8002014: 60da str r2, [r3, #12] + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + 8002016: 681a ldr r2, [r3, #0] + 8002018: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 800201c: 601a str r2, [r3, #0] + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + 800201e: 6199 str r1, [r3, #24] +} + 8002020: 4770 bx lr + 8002022: bf00 nop + 8002024: e000ed00 .word 0xe000ed00 + 8002028: 40021000 .word 0x40021000 + +0800202c : + +// clocks_setup() +// + void +clocks_setup(void) +{ + 800202c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + + // setup power supplies + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + + // Configure LSE Drive Capability + __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); + 8002030: 4c41 ldr r4, [pc, #260] ; (8002138 ) +{ + 8002032: b0c1 sub sp, #260 ; 0x104 + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); + 8002034: 2000 movs r0, #0 + 8002036: f005 f9e7 bl 8007408 + __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); + 800203a: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 800203e: f023 0318 bic.w r3, r3, #24 + 8002042: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + + // Enable HSE Oscillator and activate PLL with HSE as source + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + 8002046: 2201 movs r2, #1 + 8002048: f44f 3380 mov.w r3, #65536 ; 0x10000 + 800204c: e9cd 230a strd r2, r3, [sp, #40] ; 0x28 + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + RCC_OscInitStruct.MSIState = RCC_MSI_OFF; + + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 8002050: 2703 movs r7, #3 + + // Select PLL as system clock source and configure + // the HCLK, PCLK1 and PCLK2 clocks dividers + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK + 8002052: 230f movs r3, #15 + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + 8002054: 2500 movs r5, #0 + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 8002056: 2602 movs r6, #2 + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + 8002058: e9cd 3705 strd r3, r7, [sp, #20] + + RCC_OscInitStruct.PLL.PLLM = CKCC_CLK_PLLM; + RCC_OscInitStruct.PLL.PLLN = CKCC_CLK_PLLN; + RCC_OscInitStruct.PLL.PLLP = CKCC_CLK_PLLP; + 800205c: f04f 0807 mov.w r8, #7 + 8002060: 233c movs r3, #60 ; 0x3c + RCC_OscInitStruct.PLL.PLLQ = CKCC_CLK_PLLQ; + 8002062: f04f 0905 mov.w r9, #5 + + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_OscConfig(&RCC_OscInitStruct); + 8002066: a80a add r0, sp, #40 ; 0x28 + RCC_OscInitStruct.PLL.PLLP = CKCC_CLK_PLLP; + 8002068: e9cd 3817 strd r3, r8, [sp, #92] ; 0x5c + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + 800206c: e9cd 6714 strd r6, r7, [sp, #80] ; 0x50 + RCC_OscInitStruct.PLL.PLLR = CKCC_CLK_PLLR; + 8002070: e9cd 9619 strd r9, r6, [sp, #100] ; 0x64 + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + 8002074: e9cd 5507 strd r5, r5, [sp, #28] + RCC_OscInitStruct.LSEState = RCC_LSE_OFF; + 8002078: 950c str r5, [sp, #48] ; 0x30 + RCC_OscInitStruct.MSIState = RCC_MSI_OFF; + 800207a: 9510 str r5, [sp, #64] ; 0x40 + RCC_OscInitStruct.PLL.PLLM = CKCC_CLK_PLLM; + 800207c: 9616 str r6, [sp, #88] ; 0x58 + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + 800207e: 9509 str r5, [sp, #36] ; 0x24 + HAL_RCC_OscConfig(&RCC_OscInitStruct); + 8002080: f006 fd64 bl 8008b4c + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + 8002084: 4649 mov r1, r9 + 8002086: a805 add r0, sp, #20 + 8002088: f007 f80e bl 80090a8 + + // DIS-able MSI-Hardware auto calibration mode with LSE + CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN); + 800208c: 6823 ldr r3, [r4, #0] + 800208e: f023 0304 bic.w r3, r3, #4 + 8002092: 6023 str r3, [r4, #0] + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_I2C2 + 8002094: 4b29 ldr r3, [pc, #164] ; (800213c ) + 8002096: 931b str r3, [sp, #108] ; 0x6c + + // PLLSAI is used to clock USB, ADC, I2C1 and RNG. The frequency is + // HSE(8MHz)/PLLM(2)*PLLSAI1N(24)/PLLSAIQ(2) = 48MHz. + // + PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1; + 8002098: f04f 5380 mov.w r3, #268435456 ; 0x10000000 + 800209c: 933b str r3, [sp, #236] ; 0xec + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1; + 800209e: f04f 6380 mov.w r3, #67108864 ; 0x4000000 + 80020a2: 9338 str r3, [sp, #224] ; 0xe0 + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1; + 80020a4: 933a str r3, [sp, #232] ; 0xe8 + + PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE; + PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 2; + PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 24; + 80020a6: 2318 movs r3, #24 + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + 80020a8: f44f 7240 mov.w r2, #768 ; 0x300 + PeriphClkInitStruct.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7; + 80020ac: e9cd 381e strd r3, r8, [sp, #120] ; 0x78 + PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + |RCC_PLLSAI1_48M2CLK + |RCC_PLLSAI1_ADC1CLK; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + 80020b0: a81b add r0, sp, #108 ; 0x6c + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + 80020b2: 4b23 ldr r3, [pc, #140] ; (8002140 ) + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32; // but unused + 80020b4: 923f str r2, [sp, #252] ; 0xfc + PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK + 80020b6: 9322 str r3, [sp, #136] ; 0x88 + PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 2; + 80020b8: e9cd 761c strd r7, r6, [sp, #112] ; 0x70 + PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2; + 80020bc: e9cd 6620 strd r6, r6, [sp, #128] ; 0x80 + PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; + 80020c0: 9531 str r5, [sp, #196] ; 0xc4 + PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; + 80020c2: 9536 str r5, [sp, #216] ; 0xd8 + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + 80020c4: f007 fb14 bl 80096f0 + + __HAL_RCC_RTC_ENABLE(); + 80020c8: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 80020cc: f443 4300 orr.w r3, r3, #32768 ; 0x8000 + 80020d0: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + __HAL_RCC_HASH_CLK_ENABLE(); // for SHA256 + 80020d4: 6ce3 ldr r3, [r4, #76] ; 0x4c + 80020d6: f443 3300 orr.w r3, r3, #131072 ; 0x20000 + 80020da: 64e3 str r3, [r4, #76] ; 0x4c + 80020dc: 6ce3 ldr r3, [r4, #76] ; 0x4c + 80020de: f403 3300 and.w r3, r3, #131072 ; 0x20000 + 80020e2: 9301 str r3, [sp, #4] + 80020e4: 9b01 ldr r3, [sp, #4] + __HAL_RCC_SPI1_CLK_ENABLE(); // for OLED + 80020e6: 6e23 ldr r3, [r4, #96] ; 0x60 + 80020e8: f443 5380 orr.w r3, r3, #4096 ; 0x1000 + 80020ec: 6623 str r3, [r4, #96] ; 0x60 + 80020ee: 6e23 ldr r3, [r4, #96] ; 0x60 + 80020f0: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 80020f4: 9302 str r3, [sp, #8] + 80020f6: 9b02 ldr r3, [sp, #8] + //__HAL_RCC_SPI2_CLK_ENABLE(); // for SPI flash + __HAL_RCC_DMAMUX1_CLK_ENABLE(); // (need this) because code missing in mpy? + 80020f8: 6ca3 ldr r3, [r4, #72] ; 0x48 + 80020fa: f043 0304 orr.w r3, r3, #4 + 80020fe: 64a3 str r3, [r4, #72] ; 0x48 + 8002100: 6ca3 ldr r3, [r4, #72] ; 0x48 + 8002102: f003 0304 and.w r3, r3, #4 + 8002106: 9303 str r3, [sp, #12] + 8002108: 9b03 ldr r3, [sp, #12] + + // for SE2 + __HAL_RCC_I2C2_CLK_ENABLE(); + 800210a: 6da3 ldr r3, [r4, #88] ; 0x58 + 800210c: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 8002110: 65a3 str r3, [r4, #88] ; 0x58 + 8002112: 6da3 ldr r3, [r4, #88] ; 0x58 + 8002114: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 8002118: 9304 str r3, [sp, #16] + 800211a: 9b04 ldr r3, [sp, #16] + __HAL_RCC_I2C2_FORCE_RESET(); + 800211c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800211e: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 8002122: 63a3 str r3, [r4, #56] ; 0x38 + __HAL_RCC_I2C2_RELEASE_RESET(); + 8002124: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8002126: f423 0380 bic.w r3, r3, #4194304 ; 0x400000 + 800212a: 63a3 str r3, [r4, #56] ; 0x38 + + // setup SYSTICK, but we don't have the irq hooked up and not using HAL + // but we use it in polling mode for delay_ms() + systick_setup(); + 800212c: f7ff ff50 bl 8001fd0 + +} + 8002130: b041 add sp, #260 ; 0x104 + 8002132: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 8002136: bf00 nop + 8002138: 40021000 .word 0x40021000 + 800213c: 00066880 .word 0x00066880 + 8002140: 01110000 .word 0x01110000 + +08002144 : + } else { + + // write changes to OB flash bytes + + // Set OPTSTRT bit + SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT); + 8002144: 4b13 ldr r3, [pc, #76] ; (8002194 ) + 8002146: 695a ldr r2, [r3, #20] + 8002148: f442 3200 orr.w r2, r2, #131072 ; 0x20000 + 800214c: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { + 800214e: 691a ldr r2, [r3, #16] + 8002150: 03d2 lsls r2, r2, #15 + 8002152: d4fc bmi.n 800214e + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); + 8002154: 6919 ldr r1, [r3, #16] + if(error) { + 8002156: 4a10 ldr r2, [pc, #64] ; (8002198 ) + 8002158: 4211 tst r1, r2 + 800215a: d104 bne.n 8002166 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { + 800215c: 691a ldr r2, [r3, #16] + 800215e: 07d0 lsls r0, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + 8002160: bf44 itt mi + 8002162: 2201 movmi r2, #1 + 8002164: 611a strmi r2, [r3, #16] + + /// Wait for update to complete + _flash_wait_done(); + + // lock OB again. + SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK); + 8002166: 4b0b ldr r3, [pc, #44] ; (8002194 ) + 8002168: 695a ldr r2, [r3, #20] + 800216a: f042 4280 orr.w r2, r2, #1073741824 ; 0x40000000 + 800216e: 615a str r2, [r3, #20] + + // include "launch" to make them take effect NOW + SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH); + 8002170: 695a ldr r2, [r3, #20] + 8002172: f042 6200 orr.w r2, r2, #134217728 ; 0x8000000 + 8002176: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { + 8002178: 691a ldr r2, [r3, #16] + 800217a: 03d1 lsls r1, r2, #15 + 800217c: d4fc bmi.n 8002178 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); + 800217e: 6919 ldr r1, [r3, #16] + if(error) { + 8002180: 4a05 ldr r2, [pc, #20] ; (8002198 ) + 8002182: 4211 tst r1, r2 + 8002184: d104 bne.n 8002190 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { + 8002186: 691a ldr r2, [r3, #16] + 8002188: 07d2 lsls r2, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + 800218a: bf44 itt mi + 800218c: 2201 movmi r2, #1 + 800218e: 611a strmi r2, [r3, #16] + + _flash_wait_done(); + } +} + 8002190: 4770 bx lr + 8002192: bf00 nop + 8002194: 40022000 .word 0x40022000 + 8002198: 0002c3fa .word 0x0002c3fa + +0800219c : +{ + 800219c: b507 push {r0, r1, r2, lr} + memcpy(&_srelocate, &_etext, ((uint32_t)&_erelocate)-(uint32_t)&_srelocate); + 800219e: 4809 ldr r0, [pc, #36] ; (80021c4 ) + 80021a0: 4a09 ldr r2, [pc, #36] ; (80021c8 ) + 80021a2: 490a ldr r1, [pc, #40] ; (80021cc ) + 80021a4: 1a12 subs r2, r2, r0 + 80021a6: f00b fbaf bl 800d908 + __HAL_RCC_FLASH_CLK_ENABLE(); + 80021aa: 4b09 ldr r3, [pc, #36] ; (80021d0 ) + 80021ac: 6c9a ldr r2, [r3, #72] ; 0x48 + 80021ae: f442 7280 orr.w r2, r2, #256 ; 0x100 + 80021b2: 649a str r2, [r3, #72] ; 0x48 + 80021b4: 6c9b ldr r3, [r3, #72] ; 0x48 + 80021b6: f403 7380 and.w r3, r3, #256 ; 0x100 + 80021ba: 9301 str r3, [sp, #4] + 80021bc: 9b01 ldr r3, [sp, #4] +} + 80021be: b003 add sp, #12 + 80021c0: f85d fb04 ldr.w pc, [sp], #4 + 80021c4: 2009e000 .word 0x2009e000 + 80021c8: 2009e150 .word 0x2009e150 + 80021cc: 08010ac4 .word 0x08010ac4 + 80021d0: 40021000 .word 0x40021000 + +080021d4 : + SET_BIT(FLASH->CR, FLASH_CR_LOCK); + 80021d4: 4a02 ldr r2, [pc, #8] ; (80021e0 ) + 80021d6: 6953 ldr r3, [r2, #20] + 80021d8: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 80021dc: 6153 str r3, [r2, #20] +} + 80021de: 4770 bx lr + 80021e0: 40022000 .word 0x40022000 + +080021e4 : +{ + 80021e4: b508 push {r3, lr} + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { + 80021e6: 4b08 ldr r3, [pc, #32] ; (8002208 ) + 80021e8: 695a ldr r2, [r3, #20] + 80021ea: 2a00 cmp r2, #0 + 80021ec: da0a bge.n 8002204 + WRITE_REG(FLASH->KEYR, FLASH_KEY1); + 80021ee: 4a07 ldr r2, [pc, #28] ; (800220c ) + 80021f0: 609a str r2, [r3, #8] + WRITE_REG(FLASH->KEYR, FLASH_KEY2); + 80021f2: f102 3288 add.w r2, r2, #2290649224 ; 0x88888888 + 80021f6: 609a str r2, [r3, #8] + if(READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { + 80021f8: 695b ldr r3, [r3, #20] + 80021fa: 2b00 cmp r3, #0 + 80021fc: da02 bge.n 8002204 + INCONSISTENT("failed to unlock"); + 80021fe: 4804 ldr r0, [pc, #16] ; (8002210 ) + 8002200: f7fe fc1a bl 8000a38 +} + 8002204: bd08 pop {r3, pc} + 8002206: bf00 nop + 8002208: 40022000 .word 0x40022000 + 800220c: 45670123 .word 0x45670123 + 8002210: 0800d9a0 .word 0x0800d9a0 + +08002214 : +{ + 8002214: b510 push {r4, lr} + if(!lock) { + 8002216: b980 cbnz r0, 800223a + if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { + 8002218: 4c0a ldr r4, [pc, #40] ; (8002244 ) + 800221a: 6963 ldr r3, [r4, #20] + 800221c: 005a lsls r2, r3, #1 + 800221e: d510 bpl.n 8002242 + flash_unlock(); + 8002220: f7ff ffe0 bl 80021e4 + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); + 8002224: 4b08 ldr r3, [pc, #32] ; (8002248 ) + 8002226: 60e3 str r3, [r4, #12] + WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); + 8002228: f103 3344 add.w r3, r3, #1145324612 ; 0x44444444 + 800222c: 60e3 str r3, [r4, #12] + if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { + 800222e: 6963 ldr r3, [r4, #20] + 8002230: 005b lsls r3, r3, #1 + 8002232: d506 bpl.n 8002242 + INCONSISTENT("failed to OB unlock"); + 8002234: 4805 ldr r0, [pc, #20] ; (800224c ) + 8002236: f7fe fbff bl 8000a38 +} + 800223a: e8bd 4010 ldmia.w sp!, {r4, lr} + 800223e: f7ff bf81 b.w 8002144 + 8002242: bd10 pop {r4, pc} + 8002244: 40022000 .word 0x40022000 + 8002248: 08192a3b .word 0x08192a3b + 800224c: 0800d9a0 .word 0x0800d9a0 + +08002250 : +// +// Write the serial number of ATECC608 into flash forever. +// + void +flash_save_ae_serial(const uint8_t serial[9]) +{ + 8002250: b51f push {r0, r1, r2, r3, r4, lr} + 8002252: 4602 mov r2, r0 + uint64_t tmp[2]; + memset(&tmp, 0x0, sizeof(tmp)); + 8002254: 2300 movs r3, #0 + memcpy(&tmp, serial, 9); + 8002256: 6800 ldr r0, [r0, #0] + 8002258: 6851 ldr r1, [r2, #4] + 800225a: 7a12 ldrb r2, [r2, #8] + memset(&tmp, 0x0, sizeof(tmp)); + 800225c: e9cd 3302 strd r3, r3, [sp, #8] + memcpy(&tmp, serial, 9); + 8002260: 466b mov r3, sp + 8002262: c303 stmia r3!, {r0, r1} + 8002264: 701a strb r2, [r3, #0] + + flash_setup0(); + 8002266: f7ff ff99 bl 800219c + flash_unlock(); + 800226a: f7ff ffbb bl 80021e4 + + if(flash_burn((uint32_t)&rom_secrets->ae_serial_number[0], tmp[0])) { + 800226e: e9dd 2300 ldrd r2, r3, [sp] + 8002272: 4809 ldr r0, [pc, #36] ; (8002298 ) + 8002274: f00b fb8c bl 800d990 <__flash_burn_veneer> + 8002278: b110 cbz r0, 8002280 + INCONSISTENT("fail1"); + 800227a: 4808 ldr r0, [pc, #32] ; (800229c ) + 800227c: f7fe fbdc bl 8000a38 + } + if(flash_burn((uint32_t)&rom_secrets->ae_serial_number[1], tmp[1])) { + 8002280: e9dd 2302 ldrd r2, r3, [sp, #8] + 8002284: 4806 ldr r0, [pc, #24] ; (80022a0 ) + 8002286: f00b fb83 bl 800d990 <__flash_burn_veneer> + 800228a: 2800 cmp r0, #0 + 800228c: d1f5 bne.n 800227a + INCONSISTENT("fail2"); + } + + flash_lock(); +} + 800228e: b005 add sp, #20 + 8002290: f85d eb04 ldr.w lr, [sp], #4 + flash_lock(); + 8002294: f7ff bf9e b.w 80021d4 + 8002298: 0801c040 .word 0x0801c040 + 800229c: 0800d9a0 .word 0x0800d9a0 + 80022a0: 0801c048 .word 0x0801c048 + +080022a4 : +// +// Write bag number (probably a string) +// + void +flash_save_bag_number(const uint8_t new_number[32]) +{ + 80022a4: b570 push {r4, r5, r6, lr} + 80022a6: b088 sub sp, #32 + uint32_t dest = (uint32_t)&rom_secrets->bag_number[0]; + uint64_t tmp[4] = { 0 }; + uint64_t *src = tmp; + + STATIC_ASSERT(sizeof(tmp) == 32); + memcpy(tmp, new_number, 32); + 80022a8: 4603 mov r3, r0 + 80022aa: 466c mov r4, sp + 80022ac: f100 0520 add.w r5, r0, #32 + 80022b0: 6818 ldr r0, [r3, #0] + 80022b2: 6859 ldr r1, [r3, #4] + 80022b4: 4622 mov r2, r4 + 80022b6: c203 stmia r2!, {r0, r1} + 80022b8: 3308 adds r3, #8 + 80022ba: 42ab cmp r3, r5 + 80022bc: 4614 mov r4, r2 + 80022be: d1f7 bne.n 80022b0 + + flash_setup0(); + 80022c0: f7ff ff6c bl 800219c + flash_unlock(); + 80022c4: f7ff ff8e bl 80021e4 + uint32_t dest = (uint32_t)&rom_secrets->bag_number[0]; + 80022c8: 4d09 ldr r5, [pc, #36] ; (80022f0 ) + + // NOTE: can only write once! No provision for read/check/update. + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80022ca: 4e0a ldr r6, [pc, #40] ; (80022f4 ) + 80022cc: 466c mov r4, sp + if(flash_burn(dest, *src)) { + 80022ce: e8f4 2302 ldrd r2, r3, [r4], #8 + 80022d2: 4628 mov r0, r5 + 80022d4: f00b fb5c bl 800d990 <__flash_burn_veneer> + 80022d8: b110 cbz r0, 80022e0 + INCONSISTENT("fail write"); + 80022da: 4807 ldr r0, [pc, #28] ; (80022f8 ) + 80022dc: f7fe fbac bl 8000a38 + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 80022e0: 3508 adds r5, #8 + 80022e2: 42b5 cmp r5, r6 + 80022e4: d1f3 bne.n 80022ce + } + } + + flash_lock(); +} + 80022e6: b008 add sp, #32 + 80022e8: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + flash_lock(); + 80022ec: f7ff bf72 b.w 80021d4 + 80022f0: 0801c050 .word 0x0801c050 + 80022f4: 0801c070 .word 0x0801c070 + 80022f8: 0800d9a0 .word 0x0800d9a0 + +080022fc : +// Save bunch of stuff related to SE2. Allow updates to sections that are +// given as ones at this point. +// + void +flash_save_se2_data(const se2_secrets_t *se2) +{ + 80022fc: e92d 41f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, lr} + 8002300: 4605 mov r5, r0 + uint8_t *dest = (uint8_t *)&rom_secrets->se2; + 8002302: 4c1a ldr r4, [pc, #104] ; (800236c ) + STATIC_ASSERT(offsetof(rom_secrets_t, se2) % 8 == 0); + + flash_setup0(); + flash_unlock(); + + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 8002304: f8df 8070 ldr.w r8, [pc, #112] ; 8002378 + flash_setup0(); + 8002308: f7ff ff48 bl 800219c + flash_unlock(); + 800230c: f7ff ff6a bl 80021e4 + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 8002310: 1b2d subs r5, r5, r4 + 8002312: eb05 0c04 add.w ip, r5, r4 + uint64_t val; + memcpy(&val, src, sizeof(val)); + 8002316: 5928 ldr r0, [r5, r4] + 8002318: f8dc 1004 ldr.w r1, [ip, #4] + 800231c: 466b mov r3, sp + + // don't write if all ones or already written correctly + if(val == ~0) continue; + 800231e: f1b1 3fff cmp.w r1, #4294967295 ; 0xffffffff + 8002322: bf08 it eq + 8002324: f1b0 3fff cmpeq.w r0, #4294967295 ; 0xffffffff + memcpy(&val, src, sizeof(val)); + 8002328: c303 stmia r3!, {r0, r1} + if(val == ~0) continue; + 800232a: 4607 mov r7, r0 + 800232c: 460e mov r6, r1 + 800232e: d015 beq.n 800235c + if(check_equal(dest, src, 8)) continue; + 8002330: 2208 movs r2, #8 + 8002332: 4661 mov r1, ip + 8002334: 4620 mov r0, r4 + 8002336: f000 fa82 bl 800283e + 800233a: b978 cbnz r0, 800235c + + // can't write if not ones already + ASSERT(check_all_ones(dest, 8)); + 800233c: 2108 movs r1, #8 + 800233e: 4620 mov r0, r4 + 8002340: f000 fa64 bl 800280c + 8002344: b910 cbnz r0, 800234c + 8002346: 480a ldr r0, [pc, #40] ; (8002370 ) + + if(flash_burn((uint32_t)dest, val)) { + INCONSISTENT("fail write"); + 8002348: f7fe fb76 bl 8000a38 + if(flash_burn((uint32_t)dest, val)) { + 800234c: 463a mov r2, r7 + 800234e: 4633 mov r3, r6 + 8002350: 4620 mov r0, r4 + 8002352: f00b fb1d bl 800d990 <__flash_burn_veneer> + 8002356: b108 cbz r0, 800235c + INCONSISTENT("fail write"); + 8002358: 4806 ldr r0, [pc, #24] ; (8002374 ) + 800235a: e7f5 b.n 8002348 + for(int i=0; i<(sizeof(se2_secrets_t)/8); i++, dest+=8, src+=8) { + 800235c: 3408 adds r4, #8 + 800235e: 4544 cmp r4, r8 + 8002360: d1d7 bne.n 8002312 + } + } + + flash_lock(); +} + 8002362: b002 add sp, #8 + 8002364: e8bd 41f0 ldmia.w sp!, {r4, r5, r6, r7, r8, lr} + flash_lock(); + 8002368: f7ff bf34 b.w 80021d4 + 800236c: 0801c0b0 .word 0x0801c0b0 + 8002370: 0801046c .word 0x0801046c + 8002374: 0800d9a0 .word 0x0800d9a0 + 8002378: 0801c190 .word 0x0801c190 + +0800237c : +// +// This is really a state-machine, to recover boards that are booted w/ missing AE chip. +// + void +flash_setup(void) +{ + 800237c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + + // see if we have picked a pairing secret yet. + // NOTE: critical section for glitching (at least in past versions) + // - check_all.. functions have a rng_delay in them already + rng_delay(); + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 8002380: 4e58 ldr r6, [pc, #352] ; (80024e4 ) +{ + 8002382: b08b sub sp, #44 ; 0x2c + flash_setup0(); + 8002384: f7ff ff0a bl 800219c + rng_delay(); + 8002388: f000 fabe bl 8002908 + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 800238c: 2120 movs r1, #32 + 800238e: 4630 mov r0, r6 + 8002390: f000 fa3c bl 800280c + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 8002394: 2120 movs r1, #32 + bool blank_ps = check_all_ones(rom_secrets->pairing_secret, 32); + 8002396: 4681 mov r9, r0 + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 8002398: 4630 mov r0, r6 + 800239a: f000 fa41 bl 8002820 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 800239e: 2120 movs r1, #32 + bool zeroed_ps = check_all_zeros(rom_secrets->pairing_secret, 32); + 80023a0: 4604 mov r4, r0 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 80023a2: 4851 ldr r0, [pc, #324] ; (80024e8 ) + 80023a4: f000 fa32 bl 800280c + bool blank_ae = (~rom_secrets->ae_serial_number[0] == 0); + 80023a8: e9d6 7810 ldrd r7, r8, [r6, #64] ; 0x40 + bool blank_xor = check_all_ones(rom_secrets->pairing_secret_xor, 32); + 80023ac: 4605 mov r5, r0 + rng_delay(); + 80023ae: f000 faab bl 8002908 + + if(zeroed_ps) { + 80023b2: b124 cbz r4, 80023be + // fast brick process leaves us w/ zero pairing secret + oled_show(screen_brick); + 80023b4: 484d ldr r0, [pc, #308] ; (80024ec ) + 80023b6: f7fe fe5d bl 8001074 + // Hardware fail speaking to AE chip ... be careful not to brick here. + // Do not continue!! We might fix the board, or add missing pullup, etc. + oled_show(screen_se1_issue); + puts("SE1 config fail"); + + LOCKUP_FOREVER(); + 80023ba: f001 fc5d bl 8003c78 + if(blank_ps) { + 80023be: f1b9 0f00 cmp.w r9, #0 + 80023c2: d03e beq.n 8002442 + rng_setup(); + 80023c4: f000 fa5e bl 8002884 + oled_show(screen_se_setup); + 80023c8: 4849 ldr r0, [pc, #292] ; (80024f0 ) + 80023ca: f7fe fe53 bl 8001074 + for(int i=0; i<8; i++) { + 80023ce: ae02 add r6, sp, #8 + oled_show(screen_se_setup); + 80023d0: 46b1 mov r9, r6 + secret[i] = rng_sample(); + 80023d2: f000 fa45 bl 8002860 + for(int i=0; i<8; i++) { + 80023d6: 3401 adds r4, #1 + 80023d8: 2c08 cmp r4, #8 + secret[i] = rng_sample(); + 80023da: f849 0b04 str.w r0, [r9], #4 + for(int i=0; i<8; i++) { + 80023de: d1f8 bne.n 80023d2 + while(secret[0] == ~0) { + 80023e0: 9b02 ldr r3, [sp, #8] + 80023e2: 3301 adds r3, #1 + 80023e4: d00d beq.n 8002402 + flash_unlock(); + 80023e6: f7ff fefd bl 80021e4 + uint32_t dest = (uint32_t)&rom_secrets->pairing_secret; + 80023ea: 4c3e ldr r4, [pc, #248] ; (80024e4 ) + for(int i=0; i<8; i+=2, dest += 8) { + 80023ec: f8df 90f8 ldr.w r9, [pc, #248] ; 80024e8 + if(flash_burn(dest, val)) { + 80023f0: e9d6 3200 ldrd r3, r2, [r6] + 80023f4: 4620 mov r0, r4 + 80023f6: f00b facb bl 800d990 <__flash_burn_veneer> + 80023fa: b130 cbz r0, 800240a + INCONSISTENT("flash fail"); + 80023fc: 483d ldr r0, [pc, #244] ; (80024f4 ) + 80023fe: f7fe fb1b bl 8000a38 + secret[0] = rng_sample(); + 8002402: f000 fa2d bl 8002860 + 8002406: 9002 str r0, [sp, #8] + 8002408: e7ea b.n 80023e0 + for(int i=0; i<8; i+=2, dest += 8) { + 800240a: 3408 adds r4, #8 + 800240c: 454c cmp r4, r9 + 800240e: f106 0608 add.w r6, r6, #8 + 8002412: d1ed bne.n 80023f0 + flash_lock(); + 8002414: f7ff fede bl 80021d4 + flash_unlock(); + 8002418: f7ff fee4 bl 80021e4 + uint32_t dest = (uint32_t)&rom_secrets->hash_cache_secret; + 800241c: 4c36 ldr r4, [pc, #216] ; (80024f8 ) + for(int i=0; i) + uint64_t val = ((uint64_t)rng_sample() << 32) | rng_sample(); + 8002420: f000 fa1e bl 8002860 + 8002424: 9001 str r0, [sp, #4] + 8002426: f000 fa1b bl 8002860 + if(flash_burn(dest, val)) { + 800242a: 9b01 ldr r3, [sp, #4] + uint64_t val = ((uint64_t)rng_sample() << 32) | rng_sample(); + 800242c: 4602 mov r2, r0 + if(flash_burn(dest, val)) { + 800242e: 4620 mov r0, r4 + 8002430: f00b faae bl 800d990 <__flash_burn_veneer> + 8002434: 2800 cmp r0, #0 + 8002436: d1e1 bne.n 80023fc + for(int i=0; i + flash_lock(); + 800243e: f7ff fec9 bl 80021d4 + if(blank_xor || blank_ae) { + 8002442: b92d cbnz r5, 8002450 + 8002444: f1b8 3fff cmp.w r8, #4294967295 ; 0xffffffff + 8002448: bf08 it eq + 800244a: f1b7 3fff cmpeq.w r7, #4294967295 ; 0xffffffff + 800244e: d126 bne.n 800249e + se2_setup_config(); + 8002450: f005 fb94 bl 8007b7c + int rv = ae_setup_config(); + 8002454: f001 f992 bl 800377c + 8002458: 4604 mov r4, r0 + rng_delay(); + 800245a: f000 fa55 bl 8002908 + if(rv) { + 800245e: b134 cbz r4, 800246e + oled_show(screen_se1_issue); + 8002460: 4827 ldr r0, [pc, #156] ; (8002500 ) + 8002462: f7fe fe07 bl 8001074 + puts("SE1 config fail"); + 8002466: 4827 ldr r0, [pc, #156] ; (8002504 ) + 8002468: f002 fdfe bl 8005068 + 800246c: e7a5 b.n 80023ba + } + + rng_delay(); + 800246e: f000 fa4b bl 8002908 + if(blank_xor) { + 8002472: b195 cbz r5, 800249a + flash_unlock(); + 8002474: f7ff feb6 bl 80021e4 + uint64_t *src = (uint64_t *)&rom_secrets->pairing_secret; + 8002478: 4c1a ldr r4, [pc, #104] ; (80024e4 ) + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 800247a: 4e1b ldr r6, [pc, #108] ; (80024e8 ) + uint64_t val = ~(*src); + 800247c: e9d4 2300 ldrd r2, r3, [r4] + if(flash_burn(dest, val)) { + 8002480: f104 0020 add.w r0, r4, #32 + 8002484: 43d2 mvns r2, r2 + 8002486: 43db mvns r3, r3 + 8002488: f00b fa82 bl 800d990 <__flash_burn_veneer> + 800248c: 2800 cmp r0, #0 + 800248e: d1b5 bne.n 80023fc + for(int i=0; i<(32/8); i++, dest+=8, src++) { + 8002490: 3408 adds r4, #8 + 8002492: 42b4 cmp r4, r6 + 8002494: d1f2 bne.n 800247c + flash_lock(); + 8002496: f7ff fe9d bl 80021d4 + + // real power cycle required now. +#ifdef FOR_Q1_ONLY + // Q: just do it (we warned them) + extern void turn_power_off(void); + turn_power_off(); + 800249a: f001 fbe1 bl 8003c60 + puts("replug required"); + LOCKUP_FOREVER(); +#endif + } + + rng_delay(); + 800249e: f000 fa33 bl 8002908 + if(!blank_ps && !blank_xor) { + 80024a2: b9e5 cbnz r5, 80024de + // check the XOR value also written: 2 phase commit + uint8_t tmp[32]; + memcpy(tmp, rom_secrets->pairing_secret, 32); + 80024a4: 4d0f ldr r5, [pc, #60] ; (80024e4 ) + 80024a6: cd0f ldmia r5!, {r0, r1, r2, r3} + 80024a8: ac02 add r4, sp, #8 + 80024aa: c40f stmia r4!, {r0, r1, r2, r3} + 80024ac: e895 000f ldmia.w r5, {r0, r1, r2, r3} + 80024b0: e884 000f stmia.w r4, {r0, r1, r2, r3} + 80024b4: ab02 add r3, sp, #8 + 80024b6: 4a0c ldr r2, [pc, #48] ; (80024e8 ) +bool check_equal(const void *aV, const void *bV, int len); + +// XOR-mixin more bytes; acc = acc XOR more for each byte +void static inline xor_mixin(uint8_t *acc, const uint8_t *more, int len) +{ + for(; len; len--, more++, acc++) { + 80024b8: 4c13 ldr r4, [pc, #76] ; (8002508 ) + 80024ba: 4618 mov r0, r3 + *(acc) ^= *(more); + 80024bc: 7819 ldrb r1, [r3, #0] + 80024be: f812 5b01 ldrb.w r5, [r2], #1 + 80024c2: 4069 eors r1, r5 + for(; len; len--, more++, acc++) { + 80024c4: 42a2 cmp r2, r4 + *(acc) ^= *(more); + 80024c6: f803 1b01 strb.w r1, [r3], #1 + for(; len; len--, more++, acc++) { + 80024ca: d1f7 bne.n 80024bc + xor_mixin(tmp, rom_secrets->pairing_secret_xor, 32); + + if(!check_all_ones(tmp, 32)) { + 80024cc: 2120 movs r1, #32 + 80024ce: f000 f99d bl 800280c + 80024d2: b920 cbnz r0, 80024de + oled_show(screen_corrupt); + 80024d4: 480d ldr r0, [pc, #52] ; (800250c ) + 80024d6: f7fe fdcd bl 8001074 + puts("corrupt pair sec"); + 80024da: 480d ldr r0, [pc, #52] ; (8002510 ) + 80024dc: e7c4 b.n 8002468 + // That's fine if we intend to ship units locked already. + + // Do NOT do write every boot, as it might wear-out + // the flash bits in OB. + +} + 80024de: b00b add sp, #44 ; 0x2c + 80024e0: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 80024e4: 0801c000 .word 0x0801c000 + 80024e8: 0801c020 .word 0x0801c020 + 80024ec: 0800da61 .word 0x0800da61 + 80024f0: 0800f671 .word 0x0800f671 + 80024f4: 0800d9a0 .word 0x0800d9a0 + 80024f8: 0801c070 .word 0x0801c070 + 80024fc: 0801c0b0 .word 0x0801c0b0 + 8002500: 0800f13a .word 0x0800f13a + 8002504: 08010666 .word 0x08010666 + 8002508: 0801c040 .word 0x0801c040 + 800250c: 0800db0d .word 0x0800db0d + 8002510: 08010676 .word 0x08010676 + +08002514 : +// +// This is a one-way trip. Might need power cycle to (fully?) take effect. +// + void +flash_lockdown_hard(uint8_t rdp_level_code) +{ + 8002514: b510 push {r4, lr} + 8002516: 4604 mov r4, r0 +#if RELEASE + flash_setup0(); + 8002518: f7ff fe40 bl 800219c + + // see FLASH_OB_WRPConfig() + + flash_ob_lock(false); + 800251c: 2000 movs r0, #0 + 800251e: f7ff fe79 bl 8002214 + // lock first 128k-8k against any writes + FLASH->WRP1AR = (num_pages_locked << 16); + 8002522: 4b08 ldr r3, [pc, #32] ; (8002544 ) + 8002524: f44f 2260 mov.w r2, #917504 ; 0xe0000 + 8002528: 62da str r2, [r3, #44] ; 0x2c + FLASH->WRP1BR = 0xff; // unused. + 800252a: 22ff movs r2, #255 ; 0xff + 800252c: 631a str r2, [r3, #48] ; 0x30 + FLASH->WRP2AR = 0xff; // unused. + 800252e: 64da str r2, [r3, #76] ; 0x4c + FLASH->WRP2BR = 0xff; // unused. + 8002530: 651a str r2, [r3, #80] ; 0x50 + // the RDP level is decreased from Level 1 to Level 0)." + // - D-bus access blocked, even for code running inside the PCROP area! (AN4758) + // So literal values and constant tables and such would need special linking. + + // set protection level + uint32_t was = FLASH->OPTR & ~0xff; + 8002532: 6a1a ldr r2, [r3, #32] + 8002534: f022 02ff bic.w r2, r2, #255 ; 0xff + FLASH->OPTR = was | rdp_level_code; // select level X, other values as observed + 8002538: 4322 orrs r2, r4 + 800253a: 621a str r2, [r3, #32] +#else + puts2("flash_lockdown_hard("); + puthex2(rdp_level_code); + puts(") skipped"); +#endif +} + 800253c: e8bd 4010 ldmia.w sp!, {r4, lr} + 8002540: f7ff be00 b.w 8002144 + 8002544: 40022000 .word 0x40022000 + +08002548 : + +// record_highwater_version() +// + int +record_highwater_version(const uint8_t timestamp[8]) +{ + 8002548: b537 push {r0, r1, r2, r4, r5, lr} + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + + ASSERT(timestamp[0] < 0x40); + ASSERT(timestamp[0] >= 0x10); + 800254a: 7802 ldrb r2, [r0, #0] + 800254c: 3a10 subs r2, #16 + 800254e: 2a2f cmp r2, #47 ; 0x2f +{ + 8002550: 4603 mov r3, r0 + ASSERT(timestamp[0] >= 0x10); + 8002552: d902 bls.n 800255a + ASSERT(timestamp[0] < 0x40); + 8002554: 4810 ldr r0, [pc, #64] ; (8002598 ) + 8002556: f7fe fa6f bl 8000a38 + + uint64_t val = 0; + memcpy(&val, timestamp, 8); + 800255a: 6800 ldr r0, [r0, #0] + 800255c: 6859 ldr r1, [r3, #4] + const uint8_t *otp = (const uint8_t *)OPT_FLASH_BASE; + 800255e: 4c0f ldr r4, [pc, #60] ; (800259c ) + + // just write to first blank slot we can find. + for(int i=0; i) + memcpy(&val, timestamp, 8); + 8002562: 466a mov r2, sp + 8002564: c203 stmia r2!, {r0, r1} + if(check_all_ones(otp, 8)) { + 8002566: 2108 movs r1, #8 + 8002568: 4620 mov r0, r4 + 800256a: f000 f94f bl 800280c + 800256e: b168 cbz r0, 800258c + // write here. + flash_setup0(); + 8002570: f7ff fe14 bl 800219c + flash_unlock(); + 8002574: f7ff fe36 bl 80021e4 + flash_burn((uint32_t)otp, val); + 8002578: e9dd 2300 ldrd r2, r3, [sp] + 800257c: 4620 mov r0, r4 + 800257e: f00b fa07 bl 800d990 <__flash_burn_veneer> + flash_lock(); + 8002582: f7ff fe27 bl 80021d4 + + return 0; + 8002586: 2000 movs r0, #0 + } + } + + // no space. + return 1; +} + 8002588: b003 add sp, #12 + 800258a: bd30 pop {r4, r5, pc} + for(int i=0; i + return 1; + 8002592: 2001 movs r0, #1 + 8002594: e7f8 b.n 8002588 + 8002596: bf00 nop + 8002598: 0801046c .word 0x0801046c + 800259c: 1fff7000 .word 0x1fff7000 + 80025a0: 1fff7400 .word 0x1fff7400 + +080025a4 : + +// mcu_key_get() +// + const mcu_key_t * +mcu_key_get(bool *valid) +{ + 80025a4: b570 push {r4, r5, r6, lr} + // get current "mcu_key" value; first byte will never be 0x0 or 0xff + // - except if no key set yet/recently wiped + // - if none set, returns ptr to first available slot which will be all ones + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + + for(int i=0; i) + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + 80025a8: 4c0d ldr r4, [pc, #52] ; (80025e0 ) +{ + 80025aa: 4606 mov r6, r0 + const mcu_key_t *ptr = MCU_KEYS, *avail=NULL; + 80025ac: 2500 movs r5, #0 + if(ptr->value[0] == 0xff) { + 80025ae: 7823 ldrb r3, [r4, #0] + 80025b0: 2bff cmp r3, #255 ; 0xff + 80025b2: d10b bne.n 80025cc + if(!avail) { + 80025b4: 2d00 cmp r5, #0 + 80025b6: bf08 it eq + 80025b8: 4625 moveq r5, r4 + for(int i=0; i + *valid = true; + return ptr; + } + } + + rng_delay(); + 80025c0: f000 f9a2 bl 8002908 + *valid = false; + 80025c4: 2300 movs r3, #0 + 80025c6: 7033 strb r3, [r6, #0] + return avail; + 80025c8: 462c mov r4, r5 + 80025ca: e005 b.n 80025d8 + } else if(ptr->value[0] != 0x00) { + 80025cc: 2b00 cmp r3, #0 + 80025ce: d0f4 beq.n 80025ba + rng_delay(); + 80025d0: f000 f99a bl 8002908 + *valid = true; + 80025d4: 2301 movs r3, #1 + 80025d6: 7033 strb r3, [r6, #0] +} + 80025d8: 4620 mov r0, r4 + 80025da: bd70 pop {r4, r5, r6, pc} + 80025dc: 08020000 .word 0x08020000 + 80025e0: 0801e000 .word 0x0801e000 + +080025e4 : + +// mcu_key_clear() +// + void +mcu_key_clear(const mcu_key_t *cur) +{ + 80025e4: b513 push {r0, r1, r4, lr} + if(!cur) { + 80025e6: 4604 mov r4, r0 + 80025e8: b938 cbnz r0, 80025fa + bool valid; + cur = mcu_key_get(&valid); + 80025ea: f10d 0007 add.w r0, sp, #7 + 80025ee: f7ff ffd9 bl 80025a4 + + if(!valid) return; + 80025f2: f89d 3007 ldrb.w r3, [sp, #7] + cur = mcu_key_get(&valid); + 80025f6: 4604 mov r4, r0 + if(!valid) return; + 80025f8: b1fb cbz r3, 800263a + } + + // no delays here since decision has been made, and don't + // want to give them more time to interrupt us + flash_setup0(); + 80025fa: f7ff fdcf bl 800219c + flash_unlock(); + 80025fe: f7ff fdf1 bl 80021e4 + uint32_t pos = (uint32_t)cur; + flash_burn(pos, 0); pos += 8; + 8002602: 2200 movs r2, #0 + 8002604: 2300 movs r3, #0 + 8002606: 4620 mov r0, r4 + 8002608: f00b f9c2 bl 800d990 <__flash_burn_veneer> + flash_burn(pos, 0); pos += 8; + 800260c: 2200 movs r2, #0 + 800260e: 2300 movs r3, #0 + 8002610: f104 0008 add.w r0, r4, #8 + 8002614: f00b f9bc bl 800d990 <__flash_burn_veneer> + flash_burn(pos, 0); pos += 8; + 8002618: 2200 movs r2, #0 + 800261a: 2300 movs r3, #0 + 800261c: f104 0010 add.w r0, r4, #16 + 8002620: f00b f9b6 bl 800d990 <__flash_burn_veneer> + flash_burn(pos, 0); + 8002624: 2200 movs r2, #0 + 8002626: 2300 movs r3, #0 + 8002628: f104 0018 add.w r0, r4, #24 + 800262c: f00b f9b0 bl 800d990 <__flash_burn_veneer> + flash_lock(); +} + 8002630: b002 add sp, #8 + 8002632: e8bd 4010 ldmia.w sp!, {r4, lr} + flash_lock(); + 8002636: f7ff bdcd b.w 80021d4 +} + 800263a: b002 add sp, #8 + 800263c: bd10 pop {r4, pc} + ... + +08002640 : + +// mcu_key_usage() +// + void +mcu_key_usage(int *avail_out, int *consumed_out, int *total_out) +{ + 8002640: b5f0 push {r4, r5, r6, r7, lr} + const mcu_key_t *ptr = MCU_KEYS; + int avail = 0, used = 0; + 8002642: 2300 movs r3, #0 + const mcu_key_t *ptr = MCU_KEYS; + 8002644: 4c09 ldr r4, [pc, #36] ; (800266c ) + + for(int i=0; i) + int avail = 0, used = 0; + 8002648: 461d mov r5, r3 + if(ptr->value[0] == 0xff) { + 800264a: 7826 ldrb r6, [r4, #0] + 800264c: 2eff cmp r6, #255 ; 0xff + 800264e: d109 bne.n 8002664 + avail ++; + 8002650: 3501 adds r5, #1 + for(int i=0; i + } else if(ptr->value[0] == 0x00) { + used ++; + } + } + + *avail_out = avail; + 8002658: 6005 str r5, [r0, #0] + *consumed_out = used; + 800265a: 600b str r3, [r1, #0] + *total_out = NUM_MCU_KEYS; + 800265c: f44f 7380 mov.w r3, #256 ; 0x100 + 8002660: 6013 str r3, [r2, #0] +} + 8002662: bdf0 pop {r4, r5, r6, r7, pc} + } else if(ptr->value[0] == 0x00) { + 8002664: 2e00 cmp r6, #0 + 8002666: d1f4 bne.n 8002652 + used ++; + 8002668: 3301 adds r3, #1 + 800266a: e7f2 b.n 8002652 + 800266c: 0801e000 .word 0x0801e000 + 8002670: 08020000 .word 0x08020000 + +08002674 : + +// mcu_key_pick() +// + const mcu_key_t * +mcu_key_pick(void) +{ + 8002674: b5f0 push {r4, r5, r6, r7, lr} + 8002676: b08b sub sp, #44 ; 0x2c + mcu_key_t n; + + // get some good entropy, and whiten it just in case. + do { + rng_buffer(n.value, 32); + 8002678: ad02 add r5, sp, #8 + 800267a: 2120 movs r1, #32 + 800267c: 4628 mov r0, r5 + 800267e: f000 f92d bl 80028dc + sha256_single(n.value, 32, n.value); + 8002682: 462a mov r2, r5 + 8002684: 2120 movs r1, #32 + 8002686: 4628 mov r0, r5 + 8002688: f003 f8e0 bl 800584c + sha256_single(n.value, 32, n.value); + 800268c: 462a mov r2, r5 + 800268e: 2120 movs r1, #32 + 8002690: 4628 mov r0, r5 + 8002692: f003 f8db bl 800584c + } while(n.value[0] == 0x0 || n.value[0] == 0xff); + 8002696: f89d 3008 ldrb.w r3, [sp, #8] + 800269a: 3b01 subs r3, #1 + 800269c: b2db uxtb r3, r3 + 800269e: 2bfd cmp r3, #253 ; 0xfd + 80026a0: d8eb bhi.n 800267a + + int err = 0; + const mcu_key_t *cur; + + do { + bool valid = false; + 80026a2: 2300 movs r3, #0 + cur = mcu_key_get(&valid); + 80026a4: 4668 mov r0, sp + bool valid = false; + 80026a6: f88d 3000 strb.w r3, [sp] + cur = mcu_key_get(&valid); + 80026aa: f7ff ff7b bl 80025a4 + + if(!cur) { + 80026ae: 4604 mov r4, r0 + 80026b0: b938 cbnz r0, 80026c2 + // no free slots. we are brick. + puts("mcu full"); + 80026b2: 4828 ldr r0, [pc, #160] ; (8002754 ) + 80026b4: f002 fcd8 bl 8005068 + oled_show(screen_brick); + 80026b8: 4827 ldr r0, [pc, #156] ; (8002758 ) + 80026ba: f7fe fcdb bl 8001074 + + LOCKUP_FOREVER(); + 80026be: f001 fadb bl 8003c78 + } + + if(valid) { + 80026c2: f89d 3000 ldrb.w r3, [sp] + 80026c6: b14b cbz r3, 80026dc + // clear existing key, if it's defined. + ASSERT(cur->value[0] != 0x00); + 80026c8: 7803 ldrb r3, [r0, #0] + 80026ca: 3b01 subs r3, #1 + 80026cc: b2db uxtb r3, r3 + 80026ce: 2bfd cmp r3, #253 ; 0xfd + 80026d0: d902 bls.n 80026d8 + 80026d2: 4822 ldr r0, [pc, #136] ; (800275c ) + 80026d4: f7fe f9b0 bl 8000a38 + ASSERT(cur->value[0] != 0xff); + + mcu_key_clear(cur); + 80026d8: f7ff ff84 bl 80025e4 + continue; + } + } while(0); + + // burn it + flash_setup0(); + 80026dc: f7ff fd5e bl 800219c + flash_unlock(); + 80026e0: f7ff fd80 bl 80021e4 + uint32_t pos = (uint32_t)cur; + const uint8_t *fr = n.value; + + for(int i=0; i<32; i+= 8, pos += 8, fr += 8) { + 80026e4: 2700 movs r7, #0 + uint64_t v; + memcpy(&v, fr, sizeof(v)); + 80026e6: 19ea adds r2, r5, r7 + 80026e8: 59e8 ldr r0, [r5, r7] + 80026ea: 6851 ldr r1, [r2, #4] + 80026ec: 466b mov r3, sp + 80026ee: c303 stmia r3!, {r0, r1} + + err = flash_burn(pos, v); + 80026f0: 19e0 adds r0, r4, r7 + 80026f2: e9dd 2300 ldrd r2, r3, [sp] + 80026f6: f00b f94b bl 800d990 <__flash_burn_veneer> + if(err) break; + 80026fa: 4606 mov r6, r0 + 80026fc: b910 cbnz r0, 8002704 + for(int i=0; i<32; i+= 8, pos += 8, fr += 8) { + 80026fe: 3708 adds r7, #8 + 8002700: 2f20 cmp r7, #32 + 8002702: d1f0 bne.n 80026e6 + } + flash_lock(); + 8002704: f7ff fd66 bl 80021d4 + + // NOTE: Errors not expected, but lets be graceful about them. + + if(err) { + 8002708: b166 cbz r6, 8002724 + // what to do? + puts("burn fail: "); + 800270a: 4815 ldr r0, [pc, #84] ; (8002760 ) + 800270c: f002 fcac bl 8005068 + puthex2(err); + 8002710: b2f0 uxtb r0, r6 + 8002712: f002 fc4d bl 8004fb0 + putchar('\n'); + 8002716: 200a movs r0, #10 + 8002718: f002 fc2c bl 8004f74 + return NULL; + } + + if(after != cur || !check_equal(after->value, n.value, 32)) { + puts("bad val?"); + return NULL; + 800271c: 2400 movs r4, #0 + } + + return cur; +} + 800271e: 4620 mov r0, r4 + 8002720: b00b add sp, #44 ; 0x2c + 8002722: bdf0 pop {r4, r5, r6, r7, pc} + const mcu_key_t *after = mcu_key_get(&valid); + 8002724: 4668 mov r0, sp + bool valid = false; + 8002726: f88d 6000 strb.w r6, [sp] + const mcu_key_t *after = mcu_key_get(&valid); + 800272a: f7ff ff3b bl 80025a4 + if(!valid) { + 800272e: f89d 2000 ldrb.w r2, [sp] + 8002732: b91a cbnz r2, 800273c + puts("!valid?"); + 8002734: 480b ldr r0, [pc, #44] ; (8002764 ) + puts("bad val?"); + 8002736: f002 fc97 bl 8005068 + 800273a: e7ef b.n 800271c + if(after != cur || !check_equal(after->value, n.value, 32)) { + 800273c: 4284 cmp r4, r0 + 800273e: d001 beq.n 8002744 + puts("bad val?"); + 8002740: 4809 ldr r0, [pc, #36] ; (8002768 ) + 8002742: e7f8 b.n 8002736 + if(after != cur || !check_equal(after->value, n.value, 32)) { + 8002744: 2220 movs r2, #32 + 8002746: 4629 mov r1, r5 + 8002748: f000 f879 bl 800283e + 800274c: 2800 cmp r0, #0 + 800274e: d1e6 bne.n 800271e + 8002750: e7f6 b.n 8002740 + 8002752: bf00 nop + 8002754: 08010687 .word 0x08010687 + 8002758: 0800da61 .word 0x0800da61 + 800275c: 0801046c .word 0x0801046c + 8002760: 08010690 .word 0x08010690 + 8002764: 0801069c .word 0x0801069c + 8002768: 080106a4 .word 0x080106a4 + +0800276c : + +// fast_brick() +// + void +fast_brick(void) +{ + 800276c: b538 push {r3, r4, r5, lr} +#ifndef RELEASE + puts2("DISABLED fast brick... "); + oled_show(screen_brick); +#else + // do a fast wipe of our key + mcu_key_clear(NULL); + 800276e: 2000 movs r0, #0 + 8002770: f7ff ff38 bl 80025e4 + + // brick SE1 for future + ae_brick_myself(); + 8002774: f001 f970 bl 8003a58 + + // NOTE: could brick SE1 (somewhat) by dec'ing the counter, which will + // invalidate all PIN hashes + + // no going back from that -- but for privacy, wipe more stuff + oled_show(screen_brick); + 8002778: 480e ldr r0, [pc, #56] ; (80027b4 ) + uint32_t bot = (uint32_t)MCU_KEYS; + flash_page_erase(bot); + + // 2: LFS area first, since holds settings (AES'ed w/ lost key, but yeah) + // 3: the firmware, not a secret anyway + for(uint32_t pos=(FLASH_BASE + 0x200000 - FLASH_ERASE_SIZE); + 800277a: 4c0f ldr r4, [pc, #60] ; (80027b8 ) + 800277c: 4d0f ldr r5, [pc, #60] ; (80027bc ) + oled_show(screen_brick); + 800277e: f7fe fc79 bl 8001074 + puts2("fast brick... "); + 8002782: 480f ldr r0, [pc, #60] ; (80027c0 ) + 8002784: f002 fbe2 bl 8004f4c + flash_setup0(); + 8002788: f7ff fd08 bl 800219c + flash_unlock(); + 800278c: f7ff fd2a bl 80021e4 + flash_page_erase(bot); + 8002790: 480a ldr r0, [pc, #40] ; (80027bc ) + 8002792: f00b f901 bl 800d998 <__flash_page_erase_veneer> + pos > bot; pos -= FLASH_ERASE_SIZE) { + flash_page_erase(pos); + 8002796: 4620 mov r0, r4 + pos > bot; pos -= FLASH_ERASE_SIZE) { + 8002798: f5a4 5480 sub.w r4, r4, #4096 ; 0x1000 + flash_page_erase(pos); + 800279c: f00b f8fc bl 800d998 <__flash_page_erase_veneer> + for(uint32_t pos=(FLASH_BASE + 0x200000 - FLASH_ERASE_SIZE); + 80027a0: 42ac cmp r4, r5 + 80027a2: d1f8 bne.n 8002796 + } + flash_lock(); + puts(" done"); + 80027a4: 4807 ldr r0, [pc, #28] ; (80027c4 ) + flash_lock(); + 80027a6: f7ff fd15 bl 80021d4 + puts(" done"); + 80027aa: f002 fc5d bl 8005068 +#endif + + LOCKUP_FOREVER(); + 80027ae: f001 fa63 bl 8003c78 + 80027b2: bf00 nop + 80027b4: 0800da61 .word 0x0800da61 + 80027b8: 081ff000 .word 0x081ff000 + 80027bc: 0801e000 .word 0x0801e000 + 80027c0: 080106ad .word 0x080106ad + 80027c4: 080106bc .word 0x080106bc + +080027c8 : + +// fast_wipe() +// + void +fast_wipe(void) +{ + 80027c8: b508 push {r3, lr} + // dump (part of) the main seed key and become a new Coldcard + // - lots of other code can and will detect a missing MCU key as "blank" + // - and the check value on main seed will be garbage now + mcu_key_clear(NULL); + 80027ca: 2000 movs r0, #0 + 80027cc: f7ff ff0a bl 80025e4 + __ASM volatile ("dsb 0xF":::"memory"); + 80027d0: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80027d4: 4905 ldr r1, [pc, #20] ; (80027ec ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80027d6: 4b06 ldr r3, [pc, #24] ; (80027f0 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80027d8: 68ca ldr r2, [r1, #12] + 80027da: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80027de: 4313 orrs r3, r2 + 80027e0: 60cb str r3, [r1, #12] + 80027e2: f3bf 8f4f dsb sy + __NOP(); + 80027e6: bf00 nop + for(;;) /* wait until reset */ + 80027e8: e7fd b.n 80027e6 + 80027ea: bf00 nop + 80027ec: e000ed00 .word 0xe000ed00 + 80027f0: 05fa0004 .word 0x05fa0004 + +080027f4 : +check_all_ones_raw(const void *ptrV, int len) +{ + uint8_t rv = 0xff; + const uint8_t *ptr = (const uint8_t *)ptrV; + + for(; len; len--, ptr++) { + 80027f4: 4401 add r1, r0 + uint8_t rv = 0xff; + 80027f6: 23ff movs r3, #255 ; 0xff + for(; len; len--, ptr++) { + 80027f8: 4288 cmp r0, r1 + 80027fa: d103 bne.n 8002804 + rv &= *ptr; + } + + return (rv == 0xff); +} + 80027fc: 3bff subs r3, #255 ; 0xff + 80027fe: 4258 negs r0, r3 + 8002800: 4158 adcs r0, r3 + 8002802: 4770 bx lr + rv &= *ptr; + 8002804: f810 2b01 ldrb.w r2, [r0], #1 + 8002808: 4013 ands r3, r2 + for(; len; len--, ptr++) { + 800280a: e7f5 b.n 80027f8 + +0800280c : +// +// Return T if all bytes are 0xFF +// + bool +check_all_ones(const void *ptrV, int len) +{ + 800280c: b507 push {r0, r1, r2, lr} + bool rv = check_all_ones_raw(ptrV, len); + 800280e: f7ff fff1 bl 80027f4 + 8002812: 9001 str r0, [sp, #4] + + rng_delay(); + 8002814: f000 f878 bl 8002908 + + return rv; +} + 8002818: 9801 ldr r0, [sp, #4] + 800281a: b003 add sp, #12 + 800281c: f85d fb04 ldr.w pc, [sp], #4 + +08002820 : +// +// Return T if all bytes are 0x00 +// + bool +check_all_zeros(const void *ptrV, int len) +{ + 8002820: b510 push {r4, lr} + 8002822: 4401 add r1, r0 + uint8_t rv = 0x0; + 8002824: 2400 movs r4, #0 + const uint8_t *ptr = (const uint8_t *)ptrV; + + for(; len; len--, ptr++) { + 8002826: 4288 cmp r0, r1 + 8002828: d105 bne.n 8002836 + rv |= *ptr; + } + + rng_delay(); + 800282a: f000 f86d bl 8002908 + return (rv == 0x00); +} + 800282e: fab4 f084 clz r0, r4 + 8002832: 0940 lsrs r0, r0, #5 + 8002834: bd10 pop {r4, pc} + rv |= *ptr; + 8002836: f810 3b01 ldrb.w r3, [r0], #1 + 800283a: 431c orrs r4, r3 + for(; len; len--, ptr++) { + 800283c: e7f3 b.n 8002826 + +0800283e : + const uint8_t *left = (const uint8_t *)aV; + const uint8_t *right = (const uint8_t *)bV; + uint8_t diff = 0; + int i; + + for (i = 0; i < len; i++) { + 800283e: 2300 movs r3, #0 +{ + 8002840: b570 push {r4, r5, r6, lr} + uint8_t diff = 0; + 8002842: 461c mov r4, r3 + for (i = 0; i < len; i++) { + 8002844: 4293 cmp r3, r2 + 8002846: db05 blt.n 8002854 + diff |= (left[i] ^ right[i]); + } + + rng_delay(); + 8002848: f000 f85e bl 8002908 + return (diff == 0); +} + 800284c: fab4 f084 clz r0, r4 + 8002850: 0940 lsrs r0, r0, #5 + 8002852: bd70 pop {r4, r5, r6, pc} + diff |= (left[i] ^ right[i]); + 8002854: 5cc5 ldrb r5, [r0, r3] + 8002856: 5cce ldrb r6, [r1, r3] + 8002858: 4075 eors r5, r6 + 800285a: 432c orrs r4, r5 + for (i = 0; i < len; i++) { + 800285c: 3301 adds r3, #1 + 800285e: e7f1 b.n 8002844 + +08002860 : + } + + // Get the new number + uint32_t rv = RNG->DR; + + if(rv != last_rng_result && rv) { + 8002860: 4b06 ldr r3, [pc, #24] ; (800287c ) + while(!(RNG->SR & RNG_FLAG_DRDY)) { + 8002862: 4a07 ldr r2, [pc, #28] ; (8002880 ) + if(rv != last_rng_result && rv) { + 8002864: 6819 ldr r1, [r3, #0] + while(!(RNG->SR & RNG_FLAG_DRDY)) { + 8002866: 6850 ldr r0, [r2, #4] + 8002868: 07c0 lsls r0, r0, #31 + 800286a: d5fc bpl.n 8002866 + uint32_t rv = RNG->DR; + 800286c: 6890 ldr r0, [r2, #8] + if(rv != last_rng_result && rv) { + 800286e: 4281 cmp r1, r0 + 8002870: d0f9 beq.n 8002866 + 8002872: 2800 cmp r0, #0 + 8002874: d0f7 beq.n 8002866 + last_rng_result = rv; + 8002876: 6018 str r0, [r3, #0] + + // keep trying if not a new number + } + + // NOT-REACHED +} + 8002878: 4770 bx lr + 800287a: bf00 nop + 800287c: 2009e1bc .word 0x2009e1bc + 8002880: 50060800 .word 0x50060800 + +08002884 : + if(RNG->CR & RNG_CR_RNGEN) { + 8002884: 4b12 ldr r3, [pc, #72] ; (80028d0 ) + 8002886: 681a ldr r2, [r3, #0] + 8002888: 0752 lsls r2, r2, #29 +{ + 800288a: b513 push {r0, r1, r4, lr} + if(RNG->CR & RNG_CR_RNGEN) { + 800288c: d41d bmi.n 80028ca + __HAL_RCC_RNG_CLK_ENABLE(); + 800288e: 4a11 ldr r2, [pc, #68] ; (80028d4 ) + 8002890: 6cd1 ldr r1, [r2, #76] ; 0x4c + 8002892: f441 2180 orr.w r1, r1, #262144 ; 0x40000 + 8002896: 64d1 str r1, [r2, #76] ; 0x4c + 8002898: 6cd2 ldr r2, [r2, #76] ; 0x4c + 800289a: f402 2280 and.w r2, r2, #262144 ; 0x40000 + 800289e: 9201 str r2, [sp, #4] + 80028a0: 9a01 ldr r2, [sp, #4] + RNG->CR |= RNG_CR_RNGEN; + 80028a2: 681a ldr r2, [r3, #0] + 80028a4: f042 0204 orr.w r2, r2, #4 + 80028a8: 601a str r2, [r3, #0] + uint32_t chk = rng_sample(); + 80028aa: f7ff ffd9 bl 8002860 + 80028ae: 4604 mov r4, r0 + uint32_t chk2 = rng_sample(); + 80028b0: f7ff ffd6 bl 8002860 + if(chk == 0 || chk == ~0 + 80028b4: 1e63 subs r3, r4, #1 + 80028b6: 3303 adds r3, #3 + 80028b8: d804 bhi.n 80028c4 + || chk2 == 0 || chk2 == ~0 + 80028ba: 1e43 subs r3, r0, #1 + 80028bc: 3303 adds r3, #3 + 80028be: d801 bhi.n 80028c4 + || chk == chk2 + 80028c0: 4284 cmp r4, r0 + 80028c2: d102 bne.n 80028ca + INCONSISTENT("bad rng"); + 80028c4: 4804 ldr r0, [pc, #16] ; (80028d8 ) + 80028c6: f7fe f8b7 bl 8000a38 +} + 80028ca: b002 add sp, #8 + 80028cc: bd10 pop {r4, pc} + 80028ce: bf00 nop + 80028d0: 50060800 .word 0x50060800 + 80028d4: 40021000 .word 0x40021000 + 80028d8: 0800d9a0 .word 0x0800d9a0 + +080028dc : + +// rng_buffer() +// + void +rng_buffer(uint8_t *result, int len) +{ + 80028dc: b573 push {r0, r1, r4, r5, r6, lr} + 80028de: 460c mov r4, r1 + 80028e0: 1845 adds r5, r0, r1 + while(len > 0) { + 80028e2: 2c00 cmp r4, #0 + 80028e4: eba5 0604 sub.w r6, r5, r4 + 80028e8: dc01 bgt.n 80028ee + memcpy(result, &t, MIN(4, len)); + + len -= 4; + result += 4; + } +} + 80028ea: b002 add sp, #8 + 80028ec: bd70 pop {r4, r5, r6, pc} + uint32_t t = rng_sample(); + 80028ee: f7ff ffb7 bl 8002860 + memcpy(result, &t, MIN(4, len)); + 80028f2: 2c04 cmp r4, #4 + 80028f4: 4622 mov r2, r4 + uint32_t t = rng_sample(); + 80028f6: 9001 str r0, [sp, #4] + memcpy(result, &t, MIN(4, len)); + 80028f8: bfa8 it ge + 80028fa: 2204 movge r2, #4 + 80028fc: a901 add r1, sp, #4 + 80028fe: 4630 mov r0, r6 + 8002900: f00b f802 bl 800d908 + len -= 4; + 8002904: 3c04 subs r4, #4 + result += 4; + 8002906: e7ec b.n 80028e2 + +08002908 : +// +// Call anytime. Delays for a random time period to fustrate glitchers. +// + void +rng_delay(void) +{ + 8002908: b508 push {r3, lr} + uint32_t r = rng_sample() % 8; + 800290a: f7ff ffa9 bl 8002860 + uint32_t cnt = (1< + cnt--; + } +} + 800291e: bd08 pop {r3, pc} + +08002920 <_send_byte>: + static inline void +_send_byte(uint8_t ch) +{ + // reset timeout timer (Systick) + uint32_t ticks = 0; + SysTick->VAL = 0; + 8002920: f04f 22e0 mov.w r2, #3758153728 ; 0xe000e000 +{ + 8002924: b510 push {r4, lr} + SysTick->VAL = 0; + 8002926: 2300 movs r3, #0 + + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 8002928: 4c07 ldr r4, [pc, #28] ; (8002948 <_send_byte+0x28>) + SysTick->VAL = 0; + 800292a: 6193 str r3, [r2, #24] + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 800292c: 230b movs r3, #11 + 800292e: 69e1 ldr r1, [r4, #28] + 8002930: 0609 lsls r1, r1, #24 + 8002932: d404 bmi.n 800293e <_send_byte+0x1e> + // busy-wait until able to send (no fifo?) + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8002934: 6911 ldr r1, [r2, #16] + 8002936: 03c9 lsls r1, r1, #15 + 8002938: d5f9 bpl.n 800292e <_send_byte+0xe> + // failsafe timeout + ticks += 1; + if(ticks > 10) break; + 800293a: 3b01 subs r3, #1 + 800293c: d1f7 bne.n 800292e <_send_byte+0xe> + } + } + MY_UART->TDR = ch; + 800293e: 4b02 ldr r3, [pc, #8] ; (8002948 <_send_byte+0x28>) + 8002940: b280 uxth r0, r0 + 8002942: 8518 strh r0, [r3, #40] ; 0x28 +} + 8002944: bd10 pop {r4, pc} + 8002946: bf00 nop + 8002948: 40004c00 .word 0x40004c00 + +0800294c <_send_bits>: + +// _send_bits() +// + static void +_send_bits(uint8_t tx) +{ + 800294c: b570 push {r4, r5, r6, lr} + 800294e: 4606 mov r6, r0 + 8002950: 2508 movs r5, #8 + // serialize and send one byte + uint8_t mask = 0x1; + 8002952: 2401 movs r4, #1 + + for(int i=0; i<8; i++, mask <<= 1) { + uint8_t h = (tx & mask) ? BIT1 : BIT0; + 8002954: 4226 tst r6, r4 + + _send_byte(h); + 8002956: bf14 ite ne + 8002958: 207f movne r0, #127 ; 0x7f + 800295a: 207d moveq r0, #125 ; 0x7d + 800295c: f7ff ffe0 bl 8002920 <_send_byte> + for(int i=0; i<8; i++, mask <<= 1) { + 8002960: 0064 lsls r4, r4, #1 + 8002962: 3d01 subs r5, #1 + 8002964: b2e4 uxtb r4, r4 + 8002966: d1f5 bne.n 8002954 <_send_bits+0x8> + } +} + 8002968: bd70 pop {r4, r5, r6, pc} + +0800296a <_send_serialized>: + +// _send_serialized() +// + static void +_send_serialized(const uint8_t *buf, int len) +{ + 800296a: b538 push {r3, r4, r5, lr} + 800296c: 4604 mov r4, r0 + 800296e: 1845 adds r5, r0, r1 + for(int i=0; i + for(int i=0; i + } +} + 800297c: bd38 pop {r3, r4, r5, pc} + ... + +08002980 <_flush_rx>: +// + static inline void +_flush_rx(void) +{ + // reset timeout timer (Systick) + SysTick->VAL = 0; + 8002980: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 8002984: 2200 movs r2, #0 + + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 8002986: 490b ldr r1, [pc, #44] ; (80029b4 <_flush_rx+0x34>) + SysTick->VAL = 0; + 8002988: 619a str r2, [r3, #24] + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 800298a: 69ca ldr r2, [r1, #28] + 800298c: 0652 lsls r2, r2, #25 + 800298e: d402 bmi.n 8002996 <_flush_rx+0x16> + // wait for last bit(byte) to be serialized and sent + + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8002990: 691a ldr r2, [r3, #16] + 8002992: 03d0 lsls r0, r2, #15 + 8002994: d5f9 bpl.n 800298a <_flush_rx+0xa> + break; + } + } + + // We actually need this delay here! + __NOP(); + 8002996: bf00 nop + __NOP(); + 8002998: bf00 nop + __NOP(); + 800299a: bf00 nop + __NOP(); + 800299c: bf00 nop + __NOP(); + 800299e: bf00 nop + __NOP(); + 80029a0: bf00 nop + __NOP(); + 80029a2: bf00 nop + __NOP(); + 80029a4: bf00 nop + + // clear junk in rx buffer + MY_UART->RQR = USART_RQR_RXFRQ; + 80029a6: 4b03 ldr r3, [pc, #12] ; (80029b4 <_flush_rx+0x34>) + 80029a8: 2208 movs r2, #8 + 80029aa: 831a strh r2, [r3, #24] + + // clear overrun error + // clear rx timeout flag + // clear framing error + MY_UART->ICR = USART_ICR_ORECF | USART_ICR_RTOCF | USART_ICR_FECF; + 80029ac: f640 020a movw r2, #2058 ; 0x80a + 80029b0: 621a str r2, [r3, #32] +} + 80029b2: 4770 bx lr + 80029b4: 40004c00 .word 0x40004c00 + +080029b8 : + uint16_t crc_register = 0; + uint16_t polynom = 0x8005; + uint8_t shift_register; + uint8_t data_bit, crc_bit; + + crc_register = (((uint16_t) crc[0]) & 0x00FF) | (((uint16_t) crc[1]) << 8); + 80029b8: 8813 ldrh r3, [r2, #0] +{ + 80029ba: b5f0 push {r4, r5, r6, r7, lr} + 80029bc: 4408 add r0, r1 + + // Shift CRC to the left by 1. + crc_register <<= 1; + + if ((data_bit ^ crc_bit) != 0) + crc_register ^= polynom; + 80029be: f248 0605 movw r6, #32773 ; 0x8005 + for (counter = 0; counter < length; counter++) { + 80029c2: 4281 cmp r1, r0 + 80029c4: d103 bne.n 80029ce + } + } + + crc[0] = (uint8_t) (crc_register & 0x00FF); + 80029c6: 7013 strb r3, [r2, #0] + crc[1] = (uint8_t) (crc_register >> 8); + 80029c8: 0a1b lsrs r3, r3, #8 + 80029ca: 7053 strb r3, [r2, #1] +} + 80029cc: bdf0 pop {r4, r5, r6, r7, pc} + data_bit = (data[counter] & shift_register) ? 1 : 0; + 80029ce: f811 7b01 ldrb.w r7, [r1], #1 + 80029d2: 2508 movs r5, #8 + for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) { + 80029d4: 2401 movs r4, #1 + data_bit = (data[counter] & shift_register) ? 1 : 0; + 80029d6: 4227 tst r7, r4 + crc_bit = crc_register >> 15; + 80029d8: ea4f 3cd3 mov.w ip, r3, lsr #15 + if ((data_bit ^ crc_bit) != 0) + 80029dc: bf18 it ne + 80029de: f04f 0e01 movne.w lr, #1 + crc_register <<= 1; + 80029e2: ea4f 0343 mov.w r3, r3, lsl #1 + if ((data_bit ^ crc_bit) != 0) + 80029e6: bf08 it eq + 80029e8: f04f 0e00 moveq.w lr, #0 + 80029ec: 45e6 cmp lr, ip + crc_register <<= 1; + 80029ee: b29b uxth r3, r3 + crc_register ^= polynom; + 80029f0: bf18 it ne + 80029f2: 4073 eorne r3, r6 + for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) { + 80029f4: 0064 lsls r4, r4, #1 + 80029f6: 3d01 subs r5, #1 + 80029f8: b2e4 uxtb r4, r4 + 80029fa: d1ec bne.n 80029d6 + 80029fc: e7e1 b.n 80029c2 + +080029fe : + +// ae_check_crc() +// + static bool +ae_check_crc(const uint8_t *data, uint8_t length) +{ + 80029fe: b573 push {r0, r1, r4, r5, r6, lr} + uint8_t obs[2] = { 0, 0 }; + + if(data[0] != length) { + 8002a00: 7806 ldrb r6, [r0, #0] + uint8_t obs[2] = { 0, 0 }; + 8002a02: 2400 movs r4, #0 + if(data[0] != length) { + 8002a04: 428e cmp r6, r1 +{ + 8002a06: 4605 mov r5, r0 + uint8_t obs[2] = { 0, 0 }; + 8002a08: f8ad 4004 strh.w r4, [sp, #4] + if(data[0] != length) { + 8002a0c: d113 bne.n 8002a36 + // length is wrong + STATS(crc_len_error++); + return false; + } + + crc16_chain(length-2, data, obs); + 8002a0e: 4629 mov r1, r5 + 8002a10: 1eb0 subs r0, r6, #2 + + return (obs[0] == data[length-2] && obs[1] == data[length-1]); + 8002a12: 4435 add r5, r6 + crc16_chain(length-2, data, obs); + 8002a14: aa01 add r2, sp, #4 + 8002a16: b2c0 uxtb r0, r0 + 8002a18: f7ff ffce bl 80029b8 + return (obs[0] == data[length-2] && obs[1] == data[length-1]); + 8002a1c: f89d 2004 ldrb.w r2, [sp, #4] + 8002a20: f815 3c02 ldrb.w r3, [r5, #-2] + 8002a24: 429a cmp r2, r3 + 8002a26: d106 bne.n 8002a36 + 8002a28: f815 4c01 ldrb.w r4, [r5, #-1] + 8002a2c: f89d 0005 ldrb.w r0, [sp, #5] + 8002a30: 1a23 subs r3, r4, r0 + 8002a32: 425c negs r4, r3 + 8002a34: 415c adcs r4, r3 + return false; + 8002a36: 4620 mov r0, r4 +} + 8002a38: b002 add sp, #8 + 8002a3a: bd70 pop {r4, r5, r6, pc} + +08002a3c : +{ + 8002a3c: b508 push {r3, lr} + _send_byte(0x00); + 8002a3e: 2000 movs r0, #0 + 8002a40: f7ff ff6e bl 8002920 <_send_byte> + delay_ms(3); // measured: ~2.9ms + 8002a44: 2003 movs r0, #3 + 8002a46: f001 f81d bl 8003a84 +} + 8002a4a: e8bd 4008 ldmia.w sp!, {r3, lr} + _flush_rx(); + 8002a4e: f7ff bf97 b.w 8002980 <_flush_rx> + +08002a52 : +{ + 8002a52: b508 push {r3, lr} + ae_wake(); + 8002a54: f7ff fff2 bl 8002a3c +} + 8002a58: e8bd 4008 ldmia.w sp!, {r3, lr} + _send_bits(IOFLAG_IDLE); + 8002a5c: 20bb movs r0, #187 ; 0xbb + 8002a5e: f7ff bf75 b.w 800294c <_send_bits> + ... + +08002a64 : +{ + 8002a64: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + int max_expect = (max_len+1) * 8; + 8002a68: 3101 adds r1, #1 + uint8_t raw[max_expect]; + 8002a6a: 466b mov r3, sp + 8002a6c: eba3 03c1 sub.w r3, r3, r1, lsl #3 +{ + 8002a70: af00 add r7, sp, #0 + 8002a72: 4606 mov r6, r0 + uint8_t raw[max_expect]; + 8002a74: 469d mov sp, r3 + _send_bits(IOFLAG_TX); + 8002a76: 2088 movs r0, #136 ; 0x88 + int max_expect = (max_len+1) * 8; + 8002a78: 00cd lsls r5, r1, #3 + _send_bits(IOFLAG_TX); + 8002a7a: f7ff ff67 bl 800294c <_send_bits> + _flush_rx(); + 8002a7e: f7ff ff7f bl 8002980 <_flush_rx> + int actual = 0; + 8002a82: 2200 movs r2, #0 + while(!(MY_UART->ISR & UART_FLAG_RXNE) && !(MY_UART->ISR & UART_FLAG_RTOF)) { + 8002a84: 4829 ldr r0, [pc, #164] ; (8002b2c ) + uint8_t raw[max_expect]; + 8002a86: 466c mov r4, sp + for(uint8_t *p = raw; ; actual++) { + 8002a88: 4669 mov r1, sp + SysTick->VAL = 0; + 8002a8a: f04f 2ce0 mov.w ip, #3758153728 ; 0xe000e000 + 8002a8e: 4696 mov lr, r2 + 8002a90: f8cc e018 str.w lr, [ip, #24] + while(!(MY_UART->ISR & UART_FLAG_RXNE) && !(MY_UART->ISR & UART_FLAG_RTOF)) { + 8002a94: 2305 movs r3, #5 + 8002a96: f8d0 801c ldr.w r8, [r0, #28] + 8002a9a: f018 0f20 tst.w r8, #32 + 8002a9e: d104 bne.n 8002aaa + 8002aa0: f8d0 801c ldr.w r8, [r0, #28] + 8002aa4: f418 6f00 tst.w r8, #2048 ; 0x800 + 8002aa8: d008 beq.n 8002abc + if(MY_UART->ISR & UART_FLAG_RXNE) { + 8002aaa: 69c3 ldr r3, [r0, #28] + 8002aac: 069b lsls r3, r3, #26 + 8002aae: d52e bpl.n 8002b0e + return MY_UART->RDR & 0x7f; + 8002ab0: 8c83 ldrh r3, [r0, #36] ; 0x24 + if(actual < max_expect) { + 8002ab2: 42aa cmp r2, r5 + return MY_UART->RDR & 0x7f; + 8002ab4: b29b uxth r3, r3 + if(actual < max_expect) { + 8002ab6: db34 blt.n 8002b22 + for(uint8_t *p = raw; ; actual++) { + 8002ab8: 3201 adds r2, #1 + 8002aba: e7e9 b.n 8002a90 + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8002abc: f8dc 8010 ldr.w r8, [ip, #16] + 8002ac0: f418 3f80 tst.w r8, #65536 ; 0x10000 + 8002ac4: d0e7 beq.n 8002a96 + if(ticks >= 5) { + 8002ac6: 3b01 subs r3, #1 + 8002ac8: d1e5 bne.n 8002a96 + actual &= ~7; + 8002aca: f022 0107 bic.w r1, r2, #7 + while(from_len > 0) { + 8002ace: 3d08 subs r5, #8 + 8002ad0: 4425 add r5, r4 + 8002ad2: 4623 mov r3, r4 + 8002ad4: 4421 add r1, r4 + 8002ad6: 1ac8 subs r0, r1, r3 + 8002ad8: 2800 cmp r0, #0 + 8002ada: dd14 ble.n 8002b06 + 8002adc: f103 3cff add.w ip, r3, #4294967295 ; 0xffffffff + uint8_t rv = 0, mask = 0x1; + 8002ae0: 2001 movs r0, #1 + 8002ae2: 2400 movs r4, #0 + for(int i=0; i<8; i++, mask <<= 1) { + 8002ae4: f103 0e07 add.w lr, r3, #7 + if(from[i] == BIT1) { + 8002ae8: f81c 8f01 ldrb.w r8, [ip, #1]! + 8002aec: f1b8 0f7f cmp.w r8, #127 ; 0x7f + rv |= mask; + 8002af0: bf08 it eq + 8002af2: 4304 orreq r4, r0 + for(int i=0; i<8; i++, mask <<= 1) { + 8002af4: 0040 lsls r0, r0, #1 + 8002af6: 45f4 cmp ip, lr + 8002af8: b2c0 uxtb r0, r0 + 8002afa: d1f5 bne.n 8002ae8 + from += 8; + 8002afc: 3308 adds r3, #8 + if(max_into <= 0) break; + 8002afe: 42ab cmp r3, r5 + *(into++) = rv; + 8002b00: f806 4b01 strb.w r4, [r6], #1 + if(max_into <= 0) break; + 8002b04: d1e7 bne.n 8002ad6 + return actual / 8; + 8002b06: 10d0 asrs r0, r2, #3 +} + 8002b08: 46bd mov sp, r7 + 8002b0a: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if(MY_UART->ISR & UART_FLAG_RTOF) { + 8002b0e: 69c3 ldr r3, [r0, #28] + 8002b10: 051b lsls r3, r3, #20 + 8002b12: d503 bpl.n 8002b1c + MY_UART->ICR = USART_ICR_RTOCF; + 8002b14: f44f 6300 mov.w r3, #2048 ; 0x800 + 8002b18: 6203 str r3, [r0, #32] + if(ch < 0) { + 8002b1a: e7d6 b.n 8002aca + INCONSISTENT("rxf"); + 8002b1c: 4804 ldr r0, [pc, #16] ; (8002b30 ) + 8002b1e: f7fd ff8b bl 8000a38 + *(p++) = ch; + 8002b22: f003 037f and.w r3, r3, #127 ; 0x7f + 8002b26: f801 3b01 strb.w r3, [r1], #1 + 8002b2a: e7c5 b.n 8002ab8 + 8002b2c: 40004c00 .word 0x40004c00 + 8002b30: 0800d9a0 .word 0x0800d9a0 + +08002b34 : + if(ae_chip_is_setup == AE_CHIP_IS_SETUP) { + 8002b34: 4b04 ldr r3, [pc, #16] ; (8002b48 ) + 8002b36: 681a ldr r2, [r3, #0] + 8002b38: 4b04 ldr r3, [pc, #16] ; (8002b4c ) + 8002b3a: 429a cmp r2, r3 + 8002b3c: d102 bne.n 8002b44 + _send_bits(IOFLAG_SLEEP); + 8002b3e: 20cc movs r0, #204 ; 0xcc + 8002b40: f7ff bf04 b.w 800294c <_send_bits> +} + 8002b44: 4770 bx lr + 8002b46: bf00 nop + 8002b48: 2009e1c0 .word 0x2009e1c0 + 8002b4c: 35d25d63 .word 0x35d25d63 + +08002b50 : + __HAL_RCC_UART4_CLK_ENABLE(); + 8002b50: 4b13 ldr r3, [pc, #76] ; (8002ba0 ) + 8002b52: 6d9a ldr r2, [r3, #88] ; 0x58 + 8002b54: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 8002b58: 659a str r2, [r3, #88] ; 0x58 + 8002b5a: 6d9b ldr r3, [r3, #88] ; 0x58 +{ + 8002b5c: b082 sub sp, #8 + __HAL_RCC_UART4_CLK_ENABLE(); + 8002b5e: f403 2300 and.w r3, r3, #524288 ; 0x80000 + 8002b62: 9301 str r3, [sp, #4] + 8002b64: 9b01 ldr r3, [sp, #4] + MY_UART->CR1 = 0; + 8002b66: 4b0f ldr r3, [pc, #60] ; (8002ba4 ) + 8002b68: 2200 movs r2, #0 + 8002b6a: 601a str r2, [r3, #0] + MY_UART->CR1 = 0x1000002d & ~(0 + 8002b6c: 4a0e ldr r2, [pc, #56] ; (8002ba8 ) + 8002b6e: 601a str r2, [r3, #0] + MY_UART->RTOR = 24; // timeout in bit periods: 3 chars or so + 8002b70: 2218 movs r2, #24 + 8002b72: 615a str r2, [r3, #20] + MY_UART->CR2 = USART_CR2_RTOEN; // rx timeout enable + 8002b74: f44f 0200 mov.w r2, #8388608 ; 0x800000 + 8002b78: 605a str r2, [r3, #4] + MY_UART->CR3 = USART_CR3_HDSEL | USART_CR3_ONEBIT; + 8002b7a: f640 0208 movw r2, #2056 ; 0x808 + 8002b7e: 609a str r2, [r3, #8] + MY_UART->BRR = 521; // 230400 bps @ 120 Mhz SYSCLK + 8002b80: f240 2209 movw r2, #521 ; 0x209 + 8002b84: 60da str r2, [r3, #12] + MY_UART->ICR = USART_ICR_RTOCF; + 8002b86: f44f 6200 mov.w r2, #2048 ; 0x800 + 8002b8a: 621a str r2, [r3, #32] + MY_UART->CR1 |= USART_CR1_UE; + 8002b8c: 681a ldr r2, [r3, #0] + 8002b8e: f042 0201 orr.w r2, r2, #1 + 8002b92: 601a str r2, [r3, #0] + ae_chip_is_setup = AE_CHIP_IS_SETUP; + 8002b94: 4b05 ldr r3, [pc, #20] ; (8002bac ) + 8002b96: 4a06 ldr r2, [pc, #24] ; (8002bb0 ) + 8002b98: 601a str r2, [r3, #0] +} + 8002b9a: b002 add sp, #8 + 8002b9c: 4770 bx lr + 8002b9e: bf00 nop + 8002ba0: 40021000 .word 0x40021000 + 8002ba4: 40004c00 .word 0x40004c00 + 8002ba8: 1000002c .word 0x1000002c + 8002bac: 2009e1c0 .word 0x2009e1c0 + 8002bb0: 35d25d63 .word 0x35d25d63 + +08002bb4 : + ae_send_idle(); + 8002bb4: f7ff bf4d b.w 8002a52 + +08002bb8 : +// Read a one-byte status/error code response from chip. It's wrapped as 4 bytes: +// (len=4) (value) (crc16) (crc16) +// + int +ae_read1(void) +{ + 8002bb8: b513 push {r0, r1, r4, lr} + 8002bba: 2408 movs r4, #8 + uint8_t msg[4]; + + for(int retry=7; retry >= 0; retry--) { + // tell it we want to read a response, read it, and deserialize + int rv = ae_read_response(msg, 4); + 8002bbc: 2104 movs r1, #4 + 8002bbe: eb0d 0001 add.w r0, sp, r1 + 8002bc2: f7ff ff4f bl 8002a64 + + if(rv == 0) { + 8002bc6: 4601 mov r1, r0 + 8002bc8: b938 cbnz r0, 8002bda + // nothing heard, it's probably still processing + ERR("not rdy"); + STATS(not_ready++); + + delay_ms(5); + 8002bca: 2005 movs r0, #5 + 8002bcc: f000 ff5a bl 8003a84 + for(int retry=7; retry >= 0; retry--) { + 8002bd0: 3c01 subs r4, #1 + 8002bd2: d1f3 bne.n 8002bbc + try_again: + STATS(l1_retry++); + } + + // fail. + return -1; + 8002bd4: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8002bd8: e008 b.n 8002bec + if(rv != 4) { + 8002bda: 2804 cmp r0, #4 + 8002bdc: d1f8 bne.n 8002bd0 + if(!ae_check_crc(msg, 4)) { + 8002bde: a801 add r0, sp, #4 + 8002be0: f7ff ff0d bl 80029fe + 8002be4: 2800 cmp r0, #0 + 8002be6: d0f3 beq.n 8002bd0 + return msg[1]; + 8002be8: f89d 0005 ldrb.w r0, [sp, #5] +} + 8002bec: b002 add sp, #8 + 8002bee: bd10 pop {r4, pc} + +08002bf0 : +// Read and check CRC over N bytes, wrapped in 3-bytes of framing overhead. +// Return -1 for timeout, zero for normal, and one-byte error code otherwise. +// + int +ae_read_n(uint8_t len, uint8_t *body) +{ + 8002bf0: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + uint8_t tmp[1+len+2]; + 8002bf4: f100 030a add.w r3, r0, #10 + 8002bf8: f403 73fc and.w r3, r3, #504 ; 0x1f8 +{ + 8002bfc: af00 add r7, sp, #0 + uint8_t tmp[1+len+2]; + 8002bfe: ebad 0d03 sub.w sp, sp, r3 +{ + 8002c02: 460d mov r5, r1 + uint8_t tmp[1+len+2]; + 8002c04: 1cc6 adds r6, r0, #3 + 8002c06: 46e8 mov r8, sp + 8002c08: f04f 0908 mov.w r9, #8 + + for(int retry=7; retry >= 0; retry--) { + + int actual = ae_read_response(tmp, len+3); + 8002c0c: 4631 mov r1, r6 + 8002c0e: 4640 mov r0, r8 + 8002c10: f7ff ff28 bl 8002a64 + if(actual < 4) { + 8002c14: 2803 cmp r0, #3 + int actual = ae_read_response(tmp, len+3); + 8002c16: 4604 mov r4, r0 + if(actual < 4) { + 8002c18: dc0b bgt.n 8002c32 + + if(actual == 0) { + 8002c1a: b910 cbnz r0, 8002c22 + // nothing heard, it's probably still processing + delay_ms(5); + 8002c1c: 2005 movs r0, #5 + 8002c1e: f000 ff31 bl 8003a84 + + return 0; + + try_again: + STATS(ln_retry++); + ae_wake(); + 8002c22: f7ff ff0b bl 8002a3c + for(int retry=7; retry >= 0; retry--) { + 8002c26: f1b9 0901 subs.w r9, r9, #1 + 8002c2a: d1ef bne.n 8002c0c + } + + return -1; + 8002c2c: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8002c30: e007 b.n 8002c42 + uint8_t resp_len = tmp[0]; + 8002c32: f898 3000 ldrb.w r3, [r8] + if(resp_len != (len + 3)) { + 8002c36: 42b3 cmp r3, r6 + 8002c38: d006 beq.n 8002c48 + if(resp_len == 4) { + 8002c3a: 2b04 cmp r3, #4 + 8002c3c: d1f1 bne.n 8002c22 + return tmp[1]; + 8002c3e: f898 0001 ldrb.w r0, [r8, #1] +} + 8002c42: 46bd mov sp, r7 + 8002c44: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + if(!ae_check_crc(tmp, actual)) { + 8002c48: b2c1 uxtb r1, r0 + 8002c4a: 4640 mov r0, r8 + 8002c4c: f7ff fed7 bl 80029fe + 8002c50: 2800 cmp r0, #0 + 8002c52: d0e6 beq.n 8002c22 + memcpy(body, tmp+1, actual-3); + 8002c54: 1ee2 subs r2, r4, #3 + 8002c56: f108 0101 add.w r1, r8, #1 + 8002c5a: 4628 mov r0, r5 + 8002c5c: f00a fe54 bl 800d908 + return 0; + 8002c60: 2000 movs r0, #0 + 8002c62: e7ee b.n 8002c42 + +08002c64 : + +// ae_send_n() +// + void +ae_send_n(aeopcode_t opcode, uint8_t p1, uint16_t p2, const uint8_t *data, uint8_t data_len) +{ + 8002c64: b530 push {r4, r5, lr} + 8002c66: b085 sub sp, #20 + 8002c68: 461d mov r5, r3 + 8002c6a: f89d 4020 ldrb.w r4, [sp, #32] + uint8_t framed_len; + uint8_t op; + uint8_t p1; + uint8_t p2_lsb; + uint8_t p2_msb; + } known = { + 8002c6e: f88d 200c strb.w r2, [sp, #12] + 8002c72: 2377 movs r3, #119 ; 0x77 + 8002c74: 0a12 lsrs r2, r2, #8 + 8002c76: f88d 3008 strb.w r3, [sp, #8] + .ioflag = IOFLAG_CMD, + .framed_len = (data_len + 7), // 7 = (1 len) + (4 bytes of msg) + (2 crc) + 8002c7a: 1de3 adds r3, r4, #7 + } known = { + 8002c7c: f88d 3009 strb.w r3, [sp, #9] + 8002c80: f88d 200d strb.w r2, [sp, #13] + 8002c84: f88d 000a strb.w r0, [sp, #10] + 8002c88: f88d 100b strb.w r1, [sp, #11] + STATS(last_op = opcode); + STATS(last_p1 = p1); + STATS(last_p2 = p2); + + // important to wake chip at this point. + ae_wake(); + 8002c8c: f7ff fed6 bl 8002a3c + + _send_serialized((const uint8_t *)&known, sizeof(known)); + 8002c90: 2106 movs r1, #6 + 8002c92: a802 add r0, sp, #8 + 8002c94: f7ff fe69 bl 800296a <_send_serialized> + + // CRC will start from frame_len onwards + uint8_t crc[2] = {0, 0}; + 8002c98: 2300 movs r3, #0 + crc16_chain(sizeof(known)-1, &known.framed_len, crc); + 8002c9a: aa01 add r2, sp, #4 + 8002c9c: f10d 0109 add.w r1, sp, #9 + 8002ca0: 2005 movs r0, #5 + uint8_t crc[2] = {0, 0}; + 8002ca2: f8ad 3004 strh.w r3, [sp, #4] + crc16_chain(sizeof(known)-1, &known.framed_len, crc); + 8002ca6: f7ff fe87 bl 80029b8 + + // insert a variable-length body area (sometimes) + if(data_len) { + 8002caa: b144 cbz r4, 8002cbe + _send_serialized(data, data_len); + 8002cac: 4621 mov r1, r4 + 8002cae: 4628 mov r0, r5 + 8002cb0: f7ff fe5b bl 800296a <_send_serialized> + + crc16_chain(data_len, data, crc); + 8002cb4: aa01 add r2, sp, #4 + 8002cb6: 4629 mov r1, r5 + 8002cb8: 4620 mov r0, r4 + 8002cba: f7ff fe7d bl 80029b8 + } + + // send final CRC bytes + _send_serialized(crc, 2); + 8002cbe: 2102 movs r1, #2 + 8002cc0: a801 add r0, sp, #4 + 8002cc2: f7ff fe52 bl 800296a <_send_serialized> +} + 8002cc6: b005 add sp, #20 + 8002cc8: bd30 pop {r4, r5, pc} + +08002cca : +{ + 8002cca: b507 push {r0, r1, r2, lr} + ae_send_n(opcode, p1, p2, NULL, 0); + 8002ccc: 2300 movs r3, #0 + 8002cce: 9300 str r3, [sp, #0] + 8002cd0: f7ff ffc8 bl 8002c64 +} + 8002cd4: b003 add sp, #12 + 8002cd6: f85d fb04 ldr.w pc, [sp], #4 + +08002cda : +// +// Do Info(p1=2) command, and return result. +// + uint16_t +ae_get_info(void) +{ + 8002cda: b507 push {r0, r1, r2, lr} + // not doing error checking here + ae_send(OP_Info, 0x2, 0); + 8002cdc: 2200 movs r2, #0 + 8002cde: 2102 movs r1, #2 + 8002ce0: 2030 movs r0, #48 ; 0x30 + 8002ce2: f7ff fff2 bl 8002cca + + // note: always returns 4 bytes, but most are garbage and unused. + uint8_t tmp[4]; + ae_read_n(4, tmp); + 8002ce6: a901 add r1, sp, #4 + 8002ce8: 2004 movs r0, #4 + 8002cea: f7ff ff81 bl 8002bf0 + + return (tmp[0] << 8) | tmp[1]; + 8002cee: f8bd 0004 ldrh.w r0, [sp, #4] + 8002cf2: ba40 rev16 r0, r0 +} + 8002cf4: b280 uxth r0, r0 + 8002cf6: b003 add sp, #12 + 8002cf8: f85d fb04 ldr.w pc, [sp], #4 + +08002cfc : +// Load Tempkey with a specific value. Resulting Tempkey cannot be +// used with many commands/keys, but is needed for signing. +// + int +ae_load_nonce(const uint8_t nonce[32]) +{ + 8002cfc: b507 push {r0, r1, r2, lr} + // p1=3 + ae_send_n(OP_Nonce, 3, 0, nonce, 32); // 608a ok + 8002cfe: 2220 movs r2, #32 +{ + 8002d00: 4603 mov r3, r0 + ae_send_n(OP_Nonce, 3, 0, nonce, 32); // 608a ok + 8002d02: 9200 str r2, [sp, #0] + 8002d04: 2103 movs r1, #3 + 8002d06: 2200 movs r2, #0 + 8002d08: 2016 movs r0, #22 + 8002d0a: f7ff ffab bl 8002c64 + + return ae_read1(); +} + 8002d0e: b003 add sp, #12 + 8002d10: f85d eb04 ldr.w lr, [sp], #4 + return ae_read1(); + 8002d14: f7ff bf50 b.w 8002bb8 + +08002d18 : +// Load 32bytes of message digest with a specific value. +// Needed for signing. +// + int +ae_load_msgdigest(const uint8_t md[32]) +{ + 8002d18: b507 push {r0, r1, r2, lr} + ae_send_n(OP_Nonce, (1<<6) | 3, 0, md, 32); + 8002d1a: 2220 movs r2, #32 +{ + 8002d1c: 4603 mov r3, r0 + ae_send_n(OP_Nonce, (1<<6) | 3, 0, md, 32); + 8002d1e: 9200 str r2, [sp, #0] + 8002d20: 2143 movs r1, #67 ; 0x43 + 8002d22: 2200 movs r2, #0 + 8002d24: 2016 movs r0, #22 + 8002d26: f7ff ff9d bl 8002c64 + + return ae_read1(); +} + 8002d2a: b003 add sp, #12 + 8002d2c: f85d eb04 ldr.w lr, [sp], #4 + return ae_read1(); + 8002d30: f7ff bf42 b.w 8002bb8 + +08002d34 : +// Load Tempkey with a nonce value that we both know, but +// is random and we both know is random! Tricky! +// + int +ae_pick_nonce(const uint8_t num_in[20], uint8_t tempkey[32]) +{ + 8002d34: b5f0 push {r4, r5, r6, r7, lr} + 8002d36: b09f sub sp, #124 ; 0x7c + // We provide some 20 bytes of randomness to chip + // The chip must provide 32-bytes of random-ness, + // so no choice in args to OP.Nonce here (due to ReqRandom). + ae_send_n(OP_Nonce, 0, 0, num_in, 20); + 8002d38: 2200 movs r2, #0 + 8002d3a: 2714 movs r7, #20 + 8002d3c: 4603 mov r3, r0 +{ + 8002d3e: 4605 mov r5, r0 + 8002d40: 460e mov r6, r1 + ae_send_n(OP_Nonce, 0, 0, num_in, 20); + 8002d42: 2016 movs r0, #22 + 8002d44: 4611 mov r1, r2 + 8002d46: 9700 str r7, [sp, #0] + 8002d48: f7ff ff8c bl 8002c64 + + // Nonce command returns the RNG result, but not contents of TempKey + uint8_t randout[32]; + int rv = ae_read_n(32, randout); + 8002d4c: a903 add r1, sp, #12 + 8002d4e: 2020 movs r0, #32 + 8002d50: f7ff ff4e bl 8002bf0 + RET_IF_BAD(rv); + 8002d54: 4604 mov r4, r0 + 8002d56: b9e0 cbnz r0, 8002d92 + // + // return sha256(rndout + num_in + b'\x16\0\0').digest() + // + SHA256_CTX ctx; + + sha256_init(&ctx); + 8002d58: a80b add r0, sp, #44 ; 0x2c + 8002d5a: f002 fd0f bl 800577c + sha256_update(&ctx, randout, 32); + 8002d5e: 2220 movs r2, #32 + 8002d60: a903 add r1, sp, #12 + 8002d62: a80b add r0, sp, #44 ; 0x2c + 8002d64: f002 fd18 bl 8005798 + sha256_update(&ctx, num_in, 20); + 8002d68: 463a mov r2, r7 + 8002d6a: 4629 mov r1, r5 + 8002d6c: a80b add r0, sp, #44 ; 0x2c + 8002d6e: f002 fd13 bl 8005798 + const uint8_t fixed[3] = { 0x16, 0, 0 }; + 8002d72: 4b09 ldr r3, [pc, #36] ; (8002d98 ) + 8002d74: 881a ldrh r2, [r3, #0] + 8002d76: f8ad 2008 strh.w r2, [sp, #8] + 8002d7a: 789b ldrb r3, [r3, #2] + 8002d7c: f88d 300a strb.w r3, [sp, #10] + sha256_update(&ctx, fixed, 3); + 8002d80: a902 add r1, sp, #8 + 8002d82: a80b add r0, sp, #44 ; 0x2c + 8002d84: 2203 movs r2, #3 + 8002d86: f002 fd07 bl 8005798 + + sha256_final(&ctx, tempkey); + 8002d8a: 4631 mov r1, r6 + 8002d8c: a80b add r0, sp, #44 ; 0x2c + 8002d8e: f002 fd49 bl 8005824 + + return 0; +} + 8002d92: 4620 mov r0, r4 + 8002d94: b01f add sp, #124 ; 0x7c + 8002d96: bdf0 pop {r4, r5, r6, r7, pc} + 8002d98: 080106f0 .word 0x080106f0 + +08002d9c : +// Check that TempKey is holding what we think it does. Uses the MAC +// command over contents of Tempkey and our shared secret. +// + bool +ae_is_correct_tempkey(const uint8_t expected_tempkey[32]) +{ + 8002d9c: b570 push {r4, r5, r6, lr} + const uint8_t mode = (1<<6) // include full serial number + | (0<<2) // TempKey.SourceFlag == 0 == 'rand' + | (0<<1) // first 32 bytes are the shared secret + | (1<<0); // second 32 bytes are tempkey + + ae_send(OP_MAC, mode, KEYNUM_pairing); + 8002d9e: 2141 movs r1, #65 ; 0x41 +{ + 8002da0: b0a8 sub sp, #160 ; 0xa0 + 8002da2: 4604 mov r4, r0 + ae_send(OP_MAC, mode, KEYNUM_pairing); + 8002da4: 2201 movs r2, #1 + 8002da6: 2008 movs r0, #8 + 8002da8: f7ff ff8f bl 8002cca + + // read chip's answer + uint8_t resp[32]; + int rv = ae_read_n(32, resp); + 8002dac: a905 add r1, sp, #20 + 8002dae: 2020 movs r0, #32 + 8002db0: f7ff ff1e bl 8002bf0 + if(rv) return false; + 8002db4: 2800 cmp r0, #0 + 8002db6: d135 bne.n 8002e24 + ae_send_idle(); + 8002db8: f7ff fe4b bl 8002a52 + ae_keep_alive(); + + // Duplicate the hash process, and then compare. + SHA256_CTX ctx; + + sha256_init(&ctx); + 8002dbc: a815 add r0, sp, #84 ; 0x54 + 8002dbe: f002 fcdd bl 800577c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8002dc2: 4919 ldr r1, [pc, #100] ; (8002e28 ) + 8002dc4: 2220 movs r2, #32 + 8002dc6: a815 add r0, sp, #84 ; 0x54 + 8002dc8: f002 fce6 bl 8005798 + sha256_update(&ctx, expected_tempkey, 32); + 8002dcc: 2220 movs r2, #32 + 8002dce: 4621 mov r1, r4 + 8002dd0: a815 add r0, sp, #84 ; 0x54 + 8002dd2: f002 fce1 bl 8005798 + + const uint8_t fixed[16] = { OP_MAC, mode, KEYNUM_pairing, 0x0, + 8002dd6: 4b15 ldr r3, [pc, #84] ; (8002e2c ) + 8002dd8: aa01 add r2, sp, #4 + 8002dda: f103 0610 add.w r6, r3, #16 + 8002dde: 4615 mov r5, r2 + 8002de0: 6818 ldr r0, [r3, #0] + 8002de2: 6859 ldr r1, [r3, #4] + 8002de4: 4614 mov r4, r2 + 8002de6: c403 stmia r4!, {r0, r1} + 8002de8: 3308 adds r3, #8 + 8002dea: 42b3 cmp r3, r6 + 8002dec: 4622 mov r2, r4 + 8002dee: d1f7 bne.n 8002de0 + 0,0,0,0, 0,0,0,0, // eight zeros + 0,0,0, // three zeros + 0xEE }; + sha256_update(&ctx, fixed, sizeof(fixed)); + 8002df0: 2210 movs r2, #16 + 8002df2: 4629 mov r1, r5 + 8002df4: a815 add r0, sp, #84 ; 0x54 + 8002df6: f002 fccf bl 8005798 + + sha256_update(&ctx, ((const uint8_t *)rom_secrets->ae_serial_number)+4, 4); + 8002dfa: 490d ldr r1, [pc, #52] ; (8002e30 ) + 8002dfc: 2204 movs r2, #4 + 8002dfe: a815 add r0, sp, #84 ; 0x54 + 8002e00: f002 fcca bl 8005798 + sha256_update(&ctx, ((const uint8_t *)rom_secrets->ae_serial_number)+0, 4); + 8002e04: 2204 movs r2, #4 + 8002e06: 490b ldr r1, [pc, #44] ; (8002e34 ) + 8002e08: a815 add r0, sp, #84 ; 0x54 + 8002e0a: f002 fcc5 bl 8005798 + // this verifies no problem. + ASSERT(ctx.datalen + (ctx.bitlen/8) == 32+32+1+1+2+8+3+1+4+2+2); // == 88 +#endif + + uint8_t actual[32]; + sha256_final(&ctx, actual); + 8002e0e: a90d add r1, sp, #52 ; 0x34 + 8002e10: a815 add r0, sp, #84 ; 0x54 + 8002e12: f002 fd07 bl 8005824 + + return check_equal(actual, resp, 32); + 8002e16: 2220 movs r2, #32 + 8002e18: a905 add r1, sp, #20 + 8002e1a: a80d add r0, sp, #52 ; 0x34 + 8002e1c: f7ff fd0f bl 800283e +} + 8002e20: b028 add sp, #160 ; 0xa0 + 8002e22: bd70 pop {r4, r5, r6, pc} + if(rv) return false; + 8002e24: 2000 movs r0, #0 + 8002e26: e7fb b.n 8002e20 + 8002e28: 0801c000 .word 0x0801c000 + 8002e2c: 080106f3 .word 0x080106f3 + 8002e30: 0801c044 .word 0x0801c044 + 8002e34: 0801c040 .word 0x0801c040 + +08002e38 : +// inside the 508a/608a, like use of a specific key, but not for us to +// authenticate the 508a/608a or its contents/state. +// + int +ae_checkmac(uint8_t keynum, const uint8_t secret[32]) +{ + 8002e38: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8002e3c: b0c2 sub sp, #264 ; 0x108 + + // Since this is part of the hash, we want random bytes + // for our "other data". Also a number for "numin" of nonce + uint8_t od[32], numin[20]; + + rng_buffer(od, sizeof(od)); + 8002e3e: ad0b add r5, sp, #44 ; 0x2c +{ + 8002e40: 4607 mov r7, r0 + 8002e42: 460e mov r6, r1 + rng_buffer(od, sizeof(od)); + 8002e44: 4628 mov r0, r5 + 8002e46: 2120 movs r1, #32 + 8002e48: f7ff fd48 bl 80028dc + rng_buffer(numin, sizeof(numin)); + 8002e4c: 2114 movs r1, #20 + 8002e4e: a806 add r0, sp, #24 + 8002e50: f7ff fd44 bl 80028dc + ae_send_idle(); + 8002e54: f7ff fdfd bl 8002a52 + + // need this one, want to reset watchdog to this point. + ae_keep_alive(); + + // - load tempkey with a known nonce value + uint8_t zeros[8] = {0}; + 8002e58: 2300 movs r3, #0 + uint8_t tempkey[32]; + rv = ae_pick_nonce(numin, tempkey); + 8002e5a: a913 add r1, sp, #76 ; 0x4c + 8002e5c: a806 add r0, sp, #24 + uint8_t zeros[8] = {0}; + 8002e5e: e9cd 3304 strd r3, r3, [sp, #16] + rv = ae_pick_nonce(numin, tempkey); + 8002e62: f7ff ff67 bl 8002d34 + RET_IF_BAD(rv); + 8002e66: 4604 mov r4, r0 + 8002e68: 2800 cmp r0, #0 + 8002e6a: d15d bne.n 8002f28 + + // - hash nonce and lots of other bits together + SHA256_CTX ctx; + sha256_init(&ctx); + 8002e6c: a81b add r0, sp, #108 ; 0x6c + 8002e6e: f002 fc85 bl 800577c + + // shared secret is 32 bytes from flash + sha256_update(&ctx, secret, 32); + 8002e72: 2220 movs r2, #32 + 8002e74: 4631 mov r1, r6 + 8002e76: a81b add r0, sp, #108 ; 0x6c + 8002e78: f002 fc8e bl 8005798 + + sha256_update(&ctx, tempkey, 32); + 8002e7c: 2220 movs r2, #32 + 8002e7e: a913 add r1, sp, #76 ; 0x4c + 8002e80: a81b add r0, sp, #108 ; 0x6c + 8002e82: f002 fc89 bl 8005798 + sha256_update(&ctx, &od[0], 4); + 8002e86: 2204 movs r2, #4 + 8002e88: 4629 mov r1, r5 + 8002e8a: a81b add r0, sp, #108 ; 0x6c + 8002e8c: f002 fc84 bl 8005798 + + sha256_update(&ctx, zeros, 8); + 8002e90: 2208 movs r2, #8 + 8002e92: a904 add r1, sp, #16 + 8002e94: a81b add r0, sp, #108 ; 0x6c + 8002e96: f002 fc7f bl 8005798 + + sha256_update(&ctx, &od[4], 3); + 8002e9a: 2203 movs r2, #3 + 8002e9c: a90c add r1, sp, #48 ; 0x30 + 8002e9e: a81b add r0, sp, #108 ; 0x6c + 8002ea0: f002 fc7a bl 8005798 + + uint8_t ee = 0xEE; + 8002ea4: 23ee movs r3, #238 ; 0xee + sha256_update(&ctx, &ee, 1); + 8002ea6: 2201 movs r2, #1 + 8002ea8: f10d 010b add.w r1, sp, #11 + 8002eac: a81b add r0, sp, #108 ; 0x6c + uint8_t ee = 0xEE; + 8002eae: f88d 300b strb.w r3, [sp, #11] + sha256_update(&ctx, &ee, 1); + 8002eb2: f002 fc71 bl 8005798 + sha256_update(&ctx, &od[7], 4); + 8002eb6: 2204 movs r2, #4 + 8002eb8: f10d 0133 add.w r1, sp, #51 ; 0x33 + 8002ebc: a81b add r0, sp, #108 ; 0x6c + 8002ebe: f002 fc6b bl 8005798 + + uint8_t snp[2] = { 0x01, 0x23 }; + 8002ec2: f242 3301 movw r3, #8961 ; 0x2301 + sha256_update(&ctx, snp, 2); + 8002ec6: 2202 movs r2, #2 + 8002ec8: a903 add r1, sp, #12 + 8002eca: a81b add r0, sp, #108 ; 0x6c + uint8_t snp[2] = { 0x01, 0x23 }; + 8002ecc: f8ad 300c strh.w r3, [sp, #12] + sha256_update(&ctx, snp, 2); + 8002ed0: f002 fc62 bl 8005798 + sha256_update(&ctx, &od[11], 2); + 8002ed4: 2202 movs r2, #2 + 8002ed6: f10d 0137 add.w r1, sp, #55 ; 0x37 + 8002eda: a81b add r0, sp, #108 ; 0x6c + 8002edc: f002 fc5c bl 8005798 + uint8_t resp[32]; + uint8_t od[13]; + } req; + + // content doesn't matter, but nice and visible: + memcpy(req.ch3, copyright_msg, 32); + 8002ee0: 4b15 ldr r3, [pc, #84] ; (8002f38 ) + 8002ee2: ac2e add r4, sp, #184 ; 0xb8 + 8002ee4: f103 0220 add.w r2, r3, #32 + 8002ee8: 46a0 mov r8, r4 + 8002eea: 6818 ldr r0, [r3, #0] + 8002eec: 6859 ldr r1, [r3, #4] + 8002eee: 4626 mov r6, r4 + 8002ef0: c603 stmia r6!, {r0, r1} + 8002ef2: 3308 adds r3, #8 + 8002ef4: 4293 cmp r3, r2 + 8002ef6: 4634 mov r4, r6 + 8002ef8: d1f7 bne.n 8002eea + // this verifies no problem. + int l = (ctx.blocks * 64) + ctx.npartial; + ASSERT(l == 32+32+4+8+3+1+4+2+2); // == 88 +#endif + + sha256_final(&ctx, req.resp); + 8002efa: a936 add r1, sp, #216 ; 0xd8 + 8002efc: a81b add r0, sp, #108 ; 0x6c + 8002efe: f002 fc91 bl 8005824 + memcpy(req.od, od, 13); + 8002f02: e895 000f ldmia.w r5, {r0, r1, r2, r3} + 8002f06: ac3e add r4, sp, #248 ; 0xf8 + 8002f08: c407 stmia r4!, {r0, r1, r2} + 8002f0a: 7023 strb r3, [r4, #0] + + STATIC_ASSERT(sizeof(req) == 32 + 32 + 13); + + // Give our answer to the chip. + ae_send_n(OP_CheckMac, 0x01, keynum, (uint8_t *)&req, sizeof(req)); + 8002f0c: 234d movs r3, #77 ; 0x4d + 8002f0e: 9300 str r3, [sp, #0] + 8002f10: 463a mov r2, r7 + 8002f12: 4643 mov r3, r8 + 8002f14: 2101 movs r1, #1 + 8002f16: 2028 movs r0, #40 ; 0x28 + 8002f18: f7ff fea4 bl 8002c64 + + rv = ae_read1(); + 8002f1c: f7ff fe4c bl 8002bb8 + if(rv != 0) { + 8002f20: 4604 mov r4, r0 + 8002f22: b928 cbnz r0, 8002f30 + ae_send_idle(); + 8002f24: f7ff fd95 bl 8002a52 + + // just in case ... always restart watchdog timer. + ae_keep_alive(); + + return 0; +} + 8002f28: 4620 mov r0, r4 + 8002f2a: b042 add sp, #264 ; 0x108 + 8002f2c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + return -1; + 8002f30: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 8002f34: e7f8 b.n 8002f28 + 8002f36: bf00 nop + 8002f38: 080106c2 .word 0x080106c2 + +08002f3c : + return ae_checkmac(KEYNUM_pairing, rom_secrets->pairing_secret); + 8002f3c: 4901 ldr r1, [pc, #4] ; (8002f44 ) + 8002f3e: 2001 movs r0, #1 + 8002f40: f7ff bf7a b.w 8002e38 + 8002f44: 0801c000 .word 0x0801c000 + +08002f48 : +// Sign a message (already digested) +// + int +ae_sign_authed(uint8_t keynum, const uint8_t msg_hash[32], + uint8_t signature[64], int auth_kn, const uint8_t auth_digest[32]) +{ + 8002f48: b570 push {r4, r5, r6, lr} + 8002f4a: 460e mov r6, r1 + 8002f4c: 4604 mov r4, r0 + 8002f4e: 4615 mov r5, r2 + // indicate we know the PIN + ae_pair_unlock(); + 8002f50: f7ff fff4 bl 8002f3c + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + 8002f54: 9904 ldr r1, [sp, #16] + 8002f56: 2003 movs r0, #3 + 8002f58: f7ff ff6e bl 8002e38 + RET_IF_BAD(rv); + 8002f5c: b990 cbnz r0, 8002f84 + + // send what we need signed + rv = ae_load_msgdigest(msg_hash); + 8002f5e: 4630 mov r0, r6 + 8002f60: f7ff feda bl 8002d18 + RET_IF_BAD(rv); + 8002f64: b970 cbnz r0, 8002f84 + + do { + ae_send(OP_Sign, (7<<5), keynum); + 8002f66: b2a4 uxth r4, r4 + 8002f68: 4622 mov r2, r4 + 8002f6a: 21e0 movs r1, #224 ; 0xe0 + 8002f6c: 2041 movs r0, #65 ; 0x41 + 8002f6e: f7ff feac bl 8002cca + + delay_ms(60); // min time for processing + 8002f72: 203c movs r0, #60 ; 0x3c + 8002f74: f000 fd86 bl 8003a84 + + rv = ae_read_n(64, signature); + 8002f78: 4629 mov r1, r5 + 8002f7a: 2040 movs r0, #64 ; 0x40 + 8002f7c: f7ff fe38 bl 8002bf0 + } while(rv == AE_ECC_FAULT); + 8002f80: 2805 cmp r0, #5 + 8002f82: d0f1 beq.n 8002f68 + + return rv; +} + 8002f84: bd70 pop {r4, r5, r6, pc} + ... + +08002f88 : + +// ae_gen_ecc_key() +// + int +ae_gen_ecc_key(uint8_t keynum, uint8_t pubkey_out[64]) +{ + 8002f88: b530 push {r4, r5, lr} + int rv; + uint8_t junk[3] = { 0 }; + 8002f8a: 4b0f ldr r3, [pc, #60] ; (8002fc8 ) +{ + 8002f8c: b085 sub sp, #20 + uint8_t junk[3] = { 0 }; + 8002f8e: f8b3 3013 ldrh.w r3, [r3, #19] + 8002f92: f8ad 300c strh.w r3, [sp, #12] + 8002f96: 2300 movs r3, #0 +{ + 8002f98: 460c mov r4, r1 + uint8_t junk[3] = { 0 }; + 8002f9a: f88d 300e strb.w r3, [sp, #14] + + do { + ae_send_n(OP_GenKey, (1<<2), keynum, junk, 3); + 8002f9e: 4605 mov r5, r0 + 8002fa0: 2303 movs r3, #3 + 8002fa2: 462a mov r2, r5 + 8002fa4: 2104 movs r1, #4 + 8002fa6: 9300 str r3, [sp, #0] + 8002fa8: 2040 movs r0, #64 ; 0x40 + 8002faa: ab03 add r3, sp, #12 + 8002fac: f7ff fe5a bl 8002c64 + + delay_ms(100); // to avoid timeouts + 8002fb0: 2064 movs r0, #100 ; 0x64 + 8002fb2: f000 fd67 bl 8003a84 + + rv = ae_read_n(64, pubkey_out); + 8002fb6: 4621 mov r1, r4 + 8002fb8: 2040 movs r0, #64 ; 0x40 + 8002fba: f7ff fe19 bl 8002bf0 + } while(rv == AE_ECC_FAULT); + 8002fbe: 2805 cmp r0, #5 + 8002fc0: d0ee beq.n 8002fa0 + + return rv; +} + 8002fc2: b005 add sp, #20 + 8002fc4: bd30 pop {r4, r5, pc} + 8002fc6: bf00 nop + 8002fc8: 080106f0 .word 0x080106f0 + +08002fcc : +// 508a: Different opcode, OP_HMAC does exactly 32 bytes w/ less steps. +// 608a: Use old SHA256 command, but with new flags. +// + int +ae_hmac32(uint8_t keynum, const uint8_t msg[32], uint8_t digest[32]) +{ + 8002fcc: b530 push {r4, r5, lr} + 8002fce: b085 sub sp, #20 + 8002fd0: 4615 mov r5, r2 + 8002fd2: 9103 str r1, [sp, #12] + // Start SHA w/ HMAC setup + ae_send(OP_SHA, 4, keynum); // 4 = HMAC_Init + 8002fd4: 4602 mov r2, r0 + 8002fd6: 2104 movs r1, #4 + 8002fd8: 2047 movs r0, #71 ; 0x47 + 8002fda: f7ff fe76 bl 8002cca + + // expect zero, meaning "ready" + int rv = ae_read1(); + 8002fde: f7ff fdeb bl 8002bb8 + RET_IF_BAD(rv); + 8002fe2: b970 cbnz r0, 8003002 + + // send the contents to be hashed + ae_send_n(OP_SHA, (3<<6) | 2, 32, msg, 32); // 2 = Finalize, 3=Place output + 8002fe4: 2420 movs r4, #32 + 8002fe6: 9b03 ldr r3, [sp, #12] + 8002fe8: 9400 str r4, [sp, #0] + 8002fea: 4622 mov r2, r4 + 8002fec: 21c2 movs r1, #194 ; 0xc2 + 8002fee: 2047 movs r0, #71 ; 0x47 + 8002ff0: f7ff fe38 bl 8002c64 + + // read result + return ae_read_n(32, digest); + 8002ff4: 4629 mov r1, r5 + 8002ff6: 4620 mov r0, r4 +} + 8002ff8: b005 add sp, #20 + 8002ffa: e8bd 4030 ldmia.w sp!, {r4, r5, lr} + return ae_read_n(32, digest); + 8002ffe: f7ff bdf7 b.w 8002bf0 +} + 8003002: b005 add sp, #20 + 8003004: bd30 pop {r4, r5, pc} + +08003006 : +// +// Return the serial number: it's 9 bytes, altho 3 are fixed. +// + int +ae_get_serial(uint8_t serial[6]) +{ + 8003006: b510 push {r4, lr} + ae_send(OP_Read, 0x80, 0x0); + 8003008: 2200 movs r2, #0 +{ + 800300a: b08c sub sp, #48 ; 0x30 + ae_send(OP_Read, 0x80, 0x0); + 800300c: 2180 movs r1, #128 ; 0x80 +{ + 800300e: 4604 mov r4, r0 + ae_send(OP_Read, 0x80, 0x0); + 8003010: 2002 movs r0, #2 + 8003012: f7ff fe5a bl 8002cca + + uint8_t temp[32]; + int rv = ae_read_n(32, temp); + 8003016: a904 add r1, sp, #16 + 8003018: 2020 movs r0, #32 + 800301a: f7ff fde9 bl 8002bf0 + RET_IF_BAD(rv); + 800301e: 4603 mov r3, r0 + 8003020: b9b8 cbnz r0, 8003052 + + // reformat to 9 bytes. + uint8_t ts[9]; + memcpy(ts, &temp[0], 4); + memcpy(&ts[4], &temp[8], 5); + 8003022: e9dd 0106 ldrd r0, r1, [sp, #24] + 8003026: 9a04 ldr r2, [sp, #16] + 8003028: f88d 100c strb.w r1, [sp, #12] + + // check the hard-coded values + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 800302c: b2d1 uxtb r1, r2 + 800302e: 2901 cmp r1, #1 + memcpy(ts, &temp[0], 4); + 8003030: 9201 str r2, [sp, #4] + memcpy(&ts[4], &temp[8], 5); + 8003032: 9002 str r0, [sp, #8] + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 8003034: d110 bne.n 8003058 + 8003036: f3c2 2207 ubfx r2, r2, #8, #8 + 800303a: 2a23 cmp r2, #35 ; 0x23 + 800303c: d10c bne.n 8003058 + 800303e: f89d 200c ldrb.w r2, [sp, #12] + 8003042: 2aee cmp r2, #238 ; 0xee + 8003044: d10a bne.n 800305c + + // save only the unique bits. + memcpy(serial, ts+2, 6); + 8003046: f8dd 2006 ldr.w r2, [sp, #6] + 800304a: 6022 str r2, [r4, #0] + 800304c: f8bd 200a ldrh.w r2, [sp, #10] + 8003050: 80a2 strh r2, [r4, #4] + + return 0; +} + 8003052: 4618 mov r0, r3 + 8003054: b00c add sp, #48 ; 0x30 + 8003056: bd10 pop {r4, pc} + if((ts[0] != 0x01) || (ts[1] != 0x23) || (ts[8] != 0xEE)) return 1; + 8003058: 2301 movs r3, #1 + 800305a: e7fa b.n 8003052 + 800305c: 460b mov r3, r1 + 800305e: e7f8 b.n 8003052 + +08003060 : +{ + 8003060: b513 push {r0, r1, r4, lr} + ae_wake(); + 8003062: f7ff fceb bl 8002a3c + _send_bits(IOFLAG_SLEEP); + 8003066: 20cc movs r0, #204 ; 0xcc + 8003068: f7ff fc70 bl 800294c <_send_bits> + ae_wake(); + 800306c: f7ff fce6 bl 8002a3c + ae_read1(); + 8003070: f7ff fda2 bl 8002bb8 + uint8_t chk = ae_read1(); + 8003074: f7ff fda0 bl 8002bb8 + if(chk != AE_AFTER_WAKE) return "wk fl"; + 8003078: b2c0 uxtb r0, r0 + 800307a: 2811 cmp r0, #17 + 800307c: d10e bne.n 800309c + if(ae_get_serial(serial)) return "no ser"; + 800307e: 4668 mov r0, sp + 8003080: f7ff ffc1 bl 8003006 + 8003084: 4604 mov r4, r0 + 8003086: b938 cbnz r0, 8003098 + ae_wake(); + 8003088: f7ff fcd8 bl 8002a3c + _send_bits(IOFLAG_SLEEP); + 800308c: 20cc movs r0, #204 ; 0xcc + 800308e: f7ff fc5d bl 800294c <_send_bits> + return NULL; + 8003092: 4620 mov r0, r4 +} + 8003094: b002 add sp, #8 + 8003096: bd10 pop {r4, pc} + if(ae_get_serial(serial)) return "no ser"; + 8003098: 4801 ldr r0, [pc, #4] ; (80030a0 ) + 800309a: e7fb b.n 8003094 + if(chk != AE_AFTER_WAKE) return "wk fl"; + 800309c: 4801 ldr r0, [pc, #4] ; (80030a4 ) + 800309e: e7f9 b.n 8003094 + 80030a0: 080106e3 .word 0x080106e3 + 80030a4: 080106ea .word 0x080106ea + +080030a8 : +// +// -- can also lock it. +// + int +ae_write_data_slot(int slot_num, const uint8_t *data, int len, bool lock_it) +{ + 80030a8: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 80030ac: 4699 mov r9, r3 + ASSERT(len >= 32); + 80030ae: f1a2 0320 sub.w r3, r2, #32 +{ + 80030b2: b085 sub sp, #20 + ASSERT(len >= 32); + 80030b4: f5b3 7fc0 cmp.w r3, #384 ; 0x180 +{ + 80030b8: 4604 mov r4, r0 + 80030ba: af02 add r7, sp, #8 + 80030bc: 460d mov r5, r1 + 80030be: 4690 mov r8, r2 + ASSERT(len >= 32); + 80030c0: d902 bls.n 80030c8 + 80030c2: 482d ldr r0, [pc, #180] ; (8003178 ) + 80030c4: f7fd fcb8 bl 8000a38 + ASSERT(len <= 416); + + for(int blk=0, xlen=len; xlen>0; blk++, xlen-=32) { + // have to write each "block" of 32-bytes, separately + // zone => data + ae_send_n(OP_Write, 0x80|2, (blk<<8) | (slot_num<<3), data+(blk*32), 32); + 80030c8: ea4f 0ac0 mov.w sl, r0, lsl #3 + 80030cc: fa0f fa8a sxth.w sl, sl + 80030d0: 2600 movs r6, #0 + 80030d2: f04f 0b20 mov.w fp, #32 + 80030d6: ebc6 3246 rsb r2, r6, r6, lsl #13 + 80030da: ea4a 02c2 orr.w r2, sl, r2, lsl #3 + 80030de: b292 uxth r2, r2 + 80030e0: 1bab subs r3, r5, r6 + 80030e2: 2182 movs r1, #130 ; 0x82 + 80030e4: 2012 movs r0, #18 + 80030e6: f8cd b000 str.w fp, [sp] + 80030ea: f7ff fdbb bl 8002c64 + + int rv = ae_read1(); + 80030ee: f7ff fd63 bl 8002bb8 + RET_IF_BAD(rv); + 80030f2: 2800 cmp r0, #0 + 80030f4: d13c bne.n 8003170 + for(int blk=0, xlen=len; xlen>0; blk++, xlen-=32) { + 80030f6: 3e20 subs r6, #32 + 80030f8: eb06 0308 add.w r3, r6, r8 + 80030fc: 2b00 cmp r3, #0 + 80030fe: dcea bgt.n 80030d6 + } + + if(lock_it) { + 8003100: f1b9 0f00 cmp.w r9, #0 + 8003104: d034 beq.n 8003170 + ASSERT(slot_num != 8); // no support for mega slot 8 + 8003106: 2c08 cmp r4, #8 + if(lock_it) { + 8003108: 466e mov r6, sp + ASSERT(slot_num != 8); // no support for mega slot 8 + 800310a: d0da beq.n 80030c2 + ASSERT(len == 32); // probably not a limitation here + 800310c: f1b8 0f20 cmp.w r8, #32 + 8003110: d1d7 bne.n 80030c2 + + // Assume 36/72-byte long slot, which will be partially written, and rest + // should be ones. + const int slot_len = (slot_num <= 7) ? 36 : 72; + 8003112: 2c08 cmp r4, #8 + 8003114: bfb4 ite lt + 8003116: f04f 0824 movlt.w r8, #36 ; 0x24 + 800311a: f04f 0848 movge.w r8, #72 ; 0x48 + uint8_t copy[slot_len]; + 800311e: f108 0307 add.w r3, r8, #7 + 8003122: f003 03f8 and.w r3, r3, #248 ; 0xf8 + 8003126: ebad 0d03 sub.w sp, sp, r3 + 800312a: ab02 add r3, sp, #8 + + memset(copy, 0xff, slot_len); + 800312c: 4642 mov r2, r8 + 800312e: 21ff movs r1, #255 ; 0xff + 8003130: 4618 mov r0, r3 + 8003132: f00a fbf7 bl 800d924 + memcpy(copy, data, len); + 8003136: f105 0120 add.w r1, r5, #32 + memset(copy, 0xff, slot_len); + 800313a: 4603 mov r3, r0 + memcpy(copy, data, len); + 800313c: 4602 mov r2, r0 + 800313e: f855 0b04 ldr.w r0, [r5], #4 + 8003142: f842 0b04 str.w r0, [r2], #4 + 8003146: 428d cmp r5, r1 + 8003148: d1f9 bne.n 800313e + + // calc expected CRC + uint8_t crc[2] = {0, 0}; + 800314a: 2200 movs r2, #0 + crc16_chain(slot_len, copy, crc); + 800314c: 4619 mov r1, r3 + uint8_t crc[2] = {0, 0}; + 800314e: 80ba strh r2, [r7, #4] + crc16_chain(slot_len, copy, crc); + 8003150: 4640 mov r0, r8 + 8003152: 1d3a adds r2, r7, #4 + 8003154: f7ff fc30 bl 80029b8 + + // do the lock + ae_send(OP_Lock, 2 | (slot_num << 2), (crc[1]<<8) | crc[0]); + 8003158: 00a1 lsls r1, r4, #2 + 800315a: f041 0102 orr.w r1, r1, #2 + 800315e: 88ba ldrh r2, [r7, #4] + 8003160: f001 01fe and.w r1, r1, #254 ; 0xfe + 8003164: 2017 movs r0, #23 + 8003166: f7ff fdb0 bl 8002cca + + int rv = ae_read1(); + 800316a: f7ff fd25 bl 8002bb8 + RET_IF_BAD(rv); + 800316e: 46b5 mov sp, r6 + } + + return 0; +} + 8003170: 370c adds r7, #12 + 8003172: 46bd mov sp, r7 + 8003174: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 8003178: 0801046c .word 0x0801046c + +0800317c : + +// ae_gendig_slot() +// + int +ae_gendig_slot(int slot_num, const uint8_t slot_contents[32], uint8_t digest[32]) +{ + 800317c: b5f0 push {r4, r5, r6, r7, lr} + 800317e: b0ab sub sp, #172 ; 0xac + 8003180: 4605 mov r5, r0 + 8003182: 460f mov r7, r1 + // Construct a digest on the device (and here) that depends on the secret + // contents of a specific slot. + uint8_t num_in[20], tempkey[32]; + + rng_buffer(num_in, sizeof(num_in)); + 8003184: a803 add r0, sp, #12 + 8003186: 2114 movs r1, #20 +{ + 8003188: 4616 mov r6, r2 + rng_buffer(num_in, sizeof(num_in)); + 800318a: f7ff fba7 bl 80028dc + int rv = ae_pick_nonce(num_in, tempkey); + 800318e: a90f add r1, sp, #60 ; 0x3c + 8003190: a803 add r0, sp, #12 + 8003192: f7ff fdcf bl 8002d34 + RET_IF_BAD(rv); + 8003196: 4604 mov r4, r0 + 8003198: 2800 cmp r0, #0 + 800319a: d13d bne.n 8003218 + + //using Zone=2="Data" => "KeyID specifies a slot in the Data zone" + ae_send(OP_GenDig, 0x2, slot_num); + 800319c: b2aa uxth r2, r5 + 800319e: 2102 movs r1, #2 + 80031a0: 2015 movs r0, #21 + 80031a2: f7ff fd92 bl 8002cca + + rv = ae_read1(); + 80031a6: f7ff fd07 bl 8002bb8 + RET_IF_BAD(rv); + 80031aa: 4604 mov r4, r0 + 80031ac: bba0 cbnz r0, 8003218 + ae_send_idle(); + 80031ae: f7ff fc50 bl 8002a52 + // msg = hkey + b'\x15\x02' + ustruct.pack(" + + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 80031b8: 2302 movs r3, #2 + 80031ba: f88d 3005 strb.w r3, [sp, #5] + 80031be: 23ee movs r3, #238 ; 0xee + 80031c0: f88d 3008 strb.w r3, [sp, #8] + 80031c4: 2301 movs r3, #1 + 80031c6: 2215 movs r2, #21 + 80031c8: f88d 3009 strb.w r3, [sp, #9] + uint8_t zeros[25] = { 0 }; + 80031cc: 4621 mov r1, r4 + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 80031ce: 2323 movs r3, #35 ; 0x23 + uint8_t zeros[25] = { 0 }; + 80031d0: a809 add r0, sp, #36 ; 0x24 + uint8_t args[7] = { OP_GenDig, 2, slot_num, 0, 0xEE, 0x01, 0x23 }; + 80031d2: f88d 300a strb.w r3, [sp, #10] + 80031d6: f88d 2004 strb.w r2, [sp, #4] + 80031da: f88d 5006 strb.w r5, [sp, #6] + 80031de: f88d 4007 strb.w r4, [sp, #7] + uint8_t zeros[25] = { 0 }; + 80031e2: 9408 str r4, [sp, #32] + 80031e4: f00a fb9e bl 800d924 + + sha256_update(&ctx, slot_contents, 32); + 80031e8: 2220 movs r2, #32 + 80031ea: 4639 mov r1, r7 + 80031ec: a817 add r0, sp, #92 ; 0x5c + 80031ee: f002 fad3 bl 8005798 + sha256_update(&ctx, args, sizeof(args)); + 80031f2: 2207 movs r2, #7 + 80031f4: a901 add r1, sp, #4 + 80031f6: a817 add r0, sp, #92 ; 0x5c + 80031f8: f002 face bl 8005798 + sha256_update(&ctx, zeros, sizeof(zeros)); + 80031fc: 2219 movs r2, #25 + 80031fe: a908 add r1, sp, #32 + 8003200: a817 add r0, sp, #92 ; 0x5c + 8003202: f002 fac9 bl 8005798 + sha256_update(&ctx, tempkey, 32); + 8003206: a90f add r1, sp, #60 ; 0x3c + 8003208: a817 add r0, sp, #92 ; 0x5c + 800320a: 2220 movs r2, #32 + 800320c: f002 fac4 bl 8005798 + + sha256_final(&ctx, digest); + 8003210: 4631 mov r1, r6 + 8003212: a817 add r0, sp, #92 ; 0x5c + 8003214: f002 fb06 bl 8005824 + + return 0; +} + 8003218: 4620 mov r0, r4 + 800321a: b02b add sp, #172 ; 0xac + 800321c: bdf0 pop {r4, r5, r6, r7, pc} + ... + +08003220 : +{ + 8003220: b507 push {r0, r1, r2, lr} + 8003222: 4602 mov r2, r0 + int rv = ae_gendig_slot(KEYNUM_pairing, rom_secrets->pairing_secret, randout); + 8003224: 9001 str r0, [sp, #4] + 8003226: 490b ldr r1, [pc, #44] ; (8003254 ) + 8003228: 2001 movs r0, #1 + 800322a: f7ff ffa7 bl 800317c + if(rv || !ae_is_correct_tempkey(randout)) { + 800322e: 9a01 ldr r2, [sp, #4] + 8003230: b108 cbz r0, 8003236 + fatal_mitm(); + 8003232: f7fd fc0b bl 8000a4c + if(rv || !ae_is_correct_tempkey(randout)) { + 8003236: 4610 mov r0, r2 + 8003238: 9201 str r2, [sp, #4] + 800323a: f7ff fdaf bl 8002d9c + 800323e: 2800 cmp r0, #0 + 8003240: d0f7 beq.n 8003232 + sha256_single(randout, 32, randout); + 8003242: 9a01 ldr r2, [sp, #4] + 8003244: 2120 movs r1, #32 + 8003246: 4610 mov r0, r2 +} + 8003248: b003 add sp, #12 + 800324a: f85d eb04 ldr.w lr, [sp], #4 + sha256_single(randout, 32, randout); + 800324e: f002 bafd b.w 800584c + 8003252: bf00 nop + 8003254: 0801c000 .word 0x0801c000 + +08003258 : +{ + 8003258: b510 push {r4, lr} + 800325a: b088 sub sp, #32 + int rv = ae_gendig_slot(keynum, secret, digest); + 800325c: 466a mov r2, sp + 800325e: f7ff ff8d bl 800317c + RET_IF_BAD(rv); + 8003262: 4604 mov r4, r0 + 8003264: b930 cbnz r0, 8003274 + if(!ae_is_correct_tempkey(digest)) return -2; + 8003266: 4668 mov r0, sp + 8003268: f7ff fd98 bl 8002d9c + 800326c: 2800 cmp r0, #0 + 800326e: bf08 it eq + 8003270: f06f 0401 mvneq.w r4, #1 +} + 8003274: 4620 mov r0, r4 + 8003276: b008 add sp, #32 + 8003278: bd10 pop {r4, pc} + +0800327a : +// the digest should be, and ask the chip to do the same. Verify we match +// using MAC command (done elsewhere). +// + int +ae_gendig_counter(int counter_num, const uint32_t expected_value, uint8_t digest[32]) +{ + 800327a: b5f0 push {r4, r5, r6, r7, lr} + 800327c: b0ad sub sp, #180 ; 0xb4 + 800327e: 4605 mov r5, r0 + 8003280: 9101 str r1, [sp, #4] + uint8_t num_in[20], tempkey[32]; + + rng_buffer(num_in, sizeof(num_in)); + 8003282: a804 add r0, sp, #16 + 8003284: 2114 movs r1, #20 +{ + 8003286: 4616 mov r6, r2 + rng_buffer(num_in, sizeof(num_in)); + 8003288: f7ff fb28 bl 80028dc + int rv = ae_pick_nonce(num_in, tempkey); + 800328c: a909 add r1, sp, #36 ; 0x24 + 800328e: a804 add r0, sp, #16 + 8003290: f7ff fd50 bl 8002d34 + RET_IF_BAD(rv); + 8003294: 4604 mov r4, r0 + 8003296: 2800 cmp r0, #0 + 8003298: d148 bne.n 800332c + + //using Zone=4="Counter" => "KeyID specifies the monotonic counter ID" + ae_send(OP_GenDig, 0x4, counter_num); + 800329a: b2aa uxth r2, r5 + 800329c: 2104 movs r1, #4 + 800329e: 2015 movs r0, #21 + 80032a0: f7ff fd13 bl 8002cca + + rv = ae_read1(); + 80032a4: f7ff fc88 bl 8002bb8 + RET_IF_BAD(rv); + 80032a8: 4604 mov r4, r0 + 80032aa: 2800 cmp r0, #0 + 80032ac: d13e bne.n 800332c + ae_send_idle(); + 80032ae: f7ff fbd0 bl 8002a52 + // msg = hkey + b'\x15\x02' + ustruct.pack(" + + uint8_t zeros[32] = { 0 }; + 80032b8: 221c movs r2, #28 + 80032ba: 4621 mov r1, r4 + 80032bc: a812 add r0, sp, #72 ; 0x48 + 80032be: 9411 str r4, [sp, #68] ; 0x44 + 80032c0: f00a fb30 bl 800d924 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 80032c4: 2315 movs r3, #21 + 80032c6: f88d 3008 strb.w r3, [sp, #8] + 80032ca: 23ee movs r3, #238 ; 0xee + 80032cc: f88d 300c strb.w r3, [sp, #12] + 80032d0: 2301 movs r3, #1 + 80032d2: 2704 movs r7, #4 + 80032d4: f88d 300d strb.w r3, [sp, #13] + + sha256_update(&ctx, zeros, 32); + 80032d8: 2220 movs r2, #32 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 80032da: 2323 movs r3, #35 ; 0x23 + sha256_update(&ctx, zeros, 32); + 80032dc: a911 add r1, sp, #68 ; 0x44 + 80032de: a819 add r0, sp, #100 ; 0x64 + uint8_t args[8] = { OP_GenDig, 0x4, counter_num, 0, 0xEE, 0x01, 0x23, 0x0 }; + 80032e0: f88d 300e strb.w r3, [sp, #14] + 80032e4: f88d 7009 strb.w r7, [sp, #9] + 80032e8: f88d 500a strb.w r5, [sp, #10] + 80032ec: f88d 400b strb.w r4, [sp, #11] + 80032f0: f88d 400f strb.w r4, [sp, #15] + sha256_update(&ctx, zeros, 32); + 80032f4: f002 fa50 bl 8005798 + sha256_update(&ctx, args, sizeof(args)); + 80032f8: 2208 movs r2, #8 + 80032fa: eb0d 0102 add.w r1, sp, r2 + 80032fe: a819 add r0, sp, #100 ; 0x64 + 8003300: f002 fa4a bl 8005798 + sha256_update(&ctx, (const uint8_t *)&expected_value, 4); + 8003304: 463a mov r2, r7 + 8003306: eb0d 0107 add.w r1, sp, r7 + 800330a: a819 add r0, sp, #100 ; 0x64 + 800330c: f002 fa44 bl 8005798 + sha256_update(&ctx, zeros, 20); + 8003310: 2214 movs r2, #20 + 8003312: a911 add r1, sp, #68 ; 0x44 + 8003314: a819 add r0, sp, #100 ; 0x64 + 8003316: f002 fa3f bl 8005798 + sha256_update(&ctx, tempkey, 32); + 800331a: a909 add r1, sp, #36 ; 0x24 + 800331c: a819 add r0, sp, #100 ; 0x64 + 800331e: 2220 movs r2, #32 + 8003320: f002 fa3a bl 8005798 + + sha256_final(&ctx, digest); + 8003324: 4631 mov r1, r6 + 8003326: a819 add r0, sp, #100 ; 0x64 + 8003328: f002 fa7c bl 8005824 + + return 0; +} + 800332c: 4620 mov r0, r4 + 800332e: b02d add sp, #180 ; 0xb4 + 8003330: bdf0 pop {r4, r5, r6, r7, pc} + +08003332 : +{ + 8003332: b570 push {r4, r5, r6, lr} + ae_send(OP_Counter, 0x0, counter_number); + 8003334: 460a mov r2, r1 +{ + 8003336: b088 sub sp, #32 + 8003338: 4606 mov r6, r0 + 800333a: 460d mov r5, r1 + ae_send(OP_Counter, 0x0, counter_number); + 800333c: 2024 movs r0, #36 ; 0x24 + 800333e: 2100 movs r1, #0 + 8003340: f7ff fcc3 bl 8002cca + int rv = ae_read_n(4, (uint8_t *)result); + 8003344: 4631 mov r1, r6 + 8003346: 2004 movs r0, #4 + 8003348: f7ff fc52 bl 8002bf0 + RET_IF_BAD(rv); + 800334c: 4604 mov r4, r0 + 800334e: b960 cbnz r0, 800336a + rv = ae_gendig_counter(counter_number, *result, digest); + 8003350: 6831 ldr r1, [r6, #0] + 8003352: 466a mov r2, sp + 8003354: 4628 mov r0, r5 + 8003356: f7ff ff90 bl 800327a + RET_IF_BAD(rv); + 800335a: 4604 mov r4, r0 + 800335c: b928 cbnz r0, 800336a + if(!ae_is_correct_tempkey(digest)) { + 800335e: 4668 mov r0, sp + 8003360: f7ff fd1c bl 8002d9c + 8003364: b908 cbnz r0, 800336a + fatal_mitm(); + 8003366: f7fd fb71 bl 8000a4c +} + 800336a: 4620 mov r0, r4 + 800336c: b008 add sp, #32 + 800336e: bd70 pop {r4, r5, r6, pc} + +08003370 : +{ + 8003370: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8003374: 4606 mov r6, r0 + 8003376: b089 sub sp, #36 ; 0x24 + 8003378: 460d mov r5, r1 + 800337a: 4617 mov r7, r2 + for(int i=0; i + int rv = ae_gendig_counter(counter_number, *result, digest); + 8003388: 6831 ldr r1, [r6, #0] + 800338a: 466a mov r2, sp + 800338c: 4628 mov r0, r5 + 800338e: f7ff ff74 bl 800327a + RET_IF_BAD(rv); + 8003392: 4604 mov r4, r0 + 8003394: b998 cbnz r0, 80033be + if(!ae_is_correct_tempkey(digest)) { + 8003396: 4668 mov r0, sp + 8003398: f7ff fd00 bl 8002d9c + 800339c: b978 cbnz r0, 80033be + fatal_mitm(); + 800339e: f7fd fb55 bl 8000a4c + ae_send(OP_Counter, 0x1, counter_number); + 80033a2: 464a mov r2, r9 + 80033a4: 2101 movs r1, #1 + 80033a6: 2024 movs r0, #36 ; 0x24 + 80033a8: f7ff fc8f bl 8002cca + int rv = ae_read_n(4, (uint8_t *)result); + 80033ac: 4631 mov r1, r6 + 80033ae: 2004 movs r0, #4 + 80033b0: f7ff fc1e bl 8002bf0 + RET_IF_BAD(rv); + 80033b4: 4604 mov r4, r0 + 80033b6: b910 cbnz r0, 80033be + for(int i=0; i +} + 80033be: 4620 mov r0, r4 + 80033c0: b009 add sp, #36 ; 0x24 + 80033c2: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + +080033c6 : +// ae_encrypted_read32() +// + int +ae_encrypted_read32(int data_slot, int blk, + int read_kn, const uint8_t read_key[32], uint8_t data[32]) +{ + 80033c6: b5f0 push {r4, r5, r6, r7, lr} + 80033c8: b08b sub sp, #44 ; 0x2c + 80033ca: 4617 mov r7, r2 + 80033cc: 460e mov r6, r1 + 80033ce: 9d10 ldr r5, [sp, #64] ; 0x40 + 80033d0: 9301 str r3, [sp, #4] + 80033d2: 4604 mov r4, r0 + uint8_t digest[32]; + + ae_pair_unlock(); + 80033d4: f7ff fdb2 bl 8002f3c + + int rv = ae_gendig_slot(read_kn, read_key, digest); + 80033d8: 9901 ldr r1, [sp, #4] + 80033da: aa02 add r2, sp, #8 + 80033dc: 4638 mov r0, r7 + 80033de: f7ff fecd bl 800317c + RET_IF_BAD(rv); + 80033e2: b9c0 cbnz r0, 8003416 + + // read nth 32-byte "block" + ae_send(OP_Read, 0x82, (blk << 8) | (data_slot<<3)); + 80033e4: 00e4 lsls r4, r4, #3 + 80033e6: ea44 2206 orr.w r2, r4, r6, lsl #8 + 80033ea: 2182 movs r1, #130 ; 0x82 + 80033ec: 2002 movs r0, #2 + 80033ee: b292 uxth r2, r2 + 80033f0: f7ff fc6b bl 8002cca + + rv = ae_read_n(32, data); + 80033f4: 4629 mov r1, r5 + 80033f6: 2020 movs r0, #32 + 80033f8: f7ff fbfa bl 8002bf0 + RET_IF_BAD(rv); + 80033fc: b958 cbnz r0, 8003416 + 80033fe: 1e6a subs r2, r5, #1 + 8003400: ab02 add r3, sp, #8 + 8003402: 351f adds r5, #31 + *(acc) ^= *(more); + 8003404: f812 1f01 ldrb.w r1, [r2, #1]! + 8003408: f813 4b01 ldrb.w r4, [r3], #1 + for(; len; len--, more++, acc++) { + 800340c: 4295 cmp r5, r2 + *(acc) ^= *(more); + 800340e: ea81 0104 eor.w r1, r1, r4 + 8003412: 7011 strb r1, [r2, #0] + for(; len; len--, more++, acc++) { + 8003414: d1f6 bne.n 8003404 + + xor_mixin(data, digest, 32); + + return 0; +} + 8003416: b00b add sp, #44 ; 0x2c + 8003418: bdf0 pop {r4, r5, r6, r7, pc} + ... + +0800341c : + +// ae_encrypted_read() +// + int +ae_encrypted_read(int data_slot, int read_kn, const uint8_t read_key[32], uint8_t *data, int len) +{ + 800341c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8003420: b08b sub sp, #44 ; 0x2c + 8003422: 4607 mov r7, r0 + 8003424: 9d12 ldr r5, [sp, #72] ; 0x48 + // not clear if chip supports 4-byte encrypted reads + ASSERT((len == 32) || (len == 72)); + 8003426: 2d20 cmp r5, #32 +{ + 8003428: 4688 mov r8, r1 + 800342a: 4691 mov r9, r2 + 800342c: 461e mov r6, r3 + ASSERT((len == 32) || (len == 72)); + 800342e: d004 beq.n 800343a + 8003430: 2d48 cmp r5, #72 ; 0x48 + 8003432: d002 beq.n 800343a + 8003434: 4815 ldr r0, [pc, #84] ; (800348c ) + 8003436: f7fd faff bl 8000a38 + + int rv = ae_encrypted_read32(data_slot, 0, read_kn, read_key, data); + 800343a: 9600 str r6, [sp, #0] + 800343c: 464b mov r3, r9 + 800343e: 4642 mov r2, r8 + 8003440: 2100 movs r1, #0 + 8003442: 4638 mov r0, r7 + 8003444: f7ff ffbf bl 80033c6 + RET_IF_BAD(rv); + 8003448: 4604 mov r4, r0 + 800344a: b9d0 cbnz r0, 8003482 + + if(len == 32) return 0; + 800344c: 2d20 cmp r5, #32 + 800344e: d018 beq.n 8003482 + + rv = ae_encrypted_read32(data_slot, 1, read_kn, read_key, data+32); + 8003450: f106 0320 add.w r3, r6, #32 + 8003454: 9300 str r3, [sp, #0] + 8003456: 4642 mov r2, r8 + 8003458: 464b mov r3, r9 + 800345a: 2101 movs r1, #1 + 800345c: 4638 mov r0, r7 + 800345e: f7ff ffb2 bl 80033c6 + RET_IF_BAD(rv); + 8003462: 4604 mov r4, r0 + 8003464: b968 cbnz r0, 8003482 + + uint8_t tmp[32]; + rv = ae_encrypted_read32(data_slot, 2, read_kn, read_key, tmp); + 8003466: ad02 add r5, sp, #8 + 8003468: 9500 str r5, [sp, #0] + 800346a: 464b mov r3, r9 + 800346c: 4642 mov r2, r8 + 800346e: 2102 movs r1, #2 + 8003470: 4638 mov r0, r7 + 8003472: f7ff ffa8 bl 80033c6 + RET_IF_BAD(rv); + 8003476: 4604 mov r4, r0 + 8003478: b918 cbnz r0, 8003482 + + memcpy(data+64, tmp, 72-64); + 800347a: 462a mov r2, r5 + 800347c: ca03 ldmia r2!, {r0, r1} + 800347e: 6430 str r0, [r6, #64] ; 0x40 + 8003480: 6471 str r1, [r6, #68] ; 0x44 + + return 0; +} + 8003482: 4620 mov r0, r4 + 8003484: b00b add sp, #44 ; 0x2c + 8003486: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + 800348a: bf00 nop + 800348c: 0801046c .word 0x0801046c + +08003490 : +// ae_encrypted_write() +// + int +ae_encrypted_write32(int data_slot, int blk, int write_kn, + const uint8_t write_key[32], const uint8_t data[32]) +{ + 8003490: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8003494: b0b8 sub sp, #224 ; 0xe0 + 8003496: 4617 mov r7, r2 + 8003498: 460d mov r5, r1 + 800349a: 9e3e ldr r6, [sp, #248] ; 0xf8 + 800349c: 9303 str r3, [sp, #12] + 800349e: 4604 mov r4, r0 + uint8_t digest[32]; + + ae_pair_unlock(); + 80034a0: f7ff fd4c bl 8002f3c + + // generate a hash over shared secret and rng + int rv = ae_gendig_slot(write_kn, write_key, digest); + 80034a4: 9903 ldr r1, [sp, #12] + 80034a6: aa0d add r2, sp, #52 ; 0x34 + 80034a8: 4638 mov r0, r7 + 80034aa: f7ff fe67 bl 800317c + RET_IF_BAD(rv); + 80034ae: 2800 cmp r0, #0 + 80034b0: d151 bne.n 8003556 + 80034b2: 1e72 subs r2, r6, #1 + 80034b4: af0d add r7, sp, #52 ; 0x34 + 80034b6: a915 add r1, sp, #84 ; 0x54 + 80034b8: f106 0c1f add.w ip, r6, #31 + + // encrypt the data to be written, and append an authenticating MAC + uint8_t body[32 + 32]; + + for(int i=0; i<32; i++) { + body[i] = data[i] ^ digest[i]; + 80034bc: f812 ef01 ldrb.w lr, [r2, #1]! + 80034c0: f817 0b01 ldrb.w r0, [r7], #1 + for(int i=0; i<32; i++) { + 80034c4: 4562 cmp r2, ip + body[i] = data[i] ^ digest[i]; + 80034c6: ea80 000e eor.w r0, r0, lr + 80034ca: f801 0b01 strb.w r0, [r1], #1 + for(int i=0; i<32; i++) { + 80034ce: d1f5 bne.n 80034bc + // + (b'\0'*25) + // + new_value) + // assert len(msg) == 32+1+1+2+1+2+25+32 + // + SHA256_CTX ctx; + sha256_init(&ctx); + 80034d0: a825 add r0, sp, #148 ; 0x94 + 80034d2: f002 f953 bl 800577c + + uint8_t p1 = 0x80|2; // 32 bytes into a data slot + uint8_t p2_lsb = (data_slot << 3); + uint8_t p2_msb = blk; + + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 80034d6: 22ee movs r2, #238 ; 0xee + 80034d8: f88d 2014 strb.w r2, [sp, #20] + 80034dc: 2201 movs r2, #1 + 80034de: f88d 2015 strb.w r2, [sp, #21] + uint8_t p2_lsb = (data_slot << 3); + 80034e2: 00e4 lsls r4, r4, #3 + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 80034e4: 2223 movs r2, #35 ; 0x23 + uint8_t zeros[25] = { 0 }; + 80034e6: 2100 movs r1, #0 + uint8_t p2_lsb = (data_slot << 3); + 80034e8: b2e4 uxtb r4, r4 + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 80034ea: 2712 movs r7, #18 + 80034ec: f04f 0882 mov.w r8, #130 ; 0x82 + 80034f0: f88d 2016 strb.w r2, [sp, #22] + uint8_t zeros[25] = { 0 }; + 80034f4: a807 add r0, sp, #28 + 80034f6: 2215 movs r2, #21 + 80034f8: 9106 str r1, [sp, #24] + uint8_t args[7] = { OP_Write, p1, p2_lsb, p2_msb, 0xEE, 0x01, 0x23 }; + 80034fa: f88d 7010 strb.w r7, [sp, #16] + 80034fe: f88d 8011 strb.w r8, [sp, #17] + 8003502: f88d 4012 strb.w r4, [sp, #18] + uint8_t p2_msb = blk; + 8003506: f88d 5013 strb.w r5, [sp, #19] + uint8_t zeros[25] = { 0 }; + 800350a: f00a fa0b bl 800d924 + + sha256_update(&ctx, digest, 32); + 800350e: 2220 movs r2, #32 + 8003510: a90d add r1, sp, #52 ; 0x34 + 8003512: a825 add r0, sp, #148 ; 0x94 + 8003514: f002 f940 bl 8005798 + sha256_update(&ctx, args, sizeof(args)); + 8003518: 2207 movs r2, #7 + 800351a: a904 add r1, sp, #16 + 800351c: a825 add r0, sp, #148 ; 0x94 + 800351e: f002 f93b bl 8005798 + sha256_update(&ctx, zeros, sizeof(zeros)); + 8003522: 2219 movs r2, #25 + 8003524: a906 add r1, sp, #24 + 8003526: a825 add r0, sp, #148 ; 0x94 + 8003528: f002 f936 bl 8005798 + sha256_update(&ctx, data, 32); + 800352c: 2220 movs r2, #32 + 800352e: 4631 mov r1, r6 + 8003530: a825 add r0, sp, #148 ; 0x94 + 8003532: f002 f931 bl 8005798 + + sha256_final(&ctx, &body[32]); + 8003536: a91d add r1, sp, #116 ; 0x74 + 8003538: a825 add r0, sp, #148 ; 0x94 + 800353a: f002 f973 bl 8005824 + + ae_send_n(OP_Write, p1, (p2_msb << 8) | p2_lsb, body, sizeof(body)); + 800353e: 2140 movs r1, #64 ; 0x40 + 8003540: ea44 2205 orr.w r2, r4, r5, lsl #8 + 8003544: b292 uxth r2, r2 + 8003546: 9100 str r1, [sp, #0] + 8003548: ab15 add r3, sp, #84 ; 0x54 + 800354a: 4641 mov r1, r8 + 800354c: 4638 mov r0, r7 + 800354e: f7ff fb89 bl 8002c64 + + return ae_read1(); + 8003552: f7ff fb31 bl 8002bb8 +} + 8003556: b038 add sp, #224 ; 0xe0 + 8003558: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +0800355c : +// ae_encrypted_write() +// + int +ae_encrypted_write(int data_slot, int write_kn, const uint8_t write_key[32], + const uint8_t *data, int len) +{ + 800355c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8003560: b08a sub sp, #40 ; 0x28 + ASSERT(data_slot >= 0); + ASSERT(data_slot <= 15); + 8003562: 280f cmp r0, #15 +{ + 8003564: 9d12 ldr r5, [sp, #72] ; 0x48 + 8003566: 4606 mov r6, r0 + 8003568: 460f mov r7, r1 + 800356a: 4690 mov r8, r2 + 800356c: 4699 mov r9, r3 + ASSERT(data_slot <= 15); + 800356e: d902 bls.n 8003576 + ASSERT(data_slot >= 0); + 8003570: 4814 ldr r0, [pc, #80] ; (80035c4 ) + 8003572: f7fd fa61 bl 8000a38 + + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 8003576: 2400 movs r4, #0 + int here = MIN(32, len); + + // be nice and don't read past end of input buffer + uint8_t tmp[32] = { 0 }; + 8003578: 46a2 mov sl, r4 + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 800357a: 2d00 cmp r5, #0 + 800357c: dd1d ble.n 80035ba + uint8_t tmp[32] = { 0 }; + 800357e: 221c movs r2, #28 + 8003580: 2100 movs r1, #0 + 8003582: a803 add r0, sp, #12 + 8003584: f8cd a008 str.w sl, [sp, #8] + 8003588: f00a f9cc bl 800d924 + memcpy(tmp, data+(32*blk), here); + 800358c: ab02 add r3, sp, #8 + 800358e: 2d20 cmp r5, #32 + 8003590: 462a mov r2, r5 + 8003592: eb09 1144 add.w r1, r9, r4, lsl #5 + 8003596: bfa8 it ge + 8003598: 2220 movge r2, #32 + 800359a: 4618 mov r0, r3 + 800359c: f00a f9b4 bl 800d908 + + int rv = ae_encrypted_write32(data_slot, blk, write_kn, write_key, tmp); + 80035a0: 4643 mov r3, r8 + 80035a2: 9000 str r0, [sp, #0] + 80035a4: 463a mov r2, r7 + 80035a6: 4621 mov r1, r4 + 80035a8: 4630 mov r0, r6 + 80035aa: f7ff ff71 bl 8003490 + RET_IF_BAD(rv); + 80035ae: b928 cbnz r0, 80035bc + for(int blk=0; blk<3 && len>0; blk++, len-=32) { + 80035b0: 3401 adds r4, #1 + 80035b2: 2c03 cmp r4, #3 + 80035b4: f1a5 0520 sub.w r5, r5, #32 + 80035b8: d1df bne.n 800357a + } + + return 0; + 80035ba: 2000 movs r0, #0 +} + 80035bc: b00a add sp, #40 ; 0x28 + 80035be: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 80035c2: bf00 nop + 80035c4: 0801046c .word 0x0801046c + +080035c8 : + +// ae_read_data_slot() +// + int +ae_read_data_slot(int slot_num, uint8_t *data, int len) +{ + 80035c8: b570 push {r4, r5, r6, lr} + ASSERT((len == 4) || (len == 32) || (len == 72)); + 80035ca: 2a04 cmp r2, #4 +{ + 80035cc: b088 sub sp, #32 + 80035ce: 460d mov r5, r1 + 80035d0: 4616 mov r6, r2 + ASSERT((len == 4) || (len == 32) || (len == 72)); + 80035d2: d006 beq.n 80035e2 + 80035d4: 2a20 cmp r2, #32 + 80035d6: d038 beq.n 800364a + 80035d8: 2a48 cmp r2, #72 ; 0x48 + 80035da: d036 beq.n 800364a + 80035dc: 481c ldr r0, [pc, #112] ; (8003650 ) + 80035de: f7fd fa2b bl 8000a38 + + // zone => data + // only reading first block of 32 bytes. ignore the rest + ae_send(OP_Read, (len == 4 ? 0x00 : 0x80) | 2, (slot_num<<3)); + 80035e2: 2102 movs r1, #2 + 80035e4: 00c4 lsls r4, r0, #3 + 80035e6: b2a2 uxth r2, r4 + 80035e8: 2002 movs r0, #2 + 80035ea: f7ff fb6e bl 8002cca + + int rv = ae_read_n((len == 4) ? 4 : 32, data); + 80035ee: 2e04 cmp r6, #4 + 80035f0: 4629 mov r1, r5 + 80035f2: bf0c ite eq + 80035f4: 2004 moveq r0, #4 + 80035f6: 2020 movne r0, #32 + 80035f8: f7ff fafa bl 8002bf0 + RET_IF_BAD(rv); + 80035fc: 4603 mov r3, r0 + 80035fe: bb08 cbnz r0, 8003644 + + if(len == 72) { + 8003600: 2e48 cmp r6, #72 ; 0x48 + 8003602: d11f bne.n 8003644 + // read second block + ae_send(OP_Read, 0x82, (1<<8) | (slot_num<<3)); + 8003604: b224 sxth r4, r4 + 8003606: f444 7280 orr.w r2, r4, #256 ; 0x100 + 800360a: b292 uxth r2, r2 + 800360c: 2182 movs r1, #130 ; 0x82 + 800360e: 2002 movs r0, #2 + 8003610: f7ff fb5b bl 8002cca + + int rv = ae_read_n(32, data+32); + 8003614: f105 0120 add.w r1, r5, #32 + 8003618: 2020 movs r0, #32 + 800361a: f7ff fae9 bl 8002bf0 + RET_IF_BAD(rv); + 800361e: 4603 mov r3, r0 + 8003620: b980 cbnz r0, 8003644 + + // read third block, but only using part of it + uint8_t tmp[32]; + ae_send(OP_Read, 0x82, (2<<8) | (slot_num<<3)); + 8003622: f444 7400 orr.w r4, r4, #512 ; 0x200 + 8003626: b2a2 uxth r2, r4 + 8003628: 2182 movs r1, #130 ; 0x82 + 800362a: 2002 movs r0, #2 + 800362c: f7ff fb4d bl 8002cca + + rv = ae_read_n(32, tmp); + 8003630: 4669 mov r1, sp + 8003632: 2020 movs r0, #32 + 8003634: f7ff fadc bl 8002bf0 + RET_IF_BAD(rv); + 8003638: 4603 mov r3, r0 + 800363a: b918 cbnz r0, 8003644 + + memcpy(data+64, tmp, 72-64); + 800363c: 466a mov r2, sp + 800363e: ca03 ldmia r2!, {r0, r1} + 8003640: 6428 str r0, [r5, #64] ; 0x40 + 8003642: 6469 str r1, [r5, #68] ; 0x44 + } + + return 0; +} + 8003644: 4618 mov r0, r3 + 8003646: b008 add sp, #32 + 8003648: bd70 pop {r4, r5, r6, pc} + ae_send(OP_Read, (len == 4 ? 0x00 : 0x80) | 2, (slot_num<<3)); + 800364a: 2182 movs r1, #130 ; 0x82 + 800364c: e7ca b.n 80035e4 + 800364e: bf00 nop + 8003650: 0801046c .word 0x0801046c + +08003654 : + +// ae_set_gpio() +// + int +ae_set_gpio(int state) +{ + 8003654: b513 push {r0, r1, r4, lr} + // 1=turn on green, 0=red light (if not yet configured to be secure) + ae_send(OP_Info, 3, 2 | (!!state)); + 8003656: 1e04 subs r4, r0, #0 + 8003658: bf14 ite ne + 800365a: 2203 movne r2, #3 + 800365c: 2202 moveq r2, #2 + 800365e: 2103 movs r1, #3 + 8003660: 2030 movs r0, #48 ; 0x30 + 8003662: f7ff fb32 bl 8002cca + + // "Always return the current state in the first byte followed by three bytes of 0x00" + // - simple 1/0, in LSB. + uint8_t resp[4]; + + int rv = ae_read_n(4, resp); + 8003666: a901 add r1, sp, #4 + 8003668: 2004 movs r0, #4 + 800366a: f7ff fac1 bl 8002bf0 + RET_IF_BAD(rv); + 800366e: b928 cbnz r0, 800367c + + return (resp[0] != state) ? -1 : 0; + 8003670: f89d 0004 ldrb.w r0, [sp, #4] + 8003674: 1b00 subs r0, r0, r4 + 8003676: bf18 it ne + 8003678: f04f 30ff movne.w r0, #4294967295 ; 0xffffffff +} + 800367c: b002 add sp, #8 + 800367e: bd10 pop {r4, pc} + +08003680 : +// +// Set the GPIO using secure hash generated somehow already. +// + int +ae_set_gpio_secure(uint8_t digest[32]) +{ + 8003680: b538 push {r3, r4, r5, lr} + 8003682: 4605 mov r5, r0 + ae_pair_unlock(); + 8003684: f7ff fc5a bl 8002f3c + ae_checkmac(KEYNUM_firmware, digest); + 8003688: 4629 mov r1, r5 + 800368a: 200e movs r0, #14 + 800368c: f7ff fbd4 bl 8002e38 + + int rv = ae_set_gpio(1); + 8003690: 2001 movs r0, #1 + 8003692: f7ff ffdf bl 8003654 + + if(rv == 0) { + 8003696: 4604 mov r4, r0 + 8003698: b940 cbnz r0, 80036ac + // trust that readback, and so do a verify that the chip has + // the digest we think it does. If MitM wanted to turn off the output, + // they can do that anytime regardless. We just don't want them to be + // able to fake it being set, and therefore bypass the + // "unsigned firmware" delay and warning. + ae_pair_unlock(); + 800369a: f7ff fc4f bl 8002f3c + + if(ae_checkmac_hard(KEYNUM_firmware, digest) != 0) { + 800369e: 4629 mov r1, r5 + 80036a0: 200e movs r0, #14 + 80036a2: f7ff fdd9 bl 8003258 + 80036a6: b108 cbz r0, 80036ac + fatal_mitm(); + 80036a8: f7fd f9d0 bl 8000a4c + } + } + + return rv; +} + 80036ac: 4620 mov r0, r4 + 80036ae: bd38 pop {r3, r4, r5, pc} + +080036b0 : +// +// IMPORTANT: do not trust this result, could be MitM'ed. +// + uint8_t +ae_get_gpio(void) +{ + 80036b0: b507 push {r0, r1, r2, lr} + // not doing error checking here + ae_send(OP_Info, 0x3, 0); + 80036b2: 2200 movs r2, #0 + 80036b4: 2103 movs r1, #3 + 80036b6: 2030 movs r0, #48 ; 0x30 + 80036b8: f7ff fb07 bl 8002cca + + // note: always returns 4 bytes, but most are garbage and unused. + uint8_t tmp[4]; + ae_read_n(4, tmp); + 80036bc: a901 add r1, sp, #4 + 80036be: 2004 movs r0, #4 + 80036c0: f7ff fa96 bl 8002bf0 + + return tmp[0]; +} + 80036c4: f89d 0004 ldrb.w r0, [sp, #4] + 80036c8: b003 add sp, #12 + 80036ca: f85d fb04 ldr.w pc, [sp], #4 + +080036ce : +// +// Read a 4-byte area from config area, or -1 if fail. +// + int +ae_read_config_word(int offset, uint8_t *dest) +{ + 80036ce: b510 push {r4, lr} + offset &= 0x7f; + + // read 32 bits (aligned) + ae_send(OP_Read, 0x00, offset/4); + 80036d0: f3c0 0284 ubfx r2, r0, #2, #5 +{ + 80036d4: 460c mov r4, r1 + ae_send(OP_Read, 0x00, offset/4); + 80036d6: 2002 movs r0, #2 + 80036d8: 2100 movs r1, #0 + 80036da: f7ff faf6 bl 8002cca + + int rv = ae_read_n(4, dest); + 80036de: 4621 mov r1, r4 + 80036e0: 2004 movs r0, #4 + 80036e2: f7ff fa85 bl 8002bf0 + if(rv) return -1; + 80036e6: 3800 subs r0, #0 + 80036e8: bf18 it ne + 80036ea: 2001 movne r0, #1 + + return 0; +} + 80036ec: 4240 negs r0, r0 + 80036ee: bd10 pop {r4, pc} + +080036f0 : +{ + 80036f0: b513 push {r0, r1, r4, lr} + 80036f2: 4604 mov r4, r0 + ae_read_config_word(offset, tmp); + 80036f4: a901 add r1, sp, #4 + 80036f6: f7ff ffea bl 80036ce + return tmp[offset % 4]; + 80036fa: 4263 negs r3, r4 + 80036fc: f003 0303 and.w r3, r3, #3 + 8003700: f004 0403 and.w r4, r4, #3 + 8003704: bf58 it pl + 8003706: 425c negpl r4, r3 + 8003708: f104 0308 add.w r3, r4, #8 + 800370c: eb0d 0403 add.w r4, sp, r3 +} + 8003710: f814 0c04 ldrb.w r0, [r4, #-4] + 8003714: b002 add sp, #8 + 8003716: bd10 pop {r4, pc} + +08003718 : + +// ae_destroy_key() +// + int +ae_destroy_key(int keynum) +{ + 8003718: b510 push {r4, lr} + 800371a: b090 sub sp, #64 ; 0x40 + uint8_t numin[20]; + + // Load tempkey with a known (random) nonce value + rng_buffer(numin, sizeof(numin)); + 800371c: 2114 movs r1, #20 +{ + 800371e: 4604 mov r4, r0 + rng_buffer(numin, sizeof(numin)); + 8003720: a803 add r0, sp, #12 + 8003722: f7ff f8db bl 80028dc + ae_send_n(OP_Nonce, 0, 0, numin, 20); + 8003726: 2314 movs r3, #20 + 8003728: 2200 movs r2, #0 + 800372a: 9300 str r3, [sp, #0] + 800372c: 4611 mov r1, r2 + 800372e: 2016 movs r0, #22 + 8003730: ab03 add r3, sp, #12 + 8003732: f7ff fa97 bl 8002c64 + + // Nonce command returns the RNG result, not contents of TempKey, + // but since we are destroying, no need to calculate what it is. + uint8_t randout[32]; + int rv = ae_read_n(32, randout); + 8003736: a908 add r1, sp, #32 + 8003738: 2020 movs r0, #32 + 800373a: f7ff fa59 bl 8002bf0 + RET_IF_BAD(rv); + 800373e: b930 cbnz r0, 800374e + + // do a "DeriveKey" operation, based on that! + ae_send(OP_DeriveKey, 0x00, keynum); + 8003740: 4601 mov r1, r0 + 8003742: b2a2 uxth r2, r4 + 8003744: 201c movs r0, #28 + 8003746: f7ff fac0 bl 8002cca + + return ae_read1(); + 800374a: f7ff fa35 bl 8002bb8 +} + 800374e: b010 add sp, #64 ; 0x40 + 8003750: bd10 pop {r4, pc} + +08003752 : + +// ae_config_read() +// + int +ae_config_read(uint8_t config[128]) +{ + 8003752: b538 push {r3, r4, r5, lr} + 8003754: 4605 mov r5, r0 + for(int blk=0; blk<4; blk++) { + 8003756: 2400 movs r4, #0 + // read 32 bytes (aligned) from config "zone" + ae_send(OP_Read, 0x80, blk<<3); + 8003758: 00e2 lsls r2, r4, #3 + 800375a: 2180 movs r1, #128 ; 0x80 + 800375c: 2002 movs r0, #2 + 800375e: b292 uxth r2, r2 + 8003760: f7ff fab3 bl 8002cca + + int rv = ae_read_n(32, &config[32*blk]); + 8003764: eb05 1144 add.w r1, r5, r4, lsl #5 + 8003768: 2020 movs r0, #32 + 800376a: f7ff fa41 bl 8002bf0 + if(rv) return EIO; + 800376e: b918 cbnz r0, 8003778 + for(int blk=0; blk<4; blk++) { + 8003770: 3401 adds r4, #1 + 8003772: 2c04 cmp r4, #4 + 8003774: d1f0 bne.n 8003758 + } + + return 0; +} + 8003776: bd38 pop {r3, r4, r5, pc} + if(rv) return EIO; + 8003778: 2005 movs r0, #5 + 800377a: e7fc b.n 8003776 + +0800377c : +// us to write the (existing) pairing secret into, they would see the pairing +// secret in cleartext. They could then restore original chip and access freely. +// + int +ae_setup_config(void) +{ + 800377c: b5f0 push {r4, r5, r6, r7, lr} + 800377e: 2405 movs r4, #5 + 8003780: f5ad 7d41 sub.w sp, sp, #772 ; 0x304 + // Need to wake up AE, since many things happen before this point. + for(int retry=0; retry<5; retry++) { + if(!ae_probe()) break; + 8003784: f7ff fc6c bl 8003060 + 8003788: b108 cbz r0, 800378e + for(int retry=0; retry<5; retry++) { + 800378a: 3c01 subs r4, #1 + 800378c: d1fa bne.n 8003784 + // Is data zone is locked? + // Allow rest of function to happen if it's not. + +#if 1 + // 0x55 = unlocked; 0x00 = locked + bool data_locked = (ae_read_config_byte(86) != 0x55); + 800378e: 2056 movs r0, #86 ; 0x56 + 8003790: f7ff ffae bl 80036f0 + if(data_locked) return 0; // basically success + 8003794: 2855 cmp r0, #85 ; 0x55 + 8003796: f040 80df bne.w 8003958 + + // To lock, we need a CRC over whole thing, but we + // only set a few values... plus the serial number is + // in there, so start with some readout. + uint8_t config[128]; + int rv = ae_config_read(config); + 800379a: a838 add r0, sp, #224 ; 0xe0 + 800379c: f7ff ffd9 bl 8003752 + if(rv) return rv; + 80037a0: 4604 mov r4, r0 + 80037a2: 2800 cmp r0, #0 + 80037a4: f040 80d9 bne.w 800395a + uint8_t config[128]; + while(ae_config_read(config)) ; +#endif + + // verify some fixed values + ASSERT(config[0] == 0x01); + 80037a8: f89d 30e0 ldrb.w r3, [sp, #224] ; 0xe0 + 80037ac: 2b01 cmp r3, #1 + 80037ae: d002 beq.n 80037b6 + 80037b0: 486f ldr r0, [pc, #444] ; (8003970 ) + + ae_keep_alive(); + + // lock config zone + if(ae_lock_config_zone(config)) { + INCONSISTENT("conf lock"); + 80037b2: f7fd f941 bl 8000a38 + ASSERT(config[1] == 0x23); + 80037b6: f89d 30e1 ldrb.w r3, [sp, #225] ; 0xe1 + 80037ba: 2b23 cmp r3, #35 ; 0x23 + 80037bc: d1f8 bne.n 80037b0 + ASSERT(config[12] == 0xee); + 80037be: f89d 30ec ldrb.w r3, [sp, #236] ; 0xec + 80037c2: 2bee cmp r3, #238 ; 0xee + 80037c4: d1f4 bne.n 80037b0 + int8_t partno = ((config[6]>>4)&0xf); + 80037c6: f89d 30e6 ldrb.w r3, [sp, #230] ; 0xe6 + ASSERT(partno == 6); + 80037ca: 091b lsrs r3, r3, #4 + 80037cc: 2b06 cmp r3, #6 + 80037ce: d1ef bne.n 80037b0 + memcpy(serial, &config[0], 4); + 80037d0: 9b38 ldr r3, [sp, #224] ; 0xe0 + 80037d2: 9303 str r3, [sp, #12] + memcpy(&serial[4], &config[8], 5); + 80037d4: ab3a add r3, sp, #232 ; 0xe8 + 80037d6: e893 0003 ldmia.w r3, {r0, r1} + 80037da: 9004 str r0, [sp, #16] + 80037dc: f88d 1014 strb.w r1, [sp, #20] + if(check_all_ones(rom_secrets->ae_serial_number, 9)) { + 80037e0: 4864 ldr r0, [pc, #400] ; (8003974 ) + 80037e2: 2109 movs r1, #9 + 80037e4: f7ff f812 bl 800280c + 80037e8: b110 cbz r0, 80037f0 + flash_save_ae_serial(serial); + 80037ea: a803 add r0, sp, #12 + 80037ec: f7fe fd30 bl 8002250 + if(!check_equal(rom_secrets->ae_serial_number, serial, 9)) { + 80037f0: 4860 ldr r0, [pc, #384] ; (8003974 ) + 80037f2: 2209 movs r2, #9 + 80037f4: a903 add r1, sp, #12 + 80037f6: f7ff f822 bl 800283e + 80037fa: 2800 cmp r0, #0 + 80037fc: f000 80b6 beq.w 800396c + if(config[87] == 0x55) { + 8003800: f89d 3137 ldrb.w r3, [sp, #311] ; 0x137 + 8003804: 2b55 cmp r3, #85 ; 0x55 + 8003806: d12b bne.n 8003860 + memcpy(&config[16], config_1, sizeof(config_1)); + 8003808: 495b ldr r1, [pc, #364] ; (8003978 ) + 800380a: 2244 movs r2, #68 ; 0x44 + 800380c: a83c add r0, sp, #240 ; 0xf0 + 800380e: f00a f87b bl 800d908 + memcpy(&config[90], config_2, sizeof(config_2)); + 8003812: 4b5a ldr r3, [pc, #360] ; (800397c ) + 8003814: f50d 729d add.w r2, sp, #314 ; 0x13a + 8003818: f103 0124 add.w r1, r3, #36 ; 0x24 + 800381c: f853 0b04 ldr.w r0, [r3], #4 + 8003820: f842 0b04 str.w r0, [r2], #4 + 8003824: 428b cmp r3, r1 + 8003826: d1f9 bne.n 800381c + 8003828: 881b ldrh r3, [r3, #0] + 800382a: 8013 strh r3, [r2, #0] + for(int n=16; n<128; n+= 4) { + 800382c: 2510 movs r5, #16 + ae_send_n(OP_Write, 0, n/4, &config[n], 4); + 800382e: 2604 movs r6, #4 + if(n == 84) continue; // that word not writable + 8003830: 2d54 cmp r5, #84 ; 0x54 + 8003832: d130 bne.n 8003896 + for(int n=16; n<128; n+= 4) { + 8003834: 3504 adds r5, #4 + 8003836: 2d80 cmp r5, #128 ; 0x80 + 8003838: d1fa bne.n 8003830 + ae_send_idle(); + 800383a: f7ff f90a bl 8002a52 + uint8_t crc[2] = {0, 0}; + 800383e: 2600 movs r6, #0 + crc16_chain(128, config, crc); + 8003840: aa58 add r2, sp, #352 ; 0x160 + 8003842: a938 add r1, sp, #224 ; 0xe0 + 8003844: 4628 mov r0, r5 + uint8_t crc[2] = {0, 0}; + 8003846: f8ad 6160 strh.w r6, [sp, #352] ; 0x160 + crc16_chain(128, config, crc); + 800384a: f7ff f8b5 bl 80029b8 + ae_send(OP_Lock, 0x0, (crc[1]<<8) | crc[0]); + 800384e: f8bd 2160 ldrh.w r2, [sp, #352] ; 0x160 + 8003852: 4631 mov r1, r6 + 8003854: 2017 movs r0, #23 + 8003856: f7ff fa38 bl 8002cca + return ae_read1(); + 800385a: f7ff f9ad bl 8002bb8 + if(ae_lock_config_zone(config)) { + 800385e: bb38 cbnz r0, 80038b0 + // Load data zone with some known values. + // The datazone still unlocked, so no encryption needed (nor possible). + + // will use zeros for all PIN codes, and customer-defined-secret starting values + uint8_t zeros[72]; + memset(zeros, 0, sizeof(zeros)); + 8003860: 2248 movs r2, #72 ; 0x48 + 8003862: 2100 movs r1, #0 + 8003864: a826 add r0, sp, #152 ; 0x98 + 8003866: f00a f85d bl 800d924 + se2_save_auth_pubkey(pubkey); + break; + } + + case 0: + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 800386a: 4e45 ldr r6, [pc, #276] ; (8003980 ) + 800386c: f8bd 5138 ldrh.w r5, [sp, #312] ; 0x138 + if(ae_write_data_slot(kn, rom_secrets->pairing_secret, 32, false)) { + 8003870: 4f44 ldr r7, [pc, #272] ; (8003984 ) + ae_send_idle(); + 8003872: f7ff f8ee bl 8002a52 + if(!(unlocked & (1< + switch(kn) { + 800387e: 2c0e cmp r4, #14 + 8003880: d85c bhi.n 800393c + 8003882: e8df f004 tbb [pc, r4] + 8003886: 176e .short 0x176e + 8003888: 29202920 .word 0x29202920 + 800388c: 2d304c3e .word 0x2d304c3e + 8003890: 2d2d2d2d .word 0x2d2d2d2d + 8003894: 29 .byte 0x29 + 8003895: 00 .byte 0x00 + ae_send_n(OP_Write, 0, n/4, &config[n], 4); + 8003896: ab38 add r3, sp, #224 ; 0xe0 + 8003898: 442b add r3, r5 + 800389a: f3c5 028f ubfx r2, r5, #2, #16 + 800389e: 2100 movs r1, #0 + 80038a0: 2012 movs r0, #18 + 80038a2: 9600 str r6, [sp, #0] + 80038a4: f7ff f9de bl 8002c64 + int rv = ae_read1(); + 80038a8: f7ff f986 bl 8002bb8 + if(rv) return rv; + 80038ac: 2800 cmp r0, #0 + 80038ae: d0c1 beq.n 8003834 + INCONSISTENT("conf lock"); + 80038b0: 4835 ldr r0, [pc, #212] ; (8003988 ) + 80038b2: e77e b.n 80037b2 + if(ae_write_data_slot(kn, rom_secrets->pairing_secret, 32, false)) { + 80038b4: 2300 movs r3, #0 + 80038b6: 2220 movs r2, #32 + 80038b8: 4639 mov r1, r7 + 80038ba: 2001 movs r0, #1 + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 80038bc: f7ff fbf4 bl 80030a8 + 80038c0: 2800 cmp r0, #0 + 80038c2: d03b beq.n 800393c + 80038c4: e7f4 b.n 80038b0 + rng_buffer(tmp, sizeof(tmp)); + 80038c6: 2120 movs r1, #32 + 80038c8: a806 add r0, sp, #24 + 80038ca: f7ff f807 bl 80028dc + if(ae_write_data_slot(kn, tmp, 32, true)) { + 80038ce: 2301 movs r3, #1 + 80038d0: 2220 movs r2, #32 + 80038d2: a906 add r1, sp, #24 + if(ae_write_data_slot(kn, zeros, 32, false)) { + 80038d4: 4620 mov r0, r4 + 80038d6: e7f1 b.n 80038bc + 80038d8: 2300 movs r3, #0 + 80038da: 2220 movs r2, #32 + 80038dc: a926 add r1, sp, #152 ; 0x98 + 80038de: e7f9 b.n 80038d4 + if(ae_write_data_slot(kn, zeros, 72, false)) { + 80038e0: 2300 movs r3, #0 + 80038e2: 2248 movs r2, #72 ; 0x48 + 80038e4: e7fa b.n 80038dc + uint8_t long_zeros[416] = {0}; + 80038e6: 2300 movs r3, #0 + 80038e8: 4619 mov r1, r3 + 80038ea: f44f 72ce mov.w r2, #412 ; 0x19c + 80038ee: a859 add r0, sp, #356 ; 0x164 + 80038f0: 9358 str r3, [sp, #352] ; 0x160 + 80038f2: f00a f817 bl 800d924 + if(ae_write_data_slot(kn, long_zeros, 416, false)) { + 80038f6: 2300 movs r3, #0 + 80038f8: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 80038fc: a958 add r1, sp, #352 ; 0x160 + 80038fe: 2008 movs r0, #8 + 8003900: e7dc b.n 80038bc + uint32_t buf[32/4] = { 1024, 1024 }; + 8003902: 2218 movs r2, #24 + 8003904: 2100 movs r1, #0 + 8003906: a810 add r0, sp, #64 ; 0x40 + 8003908: f00a f80c bl 800d924 + 800390c: f44f 6380 mov.w r3, #1024 ; 0x400 + 8003910: e9cd 330e strd r3, r3, [sp, #56] ; 0x38 + if(ae_write_data_slot(KEYNUM_match_count, (const uint8_t *)buf,sizeof(buf),false)) { + 8003914: 2220 movs r2, #32 + 8003916: 2300 movs r3, #0 + 8003918: a90e add r1, sp, #56 ; 0x38 + 800391a: 2006 movs r0, #6 + 800391c: e7ce b.n 80038bc + if(ae_checkmac_hard(KEYNUM_main_pin, zeros) != 0) { + 800391e: a926 add r1, sp, #152 ; 0x98 + 8003920: 2003 movs r0, #3 + 8003922: f7ff fc99 bl 8003258 + 8003926: 2800 cmp r0, #0 + 8003928: d1c2 bne.n 80038b0 + if(ae_gen_ecc_key(KEYNUM_joiner_key, pubkey)) { + 800392a: a916 add r1, sp, #88 ; 0x58 + 800392c: 2007 movs r0, #7 + 800392e: f7ff fb2b bl 8002f88 + 8003932: 2800 cmp r0, #0 + 8003934: d1bc bne.n 80038b0 + se2_save_auth_pubkey(pubkey); + 8003936: a816 add r0, sp, #88 ; 0x58 + 8003938: f004 f9e4 bl 8007d04 + for(int kn=0; kn<16; kn++) { + 800393c: 3401 adds r4, #1 + 800393e: 2c10 cmp r4, #16 + 8003940: d197 bne.n 8003872 + ae_send_idle(); + 8003942: f7ff f886 bl 8002a52 + ae_send(OP_Lock, 0x81, 0x0000); + 8003946: 2200 movs r2, #0 + 8003948: 2181 movs r1, #129 ; 0x81 + 800394a: 2017 movs r0, #23 + 800394c: f7ff f9bd bl 8002cca + return ae_read1(); + 8003950: f7ff f932 bl 8002bb8 + } + } + + // lock the data zone and effectively enter normal operation. + ae_keep_alive(); + if(ae_lock_data_zone()) { + 8003954: 2800 cmp r0, #0 + 8003956: d1ab bne.n 80038b0 + if(data_locked) return 0; // basically success + 8003958: 2400 movs r4, #0 + INCONSISTENT("data lock"); + } + + return 0; +} + 800395a: 4620 mov r0, r4 + 800395c: f50d 7d41 add.w sp, sp, #772 ; 0x304 + 8003960: bdf0 pop {r4, r5, r6, r7, pc} + if(ae_write_data_slot(kn, (const uint8_t *)copyright_msg, 32, true)) { + 8003962: 2301 movs r3, #1 + 8003964: 2220 movs r2, #32 + 8003966: 4631 mov r1, r6 + 8003968: 2000 movs r0, #0 + 800396a: e7a7 b.n 80038bc + return EPERM; + 800396c: 2401 movs r4, #1 + 800396e: e7f4 b.n 800395a + 8003970: 0801046c .word 0x0801046c + 8003974: 0801c040 .word 0x0801c040 + 8003978: 08010706 .word 0x08010706 + 800397c: 0801074a .word 0x0801074a + 8003980: 080106c2 .word 0x080106c2 + 8003984: 0801c000 .word 0x0801c000 + 8003988: 0800d9a0 .word 0x0800d9a0 + +0800398c : +// - but our time to do each iteration is limited by software SHA256 in ae_pair_unlock +// + int +ae_stretch_iter(const uint8_t start[32], uint8_t end[32], int iterations) +{ + ASSERT(start != end); // we can't work inplace + 800398c: 4288 cmp r0, r1 +{ + 800398e: b570 push {r4, r5, r6, lr} + 8003990: 460c mov r4, r1 + 8003992: 4615 mov r5, r2 + ASSERT(start != end); // we can't work inplace + 8003994: d102 bne.n 800399c + 8003996: 4810 ldr r0, [pc, #64] ; (80039d8 ) + 8003998: f7fd f84e bl 8000a38 + memcpy(end, start, 32); + 800399c: 460b mov r3, r1 + 800399e: f100 0220 add.w r2, r0, #32 + 80039a2: f850 1b04 ldr.w r1, [r0], #4 + 80039a6: f843 1b04 str.w r1, [r3], #4 + 80039aa: 4290 cmp r0, r2 + 80039ac: d1f9 bne.n 80039a2 + + for(int i=0; i + + int rv = ae_hmac32(KEYNUM_pin_stretch, end, end); + RET_IF_BAD(rv); + } + + return 0; + 80039b4: 2000 movs r0, #0 +} + 80039b6: bd70 pop {r4, r5, r6, pc} + if(ae_pair_unlock()) return -2; + 80039b8: f7ff fac0 bl 8002f3c + 80039bc: b940 cbnz r0, 80039d0 + int rv = ae_hmac32(KEYNUM_pin_stretch, end, end); + 80039be: 4622 mov r2, r4 + 80039c0: 4621 mov r1, r4 + 80039c2: 2002 movs r0, #2 + 80039c4: f7ff fb02 bl 8002fcc + RET_IF_BAD(rv); + 80039c8: 2800 cmp r0, #0 + 80039ca: d1f4 bne.n 80039b6 + for(int i=0; i + if(ae_pair_unlock()) return -2; + 80039d0: f06f 0001 mvn.w r0, #1 + 80039d4: e7ef b.n 80039b6 + 80039d6: bf00 nop + 80039d8: 0801046c .word 0x0801046c + +080039dc : +// Apply HMAC using secret in chip as a HMAC key, then encrypt +// the result a little because read in clear over bus. +// + int +ae_mixin_key(uint8_t keynum, const uint8_t start[32], uint8_t end[32]) +{ + 80039dc: b570 push {r4, r5, r6, lr} + 80039de: b096 sub sp, #88 ; 0x58 + ASSERT(start != end); // we can't work inplace + 80039e0: 4291 cmp r1, r2 +{ + 80039e2: 460e mov r6, r1 + 80039e4: 4614 mov r4, r2 + 80039e6: f88d 0007 strb.w r0, [sp, #7] + ASSERT(start != end); // we can't work inplace + 80039ea: d102 bne.n 80039f2 + 80039ec: 4818 ldr r0, [pc, #96] ; (8003a50 ) + 80039ee: f7fd f823 bl 8000a38 + + if(ae_pair_unlock()) return -1; + 80039f2: f7ff faa3 bl 8002f3c + 80039f6: bb40 cbnz r0, 8003a4a + + ASSERT(keynum != 0); + 80039f8: f89d 0007 ldrb.w r0, [sp, #7] + 80039fc: 2800 cmp r0, #0 + 80039fe: d0f5 beq.n 80039ec + int rv = ae_hmac32(keynum, start, end); + 8003a00: 4622 mov r2, r4 + 8003a02: 4631 mov r1, r6 + 8003a04: f7ff fae2 bl 8002fcc + RET_IF_BAD(rv); + 8003a08: 4605 mov r5, r0 + 8003a0a: b9d8 cbnz r0, 8003a44 + // use the value provided in cleartext[sic--it's not] write back shortly (to test it). + // Solution: one more SHA256, and to be safe, mixin lots of values! + + SHA256_CTX ctx; + + sha256_init(&ctx); + 8003a0c: a803 add r0, sp, #12 + 8003a0e: f001 feb5 bl 800577c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003a12: 4910 ldr r1, [pc, #64] ; (8003a54 ) + 8003a14: 2220 movs r2, #32 + 8003a16: a803 add r0, sp, #12 + 8003a18: f001 febe bl 8005798 + sha256_update(&ctx, start, 32); + 8003a1c: 2220 movs r2, #32 + 8003a1e: 4631 mov r1, r6 + 8003a20: a803 add r0, sp, #12 + 8003a22: f001 feb9 bl 8005798 + sha256_update(&ctx, &keynum, 1); + 8003a26: 2201 movs r2, #1 + 8003a28: f10d 0107 add.w r1, sp, #7 + 8003a2c: a803 add r0, sp, #12 + 8003a2e: f001 feb3 bl 8005798 + sha256_update(&ctx, end, 32); + 8003a32: 4621 mov r1, r4 + 8003a34: a803 add r0, sp, #12 + 8003a36: 2220 movs r2, #32 + 8003a38: f001 feae bl 8005798 + sha256_final(&ctx, end); + 8003a3c: 4621 mov r1, r4 + 8003a3e: a803 add r0, sp, #12 + 8003a40: f001 fef0 bl 8005824 + + return 0; +} + 8003a44: 4628 mov r0, r5 + 8003a46: b016 add sp, #88 ; 0x58 + 8003a48: bd70 pop {r4, r5, r6, pc} + if(ae_pair_unlock()) return -1; + 8003a4a: f04f 35ff mov.w r5, #4294967295 ; 0xffffffff + 8003a4e: e7f9 b.n 8003a44 + 8003a50: 0801046c .word 0x0801046c + 8003a54: 0801c000 .word 0x0801c000 + +08003a58 : +// Immediately destroy the pairing secret so that we become +// a useless brick. Ignore errors but retry. +// + void +ae_brick_myself(void) +{ + 8003a58: b510 push {r4, lr} + for(int retry=0; retry<10; retry++) { + 8003a5a: 2400 movs r4, #0 + ae_reset_chip(); + 8003a5c: f7ff f86a bl 8002b34 + + if(retry) rng_delay(); + 8003a60: b10c cbz r4, 8003a66 + 8003a62: f7fe ff51 bl 8002908 + + ae_pair_unlock(); + 8003a66: f7ff fa69 bl 8002f3c + + // Concern: MitM could block this by trashing our write + // - but they have to do it without causing CRC or other comm error + // - ten times + int rv = ae_destroy_key(KEYNUM_pairing); + 8003a6a: 2001 movs r0, #1 + 8003a6c: f7ff fe54 bl 8003718 + if(rv == 0) break; + 8003a70: b120 cbz r0, 8003a7c + for(int retry=0; retry<10; retry++) { + 8003a72: 3401 adds r4, #1 + + rng_delay(); + 8003a74: f7fe ff48 bl 8002908 + for(int retry=0; retry<10; retry++) { + 8003a78: 2c0a cmp r4, #10 + 8003a7a: d1ef bne.n 8003a5c + } + + ae_reset_chip(); +} + 8003a7c: e8bd 4010 ldmia.w sp!, {r4, lr} + ae_reset_chip(); + 8003a80: f7ff b858 b.w 8002b34 + +08003a84 : +// + void +delay_ms(int ms) +{ + // Clear the COUNTFLAG and reset value to zero + SysTick->VAL = 0; + 8003a84: f04f 23e0 mov.w r3, #3758153728 ; 0xe000e000 + 8003a88: 2200 movs r2, #0 + 8003a8a: 619a str r2, [r3, #24] + //SysTick->CTRL; + + // Wait for ticks to happen + while(ms > 0) { + 8003a8c: 2800 cmp r0, #0 + 8003a8e: dc00 bgt.n 8003a92 + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + ms--; + } + } +} + 8003a90: 4770 bx lr + if(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + 8003a92: 691a ldr r2, [r3, #16] + 8003a94: 03d2 lsls r2, r2, #15 + ms--; + 8003a96: bf48 it mi + 8003a98: f100 30ff addmi.w r0, r0, #4294967295 ; 0xffffffff + 8003a9c: e7f6 b.n 8003a8c + +08003a9e : +// Replace HAL version which needs interrupts +// + void +HAL_Delay(uint32_t Delay) +{ + delay_ms(Delay); + 8003a9e: f7ff bff1 b.w 8003a84 + ... + +08003aa4 : + // NOTES: + // - try not to limit PCB changes for future revs; leave unused unchanged. + // - lcd.c controls some pins as well. + + // enable clock to GPIO's ... we will be using them all at some point + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003aa4: 4b67 ldr r3, [pc, #412] ; (8003c44 ) +{ + 8003aa6: b570 push {r4, r5, r6, lr} + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003aa8: 6cda ldr r2, [r3, #76] ; 0x4c + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + { // Onewire bus pins used for ATECC608 comms + GPIO_InitTypeDef setup = { + 8003aaa: 4c67 ldr r4, [pc, #412] ; (8003c48 ) + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003aac: f042 0201 orr.w r2, r2, #1 + 8003ab0: 64da str r2, [r3, #76] ; 0x4c + 8003ab2: 6cda ldr r2, [r3, #76] ; 0x4c +{ + 8003ab4: b08a sub sp, #40 ; 0x28 + __HAL_RCC_GPIOA_CLK_ENABLE(); + 8003ab6: f002 0201 and.w r2, r2, #1 + 8003aba: 9200 str r2, [sp, #0] + 8003abc: 9a00 ldr r2, [sp, #0] + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8003abe: 6cda ldr r2, [r3, #76] ; 0x4c + 8003ac0: f042 0202 orr.w r2, r2, #2 + 8003ac4: 64da str r2, [r3, #76] ; 0x4c + 8003ac6: 6cda ldr r2, [r3, #76] ; 0x4c + 8003ac8: f002 0202 and.w r2, r2, #2 + 8003acc: 9201 str r2, [sp, #4] + 8003ace: 9a01 ldr r2, [sp, #4] + __HAL_RCC_GPIOC_CLK_ENABLE(); + 8003ad0: 6cda ldr r2, [r3, #76] ; 0x4c + 8003ad2: f042 0204 orr.w r2, r2, #4 + 8003ad6: 64da str r2, [r3, #76] ; 0x4c + 8003ad8: 6cda ldr r2, [r3, #76] ; 0x4c + 8003ada: f002 0204 and.w r2, r2, #4 + 8003ade: 9202 str r2, [sp, #8] + 8003ae0: 9a02 ldr r2, [sp, #8] + __HAL_RCC_GPIOD_CLK_ENABLE(); + 8003ae2: 6cda ldr r2, [r3, #76] ; 0x4c + 8003ae4: f042 0208 orr.w r2, r2, #8 + 8003ae8: 64da str r2, [r3, #76] ; 0x4c + 8003aea: 6cda ldr r2, [r3, #76] ; 0x4c + 8003aec: f002 0208 and.w r2, r2, #8 + 8003af0: 9203 str r2, [sp, #12] + 8003af2: 9a03 ldr r2, [sp, #12] + __HAL_RCC_GPIOE_CLK_ENABLE(); + 8003af4: 6cda ldr r2, [r3, #76] ; 0x4c + 8003af6: f042 0210 orr.w r2, r2, #16 + 8003afa: 64da str r2, [r3, #76] ; 0x4c + 8003afc: 6cdb ldr r3, [r3, #76] ; 0x4c + 8003afe: f003 0310 and.w r3, r3, #16 + 8003b02: 9304 str r3, [sp, #16] + 8003b04: 9b04 ldr r3, [sp, #16] + GPIO_InitTypeDef setup = { + 8003b06: cc0f ldmia r4!, {r0, r1, r2, r3} + 8003b08: ad05 add r5, sp, #20 + 8003b0a: c50f stmia r5!, {r0, r1, r2, r3} + 8003b0c: 6823 ldr r3, [r4, #0] + 8003b0e: 602b str r3, [r5, #0] + .Mode = GPIO_MODE_AF_OD, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = GPIO_AF8_UART4, + }; + HAL_GPIO_Init(ONEWIRE_PORT, &setup); + 8003b10: a905 add r1, sp, #20 + 8003b12: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8003b16: f7fd fb6d bl 80011f4 + } + + // Bugfix: re-init of console port pins seems to wreck + // the mpy uart code, so avoid after first time. + if(USART1->BRR == 0) { + 8003b1a: 4b4c ldr r3, [pc, #304] ; (8003c4c ) + 8003b1c: 68de ldr r6, [r3, #12] + 8003b1e: b9ae cbnz r6, 8003b4c + // debug console: USART1 = PA9=Tx & PA10=Rx + GPIO_InitTypeDef setup = { + 8003b20: 3404 adds r4, #4 + 8003b22: cc0f ldmia r4!, {r0, r1, r2, r3} + 8003b24: ad05 add r5, sp, #20 + 8003b26: c50f stmia r5!, {r0, r1, r2, r3} + 8003b28: 6823 ldr r3, [r4, #0] + 8003b2a: 602b str r3, [r5, #0] + .Mode = GPIO_MODE_AF_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_MEDIUM, + .Alternate = GPIO_AF7_USART1, + }; + HAL_GPIO_Init(GPIOA, &setup); + 8003b2c: a905 add r1, sp, #20 + 8003b2e: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + 8003b32: f7fd fb5f bl 80011f4 + + setup.Pin = GPIO_PIN_10; + 8003b36: f44f 6380 mov.w r3, #1024 ; 0x400 + setup.Mode = GPIO_MODE_INPUT; + 8003b3a: e9cd 3605 strd r3, r6, [sp, #20] + setup.Pull = GPIO_PULLUP; + HAL_GPIO_Init(GPIOA, &setup); + 8003b3e: a905 add r1, sp, #20 + setup.Pull = GPIO_PULLUP; + 8003b40: 2301 movs r3, #1 + HAL_GPIO_Init(GPIOA, &setup); + 8003b42: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + setup.Pull = GPIO_PULLUP; + 8003b46: 9307 str r3, [sp, #28] + HAL_GPIO_Init(GPIOA, &setup); + 8003b48: f7fd fb54 bl 80011f4 + } + + { // Port B - mostly unused, but want TEAR input and pwr btn + // TEAR from LCD: PB11 + // PWR_BTN: PB12 + GPIO_InitTypeDef setup = { + 8003b4c: 2400 movs r4, #0 + // Port C - Outputs + // SD1 active LED: PC7 + // USB active LED: PC6 + // TURN OFF: PC0 + // SD mux: PC13 + { GPIO_InitTypeDef setup = { + 8003b4e: 2501 movs r5, #1 + GPIO_InitTypeDef setup = { + 8003b50: f44f 53c0 mov.w r3, #6144 ; 0x1800 + HAL_GPIO_Init(GPIOB, &setup); + 8003b54: a905 add r1, sp, #20 + 8003b56: 483e ldr r0, [pc, #248] ; (8003c50 ) + GPIO_InitTypeDef setup = { + 8003b58: 9409 str r4, [sp, #36] ; 0x24 + 8003b5a: e9cd 3405 strd r3, r4, [sp, #20] + 8003b5e: e9cd 4407 strd r4, r4, [sp, #28] + HAL_GPIO_Init(GPIOB, &setup); + 8003b62: f7fd fb47 bl 80011f4 + { GPIO_InitTypeDef setup = { + 8003b66: 23c1 movs r3, #193 ; 0xc1 + .Pin = GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_0, GPIO_PIN_13, + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); // keep power on! + 8003b68: 4622 mov r2, r4 + 8003b6a: 4629 mov r1, r5 + 8003b6c: 4839 ldr r0, [pc, #228] ; (8003c54 ) + { GPIO_InitTypeDef setup = { + 8003b6e: 9409 str r4, [sp, #36] ; 0x24 + 8003b70: e9cd 3505 strd r3, r5, [sp, #20] + 8003b74: e9cd 4407 strd r4, r4, [sp, #28] + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 0); // keep power on! + 8003b78: f7fd fcb6 bl 80014e8 + HAL_GPIO_Init(GPIOC, &setup); + 8003b7c: a905 add r1, sp, #20 + 8003b7e: 4835 ldr r0, [pc, #212] ; (8003c54 ) + 8003b80: f7fd fb38 bl 80011f4 + + // turn LEDs off, SD mux to A + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_13, 0); + 8003b84: 4622 mov r2, r4 + 8003b86: 4833 ldr r0, [pc, #204] ; (8003c54 ) + 8003b88: f44f 5103 mov.w r1, #8384 ; 0x20c0 + 8003b8c: f7fd fcac bl 80014e8 + } + + // Port C - Inputs + // SD card detect switch: PC1 battery/not + { GPIO_InitTypeDef setup = { + 8003b90: 2210 movs r2, #16 + 8003b92: 4621 mov r1, r4 + 8003b94: a806 add r0, sp, #24 + 8003b96: f009 fec5 bl 800d924 + 8003b9a: f242 0302 movw r3, #8194 ; 0x2002 + .Pin = GPIO_PIN_13 | GPIO_PIN_1, + .Mode = GPIO_MODE_INPUT, + .Pull = GPIO_PULLUP, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOC, &setup); + 8003b9e: a905 add r1, sp, #20 + 8003ba0: 482c ldr r0, [pc, #176] ; (8003c54 ) + { GPIO_InitTypeDef setup = { + 8003ba2: 9305 str r3, [sp, #20] + 8003ba4: 9507 str r5, [sp, #28] + HAL_GPIO_Init(GPIOC, &setup); + 8003ba6: f7fd fb25 bl 80011f4 + .Pin = GPIO_PIN_0, + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOD, &setup); + 8003baa: a905 add r1, sp, #20 + 8003bac: 482a ldr r0, [pc, #168] ; (8003c58 ) + { GPIO_InitTypeDef setup = { + 8003bae: 9409 str r4, [sp, #36] ; 0x24 + 8003bb0: e9cd 4407 strd r4, r4, [sp, #28] + 8003bb4: e9cd 5505 strd r5, r5, [sp, #20] + HAL_GPIO_Init(GPIOD, &setup); + 8003bb8: f7fd fb1c bl 80011f4 + + HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, 0); // turn off + 8003bbc: 4622 mov r2, r4 + 8003bbe: 4629 mov r1, r5 + 8003bc0: 4825 ldr r0, [pc, #148] ; (8003c58 ) + 8003bc2: f7fd fc91 bl 80014e8 + } + + // Port D - Inputs + // SD slots detects: PD3/4 + { GPIO_InitTypeDef setup = { + 8003bc6: 2210 movs r2, #16 + 8003bc8: 4621 mov r1, r4 + 8003bca: a806 add r0, sp, #24 + 8003bcc: f009 feaa bl 800d924 + 8003bd0: 2618 movs r6, #24 + .Pin = GPIO_PIN_3 | GPIO_PIN_4, + .Mode = GPIO_MODE_INPUT, + .Pull = GPIO_PULLUP, // required + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOD, &setup); + 8003bd2: a905 add r1, sp, #20 + 8003bd4: 4820 ldr r0, [pc, #128] ; (8003c58 ) + { GPIO_InitTypeDef setup = { + 8003bd6: 9605 str r6, [sp, #20] + 8003bd8: 9507 str r5, [sp, #28] + HAL_GPIO_Init(GPIOD, &setup); + 8003bda: f7fd fb0b bl 80011f4 + .Pin = GPIO_PIN_3 | GPIO_PIN_4, + .Mode = GPIO_MODE_OUTPUT_PP, + .Pull = GPIO_NOPULL, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + HAL_GPIO_Init(GPIOE, &setup); + 8003bde: a905 add r1, sp, #20 + 8003be0: 481e ldr r0, [pc, #120] ; (8003c5c ) + { GPIO_InitTypeDef setup = { + 8003be2: 9409 str r4, [sp, #36] ; 0x24 + 8003be4: e9cd 4407 strd r4, r4, [sp, #28] + 8003be8: e9cd 6505 strd r6, r5, [sp, #20] + HAL_GPIO_Init(GPIOE, &setup); + 8003bec: f7fd fb02 bl 80011f4 + + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_4, 0); // turn off NFC LED + 8003bf0: 4622 mov r2, r4 + 8003bf2: 481a ldr r0, [pc, #104] ; (8003c5c ) + 8003bf4: 2110 movs r1, #16 + 8003bf6: f7fd fc77 bl 80014e8 + HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, 1); // turn on Backlight: 100% + 8003bfa: 462a mov r2, r5 + 8003bfc: 4817 ldr r0, [pc, #92] ; (8003c5c ) + 8003bfe: 2108 movs r1, #8 + 8003c00: f7fd fc72 bl 80014e8 + + // GPU control: Port E: PE2=G_SWCLK_BOOT0=G_BUSY, PE5=G_CTRL, PE6=G_RESET + // - want open-drain on these outputs, so the SWD debugger can override + // - and PE2 needs to be pull-down input, because active high signal and + // GPU may not be running yet + { GPIO_InitTypeDef setup = { + 8003c04: 2260 movs r2, #96 ; 0x60 + 8003c06: 2311 movs r3, #17 + .Mode = GPIO_MODE_OUTPUT_OD, + .Pull = GPIO_PULLUP, + .Speed = GPIO_SPEED_FREQ_LOW, + }; + + HAL_GPIO_Init(GPIOE, &setup); + 8003c08: a905 add r1, sp, #20 + 8003c0a: 4814 ldr r0, [pc, #80] ; (8003c5c ) + { GPIO_InitTypeDef setup = { + 8003c0c: 9507 str r5, [sp, #28] + 8003c0e: e9cd 2305 strd r2, r3, [sp, #20] + 8003c12: e9cd 4408 strd r4, r4, [sp, #32] + HAL_GPIO_Init(GPIOE, &setup); + 8003c16: f7fd faed bl 80011f4 + + // G_BUSY: input, pull down + setup.Pin = PIN_G_BUSY; + 8003c1a: 2304 movs r3, #4 + 8003c1c: 9305 str r3, [sp, #20] + setup.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(GPIOE, &setup); + 8003c1e: a905 add r1, sp, #20 + setup.Pull = GPIO_PULLDOWN; + 8003c20: 2302 movs r3, #2 + HAL_GPIO_Init(GPIOE, &setup); + 8003c22: 480e ldr r0, [pc, #56] ; (8003c5c ) + setup.Pull = GPIO_PULLDOWN; + 8003c24: 9307 str r3, [sp, #28] + HAL_GPIO_Init(GPIOE, &setup); + 8003c26: f7fd fae5 bl 80011f4 + + // assert reset, leave others high + HAL_GPIO_WritePin(GPIOE, PIN_G_CTRL, 1); + 8003c2a: 462a mov r2, r5 + 8003c2c: 480b ldr r0, [pc, #44] ; (8003c5c ) + 8003c2e: 2120 movs r1, #32 + 8003c30: f7fd fc5a bl 80014e8 + HAL_GPIO_WritePin(GPIOE, PIN_G_RESET, 0); + 8003c34: 4809 ldr r0, [pc, #36] ; (8003c5c ) + 8003c36: 4622 mov r2, r4 + 8003c38: 2140 movs r1, #64 ; 0x40 + 8003c3a: f7fd fc55 bl 80014e8 + // RCC_MCO1SOURCE_PLLCLK (PLL R output) => (same os SYSCLK) + // RCC_MCO1SOURCE_HSI48 => 48Mhz + // RCC_MCO1SOURCE_HSE => 8Mhz (correct) + __HAL_RCC_MCO1_CONFIG(RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1); +#endif +} + 8003c3e: b00a add sp, #40 ; 0x28 + 8003c40: bd70 pop {r4, r5, r6, pc} + 8003c42: bf00 nop + 8003c44: 40021000 .word 0x40021000 + 8003c48: 08010770 .word 0x08010770 + 8003c4c: 40013800 .word 0x40013800 + 8003c50: 48000400 .word 0x48000400 + 8003c54: 48000800 .word 0x48000800 + 8003c58: 48000c00 .word 0x48000c00 + 8003c5c: 48001000 .word 0x48001000 + +08003c60 : +// +// Kill system power; instant. +// + void +turn_power_off(void) +{ + 8003c60: b508 push {r3, lr} + gpio_setup(); + 8003c62: f7ff ff1f bl 8003aa4 + + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); + 8003c66: 2201 movs r2, #1 + 8003c68: 4802 ldr r0, [pc, #8] ; (8003c74 ) + 8003c6a: 4611 mov r1, r2 + 8003c6c: f7fd fc3c bl 80014e8 + + while(1) { + __WFI(); + 8003c70: bf30 wfi + while(1) { + 8003c72: e7fd b.n 8003c70 + 8003c74: 48000800 .word 0x48000800 + +08003c78 : +// Showing a fatal msg to user; power down after a long delay +// or instantly if they touch power btn. Replaces LOCKUP_FOREVER +// + void +q1_wait_powerdown(void) +{ + 8003c78: b508 push {r3, lr} + gpio_setup(); + 8003c7a: f7ff ff13 bl 8003aa4 + + // wait for release (often problem occurs close to power up) + for(uint32_t i=0; i) + gpio_setup(); + 8003c80: 2496 movs r4, #150 ; 0x96 + if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == 1) { + 8003c82: f44f 5180 mov.w r1, #4096 ; 0x1000 + 8003c86: 4628 mov r0, r5 + 8003c88: f7fd fc28 bl 80014dc + 8003c8c: 2801 cmp r0, #1 + 8003c8e: d004 beq.n 8003c9a + break; + } + + delay_ms(100); + 8003c90: 2064 movs r0, #100 ; 0x64 + 8003c92: f7ff fef7 bl 8003a84 + for(uint32_t i=0; i + } + + // wait for press + for(uint32_t i=0; i) + gpio_setup(); + 8003c9c: 2496 movs r4, #150 ; 0x96 + if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == 0) { + 8003c9e: f44f 5180 mov.w r1, #4096 ; 0x1000 + 8003ca2: 4628 mov r0, r5 + 8003ca4: f7fd fc1a bl 80014dc + 8003ca8: b120 cbz r0, 8003cb4 + break; + } + + delay_ms(100); + 8003caa: 2064 movs r0, #100 ; 0x64 + 8003cac: f7ff feea bl 8003a84 + for(uint32_t i=0; i + } + + // turn off power + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, 1); + 8003cb4: 2201 movs r2, #1 + 8003cb6: 4804 ldr r0, [pc, #16] ; (8003cc8 ) + 8003cb8: 4611 mov r1, r2 + 8003cba: f7fd fc15 bl 80014e8 + + // not reached. + while(1) { + __WFI(); + 8003cbe: bf30 wfi + while(1) { + 8003cc0: e7fd b.n 8003cbe + 8003cc2: bf00 nop + 8003cc4: 48000400 .word 0x48000400 + 8003cc8: 48000800 .word 0x48000800 + +08003ccc : + +// reboot_nonce() +// + static inline void +reboot_nonce(SHA256_CTX *ctx) +{ + 8003ccc: b537 push {r0, r1, r2, r4, r5, lr} + uint32_t a = CRC->INIT; + 8003cce: 4d09 ldr r5, [pc, #36] ; (8003cf4 ) + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003cd0: 2204 movs r2, #4 + uint32_t a = CRC->INIT; + 8003cd2: 692b ldr r3, [r5, #16] + 8003cd4: 9301 str r3, [sp, #4] + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003cd6: eb0d 0102 add.w r1, sp, r2 +{ + 8003cda: 4604 mov r4, r0 + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003cdc: f001 fd5c bl 8005798 + + a = CRC->POL; + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003ce0: 2204 movs r2, #4 + a = CRC->POL; + 8003ce2: 696b ldr r3, [r5, #20] + 8003ce4: 9301 str r3, [sp, #4] + sha256_update(ctx, (const uint8_t *)&a, 4); + 8003ce6: eb0d 0102 add.w r1, sp, r2 + 8003cea: 4620 mov r0, r4 + 8003cec: f001 fd54 bl 8005798 +} + 8003cf0: b003 add sp, #12 + 8003cf2: bd30 pop {r4, r5, pc} + 8003cf4: 40023000 .word 0x40023000 + +08003cf8 : +// +// Hash up a string of digits into 32-bytes of goodness. +// + static void +pin_hash(const char *pin, int pin_len, uint8_t result[32], uint32_t purpose) +{ + 8003cf8: b570 push {r4, r5, r6, lr} + 8003cfa: b096 sub sp, #88 ; 0x58 + ASSERT(pin_len <= MAX_PIN_LEN); + 8003cfc: 2920 cmp r1, #32 +{ + 8003cfe: 4606 mov r6, r0 + 8003d00: 460d mov r5, r1 + 8003d02: 4614 mov r4, r2 + 8003d04: 9301 str r3, [sp, #4] + ASSERT(pin_len <= MAX_PIN_LEN); + 8003d06: dd02 ble.n 8003d0e + 8003d08: 4817 ldr r0, [pc, #92] ; (8003d68 ) + 8003d0a: f7fc fe95 bl 8000a38 + + if(pin_len == 0) { + 8003d0e: b929 cbnz r1, 8003d1c + // zero-length PIN is considered the "blank" one: all zero + memset(result, 0, 32); + 8003d10: 2220 movs r2, #32 + 8003d12: 4620 mov r0, r4 + 8003d14: f009 fe06 bl 800d924 + // and run that thru SE2 as well + se2_pin_hash(result, purpose); + + // and a second-sha256 on that, just in case. + sha256_single(result, 32, result); +} + 8003d18: b016 add sp, #88 ; 0x58 + 8003d1a: bd70 pop {r4, r5, r6, pc} + sha256_init(&ctx); + 8003d1c: a803 add r0, sp, #12 + 8003d1e: f001 fd2d bl 800577c + sha256_update(&ctx, rom_secrets->hash_cache_secret, 32); + 8003d22: a803 add r0, sp, #12 + 8003d24: 4911 ldr r1, [pc, #68] ; (8003d6c ) + 8003d26: 2220 movs r2, #32 + 8003d28: f001 fd36 bl 8005798 + sha256_update(&ctx, (uint8_t *)&purpose, 4); + 8003d2c: 2204 movs r2, #4 + 8003d2e: eb0d 0102 add.w r1, sp, r2 + 8003d32: a803 add r0, sp, #12 + 8003d34: f001 fd30 bl 8005798 + sha256_update(&ctx, (uint8_t *)pin, pin_len); + 8003d38: 462a mov r2, r5 + 8003d3a: 4631 mov r1, r6 + 8003d3c: a803 add r0, sp, #12 + 8003d3e: f001 fd2b bl 8005798 + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003d42: 2220 movs r2, #32 + 8003d44: a803 add r0, sp, #12 + 8003d46: 490a ldr r1, [pc, #40] ; (8003d70 ) + 8003d48: f001 fd26 bl 8005798 + sha256_final(&ctx, result); + 8003d4c: 4621 mov r1, r4 + 8003d4e: a803 add r0, sp, #12 + 8003d50: f001 fd68 bl 8005824 + se2_pin_hash(result, purpose); + 8003d54: 9901 ldr r1, [sp, #4] + 8003d56: 4620 mov r0, r4 + 8003d58: f004 fc46 bl 80085e8 + sha256_single(result, 32, result); + 8003d5c: 4622 mov r2, r4 + 8003d5e: 2120 movs r1, #32 + 8003d60: 4620 mov r0, r4 + 8003d62: f001 fd73 bl 800584c + 8003d66: e7d7 b.n 8003d18 + 8003d68: 0801046c .word 0x0801046c + 8003d6c: 0801c070 .word 0x0801c070 + 8003d70: 0801c000 .word 0x0801c000 + +08003d74 <_hmac_attempt>: +// +// Maybe should be proper HMAC from fips std? Can be changed later. +// + static void +_hmac_attempt(const pinAttempt_t *args, uint8_t result[32]) +{ + 8003d74: b530 push {r4, r5, lr} + 8003d76: b095 sub sp, #84 ; 0x54 + 8003d78: 4604 mov r4, r0 + SHA256_CTX ctx; + + sha256_init(&ctx); + 8003d7a: a801 add r0, sp, #4 +{ + 8003d7c: 460d mov r5, r1 + sha256_init(&ctx); + 8003d7e: f001 fcfd bl 800577c + sha256_update(&ctx, rom_secrets->pairing_secret, 32); + 8003d82: 4911 ldr r1, [pc, #68] ; (8003dc8 <_hmac_attempt+0x54>) + 8003d84: 2220 movs r2, #32 + 8003d86: a801 add r0, sp, #4 + 8003d88: f001 fd06 bl 8005798 + reboot_nonce(&ctx); + 8003d8c: a801 add r0, sp, #4 + 8003d8e: f7ff ff9d bl 8003ccc + sha256_update(&ctx, (uint8_t *)args, offsetof(pinAttempt_t, hmac)); + 8003d92: 2244 movs r2, #68 ; 0x44 + 8003d94: 4621 mov r1, r4 + 8003d96: a801 add r0, sp, #4 + 8003d98: f001 fcfe bl 8005798 + + if(args->magic_value == PA_MAGIC_V2) { + 8003d9c: 6822 ldr r2, [r4, #0] + 8003d9e: 4b0b ldr r3, [pc, #44] ; (8003dcc <_hmac_attempt+0x58>) + 8003da0: 429a cmp r2, r3 + 8003da2: d105 bne.n 8003db0 <_hmac_attempt+0x3c> + sha256_update(&ctx, (uint8_t *)args->cached_main_pin, + 8003da4: 2220 movs r2, #32 + 8003da6: f104 01f8 add.w r1, r4, #248 ; 0xf8 + 8003daa: a801 add r0, sp, #4 + 8003dac: f001 fcf4 bl 8005798 + msizeof(pinAttempt_t, cached_main_pin)); + } + + sha256_final(&ctx, result); + 8003db0: 4629 mov r1, r5 + 8003db2: a801 add r0, sp, #4 + 8003db4: f001 fd36 bl 8005824 + + // and a second-sha256 on that, just in case. + sha256_single(result, 32, result); + 8003db8: 462a mov r2, r5 + 8003dba: 2120 movs r1, #32 + 8003dbc: 4628 mov r0, r5 + 8003dbe: f001 fd45 bl 800584c +} + 8003dc2: b015 add sp, #84 ; 0x54 + 8003dc4: bd30 pop {r4, r5, pc} + 8003dc6: bf00 nop + 8003dc8: 0801c000 .word 0x0801c000 + 8003dcc: 2eaf6312 .word 0x2eaf6312 + +08003dd0 <_validate_attempt>: + +// _validate_attempt() +// + static int +_validate_attempt(const pinAttempt_t *args, bool first_time) +{ + 8003dd0: b510 push {r4, lr} + 8003dd2: 4604 mov r4, r0 + 8003dd4: b088 sub sp, #32 + if(first_time) { + 8003dd6: b969 cbnz r1, 8003df4 <_validate_attempt+0x24> + // no hmac needed for setup call + } else { + // if hmac is defined, better be right. + uint8_t actual[32]; + + _hmac_attempt(args, actual); + 8003dd8: 4669 mov r1, sp + 8003dda: f7ff ffcb bl 8003d74 <_hmac_attempt> + + if(!check_equal(actual, args->hmac, 32)) { + 8003dde: 2220 movs r2, #32 + 8003de0: f104 0144 add.w r1, r4, #68 ; 0x44 + 8003de4: 4668 mov r0, sp + 8003de6: f7fe fd2a bl 800283e + 8003dea: b918 cbnz r0, 8003df4 <_validate_attempt+0x24> + // hmac is wrong? + return EPIN_HMAC_FAIL; + 8003dec: f06f 0063 mvn.w r0, #99 ; 0x63 + if((args->change_flags & CHANGE__MASK) != args->change_flags) return EPIN_RANGE_ERR; + + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + + return 0; +} + 8003df0: b008 add sp, #32 + 8003df2: bd10 pop {r4, pc} + if(args->magic_value == PA_MAGIC_V2) { + 8003df4: 6822 ldr r2, [r4, #0] + 8003df6: 4b10 ldr r3, [pc, #64] ; (8003e38 <_validate_attempt+0x68>) + 8003df8: 429a cmp r2, r3 + 8003dfa: d117 bne.n 8003e2c <_validate_attempt+0x5c> + if(args->pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003dfc: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8003dfe: 2b20 cmp r3, #32 + 8003e00: dc17 bgt.n 8003e32 <_validate_attempt+0x62> + if(args->old_pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003e02: f8d4 3088 ldr.w r3, [r4, #136] ; 0x88 + 8003e06: 2b20 cmp r3, #32 + 8003e08: dc13 bgt.n 8003e32 <_validate_attempt+0x62> + if(args->new_pin_len > MAX_PIN_LEN) return EPIN_RANGE_ERR; + 8003e0a: f8d4 30ac ldr.w r3, [r4, #172] ; 0xac + 8003e0e: 2b20 cmp r3, #32 + 8003e10: dc0f bgt.n 8003e32 <_validate_attempt+0x62> + if((args->change_flags & CHANGE__MASK) != args->change_flags) return EPIN_RANGE_ERR; + 8003e12: 6e63 ldr r3, [r4, #100] ; 0x64 + 8003e14: f640 727f movw r2, #3967 ; 0xf7f + 8003e18: 4393 bics r3, r2 + 8003e1a: d10a bne.n 8003e32 <_validate_attempt+0x62> + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + 8003e1c: 6863 ldr r3, [r4, #4] + return 0; + 8003e1e: f033 0301 bics.w r3, r3, #1 + 8003e22: bf14 ite ne + 8003e24: f06f 0066 mvnne.w r0, #102 ; 0x66 + 8003e28: 2000 moveq r0, #0 + 8003e2a: e7e1 b.n 8003df0 <_validate_attempt+0x20> + return EPIN_BAD_MAGIC; + 8003e2c: f06f 0065 mvn.w r0, #101 ; 0x65 + 8003e30: e7de b.n 8003df0 <_validate_attempt+0x20> + if((args->is_secondary & 0x1) != args->is_secondary) return EPIN_RANGE_ERR; + 8003e32: f06f 0066 mvn.w r0, #102 ; 0x66 + 8003e36: e7db b.n 8003df0 <_validate_attempt+0x20> + 8003e38: 2eaf6312 .word 0x2eaf6312 + +08003e3c : + +// warmup_ae() +// + static int +warmup_ae(void) +{ + 8003e3c: b510 push {r4, lr} + ae_setup(); + 8003e3e: f7fe fe87 bl 8002b50 + 8003e42: 2405 movs r4, #5 + + for(int retry=0; retry<5; retry++) { + if(!ae_probe()) break; + 8003e44: f7ff f90c bl 8003060 + 8003e48: b108 cbz r0, 8003e4e + for(int retry=0; retry<5; retry++) { + 8003e4a: 3c01 subs r4, #1 + 8003e4c: d1fa bne.n 8003e44 + } + + if(ae_pair_unlock()) return -1; + 8003e4e: f7ff f875 bl 8002f3c + 8003e52: 4604 mov r4, r0 + 8003e54: b918 cbnz r0, 8003e5e + + // reset watchdog timer + ae_keep_alive(); + 8003e56: f7fe fead bl 8002bb4 + + return 0; +} + 8003e5a: 4620 mov r0, r4 + 8003e5c: bd10 pop {r4, pc} + if(ae_pair_unlock()) return -1; + 8003e5e: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 8003e62: e7fa b.n 8003e5a + +08003e64 <_read_slot_as_counter>: +{ + 8003e64: b530 push {r4, r5, lr} + 8003e66: b091 sub sp, #68 ; 0x44 + uint32_t padded[32/4] = { 0 }; + 8003e68: 2220 movs r2, #32 +{ + 8003e6a: 4604 mov r4, r0 + 8003e6c: 460d mov r5, r1 + uint32_t padded[32/4] = { 0 }; + 8003e6e: 4668 mov r0, sp + 8003e70: 2100 movs r1, #0 + 8003e72: f009 fd57 bl 800d924 + ae_pair_unlock(); + 8003e76: f7ff f861 bl 8002f3c + if(ae_read_data_slot(slot, (uint8_t *)padded, 32)) return -1; + 8003e7a: 2220 movs r2, #32 + 8003e7c: 4669 mov r1, sp + 8003e7e: 4620 mov r0, r4 + 8003e80: f7ff fba2 bl 80035c8 + 8003e84: b120 cbz r0, 8003e90 <_read_slot_as_counter+0x2c> + 8003e86: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff +} + 8003e8a: 4620 mov r0, r4 + 8003e8c: b011 add sp, #68 ; 0x44 + 8003e8e: bd30 pop {r4, r5, pc} + ae_pair_unlock(); + 8003e90: f7ff f854 bl 8002f3c + if(ae_gendig_slot(slot, (const uint8_t *)padded, tempkey)) return -1; + 8003e94: 4620 mov r0, r4 + 8003e96: aa08 add r2, sp, #32 + 8003e98: 4669 mov r1, sp + 8003e9a: f7ff f96f bl 800317c + 8003e9e: 4604 mov r4, r0 + 8003ea0: 2800 cmp r0, #0 + 8003ea2: d1f0 bne.n 8003e86 <_read_slot_as_counter+0x22> + if(!ae_is_correct_tempkey(tempkey)) fatal_mitm(); + 8003ea4: a808 add r0, sp, #32 + 8003ea6: f7fe ff79 bl 8002d9c + 8003eaa: b908 cbnz r0, 8003eb0 <_read_slot_as_counter+0x4c> + 8003eac: f7fc fdce bl 8000a4c + *dest = padded[0]; + 8003eb0: 9b00 ldr r3, [sp, #0] + 8003eb2: 602b str r3, [r5, #0] + return 0; + 8003eb4: e7e9 b.n 8003e8a <_read_slot_as_counter+0x26> + +08003eb6 : +{ + 8003eb6: b530 push {r4, r5, lr} + 8003eb8: b095 sub sp, #84 ; 0x54 + 8003eba: 4605 mov r5, r0 + ae_pair_unlock(); + 8003ebc: f7ff f83e bl 8002f3c + uint32_t padded[32/4] = { 0 }; + 8003ec0: 2220 movs r2, #32 + 8003ec2: 2100 movs r1, #0 + 8003ec4: a804 add r0, sp, #16 + 8003ec6: f009 fd2d bl 800d924 + if(ae_read_data_slot(slot, (uint8_t *)padded, 32)) return -1; + 8003eca: 2220 movs r2, #32 + 8003ecc: a904 add r1, sp, #16 + 8003ece: 2005 movs r0, #5 + 8003ed0: f7ff fb7a bl 80035c8 + 8003ed4: b118 cbz r0, 8003ede + 8003ed6: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff +} + 8003eda: b015 add sp, #84 ; 0x54 + 8003edc: bd30 pop {r4, r5, pc} + ae_pair_unlock(); + 8003ede: f7ff f82d bl 8002f3c + if(ae_gendig_slot(slot, (const uint8_t *)padded, tempkey)) return -1; + 8003ee2: aa0c add r2, sp, #48 ; 0x30 + 8003ee4: a904 add r1, sp, #16 + 8003ee6: 2005 movs r0, #5 + 8003ee8: f7ff f948 bl 800317c + 8003eec: 4604 mov r4, r0 + 8003eee: 2800 cmp r0, #0 + 8003ef0: d1f1 bne.n 8003ed6 + if(!ae_is_correct_tempkey(tempkey)) fatal_mitm(); + 8003ef2: a80c add r0, sp, #48 ; 0x30 + 8003ef4: f7fe ff52 bl 8002d9c + 8003ef8: b908 cbnz r0, 8003efe + 8003efa: f7fc fda7 bl 8000a4c + if(_read_slot_as_counter(KEYNUM_lastgood, &lastgood)) return -1; + 8003efe: a901 add r1, sp, #4 + 8003f00: 2005 movs r0, #5 + uint32_t lastgood=0, match_count=0, counter=0; + 8003f02: e9cd 4401 strd r4, r4, [sp, #4] + 8003f06: 9403 str r4, [sp, #12] + if(_read_slot_as_counter(KEYNUM_lastgood, &lastgood)) return -1; + 8003f08: f7ff ffac bl 8003e64 <_read_slot_as_counter> + 8003f0c: 2800 cmp r0, #0 + 8003f0e: d1e2 bne.n 8003ed6 + if(_read_slot_as_counter(KEYNUM_match_count, &match_count)) return -1; + 8003f10: a902 add r1, sp, #8 + 8003f12: 2006 movs r0, #6 + 8003f14: f7ff ffa6 bl 8003e64 <_read_slot_as_counter> + 8003f18: 4601 mov r1, r0 + 8003f1a: 2800 cmp r0, #0 + 8003f1c: d1db bne.n 8003ed6 + if(ae_get_counter(&counter, 0)) return -1; + 8003f1e: a803 add r0, sp, #12 + 8003f20: f7ff fa07 bl 8003332 + 8003f24: 2800 cmp r0, #0 + 8003f26: d1d6 bne.n 8003ed6 + if(lastgood > counter) { + 8003f28: 9a01 ldr r2, [sp, #4] + 8003f2a: 9903 ldr r1, [sp, #12] + match_count &= ~31; + 8003f2c: 9b02 ldr r3, [sp, #8] + if(lastgood > counter) { + 8003f2e: 428a cmp r2, r1 + match_count &= ~31; + 8003f30: f023 031f bic.w r3, r3, #31 + args->num_fails = counter - lastgood; + 8003f34: bf94 ite ls + 8003f36: 1a8a subls r2, r1, r2 + args->num_fails = 99; + 8003f38: 2263 movhi r2, #99 ; 0x63 + if(counter < match_count) { + 8003f3a: 4299 cmp r1, r3 + args->attempts_left = match_count - counter; + 8003f3c: bf34 ite cc + 8003f3e: 1a5b subcc r3, r3, r1 + args->attempts_left = 0; + 8003f40: 2300 movcs r3, #0 + 8003f42: 636a str r2, [r5, #52] ; 0x34 + 8003f44: 63ab str r3, [r5, #56] ; 0x38 + 8003f46: e7c8 b.n 8003eda + +08003f48 : + +// updates_for_good_login() +// + static int +updates_for_good_login(uint8_t digest[32]) +{ + 8003f48: b5f0 push {r4, r5, r6, r7, lr} + 8003f4a: b08d sub sp, #52 ; 0x34 + // User got the main PIN right: update the attempt counters, + // to document this (lastgood) and also bump the match counter if needed + + uint32_t count; + int rv = ae_get_counter(&count, 0); + 8003f4c: 2100 movs r1, #0 +{ + 8003f4e: 4606 mov r6, r0 + int rv = ae_get_counter(&count, 0); + 8003f50: a802 add r0, sp, #8 + 8003f52: f7ff f9ee bl 8003332 + if(rv) goto fail; + 8003f56: 4601 mov r1, r0 + 8003f58: 2800 cmp r0, #0 + 8003f5a: d13b bne.n 8003fd4 + + // Challenge: Have to update both the counter, and the target match value because + // no other way to have exact value. + + uint32_t mc = (count + MAX_TARGET_ATTEMPTS + 32) & ~31; + 8003f5c: 9b02 ldr r3, [sp, #8] + 8003f5e: f103 042d add.w r4, r3, #45 ; 0x2d + 8003f62: f024 041f bic.w r4, r4, #31 + ASSERT(mc >= count); + 8003f66: 42a3 cmp r3, r4 + 8003f68: d902 bls.n 8003f70 + 8003f6a: 481d ldr r0, [pc, #116] ; (8003fe0 ) + 8003f6c: f7fc fd64 bl 8000a38 + + int bump = (mc - MAX_TARGET_ATTEMPTS) - count; + 8003f70: 1ae3 subs r3, r4, r3 + 8003f72: f1a3 050d sub.w r5, r3, #13 + ASSERT(bump >= 1); + 8003f76: 3b0e subs r3, #14 + 8003f78: 2b1f cmp r3, #31 + 8003f7a: d8f6 bhi.n 8003f6a + // Would rather update the counter first, so that a hostile interruption can't increase + // attempts (altho the attacker knows the pin at that point?!) .. but chip won't + // let the counter go past the match value, so that has to be first. + + // set the new "match count" + { uint32_t tmp[32/4] = {mc, mc} ; + 8003f7c: 2218 movs r2, #24 + 8003f7e: eb0d 0002 add.w r0, sp, r2 + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003f82: 2720 movs r7, #32 + { uint32_t tmp[32/4] = {mc, mc} ; + 8003f84: f009 fcce bl 800d924 + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003f88: 2103 movs r1, #3 + 8003f8a: 9700 str r7, [sp, #0] + 8003f8c: ab04 add r3, sp, #16 + 8003f8e: 4632 mov r2, r6 + 8003f90: 2006 movs r0, #6 + { uint32_t tmp[32/4] = {mc, mc} ; + 8003f92: e9cd 4404 strd r4, r4, [sp, #16] + rv = ae_encrypted_write(KEYNUM_match_count, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003f96: f7ff fae1 bl 800355c + if(rv) goto fail; + 8003f9a: 4601 mov r1, r0 + 8003f9c: b9d0 cbnz r0, 8003fd4 + } + + // incr the counter a bunch to get to that-13 + uint32_t new_count = 0; + 8003f9e: 9003 str r0, [sp, #12] + rv = ae_add_counter(&new_count, 0, bump); + 8003fa0: 462a mov r2, r5 + 8003fa2: a803 add r0, sp, #12 + 8003fa4: f7ff f9e4 bl 8003370 + if(rv) goto fail; + 8003fa8: 4601 mov r1, r0 + 8003faa: b998 cbnz r0, 8003fd4 + + ASSERT(new_count == count + bump); + 8003fac: 9b02 ldr r3, [sp, #8] + 8003fae: 441d add r5, r3 + 8003fb0: 9b03 ldr r3, [sp, #12] + 8003fb2: 429d cmp r5, r3 + 8003fb4: d1d9 bne.n 8003f6a + ASSERT(mc > new_count); + 8003fb6: 42a5 cmp r5, r4 + 8003fb8: d2d7 bcs.n 8003f6a + + // Update the "last good" counter + { uint32_t tmp[32/4] = {new_count, 0 }; + 8003fba: 221c movs r2, #28 + 8003fbc: a805 add r0, sp, #20 + 8003fbe: f009 fcb1 bl 800d924 + rv = ae_encrypted_write(KEYNUM_lastgood, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003fc2: 9700 str r7, [sp, #0] + 8003fc4: ab04 add r3, sp, #16 + 8003fc6: 4632 mov r2, r6 + 8003fc8: 2103 movs r1, #3 + 8003fca: 2005 movs r0, #5 + { uint32_t tmp[32/4] = {new_count, 0 }; + 8003fcc: 9504 str r5, [sp, #16] + rv = ae_encrypted_write(KEYNUM_lastgood, KEYNUM_main_pin, digest, (void *)tmp, 32); + 8003fce: f7ff fac5 bl 800355c + if(rv) goto fail; + 8003fd2: b118 cbz r0, 8003fdc + // just be reducing attempts. + + return 0; + +fail: + ae_reset_chip(); + 8003fd4: f7fe fdae bl 8002b34 + return EPIN_AE_FAIL; + 8003fd8: f06f 0069 mvn.w r0, #105 ; 0x69 +} + 8003fdc: b00d add sp, #52 ; 0x34 + 8003fde: bdf0 pop {r4, r5, r6, r7, pc} + 8003fe0: 0801046c .word 0x0801046c + +08003fe4 : +{ + 8003fe4: b5f0 push {r4, r5, r6, r7, lr} + 8003fe6: 4615 mov r5, r2 + 8003fe8: b089 sub sp, #36 ; 0x24 + if(pin_len == 0) { + 8003fea: 460c mov r4, r1 + 8003fec: b931 cbnz r1, 8003ffc + memset(result, 0, 32); + 8003fee: 2220 movs r2, #32 + 8003ff0: 4628 mov r0, r5 + 8003ff2: f009 fc97 bl 800d924 +} + 8003ff6: 4620 mov r0, r4 + 8003ff8: b009 add sp, #36 ; 0x24 + 8003ffa: bdf0 pop {r4, r5, r6, r7, pc} + pin_hash(pin, pin_len, tmp, PIN_PURPOSE_NORMAL); + 8003ffc: 4b0f ldr r3, [pc, #60] ; (800403c ) + 8003ffe: 466a mov r2, sp + 8004000: f7ff fe7a bl 8003cf8 + int rv = ae_stretch_iter(tmp, result, KDF_ITER_PIN); + 8004004: 2208 movs r2, #8 + 8004006: 4629 mov r1, r5 + 8004008: 4668 mov r0, sp + 800400a: f7ff fcbf bl 800398c + if(rv) return EPIN_AE_FAIL; + 800400e: 4604 mov r4, r0 + 8004010: b988 cbnz r0, 8004036 + memcpy(tmp, result, 32); + 8004012: 462b mov r3, r5 + 8004014: 466e mov r6, sp + 8004016: f105 0720 add.w r7, r5, #32 + 800401a: 6818 ldr r0, [r3, #0] + 800401c: 6859 ldr r1, [r3, #4] + 800401e: 4632 mov r2, r6 + 8004020: c203 stmia r2!, {r0, r1} + 8004022: 3308 adds r3, #8 + 8004024: 42bb cmp r3, r7 + 8004026: 4616 mov r6, r2 + 8004028: d1f7 bne.n 800401a + ae_mixin_key(KEYNUM_pin_attempt, tmp, result); + 800402a: 462a mov r2, r5 + 800402c: 4669 mov r1, sp + 800402e: 2004 movs r0, #4 + 8004030: f7ff fcd4 bl 80039dc + return 0; + 8004034: e7df b.n 8003ff6 + if(rv) return EPIN_AE_FAIL; + 8004036: f06f 0469 mvn.w r4, #105 ; 0x69 + 800403a: e7dc b.n 8003ff6 + 800403c: 334d1858 .word 0x334d1858 + +08004040 : +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8004040: b5f0 push {r4, r5, r6, r7, lr} + args->delay_achieved = slot->tc_arg; + 8004042: 88cb ldrh r3, [r1, #6] + 8004044: 62c3 str r3, [r0, #44] ; 0x2c +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8004046: f5ad 7d0d sub.w sp, sp, #564 ; 0x234 + memcpy(key, &args->private_state, sizeof(args->private_state)); + 800404a: 6c03 ldr r3, [r0, #64] ; 0x40 + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 800404c: 4d0f ldr r5, [pc, #60] ; (800408c ) + memcpy(key, &args->private_state, sizeof(args->private_state)); + 800404e: 9303 str r3, [sp, #12] +set_is_trick(pinAttempt_t *args, const trick_slot_t *slot) + 8004050: 4606 mov r6, r0 + 8004052: 460f mov r7, r1 + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8004054: cd0f ldmia r5!, {r0, r1, r2, r3} + 8004056: ac04 add r4, sp, #16 + 8004058: c40f stmia r4!, {r0, r1, r2, r3} + 800405a: e895 0007 ldmia.w r5, {r0, r1, r2} + 800405e: e884 0007 stmia.w r4, {r0, r1, r2} + aes_init(&ctx); + 8004062: a80b add r0, sp, #44 ; 0x2c + 8004064: f004 fb6e bl 8008744 + aes_add(&ctx, (uint8_t *)slot, 32); + 8004068: 4639 mov r1, r7 + 800406a: a80b add r0, sp, #44 ; 0x2c + 800406c: 2220 movs r2, #32 + 800406e: f004 fb6f bl 8008750 + aes_done(&ctx, args->cached_main_pin, 32, key, NULL); + 8004072: 2300 movs r3, #0 + 8004074: 9300 str r3, [sp, #0] + 8004076: 2220 movs r2, #32 + 8004078: ab03 add r3, sp, #12 + 800407a: f106 01f8 add.w r1, r6, #248 ; 0xf8 + 800407e: a80b add r0, sp, #44 ; 0x2c + 8004080: f004 fb7c bl 800877c +} + 8004084: f50d 7d0d add.w sp, sp, #564 ; 0x234 + 8004088: bdf0 pop {r4, r5, r6, r7, pc} + 800408a: bf00 nop + 800408c: 0801c074 .word 0x0801c074 + +08004090 : + __HAL_RCC_CRC_CLK_ENABLE(); + 8004090: 4b09 ldr r3, [pc, #36] ; (80040b8 ) + 8004092: 6c9a ldr r2, [r3, #72] ; 0x48 +{ + 8004094: b513 push {r0, r1, r4, lr} + __HAL_RCC_CRC_CLK_ENABLE(); + 8004096: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 800409a: 649a str r2, [r3, #72] ; 0x48 + 800409c: 6c9b ldr r3, [r3, #72] ; 0x48 + CRC->INIT = rng_sample(); + 800409e: 4c07 ldr r4, [pc, #28] ; (80040bc ) + __HAL_RCC_CRC_CLK_ENABLE(); + 80040a0: f403 5380 and.w r3, r3, #4096 ; 0x1000 + 80040a4: 9301 str r3, [sp, #4] + 80040a6: 9b01 ldr r3, [sp, #4] + CRC->INIT = rng_sample(); + 80040a8: f7fe fbda bl 8002860 + 80040ac: 6120 str r0, [r4, #16] + CRC->POL = rng_sample(); + 80040ae: f7fe fbd7 bl 8002860 + 80040b2: 6160 str r0, [r4, #20] +} + 80040b4: b002 add sp, #8 + 80040b6: bd10 pop {r4, pc} + 80040b8: 40021000 .word 0x40021000 + 80040bc: 40023000 .word 0x40023000 + +080040c0 : +{ + 80040c0: b510 push {r4, lr} + 80040c2: b094 sub sp, #80 ; 0x50 + 80040c4: 4604 mov r4, r0 + sha256_init(&ctx); + 80040c6: a801 add r0, sp, #4 + 80040c8: f001 fb58 bl 800577c + reboot_nonce(&ctx); + 80040cc: a801 add r0, sp, #4 + 80040ce: f7ff fdfd bl 8003ccc + sha256_update(&ctx, rom_secrets->hash_cache_secret, 32); + 80040d2: 2220 movs r2, #32 + 80040d4: a801 add r0, sp, #4 + 80040d6: 4904 ldr r1, [pc, #16] ; (80040e8 ) + 80040d8: f001 fb5e bl 8005798 + sha256_final(&ctx, key); + 80040dc: 4621 mov r1, r4 + 80040de: a801 add r0, sp, #4 + 80040e0: f001 fba0 bl 8005824 +} + 80040e4: b014 add sp, #80 ; 0x50 + 80040e6: bd10 pop {r4, pc} + 80040e8: 0801c070 .word 0x0801c070 + +080040ec : +{ + 80040ec: b530 push {r4, r5, lr} + 80040ee: 460d mov r5, r1 + 80040f0: b089 sub sp, #36 ; 0x24 + 80040f2: 4604 mov r4, r0 + if(!check_all_zeros(digest, 32)) { + 80040f4: 2120 movs r1, #32 + 80040f6: 4628 mov r0, r5 + 80040f8: f7fe fb92 bl 8002820 + 80040fc: b9a0 cbnz r0, 8004128 + pin_cache_get_key(value); + 80040fe: 4668 mov r0, sp + 8004100: f7ff ffde bl 80040c0 + 8004104: 466b mov r3, sp + 8004106: f105 0120 add.w r1, r5, #32 + *(acc) ^= *(more); + 800410a: 781a ldrb r2, [r3, #0] + 800410c: f815 0b01 ldrb.w r0, [r5], #1 + 8004110: 4042 eors r2, r0 + for(; len; len--, more++, acc++) { + 8004112: 428d cmp r5, r1 + *(acc) ^= *(more); + 8004114: f803 2b01 strb.w r2, [r3], #1 + for(; len; len--, more++, acc++) { + 8004118: d1f7 bne.n 800410a + ASSERT(args->magic_value == PA_MAGIC_V2); + 800411a: 6822 ldr r2, [r4, #0] + 800411c: 4b0d ldr r3, [pc, #52] ; (8004154 ) + 800411e: 429a cmp r2, r3 + 8004120: d008 beq.n 8004134 + 8004122: 480d ldr r0, [pc, #52] ; (8004158 ) + 8004124: f7fc fc88 bl 8000a38 + memset(value, 0, 32); + 8004128: 2220 movs r2, #32 + 800412a: 2100 movs r1, #0 + 800412c: 4668 mov r0, sp + 800412e: f009 fbf9 bl 800d924 + 8004132: e7f2 b.n 800411a + memcpy(args->cached_main_pin, value, 32); + 8004134: 466b mov r3, sp + 8004136: f104 02f8 add.w r2, r4, #248 ; 0xf8 + 800413a: ad08 add r5, sp, #32 + 800413c: 461c mov r4, r3 + 800413e: cc03 ldmia r4!, {r0, r1} + 8004140: 42ac cmp r4, r5 + 8004142: 6010 str r0, [r2, #0] + 8004144: 6051 str r1, [r2, #4] + 8004146: 4623 mov r3, r4 + 8004148: f102 0208 add.w r2, r2, #8 + 800414c: d1f6 bne.n 800413c +} + 800414e: b009 add sp, #36 ; 0x24 + 8004150: bd30 pop {r4, r5, pc} + 8004152: bf00 nop + 8004154: 2eaf6312 .word 0x2eaf6312 + 8004158: 0801046c .word 0x0801046c + +0800415c : +{ + 800415c: b510 push {r4, lr} + ASSERT(args->magic_value == PA_MAGIC_V2); + 800415e: 6802 ldr r2, [r0, #0] + 8004160: 4b14 ldr r3, [pc, #80] ; (80041b4 ) + 8004162: 429a cmp r2, r3 +{ + 8004164: b088 sub sp, #32 + 8004166: 460c mov r4, r1 + ASSERT(args->magic_value == PA_MAGIC_V2); + 8004168: d002 beq.n 8004170 + 800416a: 4813 ldr r0, [pc, #76] ; (80041b8 ) + 800416c: f7fc fc64 bl 8000a38 + memcpy(digest, args->cached_main_pin, 32); + 8004170: f100 03f8 add.w r3, r0, #248 ; 0xf8 + 8004174: 460a mov r2, r1 + 8004176: f500 708c add.w r0, r0, #280 ; 0x118 + 800417a: f853 1b04 ldr.w r1, [r3], #4 + 800417e: f842 1b04 str.w r1, [r2], #4 + 8004182: 4283 cmp r3, r0 + 8004184: d1f9 bne.n 800417a + if(!check_all_zeros(digest, 32)) { + 8004186: 2120 movs r1, #32 + 8004188: 4620 mov r0, r4 + 800418a: f7fe fb49 bl 8002820 + 800418e: b970 cbnz r0, 80041ae + pin_cache_get_key(key); + 8004190: 4668 mov r0, sp + 8004192: f7ff ff95 bl 80040c0 + 8004196: 1e62 subs r2, r4, #1 + 8004198: 466b mov r3, sp + 800419a: 341f adds r4, #31 + *(acc) ^= *(more); + 800419c: f812 1f01 ldrb.w r1, [r2, #1]! + 80041a0: f813 0b01 ldrb.w r0, [r3], #1 + for(; len; len--, more++, acc++) { + 80041a4: 42a2 cmp r2, r4 + *(acc) ^= *(more); + 80041a6: ea81 0100 eor.w r1, r1, r0 + 80041aa: 7011 strb r1, [r2, #0] + for(; len; len--, more++, acc++) { + 80041ac: d1f6 bne.n 800419c +} + 80041ae: b008 add sp, #32 + 80041b0: bd10 pop {r4, pc} + 80041b2: bf00 nop + 80041b4: 2eaf6312 .word 0x2eaf6312 + 80041b8: 0801046c .word 0x0801046c + +080041bc : +{ + 80041bc: b530 push {r4, r5, lr} + 80041be: b091 sub sp, #68 ; 0x44 + pin_hash(pin_prefix, prefix_len, tmp, PIN_PURPOSE_WORDS); + 80041c0: 4b0b ldr r3, [pc, #44] ; (80041f0 ) +{ + 80041c2: 4615 mov r5, r2 + pin_hash(pin_prefix, prefix_len, tmp, PIN_PURPOSE_WORDS); + 80041c4: 466a mov r2, sp + 80041c6: f7ff fd97 bl 8003cf8 + ae_setup(); + 80041ca: f7fe fcc1 bl 8002b50 + int rv = ae_stretch_iter(tmp, digest, KDF_ITER_WORDS); + 80041ce: 2206 movs r2, #6 + 80041d0: a908 add r1, sp, #32 + 80041d2: 4668 mov r0, sp + 80041d4: f7ff fbda bl 800398c + 80041d8: 4604 mov r4, r0 + ae_reset_chip(); + 80041da: f7fe fcab bl 8002b34 + if(rv) return -1; + 80041de: b924 cbnz r4, 80041ea + memcpy(result, digest, 4); + 80041e0: 9b08 ldr r3, [sp, #32] + 80041e2: 602b str r3, [r5, #0] +} + 80041e4: 4620 mov r0, r4 + 80041e6: b011 add sp, #68 ; 0x44 + 80041e8: bd30 pop {r4, r5, pc} + if(rv) return -1; + 80041ea: f04f 34ff mov.w r4, #4294967295 ; 0xffffffff + 80041ee: e7f9 b.n 80041e4 + 80041f0: 2e6d6773 .word 0x2e6d6773 + +080041f4 : +} + 80041f4: 2000 movs r0, #0 + 80041f6: 4770 bx lr + +080041f8 : +{ + 80041f8: b5f0 push {r4, r5, r6, r7, lr} + int rv = _validate_attempt(args, true); + 80041fa: 2101 movs r1, #1 +{ + 80041fc: b091 sub sp, #68 ; 0x44 + 80041fe: 4605 mov r5, r0 + int rv = _validate_attempt(args, true); + 8004200: f7ff fde6 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 8004204: 4604 mov r4, r0 + 8004206: bb28 cbnz r0, 8004254 + if(args->is_secondary) { + 8004208: 686b ldr r3, [r5, #4] + 800420a: 2b00 cmp r3, #0 + 800420c: d158 bne.n 80042c0 + int pin_len = args->pin_len; + 800420e: 6aaf ldr r7, [r5, #40] ; 0x28 + memcpy(pin_copy, args->pin, pin_len); + 8004210: f105 0608 add.w r6, r5, #8 + 8004214: 463a mov r2, r7 + 8004216: 4631 mov r1, r6 + 8004218: 4668 mov r0, sp + 800421a: f009 fb75 bl 800d908 + memset(args, 0, PIN_ATTEMPT_SIZE_V2); + 800421e: f44f 728c mov.w r2, #280 ; 0x118 + 8004222: 4621 mov r1, r4 + 8004224: 4628 mov r0, r5 + 8004226: f009 fb7d bl 800d924 + args->magic_value = PA_MAGIC_V2; + 800422a: 4b28 ldr r3, [pc, #160] ; (80042cc ) + 800422c: 602b str r3, [r5, #0] + memcpy(args->pin, pin_copy, pin_len); + 800422e: 463a mov r2, r7 + 8004230: 4669 mov r1, sp + args->pin_len = pin_len; + 8004232: 62af str r7, [r5, #40] ; 0x28 + memcpy(args->pin, pin_copy, pin_len); + 8004234: 4630 mov r0, r6 + 8004236: f009 fb67 bl 800d908 + if(warmup_ae()) { + 800423a: f7ff fdff bl 8003e3c + 800423e: 2800 cmp r0, #0 + 8004240: d141 bne.n 80042c6 + if(get_last_success(args)) { + 8004242: 4628 mov r0, r5 + 8004244: f7ff fe37 bl 8003eb6 + 8004248: 4604 mov r4, r0 + 800424a: b130 cbz r0, 800425a + ae_reset_chip(); + 800424c: f7fe fc72 bl 8002b34 + return EPIN_AE_FAIL; + 8004250: f06f 0469 mvn.w r4, #105 ; 0x69 +} + 8004254: 4620 mov r0, r4 + 8004256: b011 add sp, #68 ; 0x44 + 8004258: bdf0 pop {r4, r5, r6, r7, pc} + uint8_t blank[32] = {0}; + 800425a: 4601 mov r1, r0 + 800425c: 221c movs r2, #28 + args->delay_achieved = 0; + 800425e: e9c5 000b strd r0, r0, [r5, #44] ; 0x2c + uint8_t blank[32] = {0}; + 8004262: 9008 str r0, [sp, #32] + 8004264: a809 add r0, sp, #36 ; 0x24 + 8004266: f009 fb5d bl 800d924 + ae_reset_chip(); + 800426a: f7fe fc63 bl 8002b34 + ae_pair_unlock(); + 800426e: f7fe fe65 bl 8002f3c + int is_blank = (ae_checkmac_hard(keynum, blank) == 0); + 8004272: a908 add r1, sp, #32 + 8004274: 2003 movs r0, #3 + 8004276: f7fe ffef bl 8003258 + 800427a: 4606 mov r6, r0 + ae_reset_chip(); + 800427c: f7fe fc5a bl 8002b34 + if(pin_is_blank(KEYNUM_main_pin)) { + 8004280: b9c6 cbnz r6, 80042b4 + args->state_flags |= PA_SUCCESSFUL | PA_IS_BLANK; + 8004282: 6beb ldr r3, [r5, #60] ; 0x3c + const uint8_t zeros[32] = {0}; + 8004284: 9408 str r4, [sp, #32] + args->state_flags |= PA_SUCCESSFUL | PA_IS_BLANK; + 8004286: f043 0303 orr.w r3, r3, #3 + 800428a: 63eb str r3, [r5, #60] ; 0x3c + const uint8_t zeros[32] = {0}; + 800428c: 221c movs r2, #28 + 800428e: 4621 mov r1, r4 + 8004290: a809 add r0, sp, #36 ; 0x24 + 8004292: f009 fb47 bl 800d924 + pin_cache_save(args, zeros); + 8004296: a908 add r1, sp, #32 + 8004298: 4628 mov r0, r5 + 800429a: f7ff ff27 bl 80040ec + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 800429e: f7fe fadf bl 8002860 + 80042a2: 4b0b ldr r3, [pc, #44] ; (80042d0 ) + 80042a4: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80042a8: f020 0001 bic.w r0, r0, #1 + args->delay_achieved = 0; + 80042ac: e9c5 440b strd r4, r4, [r5, #44] ; 0x2c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 80042b0: 4058 eors r0, r3 + 80042b2: 6428 str r0, [r5, #64] ; 0x40 + _hmac_attempt(args, args->hmac); + 80042b4: f105 0144 add.w r1, r5, #68 ; 0x44 + 80042b8: 4628 mov r0, r5 + 80042ba: f7ff fd5b bl 8003d74 <_hmac_attempt> +} + 80042be: e7c9 b.n 8004254 + return EPIN_PRIMARY_ONLY; + 80042c0: f06f 0471 mvn.w r4, #113 ; 0x71 + 80042c4: e7c6 b.n 8004254 + return EPIN_I_AM_BRICK; + 80042c6: f06f 0468 mvn.w r4, #104 ; 0x68 + 80042ca: e7c3 b.n 8004254 + 80042cc: 2eaf6312 .word 0x2eaf6312 + 80042d0: 0801c000 .word 0x0801c000 + +080042d4 : +} + 80042d4: 2000 movs r0, #0 + 80042d6: 4770 bx lr + +080042d8 : +// +// Do the PIN check, and return a value. Or fail. +// + int +pin_login_attempt(pinAttempt_t *args) +{ + 80042d8: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + bool deltamode = false; + char tmp_pin[32]; + + int rv = _validate_attempt(args, false); + 80042dc: 2100 movs r1, #0 +{ + 80042de: b0c7 sub sp, #284 ; 0x11c + 80042e0: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 80042e2: f7ff fd75 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 80042e6: 4605 mov r5, r0 + 80042e8: 2800 cmp r0, #0 + 80042ea: d179 bne.n 80043e0 + + if(args->state_flags & PA_SUCCESSFUL) { + 80042ec: 6be3 ldr r3, [r4, #60] ; 0x3c + 80042ee: 07d9 lsls r1, r3, #31 + 80042f0: f100 80c5 bmi.w 800447e + } + + // Mk4: Check SE2 first to see if this is a "trick" pin. + // - this call may have side-effects, like wiping keys, bricking, etc. + trick_slot_t slot; + bool is_trick = se2_test_trick_pin(args->pin, args->pin_len, &slot, false); + 80042f4: f104 0808 add.w r8, r4, #8 + 80042f8: 4603 mov r3, r0 + 80042fa: 6aa1 ldr r1, [r4, #40] ; 0x28 + 80042fc: aa26 add r2, sp, #152 ; 0x98 + 80042fe: 4640 mov r0, r8 + 8004300: f003 ff02 bl 8008108 + + if(is_trick) { + 8004304: 4606 mov r6, r0 + 8004306: 2800 cmp r0, #0 + 8004308: d04b beq.n 80043a2 + // Mark as success + args->state_flags = PA_SUCCESSFUL; + args->num_fails = 0; + args->attempts_left = MAX_TARGET_ATTEMPTS; + + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 800430a: f9bd 209c ldrsh.w r2, [sp, #156] ; 0x9c + args->num_fails = 0; + 800430e: 6365 str r5, [r4, #52] ; 0x34 + args->state_flags = PA_SUCCESSFUL; + 8004310: 2301 movs r3, #1 + 8004312: 63e3 str r3, [r4, #60] ; 0x3c + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 8004314: 2a00 cmp r2, #0 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 8004316: f04f 030d mov.w r3, #13 + 800431a: 63a3 str r3, [r4, #56] ; 0x38 + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 800431c: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + 8004320: da4f bge.n 80043c2 + 8004322: f413 5fc0 tst.w r3, #6144 ; 0x1800 + 8004326: bf0c ite eq + 8004328: 2701 moveq r7, #1 + 800432a: 2700 movne r7, #0 + if(check_all_zeros(slot.xdata, 32) || wipe) { + 800432c: 2120 movs r1, #32 + 800432e: a828 add r0, sp, #160 ; 0xa0 + 8004330: f7fe fa76 bl 8002820 + 8004334: b900 cbnz r0, 8004338 + 8004336: b11f cbz r7, 8004340 + args->state_flags |= PA_ZERO_SECRET; + 8004338: 6be3 ldr r3, [r4, #60] ; 0x3c + 800433a: f043 0310 orr.w r3, r3, #16 + 800433e: 63e3 str r3, [r4, #60] ; 0x3c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8004340: f7fe fa8e bl 8002860 + 8004344: 4b51 ldr r3, [pc, #324] ; (800448c ) + 8004346: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 800434a: f040 0001 orr.w r0, r0, #1 + 800434e: 4058 eors r0, r3 + args->delay_required = (slot->tc_flags & ~TC_HIDDEN_MASK); + 8004350: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8004354: 6420 str r0, [r4, #64] ; 0x40 + args->delay_required = (slot->tc_flags & ~TC_HIDDEN_MASK); + 8004356: f423 4278 bic.w r2, r3, #63488 ; 0xf800 + 800435a: 6322 str r2, [r4, #48] ; 0x30 + if(slot->tc_flags & TC_DELTA_MODE) { + 800435c: 055a lsls r2, r3, #21 + 800435e: d532 bpl.n 80043c6 + args->delay_achieved = 0; + 8004360: 2300 movs r3, #0 + 8004362: 62e3 str r3, [r4, #44] ; 0x2c + memcpy(tmp_pin, pin, pin_len); + 8004364: 6aa7 ldr r7, [r4, #40] ; 0x28 + // Thug gave wrong PIN, but we are going to let them + // past (by calculating correct PIN, up to 4 digits different), + // and the mpy firmware can do tricky stuff to protect funds + // even though the private key is known at that point. + deltamode = true; + apply_pin_delta(args->pin, args->pin_len, slot.tc_arg, tmp_pin); + 8004366: f8bd 909e ldrh.w r9, [sp, #158] ; 0x9e + memcpy(tmp_pin, pin, pin_len); + 800436a: ab04 add r3, sp, #16 + 800436c: 463a mov r2, r7 + 800436e: 4641 mov r1, r8 + 8004370: 4618 mov r0, r3 + 8004372: f009 fac9 bl 800d908 + tmp_pin[pin_len] = 0; + 8004376: 2200 movs r2, #0 + 8004378: 55c2 strb r2, [r0, r7] + char *p = &tmp_pin[pin_len-1]; + 800437a: 1e7a subs r2, r7, #1 + 800437c: 4402 add r2, r0 + 800437e: 2104 movs r1, #4 + if(*p == '-') p--; + 8004380: 7813 ldrb r3, [r2, #0] + 8004382: 2b2d cmp r3, #45 ; 0x2d + 8004384: f009 030f and.w r3, r9, #15 + 8004388: bf08 it eq + 800438a: f102 32ff addeq.w r2, r2, #4294967295 ; 0xffffffff + if((here >= 0) && (here <= 9)) { + 800438e: 2b09 cmp r3, #9 + *p = '0' + here; + 8004390: bf9c itt ls + 8004392: 3330 addls r3, #48 ; 0x30 + 8004394: 7013 strbls r3, [r2, #0] + for(int i=0; i<4; i++, p--) { + 8004396: 3901 subs r1, #1 + replacement >>= 4; + 8004398: ea4f 1919 mov.w r9, r9, lsr #4 + for(int i=0; i<4; i++, p--) { + 800439c: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 80043a0: d1ee bne.n 8004380 + return 0; + } + +real_login: + // unlock the AE chip + if(warmup_ae()) return EPIN_I_AM_BRICK; + 80043a2: f7ff fd4b bl 8003e3c + 80043a6: 2800 cmp r0, #0 + 80043a8: d16c bne.n 8004484 + + // hash up the pin now, assuming we'll use it on main PIN + uint8_t digest[32]; + rv = pin_hash_attempt(deltamode ? tmp_pin : args->pin, args->pin_len, digest); + 80043aa: b10e cbz r6, 80043b0 + 80043ac: f10d 0810 add.w r8, sp, #16 + 80043b0: 6aa1 ldr r1, [r4, #40] ; 0x28 + 80043b2: aa0c add r2, sp, #48 ; 0x30 + 80043b4: 4640 mov r0, r8 + 80043b6: f7ff fe15 bl 8003fe4 + if(rv) return EPIN_AE_FAIL; + 80043ba: b1a8 cbz r0, 80043e8 + + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + if(rv) { + ae_reset_chip(); + + return EPIN_AE_FAIL; + 80043bc: f06f 0569 mvn.w r5, #105 ; 0x69 + 80043c0: e00e b.n 80043e0 + bool wipe = (slot.tc_flags & TC_WIPE) && !(slot.tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)); + 80043c2: 462f mov r7, r5 + 80043c4: e7b2 b.n 800432c + 80043c6: a926 add r1, sp, #152 ; 0x98 + 80043c8: 4620 mov r0, r4 + 80043ca: f7ff fe39 bl 8004040 + if(slot.tc_flags & TC_DELTA_MODE) { + 80043ce: f8bd 309c ldrh.w r3, [sp, #156] ; 0x9c + 80043d2: 055b lsls r3, r3, #21 + 80043d4: d4c6 bmi.n 8004364 + _hmac_attempt(args, args->hmac); + 80043d6: f104 0144 add.w r1, r4, #68 ; 0x44 + 80043da: 4620 mov r0, r4 + 80043dc: f7ff fcca bl 8003d74 <_hmac_attempt> + } + + _sign_attempt(args); + + return 0; +} + 80043e0: 4628 mov r0, r5 + 80043e2: b047 add sp, #284 ; 0x11c + 80043e4: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + ae_reset_chip(); + 80043e8: f7fe fba4 bl 8002b34 + ae_pair_unlock(); + 80043ec: f7fe fda6 bl 8002f3c + return (ae_checkmac_hard(KEYNUM_main_pin, digest) == 0); + 80043f0: a90c add r1, sp, #48 ; 0x30 + 80043f2: 2003 movs r0, #3 + 80043f4: f7fe ff30 bl 8003258 + if(!is_main_pin(digest)) { + 80043f8: b130 cbz r0, 8004408 + se2_handle_bad_pin(args->num_fails + 1); + 80043fa: 6b60 ldr r0, [r4, #52] ; 0x34 + 80043fc: 3001 adds r0, #1 + 80043fe: f003 ff5f bl 80082c0 + return EPIN_AUTH_FAIL; + 8004402: f06f 056f mvn.w r5, #111 ; 0x6f + 8004406: e7eb b.n 80043e0 + rv = updates_for_good_login(digest); + 8004408: a80c add r0, sp, #48 ; 0x30 + 800440a: f7ff fd9d bl 8003f48 + if(rv) return EPIN_AE_FAIL; + 800440e: 4607 mov r7, r0 + 8004410: 2800 cmp r0, #0 + 8004412: d1d3 bne.n 80043bc + pin_cache_save(args, digest); + 8004414: a90c add r1, sp, #48 ; 0x30 + 8004416: 4620 mov r0, r4 + 8004418: f7ff fe68 bl 80040ec + args->state_flags = PA_SUCCESSFUL; + 800441c: 2301 movs r3, #1 + 800441e: 63e3 str r3, [r4, #60] ; 0x3c + args->num_fails = 0; + 8004420: 6367 str r7, [r4, #52] ; 0x34 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 8004422: 230d movs r3, #13 + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + 8004424: 2748 movs r7, #72 ; 0x48 + args->attempts_left = MAX_TARGET_ATTEMPTS; + 8004426: 63a3 str r3, [r4, #56] ; 0x38 + rv = ae_encrypted_read(KEYNUM_secret, KEYNUM_main_pin, digest, ts, AE_SECRET_LEN); + 8004428: 9700 str r7, [sp, #0] + 800442a: ab14 add r3, sp, #80 ; 0x50 + 800442c: aa0c add r2, sp, #48 ; 0x30 + 800442e: 2103 movs r1, #3 + 8004430: 2009 movs r0, #9 + 8004432: f7fe fff3 bl 800341c + if(rv) { + 8004436: b110 cbz r0, 800443e + ae_reset_chip(); + 8004438: f7fe fb7c bl 8002b34 + 800443c: e7be b.n 80043bc + ae_reset_chip(); + 800443e: f7fe fb79 bl 8002b34 + mcu_key_get(&mcu_key_valid); + 8004442: f10d 000f add.w r0, sp, #15 + 8004446: f7fe f8ad bl 80025a4 + if(check_all_zeros(ts, AE_SECRET_LEN) || !mcu_key_valid) { + 800444a: 4639 mov r1, r7 + 800444c: a814 add r0, sp, #80 ; 0x50 + 800444e: f7fe f9e7 bl 8002820 + 8004452: b910 cbnz r0, 800445a + 8004454: f89d 300f ldrb.w r3, [sp, #15] + 8004458: b91b cbnz r3, 8004462 + args->state_flags |= PA_ZERO_SECRET; + 800445a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800445c: f043 0310 orr.w r3, r3, #16 + 8004460: 63e3 str r3, [r4, #60] ; 0x3c + if(!deltamode) { + 8004462: 2e00 cmp r6, #0 + 8004464: d1b7 bne.n 80043d6 + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 8004466: f7fe f9fb bl 8002860 + 800446a: 4b08 ldr r3, [pc, #32] ; (800448c ) + 800446c: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8004470: f020 0001 bic.w r0, r0, #1 + 8004474: 4058 eors r0, r3 + args->delay_achieved = 0; + 8004476: e9c4 660b strd r6, r6, [r4, #44] ; 0x2c + args->private_state = ((rng_sample() & ~1) | is_trick_pin) ^ rom_secrets->hash_cache_secret[0]; + 800447a: 6420 str r0, [r4, #64] ; 0x40 + return; + 800447c: e7ab b.n 80043d6 + return EPIN_WRONG_SUCCESS; + 800447e: f06f 056c mvn.w r5, #108 ; 0x6c + 8004482: e7ad b.n 80043e0 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004484: f06f 0568 mvn.w r5, #104 ; 0x68 + 8004488: e7aa b.n 80043e0 + 800448a: bf00 nop + 800448c: 0801c000 .word 0x0801c000 + +08004490 : +// +// Verify we know the main PIN, but don't do anything with it. +// + int +pin_check_logged_in(const pinAttempt_t *args, bool *is_trick) +{ + 8004490: b570 push {r4, r5, r6, lr} + 8004492: 460e mov r6, r1 + 8004494: b088 sub sp, #32 + int rv = _validate_attempt(args, false); + 8004496: 2100 movs r1, #0 +{ + 8004498: 4605 mov r5, r0 + int rv = _validate_attempt(args, false); + 800449a: f7ff fc99 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 800449e: 4604 mov r4, r0 + 80044a0: b980 cbnz r0, 80044c4 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80044a2: 6beb ldr r3, [r5, #60] ; 0x3c + 80044a4: 07da lsls r2, r3, #31 + 80044a6: d520 bpl.n 80044ea + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 80044a8: 4b11 ldr r3, [pc, #68] ; (80044f0 ) + 80044aa: 6c2a ldr r2, [r5, #64] ; 0x40 + 80044ac: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80044b0: 4053 eors r3, r2 + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(get_is_trick(args, NULL)) { + 80044b2: 07db lsls r3, r3, #31 + 80044b4: d509 bpl.n 80044ca + // they used a trick pin to get this far. Amuse them more. + *is_trick = true; + 80044b6: 2301 movs r3, #1 + 80044b8: 7033 strb r3, [r6, #0] + + // should calibrate this, but smart money will just look at the bus + delay_ms(10); + 80044ba: 200a movs r0, #10 + 80044bc: f7ff fae2 bl 8003a84 + rng_delay(); + 80044c0: f7fe fa22 bl 8002908 + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + if(rv) return EPIN_AUTH_FAIL; + } + + return 0; +} + 80044c4: 4620 mov r0, r4 + 80044c6: b008 add sp, #32 + 80044c8: bd70 pop {r4, r5, r6, pc} + pin_cache_restore(args, auth_digest); + 80044ca: 4669 mov r1, sp + *is_trick = false; + 80044cc: 7030 strb r0, [r6, #0] + pin_cache_restore(args, auth_digest); + 80044ce: 4628 mov r0, r5 + 80044d0: f7ff fe44 bl 800415c + ae_pair_unlock(); + 80044d4: f7fe fd32 bl 8002f3c + int rv = ae_checkmac(KEYNUM_main_pin, auth_digest); + 80044d8: 4669 mov r1, sp + 80044da: 2003 movs r0, #3 + 80044dc: f7fe fcac bl 8002e38 + if(rv) return EPIN_AUTH_FAIL; + 80044e0: 1e04 subs r4, r0, #0 + 80044e2: bf18 it ne + 80044e4: f06f 046f mvnne.w r4, #111 ; 0x6f + 80044e8: e7ec b.n 80044c4 + return EPIN_WRONG_SUCCESS; + 80044ea: f06f 046c mvn.w r4, #108 ; 0x6c + 80044ee: e7e9 b.n 80044c4 + 80044f0: 0801c000 .word 0x0801c000 + +080044f4 : +// +// Change the PIN and/or the secret. (Must also know the previous value, or it must be blank) +// + int +pin_change(pinAttempt_t *args) +{ + 80044f4: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 80044f8: 2100 movs r1, #0 +{ + 80044fa: b0a4 sub sp, #144 ; 0x90 + 80044fc: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 80044fe: f7ff fc67 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 8004502: 4605 mov r5, r0 + 8004504: 2800 cmp r0, #0 + 8004506: f040 8094 bne.w 8004632 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 800450a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800450c: 07d9 lsls r1, r3, #31 + 800450e: f140 809c bpl.w 800464a + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(args->state_flags & PA_IS_BLANK) { + 8004512: 079a lsls r2, r3, #30 + 8004514: d502 bpl.n 800451c + // if blank, must provide blank value + if(args->pin_len) return EPIN_RANGE_ERR; + 8004516: 6aa3 ldr r3, [r4, #40] ; 0x28 + 8004518: 2b00 cmp r3, #0 + 800451a: d158 bne.n 80045ce + } + + // Look at change flags. + const uint32_t cf = args->change_flags; + + ASSERT(!args->is_secondary); + 800451c: 6863 ldr r3, [r4, #4] + const uint32_t cf = args->change_flags; + 800451e: f8d4 9064 ldr.w r9, [r4, #100] ; 0x64 + ASSERT(!args->is_secondary); + 8004522: b113 cbz r3, 800452a + 8004524: 484c ldr r0, [pc, #304] ; (8004658 ) + 8004526: f7fc fa87 bl 8000a38 + if(cf & CHANGE_SECONDARY_WALLET_PIN) { + // obsolete secondary support, can't support. + return EPIN_BAD_REQUEST; + } + if(cf & (CHANGE_DURESS_PIN | CHANGE_DURESS_SECRET | CHANGE_BRICKME_PIN)) { + 800452a: f019 0f36 tst.w r9, #54 ; 0x36 + 800452e: d10b bne.n 8004548 + // we need some new API for trick PIN lookup/changes. + return EPIN_BAD_REQUEST; + } + if(!(cf & (CHANGE_WALLET_PIN | CHANGE_SECRET))) { + 8004530: f019 0f09 tst.w r9, #9 + 8004534: d04b beq.n 80045ce + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004536: 4b49 ldr r3, [pc, #292] ; (800465c ) + 8004538: 6c22 ldr r2, [r4, #64] ; 0x40 + 800453a: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 800453e: 4053 eors r3, r2 + // If they authorized w/ a trick PIN, new policy is to wipe ourselves if + // they try to change PIN code or the secret. + // - it's hard to fake them out here, and they may be onto us. + // - this protects the seed, but does end the game somewhat + // - all trick PINs will still be in effect, and looks like random reset + if(get_is_trick(args, NULL)) { + 8004540: 07db lsls r3, r3, #31 + 8004542: d504 bpl.n 800454e + // User is a thug.. kill secret and reboot w/o any notice + fast_wipe(); + 8004544: f7fe f940 bl 80027c8 + return EPIN_BAD_REQUEST; + 8004548: f06f 0567 mvn.w r5, #103 ; 0x67 + 800454c: e071 b.n 8004632 + // NOT-REACHED + return EPIN_BAD_REQUEST; + } + + // unlock the AE chip + if(warmup_ae()) return EPIN_I_AM_BRICK; + 800454e: f7ff fc75 bl 8003e3c + 8004552: 4605 mov r5, r0 + 8004554: 2800 cmp r0, #0 + 8004556: d17b bne.n 8004650 + // If they tricked us to get to this point, doesn't matter as + // below SE1 validates it all again. + + // Restore cached version of PIN digest: fast + uint8_t required_digest[32]; + pin_cache_restore(args, required_digest); + 8004558: f10d 0808 add.w r8, sp, #8 + 800455c: 4641 mov r1, r8 + 800455e: 4620 mov r0, r4 + 8004560: f7ff fdfc bl 800415c + + // Calculate new PIN hashed value: will be slow to do + if(cf & CHANGE_WALLET_PIN) { + 8004564: f019 0f01 tst.w r9, #1 + 8004568: d021 beq.n 80045ae + uint8_t new_digest[32]; + rv = pin_hash_attempt(args->new_pin, args->new_pin_len, new_digest); + 800456a: f8d4 10ac ldr.w r1, [r4, #172] ; 0xac + 800456e: aa12 add r2, sp, #72 ; 0x48 + 8004570: f104 008c add.w r0, r4, #140 ; 0x8c + 8004574: f7ff fd36 bl 8003fe4 + if(rv) goto ae_fail; + 8004578: 2800 cmp r0, #0 + 800457a: d161 bne.n 8004640 + + if(ae_encrypted_write(KEYNUM_main_pin, KEYNUM_main_pin, required_digest, new_digest, 32)) { + 800457c: 2320 movs r3, #32 + 800457e: 2103 movs r1, #3 + 8004580: 9300 str r3, [sp, #0] + 8004582: 4642 mov r2, r8 + 8004584: ab12 add r3, sp, #72 ; 0x48 + 8004586: 4608 mov r0, r1 + 8004588: f7fe ffe8 bl 800355c + 800458c: 2800 cmp r0, #0 + 800458e: d157 bne.n 8004640 + goto ae_fail; + } + + memcpy(required_digest, new_digest, 32); + 8004590: af12 add r7, sp, #72 ; 0x48 + 8004592: cf0f ldmia r7!, {r0, r1, r2, r3} + 8004594: 4646 mov r6, r8 + 8004596: c60f stmia r6!, {r0, r1, r2, r3} + 8004598: e897 000f ldmia.w r7, {r0, r1, r2, r3} + 800459c: e886 000f stmia.w r6, {r0, r1, r2, r3} + + // main pin is changing; reset counter to zero (good login) and our cache + pin_cache_save(args, new_digest); + 80045a0: 4620 mov r0, r4 + 80045a2: a912 add r1, sp, #72 ; 0x48 + 80045a4: f7ff fda2 bl 80040ec + + updates_for_good_login(new_digest); + 80045a8: a812 add r0, sp, #72 ; 0x48 + 80045aa: f7ff fccd bl 8003f48 + } + + // Recording new secret. + // Note the required_digest might have just changed above. + if(cf & CHANGE_SECRET) { + 80045ae: f019 0f08 tst.w r9, #8 + 80045b2: d037 beq.n 8004624 + int which = (args->change_flags >> 8) & 0xf; + 80045b4: 6e63 ldr r3, [r4, #100] ; 0x64 + 80045b6: 121b asrs r3, r3, #8 + switch(which) { + 80045b8: f013 020c ands.w r2, r3, #12 + 80045bc: d107 bne.n 80045ce + 80045be: 4928 ldr r1, [pc, #160] ; (8004660 ) + int which = (args->change_flags >> 8) & 0xf; + 80045c0: f003 030f and.w r3, r3, #15 + 80045c4: f911 a003 ldrsb.w sl, [r1, r3] + uint8_t tmp[AE_SECRET_LEN]; + uint8_t check[32]; + + // what slot (key number) are updating? (probably: KEYNUM_secret) + int target_slot = keynum_for_secret(args); + if(target_slot < 0) return EPIN_RANGE_ERR; + 80045c8: f1ba 0f00 cmp.w sl, #0 + 80045cc: da02 bge.n 80045d4 + if(args->pin_len) return EPIN_RANGE_ERR; + 80045ce: f06f 0566 mvn.w r5, #102 ; 0x66 + 80045d2: e02e b.n 8004632 + + se2_encrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, required_digest); + 80045d4: f104 07b0 add.w r7, r4, #176 ; 0xb0 + 80045d8: ae0a add r6, sp, #40 ; 0x28 + 80045da: ab12 add r3, sp, #72 ; 0x48 + 80045dc: 2148 movs r1, #72 ; 0x48 + + // write into two slots + if(ae_encrypted_write(target_slot, KEYNUM_main_pin, + 80045de: f04f 0948 mov.w r9, #72 ; 0x48 + se2_encrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, required_digest); + 80045e2: f8cd 8004 str.w r8, [sp, #4] + 80045e6: 9600 str r6, [sp, #0] + 80045e8: 4638 mov r0, r7 + 80045ea: f003 ff47 bl 800847c + if(ae_encrypted_write(target_slot, KEYNUM_main_pin, + 80045ee: 2103 movs r1, #3 + 80045f0: f8cd 9000 str.w r9, [sp] + 80045f4: eb0d 0309 add.w r3, sp, r9 + 80045f8: 4642 mov r2, r8 + 80045fa: 4650 mov r0, sl + 80045fc: f7fe ffae bl 800355c + 8004600: 4601 mov r1, r0 + 8004602: b9e8 cbnz r0, 8004640 + required_digest, tmp, AE_SECRET_LEN)){ + goto ae_fail; + } + if(ae_encrypted_write32(KEYNUM_check_secret, 0, KEYNUM_main_pin, required_digest, check)){ + 8004604: 9600 str r6, [sp, #0] + 8004606: 4643 mov r3, r8 + 8004608: 2203 movs r2, #3 + 800460a: 200a movs r0, #10 + 800460c: f7fe ff40 bl 8003490 + 8004610: b9b0 cbnz r0, 8004640 + goto ae_fail; + } + + // update the zero-secret flag to be correct. + if(cf & CHANGE_SECRET) { + if(check_all_zeros(args->secret, AE_SECRET_LEN)) { + 8004612: 4649 mov r1, r9 + 8004614: 4638 mov r0, r7 + 8004616: f7fe f903 bl 8002820 + 800461a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800461c: b168 cbz r0, 800463a + args->state_flags |= PA_ZERO_SECRET; + 800461e: f043 0310 orr.w r3, r3, #16 + 8004622: 63e3 str r3, [r4, #60] ; 0x3c + args->state_flags &= ~PA_ZERO_SECRET; + } + } + } + + ae_reset_chip(); + 8004624: f7fe fa86 bl 8002b34 + _hmac_attempt(args, args->hmac); + 8004628: f104 0144 add.w r1, r4, #68 ; 0x44 + 800462c: 4620 mov r0, r4 + 800462e: f7ff fba1 bl 8003d74 <_hmac_attempt> + +ae_fail: + ae_reset_chip(); + + return EPIN_AE_FAIL; +} + 8004632: 4628 mov r0, r5 + 8004634: b024 add sp, #144 ; 0x90 + 8004636: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + args->state_flags &= ~PA_ZERO_SECRET; + 800463a: f023 0310 bic.w r3, r3, #16 + 800463e: e7f0 b.n 8004622 + ae_reset_chip(); + 8004640: f7fe fa78 bl 8002b34 + return EPIN_AE_FAIL; + 8004644: f06f 0569 mvn.w r5, #105 ; 0x69 + 8004648: e7f3 b.n 8004632 + return EPIN_WRONG_SUCCESS; + 800464a: f06f 056c mvn.w r5, #108 ; 0x6c + 800464e: e7f0 b.n 8004632 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004650: f06f 0568 mvn.w r5, #104 ; 0x68 + 8004654: e7ed b.n 8004632 + 8004656: bf00 nop + 8004658: 0801046c .word 0x0801046c + 800465c: 0801c000 .word 0x0801c000 + 8004660: 08010798 .word 0x08010798 + +08004664 : +// To encourage not keeping the secret in memory, a way to fetch it after you've already +// proven you know the PIN. +// + int +pin_fetch_secret(pinAttempt_t *args) +{ + 8004664: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 8004668: 2100 movs r1, #0 +{ + 800466a: f5ad 7d38 sub.w sp, sp, #736 ; 0x2e0 + 800466e: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 8004670: f7ff fbae bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 8004674: 4605 mov r5, r0 + 8004676: 2800 cmp r0, #0 + 8004678: d144 bne.n 8004704 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 800467a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800467c: 07db lsls r3, r3, #31 + 800467e: f140 80e3 bpl.w 8004848 + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + if(args->change_flags & CHANGE_DURESS_SECRET) { + 8004682: 6e65 ldr r5, [r4, #100] ; 0x64 + 8004684: f015 0510 ands.w r5, r5, #16 + 8004688: f040 80e1 bne.w 800484e + + // fetch the already-hashed pin + // - no real need to re-prove PIN knowledge. + // - if they tricked us, doesn't matter as below the SE validates it all again + uint8_t digest[32]; + pin_cache_restore(args, digest); + 800468c: f10d 081c add.w r8, sp, #28 + 8004690: 4641 mov r1, r8 + 8004692: 4620 mov r0, r4 + 8004694: f7ff fd62 bl 800415c + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004698: 4b70 ldr r3, [pc, #448] ; (800485c ) + 800469a: 6c26 ldr r6, [r4, #64] ; 0x40 + 800469c: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 80046a0: 4073 eors r3, r6 + if(!slot || !is_trick) return is_trick; + 80046a2: 07df lsls r7, r3, #31 + 80046a4: d577 bpl.n 8004796 + memset(slot, 0, sizeof(trick_slot_t)); + 80046a6: 2280 movs r2, #128 ; 0x80 + 80046a8: 4629 mov r1, r5 + 80046aa: a817 add r0, sp, #92 ; 0x5c + 80046ac: f009 f93a bl 800d924 + if(args->delay_required & TC_DELTA_MODE) { + 80046b0: 6b23 ldr r3, [r4, #48] ; 0x30 + 80046b2: 0558 lsls r0, r3, #21 + 80046b4: d52b bpl.n 800470e + slot->tc_flags = args->delay_required; + 80046b6: f8ad 3060 strh.w r3, [sp, #96] ; 0x60 + slot->slot_num = -1; // unknown + 80046ba: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 80046be: 9317 str r3, [sp, #92] ; 0x5c + + // determine if we should proceed under duress + trick_slot_t slot; + bool is_trick = get_is_trick(args, &slot); + + if(is_trick && !(slot.tc_flags & TC_DELTA_MODE)) { + 80046c0: f8bd 6060 ldrh.w r6, [sp, #96] ; 0x60 + 80046c4: f416 6180 ands.w r1, r6, #1024 ; 0x400 + 80046c8: d165 bne.n 8004796 + // emulate a 24-word wallet, or xprv based wallet + // see stash.py for encoding details + memset(args->secret, 0, AE_SECRET_LEN); + 80046ca: 2248 movs r2, #72 ; 0x48 + 80046cc: f104 00b0 add.w r0, r4, #176 ; 0xb0 + 80046d0: f009 f928 bl 800d924 + + if(slot.tc_flags & TC_WORD_WALLET) { + 80046d4: 04f1 lsls r1, r6, #19 + 80046d6: d54c bpl.n 8004772 + if(check_all_zeros(&slot.xdata[16], 16)) { + 80046d8: ae1d add r6, sp, #116 ; 0x74 + 80046da: 2110 movs r1, #16 + 80046dc: 4630 mov r0, r6 + 80046de: f7fe f89f bl 8002820 + // 2nd half is zeros, must be 12-word wallet + args->secret[0] = 0x80; // 12 word phrase + memcpy(&args->secret[1], slot.xdata, 16); + 80046e2: f104 03b1 add.w r3, r4, #177 ; 0xb1 + if(check_all_zeros(&slot.xdata[16], 16)) { + 80046e6: 2800 cmp r0, #0 + 80046e8: d034 beq.n 8004754 + args->secret[0] = 0x80; // 12 word phrase + 80046ea: 2280 movs r2, #128 ; 0x80 + 80046ec: f884 20b0 strb.w r2, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 16); + 80046f0: ac19 add r4, sp, #100 ; 0x64 + 80046f2: 4622 mov r2, r4 + 80046f4: ca03 ldmia r2!, {r0, r1} + 80046f6: 42b2 cmp r2, r6 + 80046f8: 6018 str r0, [r3, #0] + 80046fa: 6059 str r1, [r3, #4] + 80046fc: 4614 mov r4, r2 + 80046fe: f103 0308 add.w r3, r3, #8 + 8004702: d1f6 bne.n 80046f2 + ae_reset_chip(); + + if(rv) return EPIN_AE_FAIL; + + return 0; +} + 8004704: 4628 mov r0, r5 + 8004706: f50d 7d38 add.w sp, sp, #736 ; 0x2e0 + 800470a: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 800470e: 4f54 ldr r7, [pc, #336] ; (8004860 ) + memcpy(key, &args->private_state, sizeof(args->private_state)); + 8004710: 960f str r6, [sp, #60] ; 0x3c + memcpy(key+4, rom_secrets->hash_cache_secret+4, sizeof(rom_secrets->hash_cache_secret)-4); + 8004712: cf0f ldmia r7!, {r0, r1, r2, r3} + 8004714: ae10 add r6, sp, #64 ; 0x40 + 8004716: c60f stmia r6!, {r0, r1, r2, r3} + 8004718: e897 0007 ldmia.w r7, {r0, r1, r2} + 800471c: e886 0007 stmia.w r6, {r0, r1, r2} + aes_init(&ctx); + 8004720: a837 add r0, sp, #220 ; 0xdc + 8004722: f004 f80f bl 8008744 + aes_add(&ctx, args->cached_main_pin, 32); + 8004726: 2220 movs r2, #32 + 8004728: f104 01f8 add.w r1, r4, #248 ; 0xf8 + 800472c: a837 add r0, sp, #220 ; 0xdc + 800472e: f004 f80f bl 8008750 + aes_done(&ctx, (uint8_t *)slot, 32, key, NULL); + 8004732: a917 add r1, sp, #92 ; 0x5c + 8004734: 9500 str r5, [sp, #0] + 8004736: ab0f add r3, sp, #60 ; 0x3c + 8004738: 2220 movs r2, #32 + 800473a: a837 add r0, sp, #220 ; 0xdc + 800473c: f004 f81e bl 800877c + if(slot->tc_flags & (TC_WORD_WALLET|TC_XPRV_WALLET)) { + 8004740: f8bd 1060 ldrh.w r1, [sp, #96] ; 0x60 + 8004744: f411 5fc0 tst.w r1, #6144 ; 0x1800 + 8004748: d0ba beq.n 80046c0 + se2_read_trick_data(slot->slot_num, slot->tc_flags, slot->xdata); + 800474a: 9817 ldr r0, [sp, #92] ; 0x5c + 800474c: aa19 add r2, sp, #100 ; 0x64 + 800474e: f003 fca1 bl 8008094 + if(is_trick && !(slot.tc_flags & TC_DELTA_MODE)) { + 8004752: e7b5 b.n 80046c0 + args->secret[0] = 0x82; // 24 word phrase + 8004754: 2282 movs r2, #130 ; 0x82 + 8004756: f884 20b0 strb.w r2, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 32); + 800475a: ae21 add r6, sp, #132 ; 0x84 + 800475c: aa19 add r2, sp, #100 ; 0x64 + 800475e: 4614 mov r4, r2 + 8004760: cc03 ldmia r4!, {r0, r1} + 8004762: 42b4 cmp r4, r6 + 8004764: 6018 str r0, [r3, #0] + 8004766: 6059 str r1, [r3, #4] + 8004768: 4622 mov r2, r4 + 800476a: f103 0308 add.w r3, r3, #8 + 800476e: d1f6 bne.n 800475e + 8004770: e7c8 b.n 8004704 + } else if(slot.tc_flags & TC_XPRV_WALLET) { + 8004772: 0532 lsls r2, r6, #20 + 8004774: d5c6 bpl.n 8004704 + args->secret[0] = 0x01; // XPRV mode + 8004776: 2301 movs r3, #1 + 8004778: f884 30b0 strb.w r3, [r4, #176] ; 0xb0 + memcpy(&args->secret[1], slot.xdata, 64); + 800477c: aa19 add r2, sp, #100 ; 0x64 + 800477e: 34b1 adds r4, #177 ; 0xb1 + 8004780: ae29 add r6, sp, #164 ; 0xa4 + 8004782: 4613 mov r3, r2 + 8004784: cb03 ldmia r3!, {r0, r1} + 8004786: 42b3 cmp r3, r6 + 8004788: 6020 str r0, [r4, #0] + 800478a: 6061 str r1, [r4, #4] + 800478c: 461a mov r2, r3 + 800478e: f104 0408 add.w r4, r4, #8 + 8004792: d1f6 bne.n 8004782 + 8004794: e7b6 b.n 8004704 + int which = (args->change_flags >> 8) & 0xf; + 8004796: 6e63 ldr r3, [r4, #100] ; 0x64 + 8004798: 121b asrs r3, r3, #8 + switch(which) { + 800479a: f013 0f0c tst.w r3, #12 + 800479e: d159 bne.n 8004854 + 80047a0: 4a30 ldr r2, [pc, #192] ; (8004864 ) + int which = (args->change_flags >> 8) & 0xf; + 80047a2: f003 030f and.w r3, r3, #15 + 80047a6: f912 9003 ldrsb.w r9, [r2, r3] + if(kn < 0) return EPIN_RANGE_ERR; + 80047aa: f1b9 0f00 cmp.w r9, #0 + 80047ae: db51 blt.n 8004854 + 80047b0: 2703 movs r7, #3 + rv = ae_encrypted_read(kn, KEYNUM_main_pin, digest, tmp, AE_SECRET_LEN); + 80047b2: f04f 0a48 mov.w sl, #72 ; 0x48 + 80047b6: 2103 movs r1, #3 + 80047b8: f8cd a000 str.w sl, [sp] + 80047bc: ab37 add r3, sp, #220 ; 0xdc + 80047be: 4642 mov r2, r8 + 80047c0: 4648 mov r0, r9 + 80047c2: f7fe fe2b bl 800341c + if(rv) continue; + 80047c6: 4601 mov r1, r0 + 80047c8: b130 cbz r0, 80047d8 + for(int retry=0; retry<3; retry++) { + 80047ca: 3f01 subs r7, #1 + 80047cc: d1f3 bne.n 80047b6 + ae_reset_chip(); + 80047ce: f7fe f9b1 bl 8002b34 + if(rv) return EPIN_AE_FAIL; + 80047d2: f06f 0569 mvn.w r5, #105 ; 0x69 + 80047d6: e795 b.n 8004704 + rv = ae_encrypted_read32(KEYNUM_check_secret, 0, KEYNUM_main_pin, digest, check); + 80047d8: ae0f add r6, sp, #60 ; 0x3c + 80047da: 9600 str r6, [sp, #0] + 80047dc: 4643 mov r3, r8 + 80047de: 2203 movs r2, #3 + 80047e0: 200a movs r0, #10 + 80047e2: f7fe fdf0 bl 80033c6 + if(rv) continue; + 80047e6: 4605 mov r5, r0 + 80047e8: 2800 cmp r0, #0 + 80047ea: d1ee bne.n 80047ca + se2_decrypt_secret(args->secret, AE_SECRET_LEN, 0, tmp, check, digest, &is_valid); + 80047ec: f10d 071b add.w r7, sp, #27 + 80047f0: f104 00b0 add.w r0, r4, #176 ; 0xb0 + 80047f4: ab37 add r3, sp, #220 ; 0xdc + 80047f6: e9cd 8701 strd r8, r7, [sp, #4] + 80047fa: 9600 str r6, [sp, #0] + 80047fc: 462a mov r2, r5 + 80047fe: 2148 movs r1, #72 ; 0x48 + 8004800: 9005 str r0, [sp, #20] + 8004802: f003 fe91 bl 8008528 + if(!is_valid) { + 8004806: f89d 301b ldrb.w r3, [sp, #27] + 800480a: 9805 ldr r0, [sp, #20] + 800480c: b993 cbnz r3, 8004834 + memset(args->secret, 0, AE_SECRET_LEN); + 800480e: 2248 movs r2, #72 ; 0x48 + 8004810: 4629 mov r1, r5 + 8004812: f009 f887 bl 800d924 + if(!(args->state_flags & PA_ZERO_SECRET)) { + 8004816: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004818: 06db lsls r3, r3, #27 + 800481a: d408 bmi.n 800482e + args->state_flags |= PA_ZERO_SECRET; + 800481c: 6be3 ldr r3, [r4, #60] ; 0x3c + 800481e: f043 0310 orr.w r3, r3, #16 + 8004822: 63e3 str r3, [r4, #60] ; 0x3c + _hmac_attempt(args, args->hmac); + 8004824: f104 0144 add.w r1, r4, #68 ; 0x44 + 8004828: 4620 mov r0, r4 + 800482a: f7ff faa3 bl 8003d74 <_hmac_attempt> + ae_reset_chip(); + 800482e: f7fe f981 bl 8002b34 + if(rv) return EPIN_AE_FAIL; + 8004832: e767 b.n 8004704 + if(!args->secret[0] && check_all_zeros(args->secret, AE_SECRET_LEN)) { + 8004834: f894 30b0 ldrb.w r3, [r4, #176] ; 0xb0 + 8004838: 2b00 cmp r3, #0 + 800483a: d1f8 bne.n 800482e + 800483c: 2148 movs r1, #72 ; 0x48 + 800483e: f7fd ffef bl 8002820 + 8004842: 2800 cmp r0, #0 + 8004844: d0f3 beq.n 800482e + 8004846: e7e9 b.n 800481c + return EPIN_WRONG_SUCCESS; + 8004848: f06f 056c mvn.w r5, #108 ; 0x6c + 800484c: e75a b.n 8004704 + return EPIN_BAD_REQUEST; + 800484e: f06f 0567 mvn.w r5, #103 ; 0x67 + 8004852: e757 b.n 8004704 + if(kn < 0) return EPIN_RANGE_ERR; + 8004854: f06f 0566 mvn.w r5, #102 ; 0x66 + 8004858: e754 b.n 8004704 + 800485a: bf00 nop + 800485c: 0801c000 .word 0x0801c000 + 8004860: 0801c074 .word 0x0801c074 + 8004864: 08010798 .word 0x08010798 + +08004868 : +// - new API so whole thing provided in one shot? encryption issues: provide +// "dest" and all 416 bytes end up there (read case only). +// + int +pin_long_secret(pinAttempt_t *args, uint8_t *dest) +{ + 8004868: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 800486c: 460f mov r7, r1 + 800486e: b099 sub sp, #100 ; 0x64 + // Validate args and signature + int rv = _validate_attempt(args, false); + 8004870: 2100 movs r1, #0 +{ + 8004872: 4606 mov r6, r0 + int rv = _validate_attempt(args, false); + 8004874: f7ff faac bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 8004878: 4604 mov r4, r0 + 800487a: b9b8 cbnz r0, 80048ac + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 800487c: 6bf3 ldr r3, [r6, #60] ; 0x3c + 800487e: 07da lsls r2, r3, #31 + 8004880: f140 80a5 bpl.w 80049ce + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004884: 4b55 ldr r3, [pc, #340] ; (80049dc ) + 8004886: 6c32 ldr r2, [r6, #64] ; 0x40 + 8004888: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 800488c: 4053 eors r3, r2 + } + + // determine if we should proceed under duress/in some trick way + bool is_trick = get_is_trick(args, NULL); + + if(is_trick) { + 800488e: 07db lsls r3, r3, #31 + 8004890: d510 bpl.n 80048b4 + // Not supported in trick mode. Pretend it's all zeros. Accept all writes. + memset(args->secret, 0, 32); + 8004892: 4601 mov r1, r0 + 8004894: 2220 movs r2, #32 + 8004896: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 800489a: f009 f843 bl 800d924 + if(dest) memset(dest, 0, AE_LONG_SECRET_LEN); + 800489e: b12f cbz r7, 80048ac + 80048a0: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 80048a4: 4621 mov r1, r4 + 80048a6: 4638 mov r0, r7 + 80048a8: f009 f83c bl 800d924 + +se2_fail: + ae_reset_chip(); + + return EPIN_SE2_FAIL; +} + 80048ac: 4620 mov r0, r4 + 80048ae: b019 add sp, #100 ; 0x64 + 80048b0: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + int blk = (args->change_flags >> 8) & 0xf; + 80048b4: 6e73 ldr r3, [r6, #100] ; 0x64 + 80048b6: f3c3 2803 ubfx r8, r3, #8, #4 + if(blk > 13) return EPIN_RANGE_ERR; + 80048ba: f1b8 0f0d cmp.w r8, #13 + 80048be: f300 8089 bgt.w 80049d4 + pin_cache_restore(args, digest); + 80048c2: a908 add r1, sp, #32 + 80048c4: 4630 mov r0, r6 + 80048c6: f7ff fc49 bl 800415c + if(!(args->change_flags & CHANGE_SECRET)) { + 80048ca: 6e71 ldr r1, [r6, #100] ; 0x64 + 80048cc: f011 0908 ands.w r9, r1, #8 + 80048d0: d156 bne.n 8004980 + if(!dest) { + 80048d2: bb27 cbnz r7, 800491e + rv = ae_encrypted_read32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, tmp); + 80048d4: af10 add r7, sp, #64 ; 0x40 + 80048d6: 9700 str r7, [sp, #0] + 80048d8: ab08 add r3, sp, #32 + 80048da: 2203 movs r2, #3 + 80048dc: 4641 mov r1, r8 + 80048de: 2008 movs r0, #8 + 80048e0: f7fe fd71 bl 80033c6 + if(rv) goto fail; + 80048e4: 4605 mov r5, r0 + 80048e6: 2800 cmp r0, #0 + 80048e8: d16a bne.n 80049c0 + se2_decrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest, &is_valid); + 80048ea: f10d 031f add.w r3, sp, #31 + 80048ee: 9302 str r3, [sp, #8] + 80048f0: ab08 add r3, sp, #32 + 80048f2: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 80048f6: e9cd 4300 strd r4, r3, [sp] + 80048fa: ea4f 1248 mov.w r2, r8, lsl #5 + 80048fe: 463b mov r3, r7 + 8004900: 2120 movs r1, #32 + 8004902: 9005 str r0, [sp, #20] + 8004904: f003 fe10 bl 8008528 + if(!is_valid) { + 8004908: f89d 301f ldrb.w r3, [sp, #31] + 800490c: 9805 ldr r0, [sp, #20] + 800490e: b91b cbnz r3, 8004918 + memset(args->secret, 0, 32); + 8004910: 2220 movs r2, #32 + 8004912: 4621 mov r1, r4 + memset(dest, 0, AE_LONG_SECRET_LEN); + 8004914: f009 f806 bl 800d924 + ae_reset_chip(); + 8004918: f7fe f90c bl 8002b34 + if(rv) return EPIN_AE_FAIL; + 800491c: e7c6 b.n 80048ac + 800491e: 463e mov r6, r7 + rv = ae_encrypted_read32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, p); + 8004920: 9600 str r6, [sp, #0] + 8004922: ab08 add r3, sp, #32 + 8004924: 2203 movs r2, #3 + 8004926: 4649 mov r1, r9 + 8004928: 2008 movs r0, #8 + 800492a: f7fe fd4c bl 80033c6 + if(rv) goto fail; + 800492e: 4605 mov r5, r0 + 8004930: 2800 cmp r0, #0 + 8004932: d145 bne.n 80049c0 + for(blk=0; blk<13; blk++, p += 32) { + 8004934: f109 0901 add.w r9, r9, #1 + 8004938: f1b9 0f0d cmp.w r9, #13 + 800493c: f106 0620 add.w r6, r6, #32 + 8004940: d1ee bne.n 8004920 + ASSERT(p == dest+AE_LONG_SECRET_LEN); + 8004942: f507 73d0 add.w r3, r7, #416 ; 0x1a0 + 8004946: 429e cmp r6, r3 + 8004948: d002 beq.n 8004950 + 800494a: 4825 ldr r0, [pc, #148] ; (80049e0 ) + 800494c: f7fc f874 bl 8000a38 + se2_decrypt_secret(dest, AE_LONG_SECRET_LEN, 0, dest, NULL, digest, &is_valid); + 8004950: ab10 add r3, sp, #64 ; 0x40 + 8004952: 9302 str r3, [sp, #8] + 8004954: ab08 add r3, sp, #32 + 8004956: e9cd 0300 strd r0, r3, [sp] + 800495a: 4602 mov r2, r0 + 800495c: 463b mov r3, r7 + 800495e: f44f 71d0 mov.w r1, #416 ; 0x1a0 + 8004962: 4638 mov r0, r7 + 8004964: f003 fde0 bl 8008528 + if(!is_valid) { + 8004968: f89d 4040 ldrb.w r4, [sp, #64] ; 0x40 + 800496c: b924 cbnz r4, 8004978 + memset(dest, 0, AE_LONG_SECRET_LEN); + 800496e: f44f 72d0 mov.w r2, #416 ; 0x1a0 + 8004972: 4621 mov r1, r4 + 8004974: 4638 mov r0, r7 + 8004976: e7cd b.n 8004914 + ae_reset_chip(); + 8004978: f7fe f8dc bl 8002b34 + return 0; + 800497c: 462c mov r4, r5 + 800497e: e795 b.n 80048ac + uint8_t tmp[32] = {0}; + 8004980: 221c movs r2, #28 + 8004982: 4621 mov r1, r4 + 8004984: a811 add r0, sp, #68 ; 0x44 + 8004986: 9410 str r4, [sp, #64] ; 0x40 + if(se2_encrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest)) { + 8004988: ad10 add r5, sp, #64 ; 0x40 + uint8_t tmp[32] = {0}; + 800498a: f008 ffcb bl 800d924 + if(se2_encrypt_secret(args->secret, 32, blk*32, tmp, NULL, digest)) { + 800498e: ab08 add r3, sp, #32 + 8004990: e9cd 4300 strd r4, r3, [sp] + 8004994: ea4f 1248 mov.w r2, r8, lsl #5 + 8004998: 462b mov r3, r5 + 800499a: 2120 movs r1, #32 + 800499c: f106 00b0 add.w r0, r6, #176 ; 0xb0 + 80049a0: f003 fd6c bl 800847c + 80049a4: b120 cbz r0, 80049b0 + ae_reset_chip(); + 80049a6: f7fe f8c5 bl 8002b34 + return EPIN_SE2_FAIL; + 80049aa: f06f 0472 mvn.w r4, #114 ; 0x72 + 80049ae: e77d b.n 80048ac + rv = ae_encrypted_write32(KEYNUM_long_secret, blk, KEYNUM_main_pin, digest, tmp); + 80049b0: 9500 str r5, [sp, #0] + 80049b2: ab08 add r3, sp, #32 + 80049b4: 2203 movs r2, #3 + 80049b6: 4641 mov r1, r8 + 80049b8: 2008 movs r0, #8 + 80049ba: f7fe fd69 bl 8003490 + 80049be: 4605 mov r5, r0 + ae_reset_chip(); + 80049c0: f7fe f8b8 bl 8002b34 + if(rv) return EPIN_AE_FAIL; + 80049c4: 2d00 cmp r5, #0 + 80049c6: bf18 it ne + 80049c8: f06f 0469 mvnne.w r4, #105 ; 0x69 + 80049cc: e76e b.n 80048ac + return EPIN_WRONG_SUCCESS; + 80049ce: f06f 046c mvn.w r4, #108 ; 0x6c + 80049d2: e76b b.n 80048ac + if(blk > 13) return EPIN_RANGE_ERR; + 80049d4: f06f 0466 mvn.w r4, #102 ; 0x66 + 80049d8: e768 b.n 80048ac + 80049da: bf00 nop + 80049dc: 0801c000 .word 0x0801c000 + 80049e0: 0801046c .word 0x0801046c + +080049e4 : +// +// Record current flash checksum and make green light go on. +// + int +pin_firmware_greenlight(pinAttempt_t *args) +{ + 80049e4: b530 push {r4, r5, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 80049e6: 2100 movs r1, #0 +{ + 80049e8: b09b sub sp, #108 ; 0x6c + 80049ea: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 80049ec: f7ff f9f0 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 80049f0: bb20 cbnz r0, 8004a3c + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 80049f2: 6be3 ldr r3, [r4, #60] ; 0x3c + 80049f4: 07da lsls r2, r3, #31 + 80049f6: d529 bpl.n 8004a4c + // must come here with a successful PIN login (so it's rate limited nicely) + return EPIN_WRONG_SUCCESS; + } + + if(args->is_secondary) { + 80049f8: 6865 ldr r5, [r4, #4] + 80049fa: bb55 cbnz r5, 8004a52 + return EPIN_PRIMARY_ONLY; + } + + // load existing PIN's hash + uint8_t digest[32]; + pin_cache_restore(args, digest); + 80049fc: a902 add r1, sp, #8 + 80049fe: 4620 mov r0, r4 + 8004a00: f7ff fbac bl 800415c + + // step 1: calc the value to use + uint8_t fw_check[32], world_check[32]; + checksum_flash(fw_check, world_check, 0); + 8004a04: 462a mov r2, r5 + 8004a06: a912 add r1, sp, #72 ; 0x48 + 8004a08: a80a add r0, sp, #40 ; 0x28 + 8004a0a: f7fd f907 bl 8001c1c + + // step 2: write it out to chip. + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004a0e: f7ff fa15 bl 8003e3c + 8004a12: bb08 cbnz r0, 8004a58 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004a14: 4b12 ldr r3, [pc, #72] ; (8004a60 ) + 8004a16: 6c22 ldr r2, [r4, #64] ; 0x40 + 8004a18: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8004a1c: 4053 eors r3, r2 + + // under duress, we can't fake this, but we go through the motions anyway + if(!get_is_trick(args, NULL)) { + 8004a1e: 07db lsls r3, r3, #31 + 8004a20: d40e bmi.n 8004a40 + rv = ae_encrypted_write(KEYNUM_firmware, KEYNUM_main_pin, digest, world_check, 32); + 8004a22: 2320 movs r3, #32 + 8004a24: 9300 str r3, [sp, #0] + 8004a26: aa02 add r2, sp, #8 + 8004a28: ab12 add r3, sp, #72 ; 0x48 + 8004a2a: 2103 movs r1, #3 + 8004a2c: 200e movs r0, #14 + 8004a2e: f7fe fd95 bl 800355c + + if(rv) { + 8004a32: b128 cbz r0, 8004a40 + ae_reset_chip(); + 8004a34: f7fe f87e bl 8002b34 + + return EPIN_AE_FAIL; + 8004a38: f06f 0069 mvn.w r0, #105 ; 0x69 + + return EPIN_AE_FAIL; + } + + return 0; +} + 8004a3c: b01b add sp, #108 ; 0x6c + 8004a3e: bd30 pop {r4, r5, pc} + rv = ae_set_gpio_secure(world_check); + 8004a40: a812 add r0, sp, #72 ; 0x48 + 8004a42: f7fe fe1d bl 8003680 + if(rv) { + 8004a46: 2800 cmp r0, #0 + 8004a48: d0f8 beq.n 8004a3c + 8004a4a: e7f3 b.n 8004a34 + return EPIN_WRONG_SUCCESS; + 8004a4c: f06f 006c mvn.w r0, #108 ; 0x6c + 8004a50: e7f4 b.n 8004a3c + return EPIN_PRIMARY_ONLY; + 8004a52: f06f 0071 mvn.w r0, #113 ; 0x71 + 8004a56: e7f1 b.n 8004a3c + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004a58: f06f 0068 mvn.w r0, #104 ; 0x68 + 8004a5c: e7ee b.n 8004a3c + 8004a5e: bf00 nop + 8004a60: 0801c000 .word 0x0801c000 + +08004a64 : +// Update the system firmware via file in PSRAM. Arrange for +// light to stay green through out process. +// + int +pin_firmware_upgrade(pinAttempt_t *args) +{ + 8004a64: b570 push {r4, r5, r6, lr} + // Validate args and signature + int rv = _validate_attempt(args, false); + 8004a66: 2100 movs r1, #0 +{ + 8004a68: b092 sub sp, #72 ; 0x48 + 8004a6a: 4604 mov r4, r0 + int rv = _validate_attempt(args, false); + 8004a6c: f7ff f9b0 bl 8003dd0 <_validate_attempt> + if(rv) return rv; + 8004a70: 2800 cmp r0, #0 + 8004a72: d14e bne.n 8004b12 + + if((args->state_flags & PA_SUCCESSFUL) != PA_SUCCESSFUL) { + 8004a74: 6be3 ldr r3, [r4, #60] ; 0x3c + 8004a76: 07da lsls r2, r3, #31 + 8004a78: d54d bpl.n 8004b16 + // must come here with a successful PIN login + return EPIN_WRONG_SUCCESS; + } + + if(args->change_flags != CHANGE_FIRMWARE) { + 8004a7a: 6e63 ldr r3, [r4, #100] ; 0x64 + 8004a7c: 2b40 cmp r3, #64 ; 0x40 + 8004a7e: d11c bne.n 8004aba + } + + // expecting start/length relative to psram start + uint32_t *about = (uint32_t *)args->secret; + uint32_t start = about[0]; + uint32_t len = about[1]; + 8004a80: e9d4 562c ldrd r5, r6, [r4, #176] ; 0xb0 + + if(len < 32768) return EPIN_RANGE_ERR; + 8004a84: f5a6 4300 sub.w r3, r6, #32768 ; 0x8000 + 8004a88: f5b3 1ffc cmp.w r3, #2064384 ; 0x1f8000 + 8004a8c: d846 bhi.n 8004b1c + if(len > 2<<20) return EPIN_RANGE_ERR; + if(start+len > PSRAM_SIZE) return EPIN_RANGE_ERR; + 8004a8e: 19ab adds r3, r5, r6 + 8004a90: f5b3 0f00 cmp.w r3, #8388608 ; 0x800000 + 8004a94: d842 bhi.n 8004b1c + + const uint8_t *data = (const uint8_t *)PSRAM_BASE+start; + 8004a96: f105 4510 add.w r5, r5, #2415919104 ; 0x90000000 + + // verify a firmware image that's in RAM, and calc its digest + // - also applies watermark policy, etc + uint8_t world_check[32]; + bool ok = verify_firmware_in_ram(data, len, world_check); + 8004a9a: aa02 add r2, sp, #8 + 8004a9c: 4631 mov r1, r6 + 8004a9e: 4628 mov r0, r5 + 8004aa0: f7fd f9c2 bl 8001e28 + if(!ok) { + 8004aa4: 2800 cmp r0, #0 + 8004aa6: d03c beq.n 8004b22 + bool is_trick = ((args->private_state ^ rom_secrets->hash_cache_secret[0]) & 0x1); + 8004aa8: 4b21 ldr r3, [pc, #132] ; (8004b30 ) + 8004aaa: 6c22 ldr r2, [r4, #64] ; 0x40 + 8004aac: f893 3070 ldrb.w r3, [r3, #112] ; 0x70 + 8004ab0: 4053 eors r3, r2 + return EPIN_AUTH_FAIL; + } + + // under duress, we can't fake this, so kill ourselves. + if(get_is_trick(args, NULL)) { + 8004ab2: 07db lsls r3, r3, #31 + 8004ab4: d504 bpl.n 8004ac0 + // User is a thug.. kill secret and reboot w/o any notice + fast_wipe(); + 8004ab6: f7fd fe87 bl 80027c8 + return EPIN_BAD_REQUEST; + 8004aba: f06f 0067 mvn.w r0, #103 ; 0x67 + 8004abe: e028 b.n 8004b12 + return EPIN_BAD_REQUEST; + } + + // load existing PIN's hash + uint8_t digest[32]; + pin_cache_restore(args, digest); + 8004ac0: a90a add r1, sp, #40 ; 0x28 + 8004ac2: 4620 mov r0, r4 + 8004ac4: f7ff fb4a bl 800415c + + // step 1: calc the value to use, see above + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004ac8: f7ff f9b8 bl 8003e3c + 8004acc: bb60 cbnz r0, 8004b28 + + // step 2: write it out to chip. + rv = ae_encrypted_write(KEYNUM_firmware, KEYNUM_main_pin, digest, world_check, 32); + 8004ace: 2320 movs r3, #32 + 8004ad0: 9300 str r3, [sp, #0] + 8004ad2: aa0a add r2, sp, #40 ; 0x28 + 8004ad4: ab02 add r3, sp, #8 + 8004ad6: 2103 movs r1, #3 + 8004ad8: 200e movs r0, #14 + 8004ada: f7fe fd3f bl 800355c + if(rv) goto fail; + 8004ade: b9a0 cbnz r0, 8004b0a + + // this turns on green light + rv = ae_set_gpio_secure(world_check); + 8004ae0: a802 add r0, sp, #8 + 8004ae2: f7fe fdcd bl 8003680 + if(rv) goto fail; + 8004ae6: b980 cbnz r0, 8004b0a + + // -- point of no return -- + + // burn it, shows progress + psram_do_upgrade(data, len); + 8004ae8: 4631 mov r1, r6 + 8004aea: 4628 mov r0, r5 + 8004aec: f000 fbf4 bl 80052d8 + 8004af0: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8004af4: 490f ldr r1, [pc, #60] ; (8004b34 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8004af6: 4b10 ldr r3, [pc, #64] ; (8004b38 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8004af8: 68ca ldr r2, [r1, #12] + 8004afa: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8004afe: 4313 orrs r3, r2 + 8004b00: 60cb str r3, [r1, #12] + 8004b02: f3bf 8f4f dsb sy + __NOP(); + 8004b06: bf00 nop + for(;;) /* wait until reset */ + 8004b08: e7fd b.n 8004b06 + NVIC_SystemReset(); + + return 0; + +fail: + ae_reset_chip(); + 8004b0a: f7fe f813 bl 8002b34 + + return EPIN_AE_FAIL; + 8004b0e: f06f 0069 mvn.w r0, #105 ; 0x69 +} + 8004b12: b012 add sp, #72 ; 0x48 + 8004b14: bd70 pop {r4, r5, r6, pc} + return EPIN_WRONG_SUCCESS; + 8004b16: f06f 006c mvn.w r0, #108 ; 0x6c + 8004b1a: e7fa b.n 8004b12 + if(len < 32768) return EPIN_RANGE_ERR; + 8004b1c: f06f 0066 mvn.w r0, #102 ; 0x66 + 8004b20: e7f7 b.n 8004b12 + return EPIN_AUTH_FAIL; + 8004b22: f06f 006f mvn.w r0, #111 ; 0x6f + 8004b26: e7f4 b.n 8004b12 + if(warmup_ae()) return EPIN_I_AM_BRICK; + 8004b28: f06f 0068 mvn.w r0, #104 ; 0x68 + 8004b2c: e7f1 b.n 8004b12 + 8004b2e: bf00 nop + 8004b30: 0801c000 .word 0x0801c000 + 8004b34: e000ed00 .word 0xe000ed00 + 8004b38: 05fa0004 .word 0x05fa0004 + +08004b3c : + +// strcat_hex() +// + void +strcat_hex(char *msg, const void *d, int len) +{ + 8004b3c: b570 push {r4, r5, r6, lr} + 8004b3e: 4616 mov r6, r2 + 8004b40: 4604 mov r4, r0 + 8004b42: 460d mov r5, r1 + char *p = msg+strlen(msg); + 8004b44: f008 ff19 bl 800d97a + const uint8_t *h = (const uint8_t *)d; + + for(; len; len--, h++) { + *(p++) = hexmap[(*h>>4) & 0xf]; + 8004b48: 4a0b ldr r2, [pc, #44] ; (8004b78 ) + char *p = msg+strlen(msg); + 8004b4a: 4420 add r0, r4 + for(; len; len--, h++) { + 8004b4c: 1e69 subs r1, r5, #1 + 8004b4e: eb00 0646 add.w r6, r0, r6, lsl #1 + 8004b52: 42b0 cmp r0, r6 + 8004b54: d102 bne.n 8004b5c + *(p++) = hexmap[(*h>>0) & 0xf]; + } + + *(p++) = 0; + 8004b56: 2300 movs r3, #0 + 8004b58: 7003 strb r3, [r0, #0] +} + 8004b5a: bd70 pop {r4, r5, r6, pc} + *(p++) = hexmap[(*h>>4) & 0xf]; + 8004b5c: f811 3f01 ldrb.w r3, [r1, #1]! + 8004b60: 091b lsrs r3, r3, #4 + 8004b62: 5cd3 ldrb r3, [r2, r3] + 8004b64: f800 3b02 strb.w r3, [r0], #2 + *(p++) = hexmap[(*h>>0) & 0xf]; + 8004b68: 780b ldrb r3, [r1, #0] + 8004b6a: f003 030f and.w r3, r3, #15 + 8004b6e: 5cd3 ldrb r3, [r2, r3] + 8004b70: f800 3c01 strb.w r3, [r0, #-1] + for(; len; len--, h++) { + 8004b74: e7ed b.n 8004b52 + 8004b76: bf00 nop + 8004b78: 080107ce .word 0x080107ce + +08004b7c : + * parameters in the USART_InitTypeDef and initialize the associated handle. + * @param husart USART handle. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart) +{ + 8004b7c: b5f8 push {r3, r4, r5, r6, r7, lr} + /* Check the USART handle allocation */ + if (husart == NULL) + 8004b7e: 4604 mov r4, r0 + 8004b80: b910 cbnz r0, 8004b88 + { + return HAL_ERROR; + 8004b82: 2501 movs r5, #1 + /* Enable the Peripheral */ + __HAL_USART_ENABLE(husart); + + /* TEACK and/or REACK to check before moving husart->State to Ready */ + return (USART_CheckIdleState(husart)); +} + 8004b84: 4628 mov r0, r5 + 8004b86: bdf8 pop {r3, r4, r5, r6, r7, pc} + if (husart->State == HAL_USART_STATE_RESET) + 8004b88: f890 3059 ldrb.w r3, [r0, #89] ; 0x59 + 8004b8c: f003 02ff and.w r2, r3, #255 ; 0xff + 8004b90: b90b cbnz r3, 8004b96 + husart->Lock = HAL_UNLOCKED; + 8004b92: f880 2058 strb.w r2, [r0, #88] ; 0x58 + __HAL_USART_DISABLE(husart); + 8004b96: 6823 ldr r3, [r4, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 8004b98: 6921 ldr r1, [r4, #16] + husart->State = HAL_USART_STATE_BUSY; + 8004b9a: 2502 movs r5, #2 + 8004b9c: f884 5059 strb.w r5, [r4, #89] ; 0x59 + __HAL_USART_DISABLE(husart); + 8004ba0: 681a ldr r2, [r3, #0] + 8004ba2: f022 0201 bic.w r2, r2, #1 + 8004ba6: 601a str r2, [r3, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 8004ba8: 68a2 ldr r2, [r4, #8] + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 8004baa: 6818 ldr r0, [r3, #0] + tmpreg = (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode | USART_CR1_OVER8; + 8004bac: 430a orrs r2, r1 + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 8004bae: 49a9 ldr r1, [pc, #676] ; (8004e54 ) + 8004bb0: 4001 ands r1, r0 + 8004bb2: 430a orrs r2, r1 + 8004bb4: 6961 ldr r1, [r4, #20] + MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); + 8004bb6: 69a0 ldr r0, [r4, #24] + MODIFY_REG(husart->Instance->CR1, USART_CR1_FIELDS, tmpreg); + 8004bb8: 430a orrs r2, r1 + 8004bba: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 8004bbe: 601a str r2, [r3, #0] + MODIFY_REG(husart->Instance->CR2, USART_CR2_FIELDS, tmpreg); + 8004bc0: 6859 ldr r1, [r3, #4] + 8004bc2: 6a22 ldr r2, [r4, #32] + 8004bc4: f421 517c bic.w r1, r1, #16128 ; 0x3f00 + 8004bc8: f021 0109 bic.w r1, r1, #9 + 8004bcc: 4302 orrs r2, r0 + 8004bce: 430a orrs r2, r1 + 8004bd0: 69e1 ldr r1, [r4, #28] + 8004bd2: 430a orrs r2, r1 + 8004bd4: 68e1 ldr r1, [r4, #12] + 8004bd6: 430a orrs r2, r1 + 8004bd8: f442 6200 orr.w r2, r2, #2048 ; 0x800 + 8004bdc: 605a str r2, [r3, #4] + MODIFY_REG(husart->Instance->PRESC, USART_PRESC_PRESCALER, husart->Init.ClockPrescaler); + 8004bde: 6ad9 ldr r1, [r3, #44] ; 0x2c + 8004be0: 6a62 ldr r2, [r4, #36] ; 0x24 + 8004be2: f021 010f bic.w r1, r1, #15 + 8004be6: 4311 orrs r1, r2 + 8004be8: 62d9 str r1, [r3, #44] ; 0x2c + USART_GETCLOCKSOURCE(husart, clocksource); + 8004bea: 499b ldr r1, [pc, #620] ; (8004e58 ) + 8004bec: 428b cmp r3, r1 + 8004bee: d10e bne.n 8004c0e + 8004bf0: 4b9a ldr r3, [pc, #616] ; (8004e5c ) + 8004bf2: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 8004bf6: f003 0303 and.w r3, r3, #3 + 8004bfa: 42ab cmp r3, r5 + 8004bfc: f000 80cd beq.w 8004d9a + 8004c00: 2b03 cmp r3, #3 + 8004c02: d01a beq.n 8004c3a + 8004c04: 2b01 cmp r3, #1 + 8004c06: d153 bne.n 8004cb0 + pclk = HAL_RCC_GetSysClockFreq(); + 8004c08: f003 ff52 bl 8008ab0 + 8004c0c: e052 b.n 8004cb4 + USART_GETCLOCKSOURCE(husart, clocksource); + 8004c0e: 4994 ldr r1, [pc, #592] ; (8004e60 ) + 8004c10: 428b cmp r3, r1 + 8004c12: d13c bne.n 8004c8e + 8004c14: 4b91 ldr r3, [pc, #580] ; (8004e5c ) + 8004c16: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 8004c1a: f003 030c and.w r3, r3, #12 + 8004c1e: 2b08 cmp r3, #8 + 8004c20: f000 80bb beq.w 8004d9a + 8004c24: d807 bhi.n 8004c36 + 8004c26: 2b00 cmp r3, #0 + 8004c28: f000 80b4 beq.w 8004d94 + 8004c2c: 2b04 cmp r3, #4 + 8004c2e: d0eb beq.n 8004c08 + uint32_t usartdiv = 0x00000000; + 8004c30: 2300 movs r3, #0 + ret = HAL_ERROR; + 8004c32: 2501 movs r5, #1 + 8004c34: e06e b.n 8004d14 + USART_GETCLOCKSOURCE(husart, clocksource); + 8004c36: 2b0c cmp r3, #12 + 8004c38: d1fa bne.n 8004c30 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004c3a: 2a00 cmp r2, #0 + 8004c3c: f000 80fb beq.w 8004e36 + 8004c40: 2a01 cmp r2, #1 + 8004c42: f000 80fa beq.w 8004e3a + 8004c46: 2a02 cmp r2, #2 + 8004c48: f000 80f9 beq.w 8004e3e + 8004c4c: 2a03 cmp r2, #3 + 8004c4e: f000 80f8 beq.w 8004e42 + 8004c52: 2a04 cmp r2, #4 + 8004c54: f000 80f7 beq.w 8004e46 + 8004c58: 2a05 cmp r2, #5 + 8004c5a: f000 80f6 beq.w 8004e4a + 8004c5e: 2a06 cmp r2, #6 + 8004c60: f000 80f5 beq.w 8004e4e + 8004c64: 2a07 cmp r2, #7 + 8004c66: f000 8101 beq.w 8004e6c + 8004c6a: 2a08 cmp r2, #8 + 8004c6c: f000 8100 beq.w 8004e70 + 8004c70: 2a09 cmp r2, #9 + 8004c72: f000 80ff beq.w 8004e74 + 8004c76: 2a0a cmp r2, #10 + 8004c78: f000 80fe beq.w 8004e78 + 8004c7c: 2a0b cmp r2, #11 + 8004c7e: bf14 ite ne + 8004c80: 2201 movne r2, #1 + 8004c82: f44f 7280 moveq.w r2, #256 ; 0x100 + 8004c86: 6861 ldr r1, [r4, #4] + 8004c88: f44f 4300 mov.w r3, #32768 ; 0x8000 + 8004c8c: e0a1 b.n 8004dd2 + USART_GETCLOCKSOURCE(husart, clocksource); + 8004c8e: 4975 ldr r1, [pc, #468] ; (8004e64 ) + 8004c90: 428b cmp r3, r1 + 8004c92: d1cd bne.n 8004c30 + 8004c94: 4b71 ldr r3, [pc, #452] ; (8004e5c ) + 8004c96: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88 + 8004c9a: f003 0330 and.w r3, r3, #48 ; 0x30 + 8004c9e: 2b20 cmp r3, #32 + 8004ca0: d07b beq.n 8004d9a + 8004ca2: d803 bhi.n 8004cac + 8004ca4: 2b00 cmp r3, #0 + 8004ca6: d075 beq.n 8004d94 + 8004ca8: 2b10 cmp r3, #16 + 8004caa: e7c0 b.n 8004c2e + 8004cac: 2b30 cmp r3, #48 ; 0x30 + 8004cae: e7c3 b.n 8004c38 + pclk = HAL_RCC_GetPCLK2Freq(); + 8004cb0: f004 fb0c bl 80092cc + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004cb4: 6a62 ldr r2, [r4, #36] ; 0x24 + 8004cb6: 2a00 cmp r2, #0 + 8004cb8: f000 80a7 beq.w 8004e0a + 8004cbc: 2a01 cmp r2, #1 + 8004cbe: f000 80a6 beq.w 8004e0e + 8004cc2: 2a02 cmp r2, #2 + 8004cc4: f000 80a5 beq.w 8004e12 + 8004cc8: 2a03 cmp r2, #3 + 8004cca: f000 80a4 beq.w 8004e16 + 8004cce: 2a04 cmp r2, #4 + 8004cd0: f000 80a3 beq.w 8004e1a + 8004cd4: 2a05 cmp r2, #5 + 8004cd6: f000 80a2 beq.w 8004e1e + 8004cda: 2a06 cmp r2, #6 + 8004cdc: f000 80a1 beq.w 8004e22 + 8004ce0: 2a07 cmp r2, #7 + 8004ce2: f000 80a0 beq.w 8004e26 + 8004ce6: 2a08 cmp r2, #8 + 8004ce8: f000 809f beq.w 8004e2a + 8004cec: 2a09 cmp r2, #9 + 8004cee: f000 809e beq.w 8004e2e + 8004cf2: 2a0a cmp r2, #10 + 8004cf4: f000 809d beq.w 8004e32 + 8004cf8: 2a0b cmp r2, #11 + 8004cfa: bf14 ite ne + 8004cfc: 2201 movne r2, #1 + 8004cfe: f44f 7280 moveq.w r2, #256 ; 0x100 + 8004d02: 6861 ldr r1, [r4, #4] + 8004d04: fbb0 f0f2 udiv r0, r0, r2 + 8004d08: 084b lsrs r3, r1, #1 + 8004d0a: eb03 0340 add.w r3, r3, r0, lsl #1 + HAL_StatusTypeDef ret = HAL_OK; + 8004d0e: 2500 movs r5, #0 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004d10: fbb3 f3f1 udiv r3, r3, r1 + if ((usartdiv >= USART_BRR_MIN) && (usartdiv <= USART_BRR_MAX)) + 8004d14: f1a3 0110 sub.w r1, r3, #16 + 8004d18: f64f 72ef movw r2, #65519 ; 0xffef + 8004d1c: 4291 cmp r1, r2 + brrtemp = (uint16_t)(usartdiv & 0xFFF0U); + 8004d1e: bf9f itttt ls + 8004d20: f023 020f bicls.w r2, r3, #15 + 8004d24: b292 uxthls r2, r2 + brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U); + 8004d26: f3c3 0342 ubfxls r3, r3, #1, #3 + husart->Instance->BRR = brrtemp; + 8004d2a: 6821 ldrls r1, [r4, #0] + 8004d2c: bf9a itte ls + 8004d2e: 4313 orrls r3, r2 + 8004d30: 60cb strls r3, [r1, #12] + ret = HAL_ERROR; + 8004d32: 2501 movhi r5, #1 + husart->NbTxDataToProcess = 1U; + 8004d34: 2301 movs r3, #1 + husart->RxISR = NULL; + 8004d36: 2200 movs r2, #0 + if (USART_SetConfig(husart) == HAL_ERROR) + 8004d38: 429d cmp r5, r3 + husart->TxISR = NULL; + 8004d3a: e9c4 2212 strd r2, r2, [r4, #72] ; 0x48 + husart->NbTxDataToProcess = 1U; + 8004d3e: 87a3 strh r3, [r4, #60] ; 0x3c + husart->NbRxDataToProcess = 1U; + 8004d40: 8763 strh r3, [r4, #58] ; 0x3a + if (USART_SetConfig(husart) == HAL_ERROR) + 8004d42: f43f af1e beq.w 8004b82 + husart->Instance->CR2 &= ~USART_CR2_LINEN; + 8004d46: 6823 ldr r3, [r4, #0] + 8004d48: 6859 ldr r1, [r3, #4] + 8004d4a: f421 4180 bic.w r1, r1, #16384 ; 0x4000 + 8004d4e: 6059 str r1, [r3, #4] + husart->Instance->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN); + 8004d50: 6899 ldr r1, [r3, #8] + 8004d52: f021 012a bic.w r1, r1, #42 ; 0x2a + 8004d56: 6099 str r1, [r3, #8] + __HAL_USART_ENABLE(husart); + 8004d58: 6819 ldr r1, [r3, #0] + 8004d5a: f041 0101 orr.w r1, r1, #1 + 8004d5e: 6019 str r1, [r3, #0] + husart->ErrorCode = HAL_USART_ERROR_NONE; + 8004d60: 65e2 str r2, [r4, #92] ; 0x5c + tickstart = HAL_GetTick(); + 8004d62: f002 fb3b bl 80073dc + if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + 8004d66: 6823 ldr r3, [r4, #0] + 8004d68: 681b ldr r3, [r3, #0] + 8004d6a: 071a lsls r2, r3, #28 + tickstart = HAL_GetTick(); + 8004d6c: 4607 mov r7, r0 + if ((husart->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) + 8004d6e: f100 8085 bmi.w 8004e7c + if ((husart->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) + 8004d72: 6823 ldr r3, [r4, #0] + 8004d74: 681b ldr r3, [r3, #0] + 8004d76: 075b lsls r3, r3, #29 + 8004d78: d505 bpl.n 8004d86 + while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + 8004d7a: 6823 ldr r3, [r4, #0] + 8004d7c: 69de ldr r6, [r3, #28] + 8004d7e: f416 0680 ands.w r6, r6, #4194304 ; 0x400000 + 8004d82: f000 808e beq.w 8004ea2 + husart->State = HAL_USART_STATE_READY; + 8004d86: 2301 movs r3, #1 + 8004d88: f884 3059 strb.w r3, [r4, #89] ; 0x59 + __HAL_UNLOCK(husart); + 8004d8c: 2300 movs r3, #0 + 8004d8e: f884 3058 strb.w r3, [r4, #88] ; 0x58 + return HAL_OK; + 8004d92: e6f7 b.n 8004b84 + pclk = HAL_RCC_GetPCLK1Freq(); + 8004d94: f004 fa88 bl 80092a8 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004d98: e78c b.n 8004cb4 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004d9a: b302 cbz r2, 8004dde + 8004d9c: 2a01 cmp r2, #1 + 8004d9e: d020 beq.n 8004de2 + 8004da0: 2a02 cmp r2, #2 + 8004da2: d020 beq.n 8004de6 + 8004da4: 2a03 cmp r2, #3 + 8004da6: d020 beq.n 8004dea + 8004da8: 2a04 cmp r2, #4 + 8004daa: d020 beq.n 8004dee + 8004dac: 2a05 cmp r2, #5 + 8004dae: d020 beq.n 8004df2 + 8004db0: 2a06 cmp r2, #6 + 8004db2: d020 beq.n 8004df6 + 8004db4: 2a07 cmp r2, #7 + 8004db6: d020 beq.n 8004dfa + 8004db8: 2a08 cmp r2, #8 + 8004dba: d020 beq.n 8004dfe + 8004dbc: 2a09 cmp r2, #9 + 8004dbe: d020 beq.n 8004e02 + 8004dc0: 2a0a cmp r2, #10 + 8004dc2: d020 beq.n 8004e06 + 8004dc4: 2a0b cmp r2, #11 + 8004dc6: bf14 ite ne + 8004dc8: 2201 movne r2, #1 + 8004dca: f44f 7280 moveq.w r2, #256 ; 0x100 + 8004dce: 6861 ldr r1, [r4, #4] + 8004dd0: 4b25 ldr r3, [pc, #148] ; (8004e68 ) + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004dd2: fbb3 f2f2 udiv r2, r3, r2 + 8004dd6: 084b lsrs r3, r1, #1 + 8004dd8: eb03 0342 add.w r3, r3, r2, lsl #1 + 8004ddc: e797 b.n 8004d0e + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(HSI_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004dde: 2201 movs r2, #1 + 8004de0: e7f5 b.n 8004dce + 8004de2: 2202 movs r2, #2 + 8004de4: e7f3 b.n 8004dce + 8004de6: 2204 movs r2, #4 + 8004de8: e7f1 b.n 8004dce + 8004dea: 2206 movs r2, #6 + 8004dec: e7ef b.n 8004dce + 8004dee: 2208 movs r2, #8 + 8004df0: e7ed b.n 8004dce + 8004df2: 220a movs r2, #10 + 8004df4: e7eb b.n 8004dce + 8004df6: 220c movs r2, #12 + 8004df8: e7e9 b.n 8004dce + 8004dfa: 2210 movs r2, #16 + 8004dfc: e7e7 b.n 8004dce + 8004dfe: 2220 movs r2, #32 + 8004e00: e7e5 b.n 8004dce + 8004e02: 2240 movs r2, #64 ; 0x40 + 8004e04: e7e3 b.n 8004dce + 8004e06: 2280 movs r2, #128 ; 0x80 + 8004e08: e7e1 b.n 8004dce + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(pclk, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004e0a: 2201 movs r2, #1 + 8004e0c: e779 b.n 8004d02 + 8004e0e: 2202 movs r2, #2 + 8004e10: e777 b.n 8004d02 + 8004e12: 2204 movs r2, #4 + 8004e14: e775 b.n 8004d02 + 8004e16: 2206 movs r2, #6 + 8004e18: e773 b.n 8004d02 + 8004e1a: 2208 movs r2, #8 + 8004e1c: e771 b.n 8004d02 + 8004e1e: 220a movs r2, #10 + 8004e20: e76f b.n 8004d02 + 8004e22: 220c movs r2, #12 + 8004e24: e76d b.n 8004d02 + 8004e26: 2210 movs r2, #16 + 8004e28: e76b b.n 8004d02 + 8004e2a: 2220 movs r2, #32 + 8004e2c: e769 b.n 8004d02 + 8004e2e: 2240 movs r2, #64 ; 0x40 + 8004e30: e767 b.n 8004d02 + 8004e32: 2280 movs r2, #128 ; 0x80 + 8004e34: e765 b.n 8004d02 + usartdiv = (uint32_t)(USART_DIV_SAMPLING8(LSE_VALUE, husart->Init.BaudRate, husart->Init.ClockPrescaler)); + 8004e36: 2201 movs r2, #1 + 8004e38: e725 b.n 8004c86 + 8004e3a: 2202 movs r2, #2 + 8004e3c: e723 b.n 8004c86 + 8004e3e: 2204 movs r2, #4 + 8004e40: e721 b.n 8004c86 + 8004e42: 2206 movs r2, #6 + 8004e44: e71f b.n 8004c86 + 8004e46: 2208 movs r2, #8 + 8004e48: e71d b.n 8004c86 + 8004e4a: 220a movs r2, #10 + 8004e4c: e71b b.n 8004c86 + 8004e4e: 220c movs r2, #12 + 8004e50: e719 b.n 8004c86 + 8004e52: bf00 nop + 8004e54: cfff69f3 .word 0xcfff69f3 + 8004e58: 40013800 .word 0x40013800 + 8004e5c: 40021000 .word 0x40021000 + 8004e60: 40004400 .word 0x40004400 + 8004e64: 40004800 .word 0x40004800 + 8004e68: 00f42400 .word 0x00f42400 + 8004e6c: 2210 movs r2, #16 + 8004e6e: e70a b.n 8004c86 + 8004e70: 2220 movs r2, #32 + 8004e72: e708 b.n 8004c86 + 8004e74: 2240 movs r2, #64 ; 0x40 + 8004e76: e706 b.n 8004c86 + 8004e78: 2280 movs r2, #128 ; 0x80 + 8004e7a: e704 b.n 8004c86 + while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status) + 8004e7c: 6823 ldr r3, [r4, #0] + 8004e7e: 69de ldr r6, [r3, #28] + 8004e80: f416 1600 ands.w r6, r6, #2097152 ; 0x200000 + 8004e84: f47f af75 bne.w 8004d72 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 8004e88: f002 faa8 bl 80073dc + 8004e8c: 1bc0 subs r0, r0, r7 + 8004e8e: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8 + 8004e92: d9f3 bls.n 8004e7c + husart->State = HAL_USART_STATE_READY; + 8004e94: 2301 movs r3, #1 + 8004e96: f884 3059 strb.w r3, [r4, #89] ; 0x59 + __HAL_UNLOCK(husart); + 8004e9a: f884 6058 strb.w r6, [r4, #88] ; 0x58 + return HAL_TIMEOUT; + 8004e9e: 2503 movs r5, #3 + 8004ea0: e670 b.n 8004b84 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 8004ea2: f002 fa9b bl 80073dc + 8004ea6: 1bc0 subs r0, r0, r7 + 8004ea8: f5b0 7f7a cmp.w r0, #1000 ; 0x3e8 + 8004eac: f67f af65 bls.w 8004d7a + 8004eb0: e7f0 b.n 8004e94 + 8004eb2: bf00 nop + +08004eb4 : + __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); + 8004eb4: 4b14 ldr r3, [pc, #80] ; (8004f08 ) + 8004eb6: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8004eba: f022 0203 bic.w r2, r2, #3 + 8004ebe: f042 0201 orr.w r2, r2, #1 +{ + 8004ec2: b513 push {r0, r1, r4, lr} + __HAL_RCC_USART1_CONFIG(RCC_USART1CLKSOURCE_SYSCLK); + 8004ec4: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + __HAL_RCC_USART1_CLK_ENABLE(); + 8004ec8: 6e1a ldr r2, [r3, #96] ; 0x60 + memset(&con, 0, sizeof(con)); + 8004eca: 4c10 ldr r4, [pc, #64] ; (8004f0c ) + __HAL_RCC_USART1_CLK_ENABLE(); + 8004ecc: f442 4280 orr.w r2, r2, #16384 ; 0x4000 + 8004ed0: 661a str r2, [r3, #96] ; 0x60 + 8004ed2: 6e1b ldr r3, [r3, #96] ; 0x60 + 8004ed4: f403 4380 and.w r3, r3, #16384 ; 0x4000 + 8004ed8: 9301 str r3, [sp, #4] + memset(&con, 0, sizeof(con)); + 8004eda: 2258 movs r2, #88 ; 0x58 + 8004edc: 2100 movs r1, #0 + 8004ede: f104 0008 add.w r0, r4, #8 + __HAL_RCC_USART1_CLK_ENABLE(); + 8004ee2: 9b01 ldr r3, [sp, #4] + memset(&con, 0, sizeof(con)); + 8004ee4: f008 fd1e bl 800d924 + con.Init.BaudRate = 115200; + 8004ee8: 4a09 ldr r2, [pc, #36] ; (8004f10 ) + 8004eea: f44f 33e1 mov.w r3, #115200 ; 0x1c200 + 8004eee: e9c4 2300 strd r2, r3, [r4] + HAL_StatusTypeDef rv = HAL_USART_Init(&con); + 8004ef2: 4620 mov r0, r4 + con.Init.Mode = USART_MODE_TX_RX; + 8004ef4: 230c movs r3, #12 + 8004ef6: 6163 str r3, [r4, #20] + HAL_StatusTypeDef rv = HAL_USART_Init(&con); + 8004ef8: f7ff fe40 bl 8004b7c + ASSERT(rv == HAL_OK); + 8004efc: b110 cbz r0, 8004f04 + 8004efe: 4805 ldr r0, [pc, #20] ; (8004f14 ) + 8004f00: f7fb fd9a bl 8000a38 +} + 8004f04: b002 add sp, #8 + 8004f06: bd10 pop {r4, pc} + 8004f08: 40021000 .word 0x40021000 + 8004f0c: 2009e1c4 .word 0x2009e1c4 + 8004f10: 40013800 .word 0x40013800 + 8004f14: 0801046c .word 0x0801046c + +08004f18 : + * @param Timeout Timeout duration. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout) +{ + while(Size > 0U) { + 8004f18: 4b0b ldr r3, [pc, #44] ; (8004f48 ) + 8004f1a: 440a add r2, r1 + 8004f1c: 4291 cmp r1, r2 + 8004f1e: d10b bne.n 8004f38 + MY_UART->TDR = *pTxData; + pTxData++; + Size --; + } + + while(!(MY_UART->ISR & UART_FLAG_TC)) { + 8004f20: 69da ldr r2, [r3, #28] + 8004f22: 0652 lsls r2, r2, #25 + 8004f24: d5fc bpl.n 8004f20 + // wait for final byte to be sent + } + + // Clear Transmission Complete Flag + MY_UART->ICR = USART_CLEAR_TCF; + 8004f26: 2240 movs r2, #64 ; 0x40 + 8004f28: 621a str r2, [r3, #32] + + // Clear overrun flag and discard the received data + MY_UART->ICR = USART_CLEAR_OREF; + 8004f2a: 2208 movs r2, #8 + 8004f2c: 621a str r2, [r3, #32] + MY_UART->RQR = USART_RXDATA_FLUSH_REQUEST; + 8004f2e: 831a strh r2, [r3, #24] + MY_UART->RQR = USART_TXDATA_FLUSH_REQUEST; + 8004f30: 2210 movs r2, #16 + 8004f32: 831a strh r2, [r3, #24] + + return HAL_OK; +} + 8004f34: 2000 movs r0, #0 + 8004f36: 4770 bx lr + while(!(MY_UART->ISR & UART_FLAG_TXE)) { + 8004f38: 69d8 ldr r0, [r3, #28] + 8004f3a: 0600 lsls r0, r0, #24 + 8004f3c: d5fc bpl.n 8004f38 + MY_UART->TDR = *pTxData; + 8004f3e: f811 0b01 ldrb.w r0, [r1], #1 + 8004f42: 8518 strh r0, [r3, #40] ; 0x28 + Size --; + 8004f44: e7ea b.n 8004f1c + 8004f46: bf00 nop + 8004f48: 40013800 .word 0x40013800 + +08004f4c : +{ + 8004f4c: b510 push {r4, lr} + 8004f4e: 4604 mov r4, r0 + rng_delay(); + 8004f50: f7fd fcda bl 8002908 + HAL_USART_Transmit(&con, (uint8_t *)msg, strlen(msg), HAL_MAX_DELAY); + 8004f54: 4620 mov r0, r4 + 8004f56: f008 fd10 bl 800d97a + 8004f5a: 4621 mov r1, r4 + 8004f5c: b282 uxth r2, r0 + 8004f5e: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004f62: 4803 ldr r0, [pc, #12] ; (8004f70 ) + 8004f64: f7ff ffd8 bl 8004f18 +} + 8004f68: e8bd 4010 ldmia.w sp!, {r4, lr} + rng_delay(); + 8004f6c: f7fd bccc b.w 8002908 + 8004f70: 2009e1c4 .word 0x2009e1c4 + +08004f74 : +{ + 8004f74: b513 push {r0, r1, r4, lr} + 8004f76: 4604 mov r4, r0 + uint8_t cb = c; + 8004f78: f88d 0007 strb.w r0, [sp, #7] + rng_delay(); + 8004f7c: f7fd fcc4 bl 8002908 + if(cb != '\n') { + 8004f80: f89d 3007 ldrb.w r3, [sp, #7] + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004f84: 4808 ldr r0, [pc, #32] ; (8004fa8 ) + if(cb != '\n') { + 8004f86: 2b0a cmp r3, #10 + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004f88: bf08 it eq + 8004f8a: 4908 ldreq r1, [pc, #32] ; (8004fac ) + HAL_USART_Transmit(&con, &cb, 1, HAL_MAX_DELAY); + 8004f8c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8004f90: bf1a itte ne + 8004f92: 2201 movne r2, #1 + 8004f94: f10d 0107 addne.w r1, sp, #7 + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8004f98: 2202 moveq r2, #2 + 8004f9a: f7ff ffbd bl 8004f18 + rng_delay(); + 8004f9e: f7fd fcb3 bl 8002908 +} + 8004fa2: 4620 mov r0, r4 + 8004fa4: b002 add sp, #8 + 8004fa6: bd10 pop {r4, pc} + 8004fa8: 2009e1c4 .word 0x2009e1c4 + 8004fac: 080107cb .word 0x080107cb + +08004fb0 : +{ + 8004fb0: b538 push {r3, r4, r5, lr} + putchar(hexmap[(b>>4) & 0xf]); + 8004fb2: 4d06 ldr r5, [pc, #24] ; (8004fcc ) + 8004fb4: 0903 lsrs r3, r0, #4 +{ + 8004fb6: 4604 mov r4, r0 + putchar(hexmap[(b>>0) & 0xf]); + 8004fb8: f004 040f and.w r4, r4, #15 + putchar(hexmap[(b>>4) & 0xf]); + 8004fbc: 5ce8 ldrb r0, [r5, r3] + 8004fbe: f7ff ffd9 bl 8004f74 + putchar(hexmap[(b>>0) & 0xf]); + 8004fc2: 5d28 ldrb r0, [r5, r4] +} + 8004fc4: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + putchar(hexmap[(b>>0) & 0xf]); + 8004fc8: f7ff bfd4 b.w 8004f74 + 8004fcc: 080107ce .word 0x080107ce + +08004fd0 : +{ + 8004fd0: b538 push {r3, r4, r5, lr} + putchar(hexmap[(w>>12) & 0xf]); + 8004fd2: 4d0b ldr r5, [pc, #44] ; (8005000 ) + 8004fd4: 0b03 lsrs r3, r0, #12 +{ + 8004fd6: 4604 mov r4, r0 + putchar(hexmap[(w>>12) & 0xf]); + 8004fd8: 5ce8 ldrb r0, [r5, r3] + 8004fda: f7ff ffcb bl 8004f74 + putchar(hexmap[(w>>8) & 0xf]); + 8004fde: f3c4 2303 ubfx r3, r4, #8, #4 + 8004fe2: 5ce8 ldrb r0, [r5, r3] + 8004fe4: f7ff ffc6 bl 8004f74 + putchar(hexmap[(w>>4) & 0xf]); + 8004fe8: f3c4 1303 ubfx r3, r4, #4, #4 + putchar(hexmap[(w>>0) & 0xf]); + 8004fec: f004 040f and.w r4, r4, #15 + putchar(hexmap[(w>>4) & 0xf]); + 8004ff0: 5ce8 ldrb r0, [r5, r3] + 8004ff2: f7ff ffbf bl 8004f74 + putchar(hexmap[(w>>0) & 0xf]); + 8004ff6: 5d28 ldrb r0, [r5, r4] +} + 8004ff8: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + putchar(hexmap[(w>>0) & 0xf]); + 8004ffc: f7ff bfba b.w 8004f74 + 8005000: 080107ce .word 0x080107ce + +08005004 : +{ + 8005004: b510 push {r4, lr} + 8005006: 4604 mov r4, r0 + puthex4(w >> 16); + 8005008: 0c00 lsrs r0, r0, #16 + 800500a: f7ff ffe1 bl 8004fd0 + puthex4(w & 0xffff); + 800500e: b2a0 uxth r0, r4 +} + 8005010: e8bd 4010 ldmia.w sp!, {r4, lr} + puthex4(w & 0xffff); + 8005014: f7ff bfdc b.w 8004fd0 + +08005018 : +{ + 8005018: b5f8 push {r3, r4, r5, r6, r7, lr} + 800501a: 4605 mov r5, r0 + 800501c: 2604 movs r6, #4 + for(int m=1000; m; m /= 10) { + 800501e: f44f 747a mov.w r4, #1000 ; 0x3e8 + char n = '0' + ((w / m) % 10); + 8005022: 270a movs r7, #10 + if(w >= m) { + 8005024: 42a5 cmp r5, r4 + 8005026: db09 blt.n 800503c + char n = '0' + ((w / m) % 10); + 8005028: fb95 f3f4 sdiv r3, r5, r4 + 800502c: fb93 f0f7 sdiv r0, r3, r7 + 8005030: fb07 3310 mls r3, r7, r0, r3 + 8005034: 3330 adds r3, #48 ; 0x30 + putchar(n); + 8005036: b2d8 uxtb r0, r3 + 8005038: f7ff ff9c bl 8004f74 + for(int m=1000; m; m /= 10) { + 800503c: fb94 f4f7 sdiv r4, r4, r7 + 8005040: 3e01 subs r6, #1 + 8005042: d1ef bne.n 8005024 +} + 8005044: bdf8 pop {r3, r4, r5, r6, r7, pc} + +08005046 : +{ + 8005046: b570 push {r4, r5, r6, lr} + 8005048: 4606 mov r6, r0 + 800504a: 460d mov r5, r1 + for(int i=0; i +} + 8005052: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + putchar('\n'); + 8005056: 200a movs r0, #10 + 8005058: f7ff bf8c b.w 8004f74 + puthex2(data[i]); + 800505c: 5d30 ldrb r0, [r6, r4] + 800505e: f7ff ffa7 bl 8004fb0 + for(int i=0; i + ... + +08005068 : +{ + 8005068: b513 push {r0, r1, r4, lr} + 800506a: 9001 str r0, [sp, #4] + int ln = strlen(msg); + 800506c: f008 fc85 bl 800d97a + 8005070: 4604 mov r4, r0 + rng_delay(); + 8005072: f7fd fc49 bl 8002908 + if(ln) HAL_USART_Transmit(&con, (uint8_t *)msg, ln, HAL_MAX_DELAY); + 8005076: 9901 ldr r1, [sp, #4] + 8005078: b12c cbz r4, 8005086 + 800507a: 4809 ldr r0, [pc, #36] ; (80050a0 ) + 800507c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8005080: b2a2 uxth r2, r4 + 8005082: f7ff ff49 bl 8004f18 + HAL_USART_Transmit(&con, (uint8_t *)CRLF, 2, HAL_MAX_DELAY); + 8005086: 4907 ldr r1, [pc, #28] ; (80050a4 ) + 8005088: 4805 ldr r0, [pc, #20] ; (80050a0 ) + 800508a: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800508e: 2202 movs r2, #2 + 8005090: f7ff ff42 bl 8004f18 + rng_delay(); + 8005094: f7fd fc38 bl 8002908 +} + 8005098: 2001 movs r0, #1 + 800509a: b002 add sp, #8 + 800509c: bd10 pop {r4, pc} + 800509e: bf00 nop + 80050a0: 2009e1c4 .word 0x2009e1c4 + 80050a4: 080107cb .word 0x080107cb + +080050a8 : + +// psram_send_byte() +// + void +psram_send_byte(OSPI_HandleTypeDef *qh, uint8_t cmd_byte, bool is_quad) +{ + 80050a8: b570 push {r4, r5, r6, lr} + 80050aa: b094 sub sp, #80 ; 0x50 + 80050ac: 4604 mov r4, r0 + 80050ae: 460e mov r6, r1 + 80050b0: 4615 mov r5, r2 + // Send single-byte commands to the PSRAM chip. Quad mode or normal SPI. + + OSPI_RegularCmdTypeDef cmd = { + 80050b2: 2100 movs r1, #0 + 80050b4: 2250 movs r2, #80 ; 0x50 + 80050b6: 4668 mov r0, sp + 80050b8: f008 fc34 bl 800d924 + .OperationType = HAL_OSPI_OPTYPE_COMMON_CFG, + .Instruction = cmd_byte, // Exit Quad Mode + .InstructionMode = is_quad ? HAL_OSPI_INSTRUCTION_4_LINES : HAL_OSPI_INSTRUCTION_1_LINE, + 80050bc: 2d00 cmp r5, #0 + 80050be: bf14 ite ne + 80050c0: 2303 movne r3, #3 + 80050c2: 2301 moveq r3, #1 + .DataMode = HAL_OSPI_DATA_NONE, + .NbData = 0, // how much to read in bytes + }; + + // Start and finish a "Indirection functional mode" request + HAL_OSPI_Command(qh, &cmd, HAL_MAX_DELAY); + 80050c4: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 80050c8: 4669 mov r1, sp + 80050ca: 4620 mov r0, r4 + OSPI_RegularCmdTypeDef cmd = { + 80050cc: 9602 str r6, [sp, #8] + 80050ce: 9303 str r3, [sp, #12] + HAL_OSPI_Command(qh, &cmd, HAL_MAX_DELAY); + 80050d0: f006 f898 bl 800b204 +} + 80050d4: b014 add sp, #80 ; 0x50 + 80050d6: bd70 pop {r4, r5, r6, pc} + +080050d8 : + +// psram_setup() +// + void +psram_setup(void) +{ + 80050d8: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80050dc: b0c6 sub sp, #280 ; 0x118 + // Using OSPI1 block + OSPI_HandleTypeDef qh = { 0 }; + 80050de: 2250 movs r2, #80 ; 0x50 + 80050e0: 2100 movs r1, #0 + 80050e2: a80a add r0, sp, #40 ; 0x28 + 80050e4: f008 fc1e bl 800d924 + + // enable clocks + __HAL_RCC_OSPI1_CLK_ENABLE(); + 80050e8: 4b6a ldr r3, [pc, #424] ; (8005294 ) + // reset module + __HAL_RCC_OSPI1_FORCE_RESET(); + __HAL_RCC_OSPI1_RELEASE_RESET(); + + // configure pins: Port E PE10-PE15 + GPIO_InitTypeDef setup = { + 80050ea: 4c6b ldr r4, [pc, #428] ; (8005298 ) + __HAL_RCC_OSPI1_CLK_ENABLE(); + 80050ec: 6d1a ldr r2, [r3, #80] ; 0x50 + 80050ee: f442 7280 orr.w r2, r2, #256 ; 0x100 + 80050f2: 651a str r2, [r3, #80] ; 0x50 + 80050f4: 6d1a ldr r2, [r3, #80] ; 0x50 + 80050f6: f402 7280 and.w r2, r2, #256 ; 0x100 + 80050fa: 9201 str r2, [sp, #4] + 80050fc: 9a01 ldr r2, [sp, #4] + __HAL_RCC_GPIOE_CLK_ENABLE(); + 80050fe: 6cda ldr r2, [r3, #76] ; 0x4c + 8005100: f042 0210 orr.w r2, r2, #16 + 8005104: 64da str r2, [r3, #76] ; 0x4c + 8005106: 6cda ldr r2, [r3, #76] ; 0x4c + 8005108: f002 0210 and.w r2, r2, #16 + 800510c: 9202 str r2, [sp, #8] + 800510e: 9a02 ldr r2, [sp, #8] + __HAL_RCC_OSPI1_FORCE_RESET(); + 8005110: 6b1a ldr r2, [r3, #48] ; 0x30 + 8005112: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8005116: 631a str r2, [r3, #48] ; 0x30 + __HAL_RCC_OSPI1_RELEASE_RESET(); + 8005118: 6b1a ldr r2, [r3, #48] ; 0x30 + 800511a: f422 7280 bic.w r2, r2, #256 ; 0x100 + 800511e: 631a str r2, [r3, #48] ; 0x30 + GPIO_InitTypeDef setup = { + 8005120: cc0f ldmia r4!, {r0, r1, r2, r3} + 8005122: ad05 add r5, sp, #20 + 8005124: c50f stmia r5!, {r0, r1, r2, r3} + 8005126: 6823 ldr r3, [r4, #0] + .Mode = GPIO_MODE_AF_PP, // not sure + .Pull = GPIO_NOPULL, // not sure + .Speed = GPIO_SPEED_FREQ_VERY_HIGH, + .Alternate = GPIO_AF10_OCTOSPIM_P1, + }; + HAL_GPIO_Init(GPIOE, &setup); + 8005128: 485c ldr r0, [pc, #368] ; (800529c ) + GPIO_InitTypeDef setup = { + 800512a: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOE, &setup); + 800512c: a905 add r1, sp, #20 + 800512e: f7fc f861 bl 80011f4 + + + // Config operational values + qh.Instance = OCTOSPI1; + qh.Init.FifoThreshold = 1; // ?? unused + 8005132: 4b5b ldr r3, [pc, #364] ; (80052a0 ) + 8005134: 2701 movs r7, #1 + qh.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + qh.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; // want standard mode (but octo only?) + qh.Init.DeviceSize = 24; // assume max size, actual is 8Mbyte + 8005136: 2218 movs r2, #24 + qh.Init.FifoThreshold = 1; // ?? unused + 8005138: e9cd 370a strd r3, r7, [sp, #40] ; 0x28 + qh.Init.ChipSelectHighTime = 1; // 1, maxed out, seems to work + 800513c: e9cd 270e strd r2, r7, [sp, #56] ; 0x38 + qh.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE; + 8005140: 2300 movs r3, #0 + qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe? + 8005142: f04f 5280 mov.w r2, #268435456 ; 0x10000000 + qh.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; // required! + qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata) +#if HCLK_FREQUENCY == 80000000 + qh.Init.ClockPrescaler = 1; // prescaler (1=>80Mhz, 2=>40Mhz, etc) +#elif HCLK_FREQUENCY == 120000000 + qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc) + 8005146: f04f 0802 mov.w r8, #2 +#else +# error "testing needed" +#endif + qh.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED; // dont need it? + 800514a: f04f 0908 mov.w r9, #8 + // - (during reads) 3 => 400ns 4 => 660ns 5+ => 1us + // - LATER: Errata 2.8.1 => says shall not use + qh.Init.ChipSelectBoundary = 0; + + // module init + HAL_StatusTypeDef rv = HAL_OSPI_Init(&qh); + 800514e: a80a add r0, sp, #40 ; 0x28 + qh.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON; // want standard mode (but octo only?) + 8005150: e9cd 330c strd r3, r3, [sp, #48] ; 0x30 + qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata) + 8005154: e9cd 3310 strd r3, r3, [sp, #64] ; 0x40 + qh.Init.ChipSelectBoundary = 0; + 8005158: e9cd 3915 strd r3, r9, [sp, #84] ; 0x54 + qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe? + 800515c: 9214 str r2, [sp, #80] ; 0x50 + qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc) + 800515e: f8cd 8048 str.w r8, [sp, #72] ; 0x48 + HAL_StatusTypeDef rv = HAL_OSPI_Init(&qh); + 8005162: f005 ffe5 bl 800b130 + ASSERT(rv == HAL_OK); + 8005166: 4606 mov r6, r0 + 8005168: b110 cbz r0, 8005170 + 800516a: 484e ldr r0, [pc, #312] ; (80052a4 ) + 800516c: f7fb fc64 bl 8000a38 + + // do some SPI commands first + + // Exit Quad mode, to get to a known state, after first power-up + psram_send_byte(&qh, 0xf5, true); + 8005170: 463a mov r2, r7 + 8005172: 21f5 movs r1, #245 ; 0xf5 + 8005174: a80a add r0, sp, #40 ; 0x28 + 8005176: f7ff ff97 bl 80050a8 + + // Chip Reset sequence + psram_send_byte(&qh, 0x66, false); // reset enable + 800517a: 4632 mov r2, r6 + 800517c: 2166 movs r1, #102 ; 0x66 + 800517e: a80a add r0, sp, #40 ; 0x28 + 8005180: f7ff ff92 bl 80050a8 + + // Read Electronic ID + // - length not clear from datasheet, but repeats after 8 bytes + uint8_t psram_chip_eid[8]; + + { OSPI_RegularCmdTypeDef cmd = { + 8005184: ad32 add r5, sp, #200 ; 0xc8 + psram_send_byte(&qh, 0x99, false); // reset + 8005186: 4632 mov r2, r6 + 8005188: 2199 movs r1, #153 ; 0x99 + 800518a: a80a add r0, sp, #40 ; 0x28 + 800518c: f7ff ff8c bl 80050a8 + { OSPI_RegularCmdTypeDef cmd = { + 8005190: 2250 movs r2, #80 ; 0x50 + 8005192: 4631 mov r1, r6 + 8005194: 4628 mov r0, r5 + 8005196: f008 fbc5 bl 800d924 + 800519a: 239f movs r3, #159 ; 0x9f + 800519c: e9cd 3734 strd r3, r7, [sp, #208] ; 0xd0 + 80051a0: f44f 5a00 mov.w sl, #8192 ; 0x2000 + 80051a4: f44f 7380 mov.w r3, #256 ; 0x100 + 80051a8: e9cd 3a39 strd r3, sl, [sp, #228] ; 0xe4 + .DataMode = HAL_OSPI_DATA_1_LINE, + .NbData = sizeof(psram_chip_eid), // how much to read in bytes + }; + + // Start a "Indirection functional mode" request + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 80051ac: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + { OSPI_RegularCmdTypeDef cmd = { + 80051b0: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 80051b4: 4629 mov r1, r5 + 80051b6: a80a add r0, sp, #40 ; 0x28 + { OSPI_RegularCmdTypeDef cmd = { + 80051b8: e9cd 3940 strd r3, r9, [sp, #256] ; 0x100 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 80051bc: f006 f822 bl 800b204 + if(rv != HAL_OK) goto fail; + 80051c0: 2800 cmp r0, #0 + 80051c2: d15d bne.n 8005280 + + rv = HAL_OSPI_Receive(&qh, psram_chip_eid, HAL_MAX_DELAY); + 80051c4: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 80051c8: a903 add r1, sp, #12 + 80051ca: a80a add r0, sp, #40 ; 0x28 + 80051cc: f006 f94c bl 800b468 + if(rv != HAL_OK) goto fail; + 80051d0: 4606 mov r6, r0 + 80051d2: 2800 cmp r0, #0 + 80051d4: d154 bne.n 8005280 + } + + //puts2("PSRAM EID: "); + //hex_dump(psram_chip_eid, sizeof(psram_chip_eid)); + ASSERT(psram_chip_eid[0] == 0x0d); + 80051d6: f89d 300c ldrb.w r3, [sp, #12] + 80051da: 2b0d cmp r3, #13 + 80051dc: d1c5 bne.n 800516a + ASSERT(psram_chip_eid[1] == 0x5d); + 80051de: f89d 300d ldrb.w r3, [sp, #13] + 80051e2: 2b5d cmp r3, #93 ; 0x5d + 80051e4: d1c1 bne.n 800516a + // .. other bits seem pretty similar between devices, they don't claim they are UUID + + // Put into Quad mode + psram_send_byte(&qh, 0x35, false); // 0x35 = Enter Quad Mode + 80051e6: 4602 mov r2, r0 + 80051e8: 2135 movs r1, #53 ; 0x35 + 80051ea: a80a add r0, sp, #40 ; 0x28 + 80051ec: f7ff ff5c bl 80050a8 + + // Configure read/write cycles for mem-mapped mode + { OSPI_RegularCmdTypeDef cmd = { + 80051f0: 4631 mov r1, r6 + 80051f2: 224c movs r2, #76 ; 0x4c + 80051f4: a81f add r0, sp, #124 ; 0x7c + 80051f6: f008 fb95 bl 800d924 + 80051fa: f04f 0903 mov.w r9, #3 + 80051fe: f8cd 8078 str.w r8, [sp, #120] ; 0x78 + 8005202: f8cd 8080 str.w r8, [sp, #128] ; 0x80 + .DataMode = HAL_OSPI_DATA_4_LINES, + .NbData = 0, // don't care / TBD? + }; + + // Config for write + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8005206: a91e add r1, sp, #120 ; 0x78 + { OSPI_RegularCmdTypeDef cmd = { + 8005208: f44f 7840 mov.w r8, #768 ; 0x300 + 800520c: f04f 7640 mov.w r6, #50331648 ; 0x3000000 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8005210: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 8005214: a80a add r0, sp, #40 ; 0x28 + { OSPI_RegularCmdTypeDef cmd = { + 8005216: e9cd 8a25 strd r8, sl, [sp, #148] ; 0x94 + 800521a: f8cd 9084 str.w r9, [sp, #132] ; 0x84 + 800521e: 962c str r6, [sp, #176] ; 0xb0 + rv = HAL_OSPI_Command(&qh, &cmd, HAL_MAX_DELAY); + 8005220: f005 fff0 bl 800b204 + if(rv != HAL_OK) goto fail; + 8005224: 4601 mov r1, r0 + 8005226: bb58 cbnz r0, 8005280 + + // .. for read + OSPI_RegularCmdTypeDef cmd2 = { + 8005228: 224c movs r2, #76 ; 0x4c + 800522a: a833 add r0, sp, #204 ; 0xcc + 800522c: f008 fb7a bl 800d924 + 8005230: 23eb movs r3, #235 ; 0xeb + 8005232: e9cd 3934 strd r3, r9, [sp, #208] ; 0xd0 + .DataMode = HAL_OSPI_DATA_4_LINES, + .NbData = 0, // don't care / TBD? + }; + + // Config for read + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 8005236: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + OSPI_RegularCmdTypeDef cmd2 = { + 800523a: 2306 movs r3, #6 + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 800523c: 4629 mov r1, r5 + 800523e: a80a add r0, sp, #40 ; 0x28 + OSPI_RegularCmdTypeDef cmd2 = { + 8005240: e9cd 8a39 strd r8, sl, [sp, #228] ; 0xe4 + 8005244: 9732 str r7, [sp, #200] ; 0xc8 + 8005246: 9640 str r6, [sp, #256] ; 0x100 + 8005248: 9343 str r3, [sp, #268] ; 0x10c + rv = HAL_OSPI_Command(&qh, &cmd2, HAL_MAX_DELAY); + 800524a: f005 ffdb bl 800b204 + if(rv != HAL_OK) goto fail; + 800524e: b9b8 cbnz r0, 8005280 + } + + // config for memmap + { OSPI_MemoryMappedTypeDef mmap = { + 8005250: e9d4 0101 ldrd r0, r1, [r4, #4] + 8005254: e885 0003 stmia.w r5, {r0, r1} + // Need this so that CS lines returns to inactive sometimes. + .TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE, + .TimeOutPeriod = 16, // no idea, max value 0xffff + }; + + rv = HAL_OSPI_MemoryMapped(&qh, &mmap); + 8005258: 4629 mov r1, r5 + 800525a: a80a add r0, sp, #40 ; 0x28 + 800525c: f006 f9ea bl 800b634 + if(rv != HAL_OK) goto fail; + 8005260: b970 cbnz r0, 8005280 +#else + // Only a quick operational check only here. Non-destructive. + { __IO uint32_t *ptr = (uint32_t *)(PSRAM_BASE+PSRAM_SIZE-4); + uint32_t tmp; + + tmp = *ptr; + 8005262: 4b11 ldr r3, [pc, #68] ; (80052a8 ) + *ptr = 0x55aa1234; + 8005264: 4a11 ldr r2, [pc, #68] ; (80052ac ) + tmp = *ptr; + 8005266: f8d3 1ffc ldr.w r1, [r3, #4092] ; 0xffc + *ptr = 0x55aa1234; + 800526a: f8c3 2ffc str.w r2, [r3, #4092] ; 0xffc + if(*ptr != 0x55aa1234) goto fail; + 800526e: f8d3 0ffc ldr.w r0, [r3, #4092] ; 0xffc + 8005272: 4290 cmp r0, r2 + 8005274: d104 bne.n 8005280 + *ptr = tmp; + 8005276: f8c3 1ffc str.w r1, [r3, #4092] ; 0xffc + + oled_setup(); + oled_show(screen_fatal); + + LOCKUP_FOREVER(); +} + 800527a: b046 add sp, #280 ; 0x118 + 800527c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + puts("PSRAM fail"); + 8005280: 480b ldr r0, [pc, #44] ; (80052b0 ) + 8005282: f7ff fef1 bl 8005068 + oled_setup(); + 8005286: f7fb fd75 bl 8000d74 + oled_show(screen_fatal); + 800528a: 480a ldr r0, [pc, #40] ; (80052b4 ) + 800528c: f7fb fef2 bl 8001074 + LOCKUP_FOREVER(); + 8005290: f7fe fcf2 bl 8003c78 + 8005294: 40021000 .word 0x40021000 + 8005298: 0801080c .word 0x0801080c + 800529c: 48001000 .word 0x48001000 + 80052a0: a0001000 .word 0xa0001000 + 80052a4: 0801046c .word 0x0801046c + 80052a8: 907ff000 .word 0x907ff000 + 80052ac: 55aa1234 .word 0x55aa1234 + 80052b0: 080107de .word 0x080107de + 80052b4: 0800e58d .word 0x0800e58d + +080052b8 : + +// psram_wipe() +// + void +psram_wipe(void) +{ + 80052b8: b508 push {r3, lr} + if(OCTOSPI1->CR == 0) return; // PSRAM not enabled (yet?) + 80052ba: 4b06 ldr r3, [pc, #24] ; (80052d4 ) + 80052bc: 681b ldr r3, [r3, #0] + 80052be: b143 cbz r3, 80052d2 + + // Fast! But real; maybe 150ms + //puts2("PSRAM Wipe: "); + memset4((uint32_t *)PSRAM_BASE, rng_sample(), PSRAM_SIZE); + 80052c0: f7fd face bl 8002860 + 80052c4: f04f 4310 mov.w r3, #2415919104 ; 0x90000000 + *dest = value; + 80052c8: f843 0b04 str.w r0, [r3], #4 + for(; byte_len; byte_len-=4, dest++) { + 80052cc: f113 4fdf cmn.w r3, #1870659584 ; 0x6f800000 + 80052d0: d1fa bne.n 80052c8 + //puts("done"); +} + 80052d2: bd08 pop {r3, pc} + 80052d4: a0001000 .word 0xa0001000 + +080052d8 : +// NOTE: Incoming start address is typically not aligned. +// + void +psram_do_upgrade(const uint8_t *start, uint32_t size) +{ + ASSERT(size >= FW_MIN_LENGTH); + 80052d8: f5b1 2f80 cmp.w r1, #262144 ; 0x40000 +{ + 80052dc: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + 80052e0: 4606 mov r6, r0 + 80052e2: 460d mov r5, r1 + ASSERT(size >= FW_MIN_LENGTH); + 80052e4: d202 bcs.n 80052ec + 80052e6: 481e ldr r0, [pc, #120] ; (8005360 ) + 80052e8: f7fb fba6 bl 8000a38 + + // In case of reset/crash, we can recover, so save + // what we need for that -- yes, we will re-verify signatures + volatile recovery_header_t *h = RECHDR_POS; + h->start = start; + 80052ec: 4b1d ldr r3, [pc, #116] ; (8005364 ) + h->size = size; + h->magic1 = RECHDR_MAGIC1; + 80052ee: 4a1e ldr r2, [pc, #120] ; (8005368 ) + h->start = start; + 80052f0: 6058 str r0, [r3, #4] + h->size = size; + 80052f2: 6099 str r1, [r3, #8] + h->magic1 = RECHDR_MAGIC1; + 80052f4: 601a str r2, [r3, #0] + h->magic2 = RECHDR_MAGIC2; + 80052f6: 4a1d ldr r2, [pc, #116] ; (800536c ) + 80052f8: 60da str r2, [r3, #12] + + flash_setup0(); + 80052fa: f7fc ff4f bl 800219c + flash_unlock(); + 80052fe: f7fc ff71 bl 80021e4 + for(uint32_t pos=0; pos < size; pos += 8) { + uint32_t dest = FIRMWARE_START+pos; + + if(dest % (4*FLASH_ERASE_SIZE) == 0) { + // show some progress + oled_show_progress(screen_upgrading, pos*100/size); + 8005302: f8df 906c ldr.w r9, [pc, #108] ; 8005370 + for(uint32_t pos=0; pos < size; pos += 8) { + 8005306: 2400 movs r4, #0 + oled_show_progress(screen_upgrading, pos*100/size); + 8005308: f04f 0864 mov.w r8, #100 ; 0x64 + uint32_t dest = FIRMWARE_START+pos; + 800530c: f104 6700 add.w r7, r4, #134217728 ; 0x8000000 + if(dest % (4*FLASH_ERASE_SIZE) == 0) { + 8005310: f3c4 030d ubfx r3, r4, #0, #14 + 8005314: f507 3700 add.w r7, r7, #131072 ; 0x20000 + 8005318: b933 cbnz r3, 8005328 + oled_show_progress(screen_upgrading, pos*100/size); + 800531a: fb08 f104 mul.w r1, r8, r4 + 800531e: 4648 mov r0, r9 + 8005320: fbb1 f1f5 udiv r1, r1, r5 + 8005324: f7fb ff20 bl 8001168 + } + + if(dest % FLASH_ERASE_SIZE == 0) { + 8005328: f3c7 030b ubfx r3, r7, #0, #12 + 800532c: b923 cbnz r3, 8005338 + // page erase as we go + rv = flash_page_erase(dest); + 800532e: 4638 mov r0, r7 + 8005330: f008 fb32 bl 800d998 <__flash_page_erase_veneer> + puts2("erase rv="); + puthex2(rv); + putchar('\n'); + } +#endif + ASSERT(rv == 0); + 8005334: 2800 cmp r0, #0 + 8005336: d1d6 bne.n 80052e6 + } + + memcpy(&tmp, start+pos, 8); + 8005338: 1932 adds r2, r6, r4 + 800533a: 5930 ldr r0, [r6, r4] + 800533c: 6851 ldr r1, [r2, #4] + 800533e: 466b mov r3, sp + 8005340: c303 stmia r3!, {r0, r1} + rv = flash_burn(dest, tmp); + 8005342: 4638 mov r0, r7 + 8005344: e9dd 2300 ldrd r2, r3, [sp] + 8005348: f008 fb22 bl 800d990 <__flash_burn_veneer> + puts2(" addr="); + puthex8(dest); + putchar('\n'); + } +#endif + ASSERT(rv == 0); + 800534c: 2800 cmp r0, #0 + 800534e: d1ca bne.n 80052e6 + for(uint32_t pos=0; pos < size; pos += 8) { + 8005350: 3408 adds r4, #8 + 8005352: 42a5 cmp r5, r4 + 8005354: d8da bhi.n 800530c + } + + flash_lock(); +} + 8005356: b003 add sp, #12 + 8005358: e8bd 43f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, lr} + flash_lock(); + 800535c: f7fc bf3a b.w 80021d4 + 8005360: 0801046c .word 0x0801046c + 8005364: 907ff800 .word 0x907ff800 + 8005368: dbcc8350 .word 0xdbcc8350 + 800536c: bafcfba3 .word 0xbafcfba3 + 8005370: 0800ff35 .word 0x0800ff35 + +08005374 : +{ + 8005374: b510 push {r4, lr} + if( (h->magic1 != RECHDR_MAGIC1) + 8005376: 4c1f ldr r4, [pc, #124] ; (80053f4 ) + 8005378: 4b1f ldr r3, [pc, #124] ; (80053f8 ) + 800537a: 6822 ldr r2, [r4, #0] + 800537c: 429a cmp r2, r3 +{ + 800537e: b088 sub sp, #32 + if( (h->magic1 != RECHDR_MAGIC1) + 8005380: d113 bne.n 80053aa + || (h->magic2 != RECHDR_MAGIC2) + 8005382: 68e2 ldr r2, [r4, #12] + 8005384: 4b1d ldr r3, [pc, #116] ; (80053fc ) + 8005386: 429a cmp r2, r3 + 8005388: d10f bne.n 80053aa + || ((uint32_t)h->start < PSRAM_BASE) + 800538a: 6863 ldr r3, [r4, #4] + 800538c: f1b3 4f10 cmp.w r3, #2415919104 ; 0x90000000 + 8005390: d30b bcc.n 80053aa + || ((uint32_t)h->start >= PSRAM_BASE+(PSRAM_SIZE/2)) + 8005392: 6862 ldr r2, [r4, #4] + 8005394: 4b1a ldr r3, [pc, #104] ; (8005400 ) + 8005396: 429a cmp r2, r3 + 8005398: d807 bhi.n 80053aa + || (h->size > FW_MAX_LENGTH_MK4) + 800539a: 68a3 ldr r3, [r4, #8] + 800539c: f5b3 1ff0 cmp.w r3, #1966080 ; 0x1e0000 + 80053a0: d803 bhi.n 80053aa + || (h->size < FW_MIN_LENGTH) + 80053a2: 68a3 ldr r3, [r4, #8] + 80053a4: f5b3 2f80 cmp.w r3, #262144 ; 0x40000 + 80053a8: d205 bcs.n 80053b6 + puts("PSR: nada"); + 80053aa: 4816 ldr r0, [pc, #88] ; (8005404 ) + puts("PSR: version"); + 80053ac: f7ff fe5c bl 8005068 +} + 80053b0: 2000 movs r0, #0 + 80053b2: b008 add sp, #32 + 80053b4: bd10 pop {r4, pc} + bool ok = verify_firmware_in_ram(h->start, h->size, world_check); + 80053b6: 6860 ldr r0, [r4, #4] + 80053b8: 68a1 ldr r1, [r4, #8] + 80053ba: 466a mov r2, sp + 80053bc: f7fc fd34 bl 8001e28 + if(!ok) { + 80053c0: b908 cbnz r0, 80053c6 + puts("PSR: !check"); + 80053c2: 4811 ldr r0, [pc, #68] ; (8005408 ) + 80053c4: e7f2 b.n 80053ac + if(!verify_world_checksum(world_check)) { + 80053c6: 4668 mov r0, sp + 80053c8: f7fc fd82 bl 8001ed0 + 80053cc: b908 cbnz r0, 80053d2 + puts("PSR: version"); + 80053ce: 480f ldr r0, [pc, #60] ; (800540c ) + 80053d0: e7ec b.n 80053ac + psram_do_upgrade(h->start, h->size); + 80053d2: 6860 ldr r0, [r4, #4] + 80053d4: 68a1 ldr r1, [r4, #8] + 80053d6: f7ff ff7f bl 80052d8 + 80053da: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80053de: 490c ldr r1, [pc, #48] ; (8005410 ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80053e0: 4b0c ldr r3, [pc, #48] ; (8005414 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80053e2: 68ca ldr r2, [r1, #12] + 80053e4: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80053e8: 4313 orrs r3, r2 + 80053ea: 60cb str r3, [r1, #12] + 80053ec: f3bf 8f4f dsb sy + __NOP(); + 80053f0: bf00 nop + for(;;) /* wait until reset */ + 80053f2: e7fd b.n 80053f0 + 80053f4: 907ff800 .word 0x907ff800 + 80053f8: dbcc8350 .word 0xdbcc8350 + 80053fc: bafcfba3 .word 0xbafcfba3 + 8005400: 903fffff .word 0x903fffff + 8005404: 080107e9 .word 0x080107e9 + 8005408: 080107f3 .word 0x080107f3 + 800540c: 080107ff .word 0x080107ff + 8005410: e000ed00 .word 0xe000ed00 + 8005414: 05fa0004 .word 0x05fa0004 + +08005418 : + +// sdcard_light() +// + void inline +sdcard_light(bool on) +{ + 8005418: 4602 mov r2, r0 + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, !!on); // turn LED off + 800541a: 2180 movs r1, #128 ; 0x80 + 800541c: 4801 ldr r0, [pc, #4] ; (8005424 ) + 800541e: f7fc b863 b.w 80014e8 + 8005422: bf00 nop + 8005424: 48000800 .word 0x48000800 + +08005428 : + +// sdcard_is_inserted() +// + bool +sdcard_is_inserted(void) +{ + 8005428: b508 push {r3, lr} +#ifdef FOR_Q1_ONLY + return !HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_3); // PD3 - inserted when low (Q) + 800542a: 2108 movs r1, #8 + 800542c: 4803 ldr r0, [pc, #12] ; (800543c ) + 800542e: f7fc f855 bl 80014dc +#else + return !!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13); // PC13 - inserted when high (Mk4) +#endif +} + 8005432: fab0 f080 clz r0, r0 + 8005436: 0940 lsrs r0, r0, #5 + 8005438: bd08 pop {r3, pc} + 800543a: bf00 nop + 800543c: 48000c00 .word 0x48000c00 + +08005440 : + +// sdcard_try_file() +// + void +sdcard_try_file(uint32_t blk_pos) +{ + 8005440: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8005444: 4606 mov r6, r0 + 8005446: f5ad 7d0a sub.w sp, sp, #552 ; 0x228 + oled_show(screen_verify); + 800544a: 4832 ldr r0, [pc, #200] ; (8005514 ) + uint8_t *ps = (uint8_t *)PSRAM_BASE; + //uint8_t buf[512*8]; // half of all our SRAM 0x00002000 + uint8_t buf[512]; // slower, but works. + + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + int rv = HAL_SD_ReadBlocks(&hsd, buf, blk_pos+(off/512), sizeof(buf)/512, 60000); + 800544c: f8df 80e4 ldr.w r8, [pc, #228] ; 8005534 + oled_show(screen_verify); + 8005450: f7fb fe10 bl 8001074 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 8005454: 2500 movs r5, #0 + int rv = HAL_SD_ReadBlocks(&hsd, buf, blk_pos+(off/512), sizeof(buf)/512, 60000); + 8005456: f64e 2760 movw r7, #60000 ; 0xea60 + 800545a: 9700 str r7, [sp, #0] + 800545c: 2301 movs r3, #1 + 800545e: eb06 2255 add.w r2, r6, r5, lsr #9 + 8005462: a90a add r1, sp, #40 ; 0x28 + 8005464: 4640 mov r0, r8 + 8005466: f006 fe61 bl 800c12c + if(rv != HAL_OK) { + 800546a: 4604 mov r4, r0 + 800546c: b130 cbz r0, 800547c + puts("long read fail"); + 800546e: 482a ldr r0, [pc, #168] ; (8005518 ) + + // Check we have the **right** firmware, based on the world check sum + // but don't set the light at this point. + // - this includes check over bootrom (ourselves) + if(!verify_world_checksum(world_check)) { + puts("wrong world"); + 8005470: f7ff fdfa bl 8005068 + // Do the upgrade, using PSRAM data. + psram_do_upgrade(start, len); + + // done + NVIC_SystemReset(); +} + 8005474: f50d 7d0a add.w sp, sp, #552 ; 0x228 + 8005478: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + memcpy(ps + off, buf, sizeof(buf)); + 800547c: f105 4010 add.w r0, r5, #2415919104 ; 0x90000000 + 8005480: f44f 7200 mov.w r2, #512 ; 0x200 + 8005484: a90a add r1, sp, #40 ; 0x28 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 8005486: f505 7500 add.w r5, r5, #512 ; 0x200 + memcpy(ps + off, buf, sizeof(buf)); + 800548a: f008 fa3d bl 800d908 + for(uint32_t off = 0; off < FW_MAX_LENGTH_MK4; off += sizeof(buf)) { + 800548e: f5b5 1ff0 cmp.w r5, #1966080 ; 0x1e0000 + 8005492: d1e2 bne.n 800545a + for(int idx=0; idxtargets; idx++) { + 8005494: f04f 4310 mov.w r3, #2415919104 ; 0x90000000 + if(elem->addr == FIRMWARE_START) { + 8005498: 4d20 ldr r5, [pc, #128] ; (800551c ) + for(int idx=0; idxtargets; idx++) { + 800549a: 7a99 ldrb r1, [r3, #10] + 800549c: 4620 mov r0, r4 + ptr += sizeof(DFUFile_t); + 800549e: 330b adds r3, #11 + for(int idx=0; idxtargets; idx++) { + 80054a0: 4288 cmp r0, r1 + 80054a2: db01 blt.n 80054a8 + puts("DFU parse fail"); + 80054a4: 481e ldr r0, [pc, #120] ; (8005520 ) + 80054a6: e7e3 b.n 8005470 + for(int ei=0; eielements; ei++) { + 80054a8: f8d3 610e ldr.w r6, [r3, #270] ; 0x10e + 80054ac: 2200 movs r2, #0 + ptr += sizeof(DFUTarget_t); + 80054ae: f503 7389 add.w r3, r3, #274 ; 0x112 + for(int ei=0; eielements; ei++) { + 80054b2: 42b2 cmp r2, r6 + 80054b4: d101 bne.n 80054ba + for(int idx=0; idxtargets; idx++) { + 80054b6: 3001 adds r0, #1 + 80054b8: e7f2 b.n 80054a0 + ptr += sizeof(DFUElement_t); + 80054ba: 461c mov r4, r3 + if(elem->addr == FIRMWARE_START) { + 80054bc: f854 7b08 ldr.w r7, [r4], #8 + 80054c0: 42af cmp r7, r5 + 80054c2: d110 bne.n 80054e6 + *target_size = elem->size; + 80054c4: 685d ldr r5, [r3, #4] + bool ok = verify_firmware_in_ram(start, len, world_check); + 80054c6: aa02 add r2, sp, #8 + 80054c8: 4629 mov r1, r5 + 80054ca: 4620 mov r0, r4 + 80054cc: f7fc fcac bl 8001e28 + if(!ok) return; + 80054d0: 2800 cmp r0, #0 + 80054d2: d0cf beq.n 8005474 + puts("good firmware"); + 80054d4: 4813 ldr r0, [pc, #76] ; (8005524 ) + 80054d6: f7ff fdc7 bl 8005068 + if(!verify_world_checksum(world_check)) { + 80054da: a802 add r0, sp, #8 + 80054dc: f7fc fcf8 bl 8001ed0 + 80054e0: b920 cbnz r0, 80054ec + puts("wrong world"); + 80054e2: 4811 ldr r0, [pc, #68] ; (8005528 ) + 80054e4: e7c4 b.n 8005470 + for(int ei=0; eielements; ei++) { + 80054e6: 3201 adds r2, #1 + ptr += sizeof(DFUElement_t); + 80054e8: 4623 mov r3, r4 + 80054ea: e7e2 b.n 80054b2 + sdcard_light(false); + 80054ec: 2000 movs r0, #0 + 80054ee: f7ff ff93 bl 8005418 + psram_do_upgrade(start, len); + 80054f2: 4629 mov r1, r5 + 80054f4: 4620 mov r0, r4 + 80054f6: f7ff feef bl 80052d8 + 80054fa: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80054fe: 490b ldr r1, [pc, #44] ; (800552c ) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8005500: 4b0b ldr r3, [pc, #44] ; (8005530 ) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 8005502: 68ca ldr r2, [r1, #12] + 8005504: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 8005508: 4313 orrs r3, r2 + 800550a: 60cb str r3, [r1, #12] + 800550c: f3bf 8f4f dsb sy + __NOP(); + 8005510: bf00 nop + for(;;) /* wait until reset */ + 8005512: e7fd b.n 8005510 + 8005514: 0801004d .word 0x0801004d + 8005518: 08010828 .word 0x08010828 + 800551c: 08020000 .word 0x08020000 + 8005520: 08010837 .word 0x08010837 + 8005524: 08010846 .word 0x08010846 + 8005528: 08010854 .word 0x08010854 + 800552c: e000ed00 .word 0xe000ed00 + 8005530: 05fa0004 .word 0x05fa0004 + 8005534: 2009e224 .word 0x2009e224 + +08005538 : + +// sdcard_search() +// + void +sdcard_search(void) +{ + 8005538: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + oled_show(screen_search); + 800553c: 4861 ldr r0, [pc, #388] ; (80056c4 ) +{ + 800553e: f5ad 7d05 sub.w sp, sp, #532 ; 0x214 + oled_show(screen_search); + 8005542: f7fb fd97 bl 8001074 + + if(!sdcard_is_inserted()) return; + 8005546: f7ff ff6f bl 8005428 + 800554a: 2800 cmp r0, #0 + 800554c: f000 8095 beq.w 800567a + __HAL_RCC_SDMMC1_CLK_ENABLE(); + 8005550: f8df 81b0 ldr.w r8, [pc, #432] ; 8005704 + + uint32_t num_blocks; + + // open card (power it) and get details, do setup + puts2("sdcard_search: "); + 8005554: 485c ldr r0, [pc, #368] ; (80056c8 ) + { GPIO_InitTypeDef setup = { + 8005556: 4c5d ldr r4, [pc, #372] ; (80056cc ) + puts2("sdcard_search: "); + 8005558: f7ff fcf8 bl 8004f4c + __HAL_RCC_SDMMC1_CLK_ENABLE(); + 800555c: f8d8 304c ldr.w r3, [r8, #76] ; 0x4c + 8005560: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 8005564: f8c8 304c str.w r3, [r8, #76] ; 0x4c + 8005568: f8d8 304c ldr.w r3, [r8, #76] ; 0x4c + 800556c: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 8005570: 9303 str r3, [sp, #12] + 8005572: 9b03 ldr r3, [sp, #12] + { GPIO_InitTypeDef setup = { + 8005574: cc0f ldmia r4!, {r0, r1, r2, r3} + 8005576: ad04 add r5, sp, #16 + 8005578: c50f stmia r5!, {r0, r1, r2, r3} + 800557a: f854 3b04 ldr.w r3, [r4], #4 + 800557e: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOC, &setup); + 8005580: 4853 ldr r0, [pc, #332] ; (80056d0 ) + 8005582: a904 add r1, sp, #16 + 8005584: f7fb fe36 bl 80011f4 + GPIO_InitTypeDef setup = { + 8005588: 2700 movs r7, #0 + 800558a: f44f 5600 mov.w r6, #8192 ; 0x2000 + HAL_GPIO_Init(GPIOC, &setup); + 800558e: 4850 ldr r0, [pc, #320] ; (80056d0 ) + GPIO_InitTypeDef setup = { + 8005590: 9708 str r7, [sp, #32] + HAL_GPIO_Init(GPIOC, &setup); + 8005592: a904 add r1, sp, #16 + GPIO_InitTypeDef setup = { + 8005594: f04f 0901 mov.w r9, #1 + 8005598: e9cd 6904 strd r6, r9, [sp, #16] + 800559c: e9cd 7706 strd r7, r7, [sp, #24] + HAL_GPIO_Init(GPIOC, &setup); + 80055a0: f7fb fe28 bl 80011f4 + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0); // select A + 80055a4: 4631 mov r1, r6 + 80055a6: 484a ldr r0, [pc, #296] ; (80056d0 ) + 80055a8: 463a mov r2, r7 + 80055aa: f7fb ff9d bl 80014e8 + { GPIO_InitTypeDef setup = { + 80055ae: cc0f ldmia r4!, {r0, r1, r2, r3} + 80055b0: ae04 add r6, sp, #16 + 80055b2: c60f stmia r6!, {r0, r1, r2, r3} + 80055b4: 6823 ldr r3, [r4, #0] + 80055b6: 602b str r3, [r5, #0] + HAL_GPIO_Init(GPIOD, &setup); + 80055b8: a904 add r1, sp, #16 + 80055ba: 4846 ldr r0, [pc, #280] ; (80056d4 ) + memset(&hsd, 0, sizeof(SD_HandleTypeDef)); + 80055bc: 4d46 ldr r5, [pc, #280] ; (80056d8 ) + HAL_GPIO_Init(GPIOD, &setup); + 80055be: f7fb fe19 bl 80011f4 + __HAL_RCC_SDMMC1_FORCE_RESET(); + 80055c2: f8d8 302c ldr.w r3, [r8, #44] ; 0x2c + 80055c6: f443 0380 orr.w r3, r3, #4194304 ; 0x400000 + 80055ca: f8c8 302c str.w r3, [r8, #44] ; 0x2c + __HAL_RCC_SDMMC1_RELEASE_RESET(); + 80055ce: f8d8 302c ldr.w r3, [r8, #44] ; 0x2c + 80055d2: f423 0380 bic.w r3, r3, #4194304 ; 0x400000 + 80055d6: f8c8 302c str.w r3, [r8, #44] ; 0x2c + sdcard_setup(); + delay_ms(100); + 80055da: 2064 movs r0, #100 ; 0x64 + 80055dc: f7fe fa52 bl 8003a84 + memset(&hsd, 0, sizeof(SD_HandleTypeDef)); + 80055e0: 2280 movs r2, #128 ; 0x80 + 80055e2: 4639 mov r1, r7 + 80055e4: 4628 mov r0, r5 + 80055e6: f008 f99d bl 800d924 + puts2("sdcard_probe: "); + 80055ea: 483c ldr r0, [pc, #240] ; (80056dc ) + 80055ec: f7ff fcae bl 8004f4c + hsd.Instance = SDMMC1; + 80055f0: 4b3b ldr r3, [pc, #236] ; (80056e0 ) + hsd.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + 80055f2: 612f str r7, [r5, #16] + hsd.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + 80055f4: e9c5 3700 strd r3, r7, [r5] + hsd.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_ENABLE; + 80055f8: f44f 5380 mov.w r3, #4096 ; 0x1000 + hsd.Init.BusWide = SDMMC_BUS_WIDE_1B; + 80055fc: e9c5 3702 strd r3, r7, [r5, #8] + int rv = HAL_SD_Init(&hsd); + 8005600: 4628 mov r0, r5 + hsd.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV; + 8005602: 2303 movs r3, #3 + 8005604: 616b str r3, [r5, #20] + int rv = HAL_SD_Init(&hsd); + 8005606: f007 fb0b bl 800cc20 + if(rv != HAL_OK) { + 800560a: 4604 mov r4, r0 + 800560c: b130 cbz r0, 800561c + puts("init fail"); + 800560e: 4835 ldr r0, [pc, #212] ; (80056e4 ) + oled_show_progress(screen_search, pos*100 / num_blocks); + sdcard_light(true); + } + } + +} + 8005610: f50d 7d05 add.w sp, sp, #532 ; 0x214 + 8005614: e8bd 43f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, lr} + puts("bsize?"); + 8005618: f7ff bd26 b.w 8005068 + sdcard_light(true); + 800561c: 4648 mov r0, r9 + 800561e: f7ff fefb bl 8005418 + rv = HAL_SD_ConfigSpeedBusOperation(&hsd, SDMMC_SPEED_MODE_AUTO); + 8005622: 4621 mov r1, r4 + 8005624: 4628 mov r0, r5 + 8005626: f007 fbd3 bl 800cdd0 + if(rv != HAL_OK) { + 800562a: b108 cbz r0, 8005630 + puts("speed"); + 800562c: 482e ldr r0, [pc, #184] ; (80056e8 ) + 800562e: e7ef b.n 8005610 + rv = HAL_SD_ConfigWideBusOperation(&hsd, SDMMC_BUS_WIDE_4B); + 8005630: f44f 4180 mov.w r1, #16384 ; 0x4000 + 8005634: 4628 mov r0, r5 + 8005636: f007 fa1d bl 800ca74 + if(rv != HAL_OK) { + 800563a: 4604 mov r4, r0 + 800563c: b108 cbz r0, 8005642 + puts("wide"); + 800563e: 482b ldr r0, [pc, #172] ; (80056ec ) + 8005640: e7e6 b.n 8005610 + if(hsd.SdCard.BlockSize != 512) { + 8005642: 6d2b ldr r3, [r5, #80] ; 0x50 + 8005644: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 8005648: d001 beq.n 800564e + puts("bsize?"); + 800564a: 4829 ldr r0, [pc, #164] ; (80056f0 ) + 800564c: e7e0 b.n 8005610 + puts("ok"); + 800564e: 4829 ldr r0, [pc, #164] ; (80056f4 ) + *num_blocks = hsd.SdCard.BlockNbr; + 8005650: 6cee ldr r6, [r5, #76] ; 0x4c + if(memcmp(blk, "DfuSe", 5) == 0) { + 8005652: 4f29 ldr r7, [pc, #164] ; (80056f8 ) + oled_show_progress(screen_search, pos*100 / num_blocks); + 8005654: f8df 806c ldr.w r8, [pc, #108] ; 80056c4 + puts("ok"); + 8005658: f7ff fd06 bl 8005068 + for(int pos=0; pos + int rv = HAL_SD_ReadBlocks(&hsd, blk, pos, 1, 60000); + 8005660: f64e 2360 movw r3, #60000 ; 0xea60 + 8005664: 9300 str r3, [sp, #0] + 8005666: 4622 mov r2, r4 + 8005668: 2301 movs r3, #1 + 800566a: a904 add r1, sp, #16 + 800566c: 4628 mov r0, r5 + 800566e: f006 fd5d bl 800c12c + if(rv != HAL_OK) { + 8005672: b130 cbz r0, 8005682 + puts("fail read"); + 8005674: 4821 ldr r0, [pc, #132] ; (80056fc ) + 8005676: f7ff fcf7 bl 8005068 +} + 800567a: f50d 7d05 add.w sp, sp, #532 ; 0x214 + 800567e: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + if(memcmp(blk, "DfuSe", 5) == 0) { + 8005682: 2205 movs r2, #5 + 8005684: 4639 mov r1, r7 + 8005686: a804 add r0, sp, #16 + 8005688: f008 f92e bl 800d8e8 + 800568c: b9b0 cbnz r0, 80056bc + puts2("found @ "); + 800568e: 481c ldr r0, [pc, #112] ; (8005700 ) + 8005690: f7ff fc5c bl 8004f4c + puthex8(pos); + 8005694: 4620 mov r0, r4 + 8005696: f7ff fcb5 bl 8005004 + putchar('\n'); + 800569a: 200a movs r0, #10 + 800569c: f7ff fc6a bl 8004f74 + sdcard_try_file(pos); + 80056a0: 4620 mov r0, r4 + 80056a2: f7ff fecd bl 8005440 + oled_show_progress(screen_search, pos*100 / num_blocks); + 80056a6: 2164 movs r1, #100 ; 0x64 + 80056a8: 4640 mov r0, r8 + 80056aa: 4361 muls r1, r4 + 80056ac: fbb1 f1f6 udiv r1, r1, r6 + 80056b0: f7fb fd5a bl 8001168 + sdcard_light(true); + 80056b4: 2001 movs r0, #1 + 80056b6: f7ff feaf bl 8005418 + 80056ba: e001 b.n 80056c0 + if(pos % 128 == 0) { + 80056bc: 0663 lsls r3, r4, #25 + 80056be: d0f2 beq.n 80056a6 + for(int pos=0; pos + 80056c4: 0800fa95 .word 0x0800fa95 + 80056c8: 08010860 .word 0x08010860 + 80056cc: 080108c8 .word 0x080108c8 + 80056d0: 48000800 .word 0x48000800 + 80056d4: 48000c00 .word 0x48000c00 + 80056d8: 2009e224 .word 0x2009e224 + 80056dc: 08010870 .word 0x08010870 + 80056e0: 50062400 .word 0x50062400 + 80056e4: 0801087f .word 0x0801087f + 80056e8: 08010889 .word 0x08010889 + 80056ec: 0801088f .word 0x0801088f + 80056f0: 08010894 .word 0x08010894 + 80056f4: 0801089b .word 0x0801089b + 80056f8: 080108a8 .word 0x080108a8 + 80056fc: 0801089e .word 0x0801089e + 8005700: 080108ae .word 0x080108ae + 8005704: 40021000 .word 0x40021000 + +08005708 : + +// sdcard_recovery() +// + void +sdcard_recovery(void) +{ + 8005708: b508 push {r3, lr} + // Use SDCard to recover. Must be precise version they tried to + // install before, and will be slow AF. + + puts("Recovery mode."); + 800570a: 480b ldr r0, [pc, #44] ; (8005738 ) + while(1) { + // .. need them to insert a card + + sdcard_light(false); + while(!sdcard_is_inserted()) { + oled_show(screen_recovery); + 800570c: 4c0b ldr r4, [pc, #44] ; (800573c ) + puts("Recovery mode."); + 800570e: f7ff fcab bl 8005068 + sdcard_light(false); + 8005712: 2000 movs r0, #0 + 8005714: f7ff fe80 bl 8005418 + while(!sdcard_is_inserted()) { + 8005718: f7ff fe86 bl 8005428 + 800571c: b128 cbz r0, 800572a + delay_ms(200); + } + + // look for binary, will reset system if successful + sdcard_light(true); + 800571e: 2001 movs r0, #1 + 8005720: f7ff fe7a bl 8005418 + sdcard_search(); + 8005724: f7ff ff08 bl 8005538 + sdcard_light(false); + 8005728: e7f3 b.n 8005712 + oled_show(screen_recovery); + 800572a: 4620 mov r0, r4 + 800572c: f7fb fca2 bl 8001074 + delay_ms(200); + 8005730: 20c8 movs r0, #200 ; 0xc8 + 8005732: f7fe f9a7 bl 8003a84 + 8005736: e7ef b.n 8005718 + 8005738: 080108b7 .word 0x080108b7 + 800573c: 0800e85f .word 0x0800e85f + +08005740 : +#include + +// so we don't need stm32l4xx_hal_hash_ex.c +HAL_StatusTypeDef HAL_HASHEx_SHA256_Accmlt(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA256); + 8005740: 4b01 ldr r3, [pc, #4] ; (8005748 ) + 8005742: f005 ba3b b.w 800abbc + 8005746: bf00 nop + 8005748: 00040080 .word 0x00040080 + +0800574c : +} + +HAL_StatusTypeDef HAL_HASHEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 800574c: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA256); + 800574e: 4c04 ldr r4, [pc, #16] ; (8005760 ) + 8005750: 9401 str r4, [sp, #4] + 8005752: 9c04 ldr r4, [sp, #16] + 8005754: 9400 str r4, [sp, #0] + 8005756: f005 f98d bl 800aa74 +} + 800575a: b002 add sp, #8 + 800575c: bd10 pop {r4, pc} + 800575e: bf00 nop + 8005760: 00040080 .word 0x00040080 + +08005764 : + +HAL_StatusTypeDef HAL_HMACEx_SHA256_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 8005764: b513 push {r0, r1, r4, lr} + return HMAC_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA256); + 8005766: 4c04 ldr r4, [pc, #16] ; (8005778 ) + 8005768: 9401 str r4, [sp, #4] + 800576a: 9c04 ldr r4, [sp, #16] + 800576c: 9400 str r4, [sp, #0] + 800576e: f005 fbc3 bl 800aef8 +} + 8005772: b002 add sp, #8 + 8005774: bd10 pop {r4, pc} + 8005776: bf00 nop + 8005778: 00040080 .word 0x00040080 + +0800577c : + +void sha256_init(SHA256_CTX *ctx) +{ + 800577c: b510 push {r4, lr} + memset(ctx, 0, sizeof(SHA256_CTX)); + 800577e: 2248 movs r2, #72 ; 0x48 +{ + 8005780: 4604 mov r4, r0 + memset(ctx, 0, sizeof(SHA256_CTX)); + 8005782: 2100 movs r1, #0 + 8005784: 3004 adds r0, #4 + 8005786: f008 f8cd bl 800d924 + +#if 1 + ctx->num_pending = 0; + ctx->hh.Init.DataType = HASH_DATATYPE_8B; + 800578a: 2320 movs r3, #32 + 800578c: 6023 str r3, [r4, #0] + HAL_HASH_Init(&ctx->hh); + 800578e: 4620 mov r0, r4 + __HAL_HASH_RESET_MDMAT(); + + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, + HASH_ALGOSELECTION_SHA256 | HASH_CR_INIT); +#endif +} + 8005790: e8bd 4010 ldmia.w sp!, {r4, lr} + HAL_HASH_Init(&ctx->hh); + 8005794: f004 bffc b.w 800a790 + +08005798 : + +void sha256_update(SHA256_CTX *ctx, const uint8_t data[], uint32_t len) +{ + 8005798: b5f8 push {r3, r4, r5, r6, r7, lr} + HAL_StatusTypeDef rv; + + // clear out any pending bytes + if(ctx->num_pending + len >= 4) { + 800579a: f890 3048 ldrb.w r3, [r0, #72] ; 0x48 + 800579e: 4413 add r3, r2 + 80057a0: 2b03 cmp r3, #3 +{ + 80057a2: 4605 mov r5, r0 + 80057a4: 460e mov r6, r1 + 80057a6: 4614 mov r4, r2 + if(ctx->num_pending + len >= 4) { + 80057a8: d818 bhi.n 80057dc + } + } + + // write full blocks + uint32_t blocks = len / 4; + if(blocks) { + 80057aa: 2c03 cmp r4, #3 + 80057ac: d926 bls.n 80057fc +#if 1 + rv = HAL_HASHEx_SHA256_Accumulate(&ctx->hh, (uint8_t *)data, blocks*4); + 80057ae: f024 0703 bic.w r7, r4, #3 + 80057b2: 463a mov r2, r7 + 80057b4: 4631 mov r1, r6 + 80057b6: 4628 mov r0, r5 + 80057b8: f7ff ffc2 bl 8005740 + ASSERT(rv == HAL_OK); + 80057bc: b9c8 cbnz r0, 80057f2 + uint32_t tmp; + memcpy(&tmp, data, 4); + HASH->DIN = tmp; + } +#endif + len -= blocks*4; + 80057be: f004 0403 and.w r4, r4, #3 + data += blocks*4; + 80057c2: 443e add r6, r7 + 80057c4: e01a b.n 80057fc + ctx->pending[ctx->num_pending++] = *data; + 80057c6: 1c5a adds r2, r3, #1 + 80057c8: b2d2 uxtb r2, r2 + 80057ca: f885 2048 strb.w r2, [r5, #72] ; 0x48 + 80057ce: 442b add r3, r5 + 80057d0: f816 1b01 ldrb.w r1, [r6], #1 + 80057d4: f883 1044 strb.w r1, [r3, #68] ; 0x44 + if(!len) break; + 80057d8: 3c01 subs r4, #1 + 80057da: d00d beq.n 80057f8 + while(ctx->num_pending != 4) { + 80057dc: f895 3048 ldrb.w r3, [r5, #72] ; 0x48 + 80057e0: 2b04 cmp r3, #4 + 80057e2: d1f0 bne.n 80057c6 + rv = HAL_HASHEx_SHA256_Accumulate(&ctx->hh, ctx->pending, 4); + 80057e4: 2204 movs r2, #4 + 80057e6: f105 0144 add.w r1, r5, #68 ; 0x44 + 80057ea: 4628 mov r0, r5 + 80057ec: f7ff ffa8 bl 8005740 + ASSERT(rv == HAL_OK); + 80057f0: b140 cbz r0, 8005804 + 80057f2: 480b ldr r0, [pc, #44] ; (8005820 ) + 80057f4: f7fb f920 bl 8000a38 + if(ctx->num_pending == 4) { + 80057f8: 2a04 cmp r2, #4 + 80057fa: d0f3 beq.n 80057e4 + 80057fc: 4434 add r4, r6 + } + + // save runt for later + ASSERT(len <= 3); + while(len) { + 80057fe: 42b4 cmp r4, r6 + 8005800: d103 bne.n 800580a + ctx->pending[ctx->num_pending++] = *data; + data++; + len--; + } +} + 8005802: bdf8 pop {r3, r4, r5, r6, r7, pc} + ctx->num_pending = 0; + 8005804: f885 0048 strb.w r0, [r5, #72] ; 0x48 + 8005808: e7cf b.n 80057aa + ctx->pending[ctx->num_pending++] = *data; + 800580a: f895 3048 ldrb.w r3, [r5, #72] ; 0x48 + 800580e: 1c5a adds r2, r3, #1 + 8005810: f885 2048 strb.w r2, [r5, #72] ; 0x48 + 8005814: 442b add r3, r5 + 8005816: f816 2b01 ldrb.w r2, [r6], #1 + 800581a: f883 2044 strb.w r2, [r3, #68] ; 0x44 + len--; + 800581e: e7ee b.n 80057fe + 8005820: 0801046c .word 0x0801046c + +08005824 : + +void sha256_final(SHA256_CTX *ctx, uint8_t digest[32]) +{ + 8005824: b513 push {r0, r1, r4, lr} + // Do final 0-3 bytes, pad and return digest. +#if 1 + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&ctx->hh, + 8005826: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800582a: 9200 str r2, [sp, #0] +{ + 800582c: 460b mov r3, r1 + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&ctx->hh, + 800582e: f890 2048 ldrb.w r2, [r0, #72] ; 0x48 + 8005832: f100 0144 add.w r1, r0, #68 ; 0x44 + 8005836: f7ff ff89 bl 800574c + ctx->pending, ctx->num_pending, digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 800583a: b110 cbz r0, 8005842 + 800583c: 4802 ldr r0, [pc, #8] ; (8005848 ) + 800583e: f7fb f8fb bl 8000a38 + tmp = __REV(HASH_DIGEST->HR[6]); + memcpy(out, &tmp, 4); out += 4; + tmp = __REV(HASH_DIGEST->HR[7]); + memcpy(out, &tmp, 4); +#endif +} + 8005842: b002 add sp, #8 + 8005844: bd10 pop {r4, pc} + 8005846: bf00 nop + 8005848: 0801046c .word 0x0801046c + +0800584c : +// +// single-shot version (best) +// + void +sha256_single(const uint8_t data[], uint32_t len, uint8_t digest[32]) +{ + 800584c: b530 push {r4, r5, lr} + 800584e: b097 sub sp, #92 ; 0x5c + 8005850: 4604 mov r4, r0 + 8005852: 460d mov r5, r1 + 8005854: 9203 str r2, [sp, #12] + HASH_HandleTypeDef hh = {0}; + 8005856: 2100 movs r1, #0 + 8005858: 2240 movs r2, #64 ; 0x40 + 800585a: a806 add r0, sp, #24 + 800585c: f008 f862 bl 800d924 + + hh.Init.DataType = HASH_DATATYPE_8B; + 8005860: 2220 movs r2, #32 + + HAL_HASH_Init(&hh); + 8005862: a805 add r0, sp, #20 + hh.Init.DataType = HASH_DATATYPE_8B; + 8005864: 9205 str r2, [sp, #20] + HAL_HASH_Init(&hh); + 8005866: f004 ff93 bl 800a790 + + // It's called "Start" but it handles the runt packet, so really can only + // be used once at end of message, or for whole message. + HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&hh, (uint8_t *)data, len, + 800586a: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800586e: 9200 str r2, [sp, #0] + 8005870: 9b03 ldr r3, [sp, #12] + 8005872: 462a mov r2, r5 + 8005874: 4621 mov r1, r4 + 8005876: a805 add r0, sp, #20 + 8005878: f7ff ff68 bl 800574c + digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 800587c: b110 cbz r0, 8005884 + 800587e: 4802 ldr r0, [pc, #8] ; (8005888 ) + 8005880: f7fb f8da bl 8000a38 +} + 8005884: b017 add sp, #92 ; 0x5c + 8005886: bd30 pop {r4, r5, pc} + 8005888: 0801046c .word 0x0801046c + +0800588c : +// hmac_sha256_init() +// + void +hmac_sha256_init(HMAC_CTX *ctx) +{ + memset(ctx, 0, sizeof(HMAC_CTX)); + 800588c: f44f 7282 mov.w r2, #260 ; 0x104 + 8005890: 2100 movs r1, #0 + 8005892: f008 b847 b.w 800d924 + ... + +08005898 : + +// hmac_sha256_update() +// + void +hmac_sha256_update(HMAC_CTX *ctx, const uint8_t data[], uint32_t len) +{ + 8005898: b538 push {r3, r4, r5, lr} + 800589a: 4604 mov r4, r0 + // simple append + ASSERT(ctx->num_pending + len < sizeof(ctx->pending)); + 800589c: f8d0 0100 ldr.w r0, [r0, #256] ; 0x100 + 80058a0: 1883 adds r3, r0, r2 + 80058a2: 2bff cmp r3, #255 ; 0xff +{ + 80058a4: 4615 mov r5, r2 + ASSERT(ctx->num_pending + len < sizeof(ctx->pending)); + 80058a6: d902 bls.n 80058ae + 80058a8: 4805 ldr r0, [pc, #20] ; (80058c0 ) + 80058aa: f7fb f8c5 bl 8000a38 + + memcpy(ctx->pending+ctx->num_pending, data, len); + 80058ae: 4420 add r0, r4 + 80058b0: f008 f82a bl 800d908 + + ctx->num_pending += len; + 80058b4: f8d4 2100 ldr.w r2, [r4, #256] ; 0x100 + 80058b8: 442a add r2, r5 + 80058ba: f8c4 2100 str.w r2, [r4, #256] ; 0x100 +} + 80058be: bd38 pop {r3, r4, r5, pc} + 80058c0: 0801046c .word 0x0801046c + +080058c4 : + +// hmac_sha256_final() +// + void +hmac_sha256_final(HMAC_CTX *ctx, const uint8_t key[32], uint8_t digest[32]) +{ + 80058c4: b530 push {r4, r5, lr} + 80058c6: b097 sub sp, #92 ; 0x5c + 80058c8: 4604 mov r4, r0 + 80058ca: 460d mov r5, r1 + 80058cc: 9203 str r2, [sp, #12] + HASH_HandleTypeDef hh = {0}; + 80058ce: 2100 movs r1, #0 + 80058d0: 2238 movs r2, #56 ; 0x38 + 80058d2: a808 add r0, sp, #32 + 80058d4: f008 f826 bl 800d924 + + hh.Init.DataType = HASH_DATATYPE_8B; + 80058d8: 2220 movs r2, #32 + hh.Init.pKey = (uint8_t *)key; // const viol due to API dumbness + hh.Init.KeySize = 32; + + HAL_HASH_Init(&hh); + 80058da: a805 add r0, sp, #20 + hh.Init.KeySize = 32; + 80058dc: e9cd 2506 strd r2, r5, [sp, #24] + hh.Init.DataType = HASH_DATATYPE_8B; + 80058e0: 9205 str r2, [sp, #20] + HAL_HASH_Init(&hh); + 80058e2: f004 ff55 bl 800a790 + + HAL_StatusTypeDef rv = HAL_HMACEx_SHA256_Start(&hh, + 80058e6: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 80058ea: 9200 str r2, [sp, #0] + 80058ec: 9b03 ldr r3, [sp, #12] + 80058ee: f8d4 2100 ldr.w r2, [r4, #256] ; 0x100 + 80058f2: 4621 mov r1, r4 + 80058f4: a805 add r0, sp, #20 + 80058f6: f7ff ff35 bl 8005764 + ctx->pending, ctx->num_pending, digest, HAL_MAX_DELAY); + ASSERT(rv == HAL_OK); + 80058fa: b110 cbz r0, 8005902 + 80058fc: 4802 ldr r0, [pc, #8] ; (8005908 ) + 80058fe: f7fb f89b bl 8000a38 +} + 8005902: b017 add sp, #92 ; 0x5c + 8005904: bd30 pop {r4, r5, pc} + 8005906: bf00 nop + 8005908: 0801046c .word 0x0801046c + +0800590c : + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + 800590c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + ); + +#else /* Thumb-1 */ + uint32_t r4, r5, r6, r7; + + __asm__ volatile ( + 8005910: 3b01 subs r3, #1 + 8005912: 009b lsls r3, r3, #2 + 8005914: 4698 mov r8, r3 + 8005916: 005b lsls r3, r3, #1 + 8005918: 4699 mov r9, r3 + 800591a: 2300 movs r3, #0 + 800591c: 2400 movs r4, #0 + 800591e: 2500 movs r5, #0 + 8005920: 2600 movs r6, #0 + 8005922: b401 push {r0} + 8005924: 2700 movs r7, #0 + 8005926: e002 b.n 800592e + 8005928: 0037 movs r7, r6 + 800592a: 4640 mov r0, r8 + 800592c: 1a3f subs r7, r7, r0 + 800592e: b478 push {r3, r4, r5, r6} + 8005930: 1bf0 subs r0, r6, r7 + 8005932: 5814 ldr r4, [r2, r0] + 8005934: 59c8 ldr r0, [r1, r7] + 8005936: 0c03 lsrs r3, r0, #16 + 8005938: b280 uxth r0, r0 + 800593a: 0c25 lsrs r5, r4, #16 + 800593c: b2a4 uxth r4, r4 + 800593e: 001e movs r6, r3 + 8005940: 436e muls r6, r5 + 8005942: 4363 muls r3, r4 + 8005944: 4345 muls r5, r0 + 8005946: 4360 muls r0, r4 + 8005948: 2400 movs r4, #0 + 800594a: 195b adds r3, r3, r5 + 800594c: 4164 adcs r4, r4 + 800594e: 0424 lsls r4, r4, #16 + 8005950: 1936 adds r6, r6, r4 + 8005952: 041c lsls r4, r3, #16 + 8005954: 0c1b lsrs r3, r3, #16 + 8005956: 1900 adds r0, r0, r4 + 8005958: 415e adcs r6, r3 + 800595a: bc38 pop {r3, r4, r5} + 800595c: 181b adds r3, r3, r0 + 800595e: 4174 adcs r4, r6 + 8005960: 2000 movs r0, #0 + 8005962: 4145 adcs r5, r0 + 8005964: bc40 pop {r6} + 8005966: 3704 adds r7, #4 + 8005968: 4547 cmp r7, r8 + 800596a: dc01 bgt.n 8005970 + 800596c: 42b7 cmp r7, r6 + 800596e: ddde ble.n 800592e + 8005970: 9800 ldr r0, [sp, #0] + 8005972: 5183 str r3, [r0, r6] + 8005974: 4623 mov r3, r4 + 8005976: 462c mov r4, r5 + 8005978: 2500 movs r5, #0 + 800597a: 3604 adds r6, #4 + 800597c: 4546 cmp r6, r8 + 800597e: ddd1 ble.n 8005924 + 8005980: 454e cmp r6, r9 + 8005982: ddd1 ble.n 8005928 + 8005984: 5183 str r3, [r0, r6] + 8005986: bc01 pop {r0} + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left), [r2] "l" (right) + : "r8", "r9", "cc", "memory" + ); +#endif +} + 8005988: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + +0800598c : + +#if !asm_clear +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + vli[i] = 0; + 800598c: ea21 71e1 bic.w r1, r1, r1, asr #31 + 8005990: 008a lsls r2, r1, #2 + 8005992: 2100 movs r1, #0 + 8005994: f007 bfc6 b.w 800d924 + +08005998 : +} +#endif /* !asm_clear */ + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { + 8005998: b510 push {r4, lr} + uECC_word_t bits = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + 800599a: 2300 movs r3, #0 + uECC_word_t bits = 0; + 800599c: 461a mov r2, r3 + for (i = 0; i < num_words; ++i) { + 800599e: b25c sxtb r4, r3 + 80059a0: 42a1 cmp r1, r4 + 80059a2: dc03 bgt.n 80059ac + bits |= vli[i]; + } + return (bits == 0); +} + 80059a4: fab2 f082 clz r0, r2 + 80059a8: 0940 lsrs r0, r0, #5 + 80059aa: bd10 pop {r4, pc} + bits |= vli[i]; + 80059ac: f850 4023 ldr.w r4, [r0, r3, lsl #2] + 80059b0: 3301 adds r3, #1 + 80059b2: 4322 orrs r2, r4 + for (i = 0; i < num_words; ++i) { + 80059b4: e7f3 b.n 800599e + +080059b6 : + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) { + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 80059b6: 114a asrs r2, r1, #5 + 80059b8: 2301 movs r3, #1 + 80059ba: f850 0022 ldr.w r0, [r0, r2, lsl #2] + 80059be: f001 011f and.w r1, r1, #31 + 80059c2: fa03 f101 lsl.w r1, r3, r1 +} + 80059c6: 4008 ands r0, r1 + 80059c8: 4770 bx lr + +080059ca : +/* Counts the number of words in vli. */ +static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_words) { + wordcount_t i; + /* Search from the end until we find a non-zero digit. + We do it in reverse because we expect that most digits will be nonzero. */ + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + 80059ca: 3901 subs r1, #1 + + return (i + 1); +} + +/* Counts the number of bits required to represent vli. */ +uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { + 80059cc: b510 push {r4, lr} + 80059ce: b249 sxtb r1, r1 + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + 80059d0: 1d04 adds r4, r0, #4 + 80059d2: 060a lsls r2, r1, #24 + 80059d4: b2cb uxtb r3, r1 + 80059d6: d404 bmi.n 80059e2 + 80059d8: 3901 subs r1, #1 + 80059da: f854 2021 ldr.w r2, [r4, r1, lsl #2] + 80059de: 2a00 cmp r2, #0 + 80059e0: d0f7 beq.n 80059d2 + return (i + 1); + 80059e2: 3301 adds r3, #1 + 80059e4: b25b sxtb r3, r3 + uECC_word_t i; + uECC_word_t digit; + + wordcount_t num_digits = vli_numDigits(vli, max_words); + if (num_digits == 0) { + 80059e6: b173 cbz r3, 8005a06 + return 0; + } + + digit = vli[num_digits - 1]; + 80059e8: f103 4280 add.w r2, r3, #1073741824 ; 0x40000000 + 80059ec: 3a01 subs r2, #1 + 80059ee: f850 2022 ldr.w r2, [r0, r2, lsl #2] + for (i = 0; digit; ++i) { + 80059f2: 2000 movs r0, #0 + 80059f4: b922 cbnz r2, 8005a00 + digit >>= 1; + } + + return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i); + 80059f6: 3b01 subs r3, #1 + 80059f8: eb00 1343 add.w r3, r0, r3, lsl #5 + 80059fc: b218 sxth r0, r3 +} + 80059fe: bd10 pop {r4, pc} + digit >>= 1; + 8005a00: 0852 lsrs r2, r2, #1 + for (i = 0; digit; ++i) { + 8005a02: 3001 adds r0, #1 + 8005a04: e7f6 b.n 80059f4 + return 0; + 8005a06: 4618 mov r0, r3 + 8005a08: e7f9 b.n 80059fe + +08005a0a : + +/* Sets dest = src. */ +#if !asm_set +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + 8005a0a: b510 push {r4, lr} + wordcount_t i; + for (i = 0; i < num_words; ++i) { + 8005a0c: 2300 movs r3, #0 + 8005a0e: b25c sxtb r4, r3 + 8005a10: 42a2 cmp r2, r4 + 8005a12: dc00 bgt.n 8005a16 + dest[i] = src[i]; + } +} + 8005a14: bd10 pop {r4, pc} + dest[i] = src[i]; + 8005a16: f851 4023 ldr.w r4, [r1, r3, lsl #2] + 8005a1a: f840 4023 str.w r4, [r0, r3, lsl #2] + for (i = 0; i < num_words; ++i) { + 8005a1e: 3301 adds r3, #1 + 8005a20: e7f5 b.n 8005a0e + +08005a22 : +#endif /* !asm_set */ + +/* Returns sign of left - right. */ +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + 8005a22: b510 push {r4, lr} + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + 8005a24: 3a01 subs r2, #1 + 8005a26: b252 sxtb r2, r2 + 8005a28: 0613 lsls r3, r2, #24 + 8005a2a: d501 bpl.n 8005a30 + return 1; + } else if (left[i] < right[i]) { + return -1; + } + } + return 0; + 8005a2c: 2000 movs r0, #0 +} + 8005a2e: bd10 pop {r4, pc} + if (left[i] > right[i]) { + 8005a30: f850 4022 ldr.w r4, [r0, r2, lsl #2] + 8005a34: f851 3022 ldr.w r3, [r1, r2, lsl #2] + 8005a38: 429c cmp r4, r3 + 8005a3a: d805 bhi.n 8005a48 + } else if (left[i] < right[i]) { + 8005a3c: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 8005a40: d2f2 bcs.n 8005a28 + return -1; + 8005a42: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 8005a46: e7f2 b.n 8005a2e + return 1; + 8005a48: 2001 movs r0, #1 + 8005a4a: e7f0 b.n 8005a2e + +08005a4c : +#if !asm_rshift1 +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t *end = vli; + uECC_word_t carry = 0; + + vli += num_words; + 8005a4c: eb00 0181 add.w r1, r0, r1, lsl #2 + uECC_word_t carry = 0; + 8005a50: 2300 movs r3, #0 + while (vli-- > end) { + 8005a52: 4288 cmp r0, r1 + 8005a54: d300 bcc.n 8005a58 + uECC_word_t temp = *vli; + *vli = (temp >> 1) | carry; + carry = temp << (uECC_WORD_BITS - 1); + } +} + 8005a56: 4770 bx lr + uECC_word_t temp = *vli; + 8005a58: f851 2d04 ldr.w r2, [r1, #-4]! + *vli = (temp >> 1) | carry; + 8005a5c: ea43 0352 orr.w r3, r3, r2, lsr #1 + 8005a60: 600b str r3, [r1, #0] + carry = temp << (uECC_WORD_BITS - 1); + 8005a62: 07d3 lsls r3, r2, #31 + 8005a64: e7f5 b.n 8005a52 + +08005a66 : +/* Computes result = (left * right) % mod. */ +uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + 8005a66: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8005a6a: b0b5 sub sp, #212 ; 0xd4 + 8005a6c: 461f mov r7, r3 + 8005a6e: f99d 50f8 ldrsb.w r5, [sp, #248] ; 0xf8 + 8005a72: 4680 mov r8, r0 + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, num_words); + 8005a74: 462b mov r3, r5 + 8005a76: a804 add r0, sp, #16 + 8005a78: f7ff ff48 bl 800590c + uECC_word_t *v[2] = {tmp, product}; + 8005a7c: ab24 add r3, sp, #144 ; 0x90 + 8005a7e: e9cd 3002 strd r3, r0, [sp, #8] + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words); + 8005a82: 4629 mov r1, r5 + 8005a84: 4638 mov r0, r7 + 8005a86: f7ff ffa0 bl 80059ca + 8005a8a: ebc0 1085 rsb r0, r0, r5, lsl #6 + 8005a8e: b204 sxth r4, r0 + wordcount_t word_shift = shift / uECC_WORD_BITS; + 8005a90: 2c00 cmp r4, #0 + 8005a92: 4626 mov r6, r4 + 8005a94: bfb8 it lt + 8005a96: f104 061f addlt.w r6, r4, #31 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 8005a9a: 4263 negs r3, r4 + wordcount_t word_shift = shift / uECC_WORD_BITS; + 8005a9c: f346 1647 sbfx r6, r6, #5, #8 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 8005aa0: f003 031f and.w r3, r3, #31 + 8005aa4: f004 091f and.w r9, r4, #31 + uECC_vli_clear(mod_multiple, word_shift); + 8005aa8: 4631 mov r1, r6 + wordcount_t bit_shift = shift % uECC_WORD_BITS; + 8005aaa: bf58 it pl + 8005aac: f1c3 0900 rsbpl r9, r3, #0 + uECC_vli_clear(mod_multiple, word_shift); + 8005ab0: a814 add r0, sp, #80 ; 0x50 + 8005ab2: f7ff ff6b bl 800598c + if (bit_shift > 0) { + 8005ab6: f1b9 0f00 cmp.w r9, #0 + 8005aba: b236 sxth r6, r6 + 8005abc: dd2b ble.n 8005b16 + 8005abe: ab14 add r3, sp, #80 ; 0x50 + uECC_word_t carry = 0; + 8005ac0: 2200 movs r2, #0 + 8005ac2: eb03 0686 add.w r6, r3, r6, lsl #2 + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + 8005ac6: f1c9 0c20 rsb ip, r9, #32 + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 8005aca: 4613 mov r3, r2 + 8005acc: 42ab cmp r3, r5 + 8005ace: d317 bcc.n 8005b00 + for (i = 0; i < num_words * 2; ++i) { + 8005ad0: 006b lsls r3, r5, #1 + 8005ad2: 9301 str r3, [sp, #4] + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005ad4: ab14 add r3, sp, #80 ; 0x50 + 8005ad6: eb03 0985 add.w r9, r3, r5, lsl #2 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 8005ada: 1e6f subs r7, r5, #1 + 8005adc: ab34 add r3, sp, #208 ; 0xd0 + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005ade: 2601 movs r6, #1 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 8005ae0: eb03 0787 add.w r7, r3, r7, lsl #2 + for (index = 1; shift >= 0; --shift) { + 8005ae4: 2c00 cmp r4, #0 + 8005ae6: da54 bge.n 8005b92 + uECC_vli_set(result, v[index], num_words); + 8005ae8: ab34 add r3, sp, #208 ; 0xd0 + 8005aea: eb03 0686 add.w r6, r3, r6, lsl #2 + 8005aee: 462a mov r2, r5 + 8005af0: f856 1cc8 ldr.w r1, [r6, #-200] + 8005af4: 4640 mov r0, r8 + 8005af6: f7ff ff88 bl 8005a0a + uECC_vli_mmod(result, product, mod, num_words); +} + 8005afa: b035 add sp, #212 ; 0xd4 + 8005afc: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; + 8005b00: f857 0023 ldr.w r0, [r7, r3, lsl #2] + 8005b04: fa00 f109 lsl.w r1, r0, r9 + 8005b08: 430a orrs r2, r1 + 8005b0a: f846 2b04 str.w r2, [r6], #4 + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 8005b0e: 3301 adds r3, #1 + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + 8005b10: fa20 f20c lsr.w r2, r0, ip + for(index = 0; index < (uECC_word_t)num_words; ++index) { + 8005b14: e7da b.n 8005acc + uECC_vli_set(mod_multiple + word_shift, mod, num_words); + 8005b16: ab14 add r3, sp, #80 ; 0x50 + 8005b18: 462a mov r2, r5 + 8005b1a: 4639 mov r1, r7 + 8005b1c: eb03 0086 add.w r0, r3, r6, lsl #2 + 8005b20: f7ff ff73 bl 8005a0a + 8005b24: e7d4 b.n 8005ad0 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 8005b26: fa0f fe82 sxth.w lr, r2 + 8005b2a: f85a 3cc8 ldr.w r3, [sl, #-200] + 8005b2e: f853 b02e ldr.w fp, [r3, lr, lsl #2] + 8005b32: ab34 add r3, sp, #208 ; 0xd0 + 8005b34: eb03 0282 add.w r2, r3, r2, lsl #2 + 8005b38: 3001 adds r0, #1 + 8005b3a: f852 3c80 ldr.w r3, [r2, #-128] + 8005b3e: 440b add r3, r1 + 8005b40: ebbb 0303 subs.w r3, fp, r3 + 8005b44: bf34 ite cc + 8005b46: 2201 movcc r2, #1 + 8005b48: 2200 movcs r2, #0 + if (diff != v[index][i]) { + 8005b4a: 459b cmp fp, r3 + borrow = (diff > v[index][i]); + 8005b4c: bf18 it ne + 8005b4e: 4611 movne r1, r2 + v[1 - index][i] = diff; + 8005b50: f85c 2cc8 ldr.w r2, [ip, #-200] + 8005b54: f842 302e str.w r3, [r2, lr, lsl #2] + for (i = 0; i < num_words * 2; ++i) { + 8005b58: 9b01 ldr r3, [sp, #4] + 8005b5a: b242 sxtb r2, r0 + 8005b5c: 429a cmp r2, r3 + 8005b5e: dbe2 blt.n 8005b26 + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + 8005b60: 1a73 subs r3, r6, r1 + 8005b62: 425e negs r6, r3 + uECC_vli_rshift1(mod_multiple, num_words); + 8005b64: 4629 mov r1, r5 + 8005b66: a814 add r0, sp, #80 ; 0x50 + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + 8005b68: 415e adcs r6, r3 + uECC_vli_rshift1(mod_multiple, num_words); + 8005b6a: f7ff ff6f bl 8005a4c + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 8005b6e: ab34 add r3, sp, #208 ; 0xd0 + 8005b70: eb03 0385 add.w r3, r3, r5, lsl #2 + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005b74: 4629 mov r1, r5 + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + 8005b76: f853 2c80 ldr.w r2, [r3, #-128] + 8005b7a: f857 3c80 ldr.w r3, [r7, #-128] + 8005b7e: ea43 73c2 orr.w r3, r3, r2, lsl #31 + 8005b82: f847 3c80 str.w r3, [r7, #-128] + uECC_vli_rshift1(mod_multiple + num_words, num_words); + 8005b86: 4648 mov r0, r9 + 8005b88: 3c01 subs r4, #1 + 8005b8a: f7ff ff5f bl 8005a4c + for (index = 1; shift >= 0; --shift) { + 8005b8e: b224 sxth r4, r4 + 8005b90: e7a8 b.n 8005ae4 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 8005b92: ab34 add r3, sp, #208 ; 0xd0 + 8005b94: 2000 movs r0, #0 + v[1 - index][i] = diff; + 8005b96: f1c6 0c01 rsb ip, r6, #1 + uECC_word_t borrow = 0; + 8005b9a: 4601 mov r1, r0 + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + 8005b9c: eb03 0a86 add.w sl, r3, r6, lsl #2 + v[1 - index][i] = diff; + 8005ba0: eb03 0c8c add.w ip, r3, ip, lsl #2 + 8005ba4: e7d8 b.n 8005b58 + +08005ba6 : + +uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve) { + 8005ba6: b530 push {r4, r5, lr} + 8005ba8: 461c mov r4, r3 + 8005baa: b091 sub sp, #68 ; 0x44 + 8005bac: 4605 mov r5, r0 + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); + 8005bae: f993 3000 ldrsb.w r3, [r3] + 8005bb2: 4668 mov r0, sp + 8005bb4: f7ff feaa bl 800590c +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); + 8005bb8: 4601 mov r1, r0 + 8005bba: f8d4 30b0 ldr.w r3, [r4, #176] ; 0xb0 + 8005bbe: 4628 mov r0, r5 + 8005bc0: 4798 blx r3 +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + 8005bc2: b011 add sp, #68 ; 0x44 + 8005bc4: bd30 pop {r4, r5, pc} + +08005bc6 : +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + 8005bc6: 4613 mov r3, r2 + uECC_vli_modMult_fast(result, left, left, curve); + 8005bc8: 460a mov r2, r1 + 8005bca: f7ff bfec b.w 8005ba6 + +08005bce : + +/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ +static void apply_z(uECC_word_t * X1, + uECC_word_t * Y1, + const uECC_word_t * const Z, + uECC_Curve curve) { + 8005bce: b570 push {r4, r5, r6, lr} + 8005bd0: 4614 mov r4, r2 + 8005bd2: b08a sub sp, #40 ; 0x28 + 8005bd4: 4606 mov r6, r0 + 8005bd6: 460d mov r5, r1 + uECC_word_t t1[uECC_MAX_WORDS]; + + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + 8005bd8: 461a mov r2, r3 + 8005bda: 4621 mov r1, r4 + 8005bdc: a802 add r0, sp, #8 + 8005bde: 9301 str r3, [sp, #4] + 8005be0: f7ff fff1 bl 8005bc6 + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + 8005be4: 9b01 ldr r3, [sp, #4] + 8005be6: aa02 add r2, sp, #8 + 8005be8: 4631 mov r1, r6 + 8005bea: 4630 mov r0, r6 + 8005bec: f7ff ffdb bl 8005ba6 + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + 8005bf0: a902 add r1, sp, #8 + 8005bf2: 9b01 ldr r3, [sp, #4] + 8005bf4: 4622 mov r2, r4 + 8005bf6: 4608 mov r0, r1 + 8005bf8: f7ff ffd5 bl 8005ba6 + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ + 8005bfc: 9b01 ldr r3, [sp, #4] + 8005bfe: aa02 add r2, sp, #8 + 8005c00: 4629 mov r1, r5 + 8005c02: 4628 mov r0, r5 + 8005c04: f7ff ffcf bl 8005ba6 +} + 8005c08: b00a add sp, #40 ; 0x28 + 8005c0a: bd70 pop {r4, r5, r6, pc} + +08005c0c : + +#else + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uECC_word_t *native) { + 8005c0c: b5f0 push {r4, r5, r6, r7, lr} + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + 8005c0e: 2500 movs r5, #0 + unsigned b = num_bytes - 1 - i; + 8005c10: 1e4f subs r7, r1, #1 + 8005c12: b26c sxtb r4, r5 + for (i = 0; i < num_bytes; ++i) { + 8005c14: 428c cmp r4, r1 + 8005c16: f105 0501 add.w r5, r5, #1 + 8005c1a: db00 blt.n 8005c1e + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + } +} + 8005c1c: bdf0 pop {r4, r5, r6, r7, pc} + unsigned b = num_bytes - 1 - i; + 8005c1e: 1b3b subs r3, r7, r4 + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + 8005c20: f023 0603 bic.w r6, r3, #3 + 8005c24: f003 0303 and.w r3, r3, #3 + 8005c28: 5996 ldr r6, [r2, r6] + 8005c2a: 00db lsls r3, r3, #3 + 8005c2c: fa26 f303 lsr.w r3, r6, r3 + 8005c30: 5503 strb r3, [r0, r4] + for (i = 0; i < num_bytes; ++i) { + 8005c32: e7ee b.n 8005c12 + +08005c34 : + +uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native, + const uint8_t *bytes, + int num_bytes) { + 8005c34: b5f8 push {r3, r4, r5, r6, r7, lr} + 8005c36: 460e mov r6, r1 + wordcount_t i; + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005c38: 1cd1 adds r1, r2, #3 + 8005c3a: bf48 it mi + 8005c3c: 1d91 addmi r1, r2, #6 + int num_bytes) { + 8005c3e: 4614 mov r4, r2 + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005c40: f341 0187 sbfx r1, r1, #2, #8 + int num_bytes) { + 8005c44: 4605 mov r5, r0 + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + 8005c46: 1e67 subs r7, r4, #1 + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + 8005c48: f7ff fea0 bl 800598c + for (i = 0; i < num_bytes; ++i) { + 8005c4c: 2000 movs r0, #0 + 8005c4e: b242 sxtb r2, r0 + 8005c50: 42a2 cmp r2, r4 + 8005c52: f100 0001 add.w r0, r0, #1 + 8005c56: db00 blt.n 8005c5a + native[b / uECC_WORD_SIZE] |= + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + } +} + 8005c58: bdf8 pop {r3, r4, r5, r6, r7, pc} + unsigned b = num_bytes - 1 - i; + 8005c5a: 1abb subs r3, r7, r2 + native[b / uECC_WORD_SIZE] |= + 8005c5c: f023 0103 bic.w r1, r3, #3 + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + 8005c60: 5cb2 ldrb r2, [r6, r2] + 8005c62: f003 0303 and.w r3, r3, #3 + 8005c66: 00db lsls r3, r3, #3 + 8005c68: fa02 f303 lsl.w r3, r2, r3 + native[b / uECC_WORD_SIZE] |= + 8005c6c: 586a ldr r2, [r5, r1] + 8005c6e: 431a orrs r2, r3 + 8005c70: 506a str r2, [r5, r1] + for (i = 0; i < num_bytes; ++i) { + 8005c72: e7ec b.n 8005c4e + +08005c74 : + return 0; +} + +/* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always + the same size as the hash result size. */ +static void HMAC_init(uECC_HashContext *hash_context, const uint8_t *K) { + 8005c74: b570 push {r4, r5, r6, lr} + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 8005c76: e9d0 3504 ldrd r3, r5, [r0, #16] +static void HMAC_init(uECC_HashContext *hash_context, const uint8_t *K) { + 8005c7a: 4604 mov r4, r0 + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 8005c7c: eb05 0543 add.w r5, r5, r3, lsl #1 + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + 8005c80: 2300 movs r3, #0 + 8005c82: 6922 ldr r2, [r4, #16] + 8005c84: 429a cmp r2, r3 + 8005c86: d80d bhi.n 8005ca4 + pad[i] = K[i] ^ 0x36; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x36; + 8005c88: 2136 movs r1, #54 ; 0x36 + for (; i < hash_context->block_size; ++i) + 8005c8a: 68e2 ldr r2, [r4, #12] + 8005c8c: 429a cmp r2, r3 + 8005c8e: d80f bhi.n 8005cb0 + + hash_context->init_hash(hash_context); + 8005c90: 6823 ldr r3, [r4, #0] + 8005c92: 4620 mov r0, r4 + 8005c94: 4798 blx r3 + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 8005c96: 6863 ldr r3, [r4, #4] + 8005c98: 68e2 ldr r2, [r4, #12] + 8005c9a: 4629 mov r1, r5 + 8005c9c: 4620 mov r0, r4 +} + 8005c9e: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 8005ca2: 4718 bx r3 + pad[i] = K[i] ^ 0x36; + 8005ca4: 5cca ldrb r2, [r1, r3] + 8005ca6: f082 0236 eor.w r2, r2, #54 ; 0x36 + 8005caa: 54ea strb r2, [r5, r3] + for (i = 0; i < hash_context->result_size; ++i) + 8005cac: 3301 adds r3, #1 + 8005cae: e7e8 b.n 8005c82 + pad[i] = 0x36; + 8005cb0: 54e9 strb r1, [r5, r3] + for (; i < hash_context->block_size; ++i) + 8005cb2: 3301 adds r3, #1 + 8005cb4: e7e9 b.n 8005c8a + +08005cb6 : + +static void HMAC_update(uECC_HashContext *hash_context, + const uint8_t *message, + unsigned message_size) { + hash_context->update_hash(hash_context, message, message_size); + 8005cb6: 6843 ldr r3, [r0, #4] + 8005cb8: 4718 bx r3 + +08005cba : +} + +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 8005cba: b570 push {r4, r5, r6, lr} + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 8005cbc: e9d0 3604 ldrd r3, r6, [r0, #16] +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 8005cc0: 4604 mov r4, r0 + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + 8005cc2: eb06 0643 add.w r6, r6, r3, lsl #1 +static void HMAC_finish(uECC_HashContext *hash_context, const uint8_t *K, uint8_t *result) { + 8005cc6: 4615 mov r5, r2 + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + 8005cc8: 2300 movs r3, #0 + 8005cca: 6922 ldr r2, [r4, #16] + 8005ccc: 429a cmp r2, r3 + 8005cce: d81a bhi.n 8005d06 + pad[i] = K[i] ^ 0x5c; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x5c; + 8005cd0: 215c movs r1, #92 ; 0x5c + for (; i < hash_context->block_size; ++i) + 8005cd2: 68e2 ldr r2, [r4, #12] + 8005cd4: 429a cmp r2, r3 + 8005cd6: d81c bhi.n 8005d12 + + hash_context->finish_hash(hash_context, result); + 8005cd8: 4629 mov r1, r5 + 8005cda: 68a3 ldr r3, [r4, #8] + 8005cdc: 4620 mov r0, r4 + 8005cde: 4798 blx r3 + + hash_context->init_hash(hash_context); + 8005ce0: 6823 ldr r3, [r4, #0] + 8005ce2: 4620 mov r0, r4 + 8005ce4: 4798 blx r3 + hash_context->update_hash(hash_context, pad, hash_context->block_size); + 8005ce6: 6863 ldr r3, [r4, #4] + 8005ce8: 68e2 ldr r2, [r4, #12] + 8005cea: 4631 mov r1, r6 + 8005cec: 4620 mov r0, r4 + 8005cee: 4798 blx r3 + hash_context->update_hash(hash_context, result, hash_context->result_size); + 8005cf0: 6863 ldr r3, [r4, #4] + 8005cf2: 6922 ldr r2, [r4, #16] + 8005cf4: 4629 mov r1, r5 + 8005cf6: 4620 mov r0, r4 + 8005cf8: 4798 blx r3 + hash_context->finish_hash(hash_context, result); + 8005cfa: 68a3 ldr r3, [r4, #8] + 8005cfc: 4629 mov r1, r5 + 8005cfe: 4620 mov r0, r4 +} + 8005d00: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + hash_context->finish_hash(hash_context, result); + 8005d04: 4718 bx r3 + pad[i] = K[i] ^ 0x5c; + 8005d06: 5cca ldrb r2, [r1, r3] + 8005d08: f082 025c eor.w r2, r2, #92 ; 0x5c + 8005d0c: 54f2 strb r2, [r6, r3] + for (i = 0; i < hash_context->result_size; ++i) + 8005d0e: 3301 adds r3, #1 + 8005d10: e7db b.n 8005cca + pad[i] = 0x5c; + 8005d12: 54f1 strb r1, [r6, r3] + for (; i < hash_context->block_size; ++i) + 8005d14: 3301 adds r3, #1 + 8005d16: e7dc b.n 8005cd2 + +08005d18 : + +/* V = HMAC_K(V) */ +static void update_V(uECC_HashContext *hash_context, uint8_t *K, uint8_t *V) { + 8005d18: b570 push {r4, r5, r6, lr} + 8005d1a: 4604 mov r4, r0 + 8005d1c: 4615 mov r5, r2 + 8005d1e: 460e mov r6, r1 + HMAC_init(hash_context, K); + 8005d20: f7ff ffa8 bl 8005c74 + HMAC_update(hash_context, V, hash_context->result_size); + 8005d24: 6922 ldr r2, [r4, #16] + 8005d26: 4629 mov r1, r5 + 8005d28: 4620 mov r0, r4 + 8005d2a: f7ff ffc4 bl 8005cb6 + HMAC_finish(hash_context, K, V); + 8005d2e: 462a mov r2, r5 + 8005d30: 4631 mov r1, r6 + 8005d32: 4620 mov r0, r4 +} + 8005d34: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + HMAC_finish(hash_context, K, V); + 8005d38: f7ff bfbf b.w 8005cba + +08005d3c : +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + 8005d3c: b530 push {r4, r5, lr} + __asm__ volatile ( + 8005d3e: 2300 movs r3, #0 + 8005d40: c910 ldmia r1!, {r4} + 8005d42: ca20 ldmia r2!, {r5} + 8005d44: 1b64 subs r4, r4, r5 + 8005d46: c010 stmia r0!, {r4} + 8005d48: c910 ldmia r1!, {r4} + 8005d4a: ca20 ldmia r2!, {r5} + 8005d4c: 41ac sbcs r4, r5 + 8005d4e: c010 stmia r0!, {r4} + 8005d50: c910 ldmia r1!, {r4} + 8005d52: ca20 ldmia r2!, {r5} + 8005d54: 41ac sbcs r4, r5 + 8005d56: c010 stmia r0!, {r4} + 8005d58: c910 ldmia r1!, {r4} + 8005d5a: ca20 ldmia r2!, {r5} + 8005d5c: 41ac sbcs r4, r5 + 8005d5e: c010 stmia r0!, {r4} + 8005d60: c910 ldmia r1!, {r4} + 8005d62: ca20 ldmia r2!, {r5} + 8005d64: 41ac sbcs r4, r5 + 8005d66: c010 stmia r0!, {r4} + 8005d68: c910 ldmia r1!, {r4} + 8005d6a: ca20 ldmia r2!, {r5} + 8005d6c: 41ac sbcs r4, r5 + 8005d6e: c010 stmia r0!, {r4} + 8005d70: c910 ldmia r1!, {r4} + 8005d72: ca20 ldmia r2!, {r5} + 8005d74: 41ac sbcs r4, r5 + 8005d76: c010 stmia r0!, {r4} + 8005d78: c910 ldmia r1!, {r4} + 8005d7a: ca20 ldmia r2!, {r5} + 8005d7c: 41ac sbcs r4, r5 + 8005d7e: c010 stmia r0!, {r4} + 8005d80: 415b adcs r3, r3 +} + 8005d82: fab3 f083 clz r0, r3 + 8005d86: 0940 lsrs r0, r0, #5 + 8005d88: bd30 pop {r4, r5, pc} + +08005d8a : + uECC_Curve curve) { + 8005d8a: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 8005d8e: 4698 mov r8, r3 + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005d90: f9b3 3002 ldrsh.w r3, [r3, #2] + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005d94: f113 041f adds.w r4, r3, #31 + 8005d98: bf48 it mi + 8005d9a: f103 043e addmi.w r4, r3, #62 ; 0x3e + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005d9e: 1ddd adds r5, r3, #7 + 8005da0: bf48 it mi + 8005da2: f103 050e addmi.w r5, r3, #14 + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005da6: 1166 asrs r6, r4, #5 + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + 8005da8: 10ec asrs r4, r5, #3 + 8005daa: 4294 cmp r4, r2 + uECC_vli_clear(native, num_n_words); + 8005dac: b275 sxtb r5, r6 + 8005dae: bf28 it cs + 8005db0: 4614 movcs r4, r2 + uECC_Curve curve) { + 8005db2: 4607 mov r7, r0 + 8005db4: 4689 mov r9, r1 + uECC_vli_clear(native, num_n_words); + 8005db6: 4629 mov r1, r5 + 8005db8: f7ff fde8 bl 800598c + uECC_vli_bytesToNative(native, bits, bits_size); + 8005dbc: 4622 mov r2, r4 + 8005dbe: 4649 mov r1, r9 + 8005dc0: 4638 mov r0, r7 + 8005dc2: f7ff ff37 bl 8005c34 + if (bits_size * 8 <= (unsigned)curve->num_n_bits) { + 8005dc6: f9b8 2002 ldrsh.w r2, [r8, #2] + 8005dca: ebb2 0fc4 cmp.w r2, r4, lsl #3 + 8005dce: ea4f 03c4 mov.w r3, r4, lsl #3 + 8005dd2: d21f bcs.n 8005e14 + int shift = bits_size * 8 - curve->num_n_bits; + 8005dd4: 1a9b subs r3, r3, r2 + uECC_word_t *ptr = native + num_n_words; + 8005dd6: eb07 0486 add.w r4, r7, r6, lsl #2 + uECC_word_t carry = 0; + 8005dda: 2100 movs r1, #0 + carry = temp << (uECC_WORD_BITS - shift); + 8005ddc: f1c3 0620 rsb r6, r3, #32 + while (ptr-- > native) { + 8005de0: 42a7 cmp r7, r4 + 8005de2: d30e bcc.n 8005e02 + if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) { + 8005de4: f108 0824 add.w r8, r8, #36 ; 0x24 + 8005de8: 462a mov r2, r5 + 8005dea: 4639 mov r1, r7 + 8005dec: 4640 mov r0, r8 + 8005dee: f7ff fe18 bl 8005a22 + 8005df2: 2801 cmp r0, #1 + 8005df4: d00e beq.n 8005e14 + uECC_vli_sub(native, native, curve->n, num_n_words); + 8005df6: 4642 mov r2, r8 + 8005df8: 4638 mov r0, r7 +} + 8005dfa: e8bd 43f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + uECC_vli_sub(native, native, curve->n, num_n_words); + 8005dfe: f7ff bf9d b.w 8005d3c + uECC_word_t temp = *ptr; + 8005e02: f854 0d04 ldr.w r0, [r4, #-4]! + *ptr = (temp >> shift) | carry; + 8005e06: fa20 f203 lsr.w r2, r0, r3 + 8005e0a: 430a orrs r2, r1 + 8005e0c: 6022 str r2, [r4, #0] + carry = temp << (uECC_WORD_BITS - shift); + 8005e0e: fa00 f106 lsl.w r1, r0, r6 + 8005e12: e7e5 b.n 8005de0 +} + 8005e14: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + +08005e18 : + wordcount_t num_words) { + 8005e18: b530 push {r4, r5, lr} + 8005e1a: b089 sub sp, #36 ; 0x24 + 8005e1c: 4615 mov r5, r2 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005e1e: 460a mov r2, r1 + 8005e20: 4601 mov r1, r0 + 8005e22: 4668 mov r0, sp + 8005e24: f7ff ff8a bl 8005d3c + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + 8005e28: 4629 mov r1, r5 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005e2a: 4604 mov r4, r0 + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + 8005e2c: 4668 mov r0, sp + 8005e2e: f7ff fdb3 bl 8005998 + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + 8005e32: 3c00 subs r4, #0 + 8005e34: bf18 it ne + 8005e36: 2401 movne r4, #1 + return (!equal - 2 * neg); + 8005e38: 0064 lsls r4, r4, #1 +} + 8005e3a: 2800 cmp r0, #0 + 8005e3c: bf14 ite ne + 8005e3e: 4260 negne r0, r4 + 8005e40: f1c4 0001 rsbeq r0, r4, #1 + 8005e44: b009 add sp, #36 ; 0x24 + 8005e46: bd30 pop {r4, r5, pc} + +08005e48 : + wordcount_t num_words) { + 8005e48: e92d 4ff8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8005e4c: 460f mov r7, r1 + if (!g_rng_function) { + 8005e4e: f8df a06c ldr.w sl, [pc, #108] ; 8005ebc + wordcount_t num_words) { + 8005e52: 4606 mov r6, r0 + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + 8005e54: 4611 mov r1, r2 + 8005e56: 4638 mov r0, r7 + wordcount_t num_words) { + 8005e58: 4614 mov r4, r2 + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + 8005e5a: f7ff fdb6 bl 80059ca + if (!g_rng_function) { + 8005e5e: f8da 3000 ldr.w r3, [sl] + 8005e62: b303 cbz r3, 8005ea6 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005e64: 2504 movs r5, #4 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005e66: ebc0 1044 rsb r0, r0, r4, lsl #5 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005e6a: fb14 fb05 smulbb fp, r4, r5 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005e6e: b200 sxth r0, r0 + 8005e70: fb05 6504 mla r5, r5, r4, r6 + 8005e74: f04f 38ff mov.w r8, #4294967295 ; 0xffffffff + 8005e78: 3d04 subs r5, #4 + 8005e7a: fa28 f800 lsr.w r8, r8, r0 + 8005e7e: f04f 0940 mov.w r9, #64 ; 0x40 + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + 8005e82: f8da 3000 ldr.w r3, [sl] + 8005e86: 4659 mov r1, fp + 8005e88: 4630 mov r0, r6 + 8005e8a: 4798 blx r3 + 8005e8c: b158 cbz r0, 8005ea6 + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + 8005e8e: 682b ldr r3, [r5, #0] + 8005e90: ea03 0308 and.w r3, r3, r8 + 8005e94: 602b str r3, [r5, #0] + if (!uECC_vli_isZero(random, num_words) && + 8005e96: 4621 mov r1, r4 + 8005e98: 4630 mov r0, r6 + 8005e9a: f7ff fd7d bl 8005998 + 8005e9e: b120 cbz r0, 8005eaa + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8005ea0: f1b9 0901 subs.w r9, r9, #1 + 8005ea4: d1ed bne.n 8005e82 + return 0; + 8005ea6: 2000 movs r0, #0 + 8005ea8: e006 b.n 8005eb8 + uECC_vli_cmp(top, random, num_words) == 1) { + 8005eaa: 4622 mov r2, r4 + 8005eac: 4631 mov r1, r6 + 8005eae: 4638 mov r0, r7 + 8005eb0: f7ff ffb2 bl 8005e18 + if (!uECC_vli_isZero(random, num_words) && + 8005eb4: 2801 cmp r0, #1 + 8005eb6: d1f3 bne.n 8005ea0 +} + 8005eb8: e8bd 8ff8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, pc} + 8005ebc: 2009e2a4 .word 0x2009e2a4 + +08005ec0 : +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + 8005ec0: b530 push {r4, r5, lr} + __asm__ volatile ( + 8005ec2: 4603 mov r3, r0 + 8005ec4: 2000 movs r0, #0 + 8005ec6: c910 ldmia r1!, {r4} + 8005ec8: ca20 ldmia r2!, {r5} + 8005eca: 1964 adds r4, r4, r5 + 8005ecc: c310 stmia r3!, {r4} + 8005ece: c910 ldmia r1!, {r4} + 8005ed0: ca20 ldmia r2!, {r5} + 8005ed2: 416c adcs r4, r5 + 8005ed4: c310 stmia r3!, {r4} + 8005ed6: c910 ldmia r1!, {r4} + 8005ed8: ca20 ldmia r2!, {r5} + 8005eda: 416c adcs r4, r5 + 8005edc: c310 stmia r3!, {r4} + 8005ede: c910 ldmia r1!, {r4} + 8005ee0: ca20 ldmia r2!, {r5} + 8005ee2: 416c adcs r4, r5 + 8005ee4: c310 stmia r3!, {r4} + 8005ee6: c910 ldmia r1!, {r4} + 8005ee8: ca20 ldmia r2!, {r5} + 8005eea: 416c adcs r4, r5 + 8005eec: c310 stmia r3!, {r4} + 8005eee: c910 ldmia r1!, {r4} + 8005ef0: ca20 ldmia r2!, {r5} + 8005ef2: 416c adcs r4, r5 + 8005ef4: c310 stmia r3!, {r4} + 8005ef6: c910 ldmia r1!, {r4} + 8005ef8: ca20 ldmia r2!, {r5} + 8005efa: 416c adcs r4, r5 + 8005efc: c310 stmia r3!, {r4} + 8005efe: c910 ldmia r1!, {r4} + 8005f00: ca20 ldmia r2!, {r5} + 8005f02: 416c adcs r4, r5 + 8005f04: c310 stmia r3!, {r4} + 8005f06: 4140 adcs r0, r0 +} + 8005f08: bd30 pop {r4, r5, pc} + +08005f0a : + uECC_Curve curve) { + 8005f0a: b573 push {r0, r1, r4, r5, r6, lr} + 8005f0c: 460d mov r5, r1 + 8005f0e: 4616 mov r6, r2 + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005f10: 4601 mov r1, r0 + 8005f12: f103 0224 add.w r2, r3, #36 ; 0x24 + 8005f16: 4628 mov r0, r5 + 8005f18: 9201 str r2, [sp, #4] + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005f1a: f9b3 4002 ldrsh.w r4, [r3, #2] + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005f1e: f7ff ffcf bl 8005ec0 + 8005f22: 9a01 ldr r2, [sp, #4] + 8005f24: b9c8 cbnz r0, 8005f5a + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8005f26: f114 031f adds.w r3, r4, #31 + 8005f2a: bf48 it mi + 8005f2c: f104 033e addmi.w r3, r4, #62 ; 0x3e + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + 8005f30: f343 1347 sbfx r3, r3, #5, #8 + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005f34: ebb4 1f43 cmp.w r4, r3, lsl #5 + 8005f38: da11 bge.n 8005f5e + uECC_vli_testBit(k0, num_n_bits)); + 8005f3a: 4621 mov r1, r4 + 8005f3c: 4628 mov r0, r5 + 8005f3e: 9201 str r2, [sp, #4] + 8005f40: f7ff fd39 bl 80059b6 + 8005f44: 9a01 ldr r2, [sp, #4] + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + 8005f46: 1e04 subs r4, r0, #0 + 8005f48: bf18 it ne + 8005f4a: 2401 movne r4, #1 + uECC_vli_add(k1, k0, curve->n, num_n_words); + 8005f4c: 4629 mov r1, r5 + 8005f4e: 4630 mov r0, r6 + 8005f50: f7ff ffb6 bl 8005ec0 +} + 8005f54: 4620 mov r0, r4 + 8005f56: b002 add sp, #8 + 8005f58: bd70 pop {r4, r5, r6, pc} + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + 8005f5a: 2401 movs r4, #1 + 8005f5c: e7f6 b.n 8005f4c + 8005f5e: 2400 movs r4, #0 + 8005f60: e7f4 b.n 8005f4c + +08005f62 : + /* add the 2^32 multiple */ + result[4 + num_words_secp256k1] = + uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + 8005f62: b5f8 push {r3, r4, r5, r6, r7, lr} + 8005f64: 460a mov r2, r1 + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uint32_t carry = 0; + 8005f66: 2300 movs r3, #0 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + 8005f68: 4604 mov r4, r0 + 8005f6a: 3904 subs r1, #4 + 8005f6c: 3804 subs r0, #4 + 8005f6e: f102 071c add.w r7, r2, #28 + wordcount_t k; + + for (k = 0; k < num_words_secp256k1; ++k) { + uint64_t p = (uint64_t)0x3D1 * right[k] + carry; + 8005f72: 469e mov lr, r3 + 8005f74: f240 35d1 movw r5, #977 ; 0x3d1 + 8005f78: f851 6f04 ldr.w r6, [r1, #4]! + 8005f7c: 46f4 mov ip, lr + 8005f7e: fbe6 3c05 umlal r3, ip, r6, r5 + for (k = 0; k < num_words_secp256k1; ++k) { + 8005f82: 428f cmp r7, r1 + result[k] = p; + 8005f84: f840 3f04 str.w r3, [r0, #4]! + carry = p >> 32; + 8005f88: 4663 mov r3, ip + for (k = 0; k < num_words_secp256k1; ++k) { + 8005f8a: d1f5 bne.n 8005f78 + } + result[num_words_secp256k1] = carry; + /* add the 2^32 multiple */ + result[1 + num_words_secp256k1] = + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); + 8005f8c: 1d21 adds r1, r4, #4 + result[num_words_secp256k1] = carry; + 8005f8e: f8c4 c020 str.w ip, [r4, #32] + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); + 8005f92: 4608 mov r0, r1 + 8005f94: f7ff ff94 bl 8005ec0 + result[1 + num_words_secp256k1] = + 8005f98: 6260 str r0, [r4, #36] ; 0x24 +} + 8005f9a: bdf8 pop {r3, r4, r5, r6, r7, pc} + +08005f9c : +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + 8005f9c: b570 push {r4, r5, r6, lr} + 8005f9e: b090 sub sp, #64 ; 0x40 + 8005fa0: 460e mov r6, r1 + 8005fa2: 4604 mov r4, r0 + uECC_vli_clear(tmp, num_words_secp256k1); + 8005fa4: 2108 movs r1, #8 + 8005fa6: 4668 mov r0, sp + 8005fa8: f7ff fcf0 bl 800598c + uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); + 8005fac: 2108 movs r1, #8 + 8005fae: a808 add r0, sp, #32 + 8005fb0: f7ff fcec bl 800598c + omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ + 8005fb4: f106 0120 add.w r1, r6, #32 + 8005fb8: 4668 mov r0, sp + 8005fba: f7ff ffd2 bl 8005f62 + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + 8005fbe: 466a mov r2, sp + 8005fc0: 4631 mov r1, r6 + 8005fc2: 4620 mov r0, r4 + 8005fc4: f7ff ff7c bl 8005ec0 + uECC_vli_clear(product, num_words_secp256k1); + 8005fc8: 2108 movs r1, #8 + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + 8005fca: 4605 mov r5, r0 + uECC_vli_clear(product, num_words_secp256k1); + 8005fcc: 4630 mov r0, r6 + 8005fce: f7ff fcdd bl 800598c + omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ + 8005fd2: 4630 mov r0, r6 + 8005fd4: a908 add r1, sp, #32 + 8005fd6: f7ff ffc4 bl 8005f62 + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + 8005fda: 4632 mov r2, r6 + 8005fdc: 4621 mov r1, r4 + 8005fde: 4620 mov r0, r4 + 8005fe0: f7ff ff6e bl 8005ec0 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005fe4: 4e0b ldr r6, [pc, #44] ; (8006014 ) + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + 8005fe6: 4405 add r5, r0 + while (carry > 0) { + 8005fe8: b96d cbnz r5, 8006006 + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) > 0) { + 8005fea: 490a ldr r1, [pc, #40] ; (8006014 ) + 8005fec: 2208 movs r2, #8 + 8005fee: 4620 mov r0, r4 + 8005ff0: f7ff fd17 bl 8005a22 + 8005ff4: 2800 cmp r0, #0 + 8005ff6: dd04 ble.n 8006002 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8005ff8: 460a mov r2, r1 + 8005ffa: 4620 mov r0, r4 + 8005ffc: 4621 mov r1, r4 + 8005ffe: f7ff fe9d bl 8005d3c +} + 8006002: b010 add sp, #64 ; 0x40 + 8006004: bd70 pop {r4, r5, r6, pc} + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 8006006: 4632 mov r2, r6 + 8006008: 4621 mov r1, r4 + 800600a: 4620 mov r0, r4 + --carry; + 800600c: 3d01 subs r5, #1 + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + 800600e: f7ff fe95 bl 8005d3c + 8006012: e7e9 b.n 8005fe8 + 8006014: 080108f4 .word 0x080108f4 + +08006018 : +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 8006018: e92d 44f0 stmdb sp!, {r4, r5, r6, r7, sl, lr} + uECC_vli_set(result, product, num_words_secp256r1); + 800601c: 2208 movs r2, #8 +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 800601e: b088 sub sp, #32 + uECC_vli_set(result, product, num_words_secp256r1); + 8006020: f7ff fcf3 bl 8005a0a + tmp[3] = product[11]; + 8006024: 6acb ldr r3, [r1, #44] ; 0x2c + 8006026: 9303 str r3, [sp, #12] + tmp[4] = product[12]; + 8006028: 6b0b ldr r3, [r1, #48] ; 0x30 + 800602a: 9304 str r3, [sp, #16] + tmp[5] = product[13]; + 800602c: 6b4b ldr r3, [r1, #52] ; 0x34 + 800602e: 9305 str r3, [sp, #20] + tmp[6] = product[14]; + 8006030: 6b8b ldr r3, [r1, #56] ; 0x38 + 8006032: 9306 str r3, [sp, #24] +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + 8006034: 460c mov r4, r1 + 8006036: 4682 mov sl, r0 + tmp[0] = tmp[1] = tmp[2] = 0; + 8006038: 2700 movs r7, #0 + tmp[7] = product[15]; + 800603a: 6bcb ldr r3, [r1, #60] ; 0x3c + 800603c: 9307 str r3, [sp, #28] + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 800603e: 466a mov r2, sp + 8006040: 4669 mov r1, sp + 8006042: 4668 mov r0, sp + tmp[0] = tmp[1] = tmp[2] = 0; + 8006044: e9cd 7701 strd r7, r7, [sp, #4] + 8006048: 9700 str r7, [sp, #0] + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 800604a: f7ff ff39 bl 8005ec0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 800604e: 466a mov r2, sp + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8006050: 4605 mov r5, r0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8006052: 4651 mov r1, sl + 8006054: 4650 mov r0, sl + 8006056: f7ff ff33 bl 8005ec0 + tmp[3] = product[12]; + 800605a: 6b23 ldr r3, [r4, #48] ; 0x30 + 800605c: 9303 str r3, [sp, #12] + tmp[4] = product[13]; + 800605e: 6b63 ldr r3, [r4, #52] ; 0x34 + 8006060: 9304 str r3, [sp, #16] + tmp[5] = product[14]; + 8006062: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8006064: 9305 str r3, [sp, #20] + tmp[6] = product[15]; + 8006066: 6be3 ldr r3, [r4, #60] ; 0x3c + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8006068: 4405 add r5, r0 + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 800606a: 466a mov r2, sp + 800606c: 4669 mov r1, sp + 800606e: 4668 mov r0, sp + tmp[7] = 0; + 8006070: e9cd 3706 strd r3, r7, [sp, #24] + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 8006074: f7ff ff24 bl 8005ec0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8006078: 466a mov r2, sp + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + 800607a: 4405 add r5, r0 + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 800607c: 4651 mov r1, sl + 800607e: 4650 mov r0, sl + 8006080: f7ff ff1e bl 8005ec0 + tmp[0] = product[8]; + 8006084: 6a23 ldr r3, [r4, #32] + 8006086: 9300 str r3, [sp, #0] + tmp[1] = product[9]; + 8006088: 6a63 ldr r3, [r4, #36] ; 0x24 + 800608a: 9301 str r3, [sp, #4] + tmp[2] = product[10]; + 800608c: 6aa3 ldr r3, [r4, #40] ; 0x28 + 800608e: 9302 str r3, [sp, #8] + tmp[6] = product[14]; + 8006090: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8006092: 9306 str r3, [sp, #24] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 8006094: 4405 add r5, r0 + tmp[7] = product[15]; + 8006096: 6be3 ldr r3, [r4, #60] ; 0x3c + 8006098: 9307 str r3, [sp, #28] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 800609a: 466a mov r2, sp + 800609c: 4651 mov r1, sl + 800609e: 4650 mov r0, sl + tmp[3] = tmp[4] = tmp[5] = 0; + 80060a0: e9cd 7704 strd r7, r7, [sp, #16] + 80060a4: 9703 str r7, [sp, #12] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 80060a6: f7ff ff0b bl 8005ec0 + tmp[0] = product[9]; + 80060aa: 6a63 ldr r3, [r4, #36] ; 0x24 + 80060ac: 9300 str r3, [sp, #0] + tmp[1] = product[10]; + 80060ae: 6aa3 ldr r3, [r4, #40] ; 0x28 + tmp[4] = product[14]; + 80060b0: 6ba2 ldr r2, [r4, #56] ; 0x38 + tmp[1] = product[10]; + 80060b2: 9301 str r3, [sp, #4] + tmp[2] = product[11]; + 80060b4: 6ae3 ldr r3, [r4, #44] ; 0x2c + 80060b6: 9302 str r3, [sp, #8] + tmp[4] = product[14]; + 80060b8: 9204 str r2, [sp, #16] + tmp[3] = product[13]; + 80060ba: 6b63 ldr r3, [r4, #52] ; 0x34 + tmp[5] = product[15]; + 80060bc: 6be2 ldr r2, [r4, #60] ; 0x3c + tmp[3] = product[13]; + 80060be: 9303 str r3, [sp, #12] + tmp[6] = product[13]; + 80060c0: e9cd 2305 strd r2, r3, [sp, #20] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 80060c4: 182e adds r6, r5, r0 + tmp[7] = product[8]; + 80060c6: 6a23 ldr r3, [r4, #32] + 80060c8: 9307 str r3, [sp, #28] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 80060ca: 466a mov r2, sp + 80060cc: 4651 mov r1, sl + 80060ce: 4650 mov r0, sl + 80060d0: f7ff fef6 bl 8005ec0 + tmp[0] = product[11]; + 80060d4: 6ae3 ldr r3, [r4, #44] ; 0x2c + 80060d6: 9300 str r3, [sp, #0] + tmp[1] = product[12]; + 80060d8: 6b23 ldr r3, [r4, #48] ; 0x30 + 80060da: 9301 str r3, [sp, #4] + tmp[2] = product[13]; + 80060dc: 6b63 ldr r3, [r4, #52] ; 0x34 + 80060de: 9302 str r3, [sp, #8] + tmp[6] = product[8]; + 80060e0: 6a23 ldr r3, [r4, #32] + 80060e2: 9306 str r3, [sp, #24] + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + 80060e4: 1835 adds r5, r6, r0 + tmp[7] = product[10]; + 80060e6: 6aa3 ldr r3, [r4, #40] ; 0x28 + 80060e8: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 80060ea: 466a mov r2, sp + 80060ec: 4651 mov r1, sl + 80060ee: 4650 mov r0, sl + tmp[3] = tmp[4] = tmp[5] = 0; + 80060f0: e9cd 7704 strd r7, r7, [sp, #16] + 80060f4: 9703 str r7, [sp, #12] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 80060f6: f7ff fe21 bl 8005d3c + tmp[0] = product[12]; + 80060fa: 6b23 ldr r3, [r4, #48] ; 0x30 + 80060fc: 9300 str r3, [sp, #0] + tmp[1] = product[13]; + 80060fe: 6b63 ldr r3, [r4, #52] ; 0x34 + 8006100: 9301 str r3, [sp, #4] + tmp[2] = product[14]; + 8006102: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8006104: 9302 str r3, [sp, #8] + tmp[3] = product[15]; + 8006106: 6be3 ldr r3, [r4, #60] ; 0x3c + 8006108: 9303 str r3, [sp, #12] + tmp[6] = product[9]; + 800610a: 6a63 ldr r3, [r4, #36] ; 0x24 + 800610c: 9306 str r3, [sp, #24] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 800610e: 1a2e subs r6, r5, r0 + tmp[7] = product[11]; + 8006110: 6ae3 ldr r3, [r4, #44] ; 0x2c + 8006112: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8006114: 466a mov r2, sp + 8006116: 4651 mov r1, sl + 8006118: 4650 mov r0, sl + tmp[4] = tmp[5] = 0; + 800611a: e9cd 7704 strd r7, r7, [sp, #16] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 800611e: f7ff fe0d bl 8005d3c + tmp[0] = product[13]; + 8006122: 6b63 ldr r3, [r4, #52] ; 0x34 + 8006124: 9300 str r3, [sp, #0] + tmp[1] = product[14]; + 8006126: 6ba3 ldr r3, [r4, #56] ; 0x38 + 8006128: 9301 str r3, [sp, #4] + tmp[2] = product[15]; + 800612a: 6be3 ldr r3, [r4, #60] ; 0x3c + 800612c: 9302 str r3, [sp, #8] + tmp[3] = product[8]; + 800612e: 6a23 ldr r3, [r4, #32] + 8006130: 9303 str r3, [sp, #12] + tmp[4] = product[9]; + 8006132: 6a63 ldr r3, [r4, #36] ; 0x24 + 8006134: 9304 str r3, [sp, #16] + tmp[5] = product[10]; + 8006136: 6aa3 ldr r3, [r4, #40] ; 0x28 + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8006138: 1a36 subs r6, r6, r0 + tmp[6] = 0; + 800613a: e9cd 3705 strd r3, r7, [sp, #20] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 800613e: 466a mov r2, sp + tmp[7] = product[12]; + 8006140: 6b23 ldr r3, [r4, #48] ; 0x30 + 8006142: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8006144: 4651 mov r1, sl + 8006146: 4650 mov r0, sl + 8006148: f7ff fdf8 bl 8005d3c + tmp[0] = product[14]; + 800614c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800614e: 9300 str r3, [sp, #0] + tmp[1] = product[15]; + 8006150: 6be3 ldr r3, [r4, #60] ; 0x3c + tmp[2] = 0; + 8006152: e9cd 3701 strd r3, r7, [sp, #4] + tmp[3] = product[9]; + 8006156: 6a63 ldr r3, [r4, #36] ; 0x24 + 8006158: 9303 str r3, [sp, #12] + tmp[4] = product[10]; + 800615a: 6aa3 ldr r3, [r4, #40] ; 0x28 + 800615c: 9304 str r3, [sp, #16] + tmp[5] = product[11]; + 800615e: 6ae3 ldr r3, [r4, #44] ; 0x2c + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8006160: 1a36 subs r6, r6, r0 + tmp[6] = 0; + 8006162: e9cd 3705 strd r3, r7, [sp, #20] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 8006166: 466a mov r2, sp + tmp[7] = product[13]; + 8006168: 6b63 ldr r3, [r4, #52] ; 0x34 + 800616a: 9307 str r3, [sp, #28] + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + 800616c: 4651 mov r1, sl + 800616e: 4650 mov r0, sl + 8006170: f7ff fde4 bl 8005d3c + if (carry < 0) { + 8006174: 1a36 subs r6, r6, r0 + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + 8006176: 4c0d ldr r4, [pc, #52] ; (80061ac ) + if (carry < 0) { + 8006178: d40e bmi.n 8006198 + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + 800617a: b936 cbnz r6, 800618a + 800617c: 2208 movs r2, #8 + 800617e: 4651 mov r1, sl + 8006180: 4620 mov r0, r4 + 8006182: f7ff fc4e bl 8005a22 + 8006186: 2801 cmp r0, #1 + 8006188: d00d beq.n 80061a6 + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + 800618a: 4622 mov r2, r4 + 800618c: 4651 mov r1, sl + 800618e: 4650 mov r0, sl + 8006190: f7ff fdd4 bl 8005d3c + 8006194: 1a36 subs r6, r6, r0 + 8006196: e7f0 b.n 800617a + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + 8006198: 4622 mov r2, r4 + 800619a: 4651 mov r1, sl + 800619c: 4650 mov r0, sl + 800619e: f7ff fe8f bl 8005ec0 + } while (carry < 0); + 80061a2: 1836 adds r6, r6, r0 + 80061a4: d4f8 bmi.n 8006198 +} + 80061a6: b008 add sp, #32 + 80061a8: e8bd 84f0 ldmia.w sp!, {r4, r5, r6, r7, sl, pc} + 80061ac: 080109a8 .word 0x080109a8 + +080061b0 : +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + 80061b0: b5f0 push {r4, r5, r6, r7, lr} + 80061b2: b091 sub sp, #68 ; 0x44 + 80061b4: 460d mov r5, r1 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 80061b6: 221c movs r2, #28 + 80061b8: 2100 movs r1, #0 +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + 80061ba: 4606 mov r6, r0 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 80061bc: a801 add r0, sp, #4 + 80061be: f007 fbb1 bl 800d924 + 80061c2: 2401 movs r4, #1 + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 80061c4: 221c movs r2, #28 + 80061c6: 2100 movs r1, #0 + 80061c8: a809 add r0, sp, #36 ; 0x24 + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + 80061ca: 9400 str r4, [sp, #0] + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 80061cc: f007 fbaa bl 800d924 + wordcount_t num_words = curve->num_words; + 80061d0: 4629 mov r1, r5 + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + 80061d2: 466a mov r2, sp + wordcount_t num_words = curve->num_words; + 80061d4: f911 7b04 ldrsb.w r7, [r1], #4 + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + 80061d8: 9408 str r4, [sp, #32] + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + 80061da: 4668 mov r0, sp + 80061dc: f7ff fe70 bl 8005ec0 + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + 80061e0: 4639 mov r1, r7 + 80061e2: 4668 mov r0, sp + 80061e4: f7ff fbf1 bl 80059ca + 80061e8: 1e44 subs r4, r0, #1 + 80061ea: b224 sxth r4, r4 + 80061ec: 2c01 cmp r4, #1 + 80061ee: dc06 bgt.n 80061fe + uECC_vli_set(a, l_result, num_words); + 80061f0: 463a mov r2, r7 + 80061f2: a908 add r1, sp, #32 + 80061f4: 4630 mov r0, r6 + 80061f6: f7ff fc08 bl 8005a0a +} + 80061fa: b011 add sp, #68 ; 0x44 + 80061fc: bdf0 pop {r4, r5, r6, r7, pc} + uECC_vli_modSquare_fast(l_result, l_result, curve); + 80061fe: a908 add r1, sp, #32 + 8006200: 4608 mov r0, r1 + 8006202: 462a mov r2, r5 + 8006204: f7ff fcdf bl 8005bc6 + if (uECC_vli_testBit(p1, i)) { + 8006208: 4621 mov r1, r4 + 800620a: 4668 mov r0, sp + 800620c: f7ff fbd3 bl 80059b6 + 8006210: b128 cbz r0, 800621e + uECC_vli_modMult_fast(l_result, l_result, a, curve); + 8006212: a908 add r1, sp, #32 + 8006214: 462b mov r3, r5 + 8006216: 4632 mov r2, r6 + 8006218: 4608 mov r0, r1 + 800621a: f7ff fcc4 bl 8005ba6 + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + 800621e: 3c01 subs r4, #1 + 8006220: e7e3 b.n 80061ea + +08006222 : + if (!EVEN(uv)) { + 8006222: 6803 ldr r3, [r0, #0] + wordcount_t num_words) { + 8006224: b570 push {r4, r5, r6, lr} + if (!EVEN(uv)) { + 8006226: f013 0601 ands.w r6, r3, #1 + wordcount_t num_words) { + 800622a: 4605 mov r5, r0 + 800622c: 4614 mov r4, r2 + if (!EVEN(uv)) { + 800622e: d004 beq.n 800623a + carry = uECC_vli_add(uv, uv, mod, num_words); + 8006230: 460a mov r2, r1 + 8006232: 4601 mov r1, r0 + 8006234: f7ff fe44 bl 8005ec0 + 8006238: 4606 mov r6, r0 + uECC_vli_rshift1(uv, num_words); + 800623a: 4621 mov r1, r4 + 800623c: 4628 mov r0, r5 + 800623e: f7ff fc05 bl 8005a4c + if (carry) { + 8006242: b146 cbz r6, 8006256 + uv[num_words - 1] |= HIGH_BIT_SET; + 8006244: f104 4280 add.w r2, r4, #1073741824 ; 0x40000000 + 8006248: 3a01 subs r2, #1 + 800624a: f855 3022 ldr.w r3, [r5, r2, lsl #2] + 800624e: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 8006252: f845 3022 str.w r3, [r5, r2, lsl #2] +} + 8006256: bd70 pop {r4, r5, r6, pc} + +08006258 : + wordcount_t num_words) { + 8006258: b5f0 push {r4, r5, r6, r7, lr} + 800625a: 460f mov r7, r1 + 800625c: b0a1 sub sp, #132 ; 0x84 + 800625e: 4606 mov r6, r0 + if (uECC_vli_isZero(input, num_words)) { + 8006260: 4619 mov r1, r3 + 8006262: 4638 mov r0, r7 + wordcount_t num_words) { + 8006264: 4615 mov r5, r2 + 8006266: 461c mov r4, r3 + if (uECC_vli_isZero(input, num_words)) { + 8006268: f7ff fb96 bl 8005998 + 800626c: b128 cbz r0, 800627a + uECC_vli_clear(result, num_words); + 800626e: 4630 mov r0, r6 +} + 8006270: b021 add sp, #132 ; 0x84 + 8006272: e8bd 40f0 ldmia.w sp!, {r4, r5, r6, r7, lr} + uECC_vli_clear(result, num_words); + 8006276: f7ff bb89 b.w 800598c + uECC_vli_set(a, input, num_words); + 800627a: 4622 mov r2, r4 + 800627c: 4639 mov r1, r7 + 800627e: 4668 mov r0, sp + 8006280: f7ff fbc3 bl 8005a0a + uECC_vli_set(b, mod, num_words); + 8006284: 4629 mov r1, r5 + 8006286: a808 add r0, sp, #32 + 8006288: f7ff fbbf bl 8005a0a + uECC_vli_clear(u, num_words); + 800628c: 4621 mov r1, r4 + 800628e: a810 add r0, sp, #64 ; 0x40 + 8006290: f7ff fb7c bl 800598c + u[0] = 1; + 8006294: 2301 movs r3, #1 + uECC_vli_clear(v, num_words); + 8006296: 4621 mov r1, r4 + 8006298: a818 add r0, sp, #96 ; 0x60 + u[0] = 1; + 800629a: 9310 str r3, [sp, #64] ; 0x40 + uECC_vli_clear(v, num_words); + 800629c: f7ff fb76 bl 800598c + while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) { + 80062a0: 4622 mov r2, r4 + 80062a2: a908 add r1, sp, #32 + 80062a4: 4668 mov r0, sp + 80062a6: f7ff fbbc bl 8005a22 + 80062aa: b930 cbnz r0, 80062ba + uECC_vli_set(result, u, num_words); + 80062ac: 4622 mov r2, r4 + 80062ae: a910 add r1, sp, #64 ; 0x40 + 80062b0: 4630 mov r0, r6 + 80062b2: f7ff fbaa bl 8005a0a +} + 80062b6: b021 add sp, #132 ; 0x84 + 80062b8: bdf0 pop {r4, r5, r6, r7, pc} + if (EVEN(a)) { + 80062ba: 9b00 ldr r3, [sp, #0] + 80062bc: 07da lsls r2, r3, #31 + 80062be: d409 bmi.n 80062d4 + uECC_vli_rshift1(a, num_words); + 80062c0: 4621 mov r1, r4 + 80062c2: 4668 mov r0, sp + 80062c4: f7ff fbc2 bl 8005a4c + vli_modInv_update(u, mod, num_words); + 80062c8: 4622 mov r2, r4 + 80062ca: 4629 mov r1, r5 + 80062cc: a810 add r0, sp, #64 ; 0x40 + vli_modInv_update(v, mod, num_words); + 80062ce: f7ff ffa8 bl 8006222 + 80062d2: e7e5 b.n 80062a0 + } else if (EVEN(b)) { + 80062d4: 9b08 ldr r3, [sp, #32] + 80062d6: 07db lsls r3, r3, #31 + 80062d8: d407 bmi.n 80062ea + uECC_vli_rshift1(b, num_words); + 80062da: 4621 mov r1, r4 + 80062dc: a808 add r0, sp, #32 + 80062de: f7ff fbb5 bl 8005a4c + vli_modInv_update(v, mod, num_words); + 80062e2: 4622 mov r2, r4 + 80062e4: 4629 mov r1, r5 + 80062e6: a818 add r0, sp, #96 ; 0x60 + 80062e8: e7f1 b.n 80062ce + } else if (cmpResult > 0) { + 80062ea: 2800 cmp r0, #0 + 80062ec: dd1a ble.n 8006324 + uECC_vli_sub(a, a, b, num_words); + 80062ee: aa08 add r2, sp, #32 + 80062f0: 4669 mov r1, sp + 80062f2: 4668 mov r0, sp + 80062f4: f7ff fd22 bl 8005d3c + uECC_vli_rshift1(a, num_words); + 80062f8: 4621 mov r1, r4 + 80062fa: 4668 mov r0, sp + 80062fc: f7ff fba6 bl 8005a4c + if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) { + 8006300: 4622 mov r2, r4 + 8006302: a918 add r1, sp, #96 ; 0x60 + 8006304: a810 add r0, sp, #64 ; 0x40 + 8006306: f7ff fb8c bl 8005a22 + 800630a: 2800 cmp r0, #0 + 800630c: da04 bge.n 8006318 + uECC_vli_add(u, u, mod, num_words); + 800630e: a910 add r1, sp, #64 ; 0x40 + 8006310: 462a mov r2, r5 + 8006312: 4608 mov r0, r1 + 8006314: f7ff fdd4 bl 8005ec0 + uECC_vli_sub(u, u, v, num_words); + 8006318: a910 add r1, sp, #64 ; 0x40 + 800631a: aa18 add r2, sp, #96 ; 0x60 + 800631c: 4608 mov r0, r1 + 800631e: f7ff fd0d bl 8005d3c + 8006322: e7d1 b.n 80062c8 + uECC_vli_sub(b, b, a, num_words); + 8006324: 466a mov r2, sp + 8006326: a808 add r0, sp, #32 + 8006328: f7ff fd08 bl 8005d3c + uECC_vli_rshift1(b, num_words); + 800632c: 4621 mov r1, r4 + 800632e: a808 add r0, sp, #32 + 8006330: f7ff fb8c bl 8005a4c + if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) { + 8006334: 4622 mov r2, r4 + 8006336: a910 add r1, sp, #64 ; 0x40 + 8006338: a818 add r0, sp, #96 ; 0x60 + 800633a: f7ff fb72 bl 8005a22 + 800633e: 2800 cmp r0, #0 + 8006340: da04 bge.n 800634c + uECC_vli_add(v, v, mod, num_words); + 8006342: a918 add r1, sp, #96 ; 0x60 + 8006344: 462a mov r2, r5 + 8006346: 4608 mov r0, r1 + 8006348: f7ff fdba bl 8005ec0 + uECC_vli_sub(v, v, u, num_words); + 800634c: a918 add r1, sp, #96 ; 0x60 + 800634e: aa10 add r2, sp, #64 ; 0x40 + 8006350: 4608 mov r0, r1 + 8006352: f7ff fcf3 bl 8005d3c + 8006356: e7c4 b.n 80062e2 + +08006358 : + wordcount_t num_words) { + 8006358: b570 push {r4, r5, r6, lr} + 800635a: 4604 mov r4, r0 + 800635c: f99d 6010 ldrsb.w r6, [sp, #16] + 8006360: 461d mov r5, r3 + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + 8006362: f7ff fdad bl 8005ec0 + if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) { + 8006366: b930 cbnz r0, 8006376 + 8006368: 4632 mov r2, r6 + 800636a: 4621 mov r1, r4 + 800636c: 4628 mov r0, r5 + 800636e: f7ff fb58 bl 8005a22 + 8006372: 2801 cmp r0, #1 + 8006374: d006 beq.n 8006384 + uECC_vli_sub(result, result, mod, num_words); + 8006376: 462a mov r2, r5 + 8006378: 4621 mov r1, r4 + 800637a: 4620 mov r0, r4 +} + 800637c: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr} + uECC_vli_sub(result, result, mod, num_words); + 8006380: f7ff bcdc b.w 8005d3c +} + 8006384: bd70 pop {r4, r5, r6, pc} + +08006386 : +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + 8006386: b573 push {r0, r1, r4, r5, r6, lr} + 8006388: 4604 mov r4, r0 + 800638a: 4615 mov r5, r2 + 800638c: 460e mov r6, r1 + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 800638e: f7ff fc1a bl 8005bc6 + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ + 8006392: 462b mov r3, r5 + 8006394: 4632 mov r2, r6 + 8006396: 4621 mov r1, r4 + 8006398: 4620 mov r0, r4 + 800639a: f7ff fc04 bl 8005ba6 + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ + 800639e: 2308 movs r3, #8 + 80063a0: 9300 str r3, [sp, #0] + 80063a2: f105 0284 add.w r2, r5, #132 ; 0x84 + 80063a6: 1d2b adds r3, r5, #4 + 80063a8: 4621 mov r1, r4 + 80063aa: 4620 mov r0, r4 + 80063ac: f7ff ffd4 bl 8006358 +} + 80063b0: b002 add sp, #8 + 80063b2: bd70 pop {r4, r5, r6, pc} + +080063b4 : +uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result, + 80063b4: b538 push {r3, r4, r5, lr} + 80063b6: 4604 mov r4, r0 + 80063b8: 461d mov r5, r3 + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); + 80063ba: f7ff fcbf bl 8005d3c + if (l_borrow) { + 80063be: b130 cbz r0, 80063ce + uECC_vli_add(result, result, mod, num_words); + 80063c0: 462a mov r2, r5 + 80063c2: 4621 mov r1, r4 + 80063c4: 4620 mov r0, r4 +} + 80063c6: e8bd 4038 ldmia.w sp!, {r3, r4, r5, lr} + uECC_vli_add(result, result, mod, num_words); + 80063ca: f7ff bd79 b.w 8005ec0 +} + 80063ce: bd38 pop {r3, r4, r5, pc} + +080063d0 : + uECC_Curve curve) { + 80063d0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80063d4: b09a sub sp, #104 ; 0x68 + 80063d6: 4615 mov r5, r2 + 80063d8: 9f22 ldr r7, [sp, #136] ; 0x88 + wordcount_t num_words = curve->num_words; + 80063da: 463c mov r4, r7 + uECC_Curve curve) { + 80063dc: 4698 mov r8, r3 + wordcount_t num_words = curve->num_words; + 80063de: f914 ab04 ldrsb.w sl, [r4], #4 + uECC_Curve curve) { + 80063e2: 4606 mov r6, r0 + 80063e4: 4689 mov r9, r1 + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + 80063e6: 4623 mov r3, r4 + 80063e8: 4602 mov r2, r0 + 80063ea: 4629 mov r1, r5 + 80063ec: a802 add r0, sp, #8 + 80063ee: f7ff ffe1 bl 80063b4 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + 80063f2: a902 add r1, sp, #8 + 80063f4: 463a mov r2, r7 + 80063f6: 4608 mov r0, r1 + 80063f8: f7ff fbe5 bl 8005bc6 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + 80063fc: 463b mov r3, r7 + 80063fe: aa02 add r2, sp, #8 + 8006400: 4631 mov r1, r6 + 8006402: 4630 mov r0, r6 + 8006404: f7ff fbcf bl 8005ba6 + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + 8006408: 463b mov r3, r7 + 800640a: aa02 add r2, sp, #8 + 800640c: 4629 mov r1, r5 + 800640e: 4628 mov r0, r5 + 8006410: f7ff fbc9 bl 8005ba6 + uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */ + 8006414: 4623 mov r3, r4 + 8006416: 464a mov r2, r9 + 8006418: 4641 mov r1, r8 + 800641a: a802 add r0, sp, #8 + 800641c: f8cd a000 str.w sl, [sp] + 8006420: f7ff ff9a bl 8006358 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + 8006424: 4623 mov r3, r4 + 8006426: 464a mov r2, r9 + 8006428: 4641 mov r1, r8 + 800642a: 4640 mov r0, r8 + 800642c: f7ff ffc2 bl 80063b4 + uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */ + 8006430: 4623 mov r3, r4 + 8006432: 4632 mov r2, r6 + 8006434: 4629 mov r1, r5 + 8006436: a80a add r0, sp, #40 ; 0x28 + 8006438: f7ff ffbc bl 80063b4 + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + 800643c: 463b mov r3, r7 + 800643e: aa0a add r2, sp, #40 ; 0x28 + 8006440: 4649 mov r1, r9 + 8006442: 4648 mov r0, r9 + 8006444: f7ff fbaf bl 8005ba6 + uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */ + 8006448: 4623 mov r3, r4 + 800644a: 462a mov r2, r5 + 800644c: 4631 mov r1, r6 + 800644e: a80a add r0, sp, #40 ; 0x28 + 8006450: f8cd a000 str.w sl, [sp] + 8006454: f7ff ff80 bl 8006358 + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + 8006458: 463a mov r2, r7 + 800645a: 4641 mov r1, r8 + 800645c: 4628 mov r0, r5 + 800645e: f7ff fbb2 bl 8005bc6 + uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */ + 8006462: 4623 mov r3, r4 + 8006464: aa0a add r2, sp, #40 ; 0x28 + 8006466: 4629 mov r1, r5 + 8006468: 4628 mov r0, r5 + 800646a: f7ff ffa3 bl 80063b4 + uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */ + 800646e: 4623 mov r3, r4 + 8006470: 462a mov r2, r5 + 8006472: 4631 mov r1, r6 + 8006474: a812 add r0, sp, #72 ; 0x48 + 8006476: f7ff ff9d bl 80063b4 + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + 800647a: 463b mov r3, r7 + 800647c: aa12 add r2, sp, #72 ; 0x48 + 800647e: 4641 mov r1, r8 + 8006480: 4640 mov r0, r8 + 8006482: f7ff fb90 bl 8005ba6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ + 8006486: 4623 mov r3, r4 + 8006488: 464a mov r2, r9 + 800648a: 4641 mov r1, r8 + 800648c: 4640 mov r0, r8 + 800648e: f7ff ff91 bl 80063b4 + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + 8006492: 463a mov r2, r7 + 8006494: a902 add r1, sp, #8 + 8006496: a812 add r0, sp, #72 ; 0x48 + 8006498: f7ff fb95 bl 8005bc6 + uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */ + 800649c: a912 add r1, sp, #72 ; 0x48 + 800649e: 4623 mov r3, r4 + 80064a0: aa0a add r2, sp, #40 ; 0x28 + 80064a2: 4608 mov r0, r1 + 80064a4: f7ff ff86 bl 80063b4 + uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */ + 80064a8: 4623 mov r3, r4 + 80064aa: 4632 mov r2, r6 + 80064ac: a912 add r1, sp, #72 ; 0x48 + 80064ae: a80a add r0, sp, #40 ; 0x28 + 80064b0: f7ff ff80 bl 80063b4 + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + 80064b4: a90a add r1, sp, #40 ; 0x28 + 80064b6: 463b mov r3, r7 + 80064b8: aa02 add r2, sp, #8 + 80064ba: 4608 mov r0, r1 + 80064bc: f7ff fb73 bl 8005ba6 + uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */ + 80064c0: 4623 mov r3, r4 + 80064c2: 464a mov r2, r9 + 80064c4: a90a add r1, sp, #40 ; 0x28 + 80064c6: 4648 mov r0, r9 + 80064c8: f7ff ff74 bl 80063b4 + uECC_vli_set(X1, t7, num_words); + 80064cc: 4652 mov r2, sl + 80064ce: a912 add r1, sp, #72 ; 0x48 + 80064d0: 4630 mov r0, r6 + 80064d2: f7ff fa9a bl 8005a0a +} + 80064d6: b01a add sp, #104 ; 0x68 + 80064d8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + +080064dc : + uECC_Curve curve) { + 80064dc: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 80064e0: b088 sub sp, #32 + 80064e2: 4614 mov r4, r2 + 80064e4: f8dd 8040 ldr.w r8, [sp, #64] ; 0x40 + wordcount_t num_words = curve->num_words; + 80064e8: 4645 mov r5, r8 + uECC_Curve curve) { + 80064ea: 461e mov r6, r3 + wordcount_t num_words = curve->num_words; + 80064ec: f915 ab04 ldrsb.w sl, [r5], #4 + uECC_Curve curve) { + 80064f0: 4607 mov r7, r0 + 80064f2: 4689 mov r9, r1 + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + 80064f4: 462b mov r3, r5 + 80064f6: 4602 mov r2, r0 + 80064f8: 4621 mov r1, r4 + 80064fa: 4668 mov r0, sp + 80064fc: f7ff ff5a bl 80063b4 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + 8006500: 4642 mov r2, r8 + 8006502: 4669 mov r1, sp + 8006504: 4668 mov r0, sp + 8006506: f7ff fb5e bl 8005bc6 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + 800650a: 4643 mov r3, r8 + 800650c: 466a mov r2, sp + 800650e: 4639 mov r1, r7 + 8006510: 4638 mov r0, r7 + 8006512: f7ff fb48 bl 8005ba6 + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + 8006516: 4643 mov r3, r8 + 8006518: 466a mov r2, sp + 800651a: 4621 mov r1, r4 + 800651c: 4620 mov r0, r4 + 800651e: f7ff fb42 bl 8005ba6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + 8006522: 462b mov r3, r5 + 8006524: 464a mov r2, r9 + 8006526: 4631 mov r1, r6 + 8006528: 4630 mov r0, r6 + 800652a: f7ff ff43 bl 80063b4 + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + 800652e: 4642 mov r2, r8 + 8006530: 4631 mov r1, r6 + 8006532: 4668 mov r0, sp + 8006534: f7ff fb47 bl 8005bc6 + uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */ + 8006538: 462b mov r3, r5 + 800653a: 463a mov r2, r7 + 800653c: 4669 mov r1, sp + 800653e: 4668 mov r0, sp + 8006540: f7ff ff38 bl 80063b4 + uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */ + 8006544: 462b mov r3, r5 + 8006546: 4622 mov r2, r4 + 8006548: 4669 mov r1, sp + 800654a: 4668 mov r0, sp + 800654c: f7ff ff32 bl 80063b4 + uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */ + 8006550: 462b mov r3, r5 + 8006552: 463a mov r2, r7 + 8006554: 4621 mov r1, r4 + 8006556: 4620 mov r0, r4 + 8006558: f7ff ff2c bl 80063b4 + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + 800655c: 4643 mov r3, r8 + 800655e: 4622 mov r2, r4 + 8006560: 4649 mov r1, r9 + 8006562: 4648 mov r0, r9 + 8006564: f7ff fb1f bl 8005ba6 + uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */ + 8006568: 462b mov r3, r5 + 800656a: 466a mov r2, sp + 800656c: 4639 mov r1, r7 + 800656e: 4620 mov r0, r4 + 8006570: f7ff ff20 bl 80063b4 + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + 8006574: 4643 mov r3, r8 + 8006576: 4622 mov r2, r4 + 8006578: 4631 mov r1, r6 + 800657a: 4630 mov r0, r6 + 800657c: f7ff fb13 bl 8005ba6 + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */ + 8006580: 462b mov r3, r5 + 8006582: 464a mov r2, r9 + 8006584: 4631 mov r1, r6 + 8006586: 4630 mov r0, r6 + 8006588: f7ff ff14 bl 80063b4 + uECC_vli_set(X2, t5, num_words); + 800658c: 4652 mov r2, sl + 800658e: 4669 mov r1, sp + 8006590: 4620 mov r0, r4 + 8006592: f7ff fa3a bl 8005a0a +} + 8006596: b008 add sp, #32 + 8006598: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + +0800659c : + uECC_Curve curve) { + 800659c: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 80065a0: b0b1 sub sp, #196 ; 0xc4 + 80065a2: e9cd 0102 strd r0, r1, [sp, #8] + 80065a6: 9c3b ldr r4, [sp, #236] ; 0xec + 80065a8: 9204 str r2, [sp, #16] + wordcount_t num_words = curve->num_words; + 80065aa: f994 9000 ldrsb.w r9, [r4] + uECC_vli_set(Rx[1], point, num_words); + 80065ae: a818 add r0, sp, #96 ; 0x60 + 80065b0: 464a mov r2, r9 + uECC_Curve curve) { + 80065b2: 461d mov r5, r3 + uECC_vli_set(Rx[1], point, num_words); + 80065b4: f7ff fa29 bl 8005a0a + uECC_vli_set(Ry[1], point + num_words, num_words); + 80065b8: ea4f 0389 mov.w r3, r9, lsl #2 + 80065bc: 9305 str r3, [sp, #20] + 80065be: 9b03 ldr r3, [sp, #12] + 80065c0: eb03 0a89 add.w sl, r3, r9, lsl #2 + 80065c4: 4651 mov r1, sl + 80065c6: a828 add r0, sp, #160 ; 0xa0 + 80065c8: f7ff fa1f bl 8005a0a + wordcount_t num_words = curve->num_words; + 80065cc: f994 2000 ldrsb.w r2, [r4] + if (initial_Z) { + 80065d0: 2d00 cmp r5, #0 + 80065d2: f000 8082 beq.w 80066da + uECC_vli_set(z, initial_Z, num_words); + 80065d6: 4629 mov r1, r5 + 80065d8: a808 add r0, sp, #32 + 80065da: f7ff fa16 bl 8005a0a + uECC_vli_set(X2, X1, num_words); + 80065de: af10 add r7, sp, #64 ; 0x40 + 80065e0: a918 add r1, sp, #96 ; 0x60 + 80065e2: 4638 mov r0, r7 + uECC_vli_set(Y2, Y1, num_words); + 80065e4: f10d 0880 add.w r8, sp, #128 ; 0x80 + uECC_vli_set(X2, X1, num_words); + 80065e8: f7ff fa0f bl 8005a0a + uECC_vli_set(Y2, Y1, num_words); + 80065ec: a928 add r1, sp, #160 ; 0xa0 + 80065ee: 4640 mov r0, r8 + 80065f0: f7ff fa0b bl 8005a0a + apply_z(X1, Y1, z, curve); + 80065f4: 4623 mov r3, r4 + 80065f6: aa08 add r2, sp, #32 + 80065f8: a818 add r0, sp, #96 ; 0x60 + 80065fa: f7ff fae8 bl 8005bce + curve->double_jacobian(X1, Y1, z, curve); + 80065fe: f8d4 50a4 ldr.w r5, [r4, #164] ; 0xa4 + 8006602: 4623 mov r3, r4 + 8006604: aa08 add r2, sp, #32 + 8006606: a928 add r1, sp, #160 ; 0xa0 + 8006608: a818 add r0, sp, #96 ; 0x60 + 800660a: 47a8 blx r5 + apply_z(X2, Y2, z, curve); + 800660c: 4623 mov r3, r4 + 800660e: aa08 add r2, sp, #32 + 8006610: 4641 mov r1, r8 + 8006612: 4638 mov r0, r7 + 8006614: f7ff fadb bl 8005bce + for (i = num_bits - 2; i > 0; --i) { + 8006618: f9bd 50e8 ldrsh.w r5, [sp, #232] ; 0xe8 + 800661c: 3d02 subs r5, #2 + 800661e: b22d sxth r5, r5 + 8006620: 2d00 cmp r5, #0 + 8006622: dc63 bgt.n 80066ec + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 8006624: 9b04 ldr r3, [sp, #16] + 8006626: 681d ldr r5, [r3, #0] + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 8006628: 9400 str r4, [sp, #0] + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 800662a: f005 0601 and.w r6, r5, #1 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 800662e: ab10 add r3, sp, #64 ; 0x40 + 8006630: eb03 1746 add.w r7, r3, r6, lsl #5 + 8006634: 43ed mvns r5, r5 + 8006636: ab20 add r3, sp, #128 ; 0x80 + 8006638: eb03 1646 add.w r6, r3, r6, lsl #5 + 800663c: f005 0501 and.w r5, r5, #1 + 8006640: ab10 add r3, sp, #64 ; 0x40 + 8006642: eb03 1845 add.w r8, r3, r5, lsl #5 + 8006646: ab20 add r3, sp, #128 ; 0x80 + 8006648: eb03 1545 add.w r5, r3, r5, lsl #5 + 800664c: 462b mov r3, r5 + 800664e: 4642 mov r2, r8 + 8006650: 4631 mov r1, r6 + 8006652: 4638 mov r0, r7 + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + 8006654: f104 0b04 add.w fp, r4, #4 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 8006658: f7ff feba bl 80063d0 + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + 800665c: 465b mov r3, fp + 800665e: aa10 add r2, sp, #64 ; 0x40 + 8006660: a918 add r1, sp, #96 ; 0x60 + 8006662: a808 add r0, sp, #32 + 8006664: f7ff fea6 bl 80063b4 + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + 8006668: a908 add r1, sp, #32 + 800666a: 4623 mov r3, r4 + 800666c: 4632 mov r2, r6 + 800666e: 4608 mov r0, r1 + 8006670: f7ff fa99 bl 8005ba6 + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + 8006674: a908 add r1, sp, #32 + 8006676: 9a03 ldr r2, [sp, #12] + 8006678: 4623 mov r3, r4 + 800667a: 4608 mov r0, r1 + 800667c: f7ff fa93 bl 8005ba6 + uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */ + 8006680: a908 add r1, sp, #32 + 8006682: 464b mov r3, r9 + 8006684: 465a mov r2, fp + 8006686: 4608 mov r0, r1 + 8006688: f7ff fde6 bl 8006258 + uECC_vli_modMult_fast(z, z, point + num_words, curve); + 800668c: a908 add r1, sp, #32 + 800668e: 4623 mov r3, r4 + 8006690: 4652 mov r2, sl + 8006692: 4608 mov r0, r1 + 8006694: f7ff fa87 bl 8005ba6 + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + 8006698: a908 add r1, sp, #32 + 800669a: 4623 mov r3, r4 + 800669c: 463a mov r2, r7 + 800669e: 4608 mov r0, r1 + 80066a0: f7ff fa81 bl 8005ba6 + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + 80066a4: 4633 mov r3, r6 + 80066a6: 463a mov r2, r7 + 80066a8: 4629 mov r1, r5 + 80066aa: 4640 mov r0, r8 + 80066ac: 9400 str r4, [sp, #0] + 80066ae: f7ff ff15 bl 80064dc + apply_z(Rx[0], Ry[0], z, curve); + 80066b2: 4623 mov r3, r4 + 80066b4: aa08 add r2, sp, #32 + 80066b6: a920 add r1, sp, #128 ; 0x80 + 80066b8: a810 add r0, sp, #64 ; 0x40 + 80066ba: f7ff fa88 bl 8005bce + uECC_vli_set(result, Rx[0], num_words); + 80066be: 9802 ldr r0, [sp, #8] + 80066c0: 464a mov r2, r9 + 80066c2: a910 add r1, sp, #64 ; 0x40 + 80066c4: f7ff f9a1 bl 8005a0a + uECC_vli_set(result + num_words, Ry[0], num_words); + 80066c8: 9802 ldr r0, [sp, #8] + 80066ca: 9b05 ldr r3, [sp, #20] + 80066cc: a920 add r1, sp, #128 ; 0x80 + 80066ce: 4418 add r0, r3 + 80066d0: f7ff f99b bl 8005a0a +} + 80066d4: b031 add sp, #196 ; 0xc4 + 80066d6: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + uECC_vli_clear(z, num_words); + 80066da: 4611 mov r1, r2 + 80066dc: a808 add r0, sp, #32 + 80066de: 9206 str r2, [sp, #24] + 80066e0: f7ff f954 bl 800598c + z[0] = 1; + 80066e4: 2301 movs r3, #1 + 80066e6: 9a06 ldr r2, [sp, #24] + 80066e8: 9308 str r3, [sp, #32] + 80066ea: e778 b.n 80065de + nb = !uECC_vli_testBit(scalar, i); + 80066ec: 4629 mov r1, r5 + 80066ee: 9804 ldr r0, [sp, #16] + 80066f0: f7ff f961 bl 80059b6 + 80066f4: fab0 f680 clz r6, r0 + 80066f8: 0976 lsrs r6, r6, #5 + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + 80066fa: f1c6 0101 rsb r1, r6, #1 + 80066fe: eb07 1b46 add.w fp, r7, r6, lsl #5 + 8006702: eb08 1646 add.w r6, r8, r6, lsl #5 + 8006706: eb07 1041 add.w r0, r7, r1, lsl #5 + 800670a: 4633 mov r3, r6 + 800670c: eb08 1141 add.w r1, r8, r1, lsl #5 + 8006710: 465a mov r2, fp + 8006712: 9400 str r4, [sp, #0] + 8006714: e9cd 0106 strd r0, r1, [sp, #24] + 8006718: f7ff fe5a bl 80063d0 + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + 800671c: 9907 ldr r1, [sp, #28] + 800671e: 9806 ldr r0, [sp, #24] + 8006720: 9400 str r4, [sp, #0] + 8006722: 460b mov r3, r1 + 8006724: 4602 mov r2, r0 + 8006726: 4631 mov r1, r6 + 8006728: 4658 mov r0, fp + 800672a: f7ff fed7 bl 80064dc + for (i = num_bits - 2; i > 0; --i) { + 800672e: 3d01 subs r5, #1 + 8006730: e775 b.n 800661e + +08006732 : + uECC_Curve curve) { + 8006732: b530 push {r4, r5, lr} + 8006734: 4614 mov r4, r2 + 8006736: b095 sub sp, #84 ; 0x54 + 8006738: 4605 mov r5, r0 + uECC_word_t *p2[2] = {tmp1, tmp2}; + 800673a: aa0c add r2, sp, #48 ; 0x30 + carry = regularize_k(private, tmp1, tmp2, curve); + 800673c: 4623 mov r3, r4 + uECC_Curve curve) { + 800673e: 4608 mov r0, r1 + uECC_word_t *p2[2] = {tmp1, tmp2}; + 8006740: a904 add r1, sp, #16 + 8006742: 9102 str r1, [sp, #8] + 8006744: 9203 str r2, [sp, #12] + carry = regularize_k(private, tmp1, tmp2, curve); + 8006746: f7ff fbe0 bl 8005f0a + EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve); + 800674a: fab0 f380 clz r3, r0 + 800674e: 095b lsrs r3, r3, #5 + 8006750: aa14 add r2, sp, #80 ; 0x50 + 8006752: eb02 0283 add.w r2, r2, r3, lsl #2 + 8006756: 8863 ldrh r3, [r4, #2] + 8006758: 9401 str r4, [sp, #4] + 800675a: 3301 adds r3, #1 + 800675c: b21b sxth r3, r3 + 800675e: 9300 str r3, [sp, #0] + 8006760: f852 2c48 ldr.w r2, [r2, #-72] + 8006764: 2300 movs r3, #0 + 8006766: f104 0144 add.w r1, r4, #68 ; 0x44 + 800676a: 4628 mov r0, r5 + 800676c: f7ff ff16 bl 800659c + if (EccPoint_isZero(result, curve)) { + 8006770: 7821 ldrb r1, [r4, #0] + 8006772: 0049 lsls r1, r1, #1 + 8006774: b249 sxtb r1, r1 + 8006776: 4628 mov r0, r5 + 8006778: f7ff f90e bl 8005998 +} + 800677c: fab0 f080 clz r0, r0 + 8006780: 0940 lsrs r0, r0, #5 + 8006782: b015 add sp, #84 ; 0x54 + 8006784: bd30 pop {r4, r5, pc} + ... + +08006788 : + uECC_Curve curve) { + 8006788: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800678c: ed2d 8b02 vpush {d8} + 8006790: b0a7 sub sp, #156 ; 0x9c + 8006792: 461e mov r6, r3 + 8006794: 9d33 ldr r5, [sp, #204] ; 0xcc + wordcount_t num_words = curve->num_words; + 8006796: f995 a000 ldrsb.w sl, [r5] + uECC_Curve curve) { + 800679a: ee08 1a10 vmov s16, r1 + 800679e: 4683 mov fp, r0 + uECC_word_t *k2[2] = {tmp, s}; + 80067a0: f10d 0918 add.w r9, sp, #24 + 80067a4: ab0e add r3, sp, #56 ; 0x38 + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80067a6: 4651 mov r1, sl + 80067a8: 4630 mov r0, r6 + uECC_Curve curve) { + 80067aa: ee08 2a90 vmov s17, r2 + uECC_word_t *k2[2] = {tmp, s}; + 80067ae: f8cd 9010 str.w r9, [sp, #16] + 80067b2: 9305 str r3, [sp, #20] + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80067b4: f7ff f8f0 bl 8005998 + 80067b8: b128 cbz r0, 80067c6 + return 0; + 80067ba: 2000 movs r0, #0 +} + 80067bc: b027 add sp, #156 ; 0x9c + 80067be: ecbd 8b02 vpop {d8} + 80067c2: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 80067c6: f9b5 8002 ldrsh.w r8, [r5, #2] + 80067ca: f118 041f adds.w r4, r8, #31 + 80067ce: bf48 it mi + 80067d0: f108 043e addmi.w r4, r8, #62 ; 0x3e + 80067d4: f344 1447 sbfx r4, r4, #5, #8 + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + 80067d8: f105 0724 add.w r7, r5, #36 ; 0x24 + 80067dc: 4622 mov r2, r4 + 80067de: 4631 mov r1, r6 + 80067e0: 4638 mov r0, r7 + 80067e2: f7ff fb19 bl 8005e18 + 80067e6: 2801 cmp r0, #1 + 80067e8: 9003 str r0, [sp, #12] + 80067ea: d1e6 bne.n 80067ba + carry = regularize_k(k, tmp, s, curve); + 80067ec: 462b mov r3, r5 + 80067ee: aa0e add r2, sp, #56 ; 0x38 + 80067f0: 4649 mov r1, r9 + 80067f2: 4630 mov r0, r6 + 80067f4: f7ff fb89 bl 8005f0a + EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve); + 80067f8: fab0 f080 clz r0, r0 + 80067fc: ab26 add r3, sp, #152 ; 0x98 + 80067fe: 0940 lsrs r0, r0, #5 + 8006800: f108 0801 add.w r8, r8, #1 + 8006804: eb03 0080 add.w r0, r3, r0, lsl #2 + 8006808: fa0f f388 sxth.w r3, r8 + 800680c: 9300 str r3, [sp, #0] + 800680e: 9501 str r5, [sp, #4] + 8006810: f850 2c88 ldr.w r2, [r0, #-136] + 8006814: f105 0144 add.w r1, r5, #68 ; 0x44 + 8006818: a816 add r0, sp, #88 ; 0x58 + 800681a: 2300 movs r3, #0 + 800681c: f7ff febe bl 800659c + if (uECC_vli_isZero(p, num_words)) { + 8006820: 4651 mov r1, sl + 8006822: a816 add r0, sp, #88 ; 0x58 + 8006824: f7ff f8b8 bl 8005998 + 8006828: 2800 cmp r0, #0 + 800682a: d1c6 bne.n 80067ba + uECC_recid = (p[curve->num_words] & 0x01); + 800682c: f995 3000 ldrsb.w r3, [r5] + 8006830: aa26 add r2, sp, #152 ; 0x98 + 8006832: eb02 0383 add.w r3, r2, r3, lsl #2 + 8006836: 4a3b ldr r2, [pc, #236] ; (8006924 ) + 8006838: f853 3c40 ldr.w r3, [r3, #-64] + 800683c: f003 0301 and.w r3, r3, #1 + 8006840: 7013 strb r3, [r2, #0] + if (!g_rng_function) { + 8006842: 4b39 ldr r3, [pc, #228] ; (8006928 ) + 8006844: 681b ldr r3, [r3, #0] + 8006846: 2b00 cmp r3, #0 + 8006848: d163 bne.n 8006912 + uECC_vli_clear(tmp, num_n_words); + 800684a: 4621 mov r1, r4 + 800684c: 4648 mov r0, r9 + 800684e: f7ff f89d bl 800598c + tmp[0] = 1; + 8006852: 9b03 ldr r3, [sp, #12] + 8006854: 9306 str r3, [sp, #24] + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */ + 8006856: 463b mov r3, r7 + 8006858: aa06 add r2, sp, #24 + 800685a: 4631 mov r1, r6 + 800685c: 4630 mov r0, r6 + 800685e: 9400 str r4, [sp, #0] + 8006860: f7ff f901 bl 8005a66 + uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */ + 8006864: 4623 mov r3, r4 + 8006866: 463a mov r2, r7 + 8006868: 4631 mov r1, r6 + 800686a: 4630 mov r0, r6 + 800686c: f7ff fcf4 bl 8006258 + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */ + 8006870: 463b mov r3, r7 + 8006872: aa06 add r2, sp, #24 + 8006874: 4631 mov r1, r6 + 8006876: 4630 mov r0, r6 + 8006878: 9400 str r4, [sp, #0] + 800687a: f7ff f8f4 bl 8005a66 + uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */ + 800687e: f995 1001 ldrsb.w r1, [r5, #1] + 8006882: 9832 ldr r0, [sp, #200] ; 0xc8 + 8006884: aa16 add r2, sp, #88 ; 0x58 + 8006886: f7ff f9c1 bl 8005c0c + uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */ + 800688a: f9b5 3002 ldrsh.w r3, [r5, #2] + 800688e: 1dda adds r2, r3, #7 + 8006890: bf48 it mi + 8006892: f103 020e addmi.w r2, r3, #14 + 8006896: 10d2 asrs r2, r2, #3 + 8006898: 4659 mov r1, fp + 800689a: a806 add r0, sp, #24 + 800689c: f7ff f9ca bl 8005c34 + s[num_n_words - 1] = 0; + 80068a0: aa26 add r2, sp, #152 ; 0x98 + 80068a2: 1e63 subs r3, r4, #1 + 80068a4: eb02 0383 add.w r3, r2, r3, lsl #2 + 80068a8: 2200 movs r2, #0 + uECC_vli_set(s, p, num_words); + 80068aa: a80e add r0, sp, #56 ; 0x38 + s[num_n_words - 1] = 0; + 80068ac: f843 2c60 str.w r2, [r3, #-96] + uECC_vli_set(s, p, num_words); + 80068b0: a916 add r1, sp, #88 ; 0x58 + 80068b2: 4652 mov r2, sl + 80068b4: f7ff f8a9 bl 8005a0a + uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */ + 80068b8: 4602 mov r2, r0 + 80068ba: 463b mov r3, r7 + 80068bc: a906 add r1, sp, #24 + 80068be: 9400 str r4, [sp, #0] + 80068c0: f7ff f8d1 bl 8005a66 + bits2int(tmp, message_hash, hash_size, curve); + 80068c4: ee18 2a90 vmov r2, s17 + 80068c8: ee18 1a10 vmov r1, s16 + 80068cc: 462b mov r3, r5 + 80068ce: a806 add r0, sp, #24 + 80068d0: f7ff fa5b bl 8005d8a + uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */ + 80068d4: aa0e add r2, sp, #56 ; 0x38 + 80068d6: 4610 mov r0, r2 + 80068d8: 463b mov r3, r7 + 80068da: a906 add r1, sp, #24 + 80068dc: 9400 str r4, [sp, #0] + 80068de: f7ff fd3b bl 8006358 + uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */ + 80068e2: a90e add r1, sp, #56 ; 0x38 + 80068e4: 4608 mov r0, r1 + 80068e6: 463b mov r3, r7 + 80068e8: 4632 mov r2, r6 + 80068ea: 9400 str r4, [sp, #0] + 80068ec: f7ff f8bb bl 8005a66 + if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) { + 80068f0: 4621 mov r1, r4 + 80068f2: a80e add r0, sp, #56 ; 0x38 + 80068f4: f7ff f869 bl 80059ca + 80068f8: f995 1001 ldrsb.w r1, [r5, #1] + 80068fc: ebb0 0fc1 cmp.w r0, r1, lsl #3 + 8006900: f73f af5b bgt.w 80067ba + uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s); + 8006904: 9b32 ldr r3, [sp, #200] ; 0xc8 + 8006906: aa0e add r2, sp, #56 ; 0x38 + 8006908: 1858 adds r0, r3, r1 + 800690a: f7ff f97f bl 8005c0c + return 1; + 800690e: 2001 movs r0, #1 + 8006910: e754 b.n 80067bc + } else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) { + 8006912: 4622 mov r2, r4 + 8006914: 4639 mov r1, r7 + 8006916: 4648 mov r0, r9 + 8006918: f7ff fa96 bl 8005e48 + 800691c: 2800 cmp r0, #0 + 800691e: d19a bne.n 8006856 + 8006920: e74b b.n 80067ba + 8006922: bf00 nop + 8006924: 2009e2a8 .word 0x2009e2a8 + 8006928: 2009e2a4 .word 0x2009e2a4 + +0800692c : + uECC_Curve curve) { + 800692c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8006930: 4605 mov r5, r0 + 8006932: b093 sub sp, #76 ; 0x4c + 8006934: 460c mov r4, r1 + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + 8006936: 4610 mov r0, r2 + 8006938: 2108 movs r1, #8 + uECC_Curve curve) { + 800693a: 4617 mov r7, r2 + 800693c: 461e mov r6, r3 + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + 800693e: f7ff f82b bl 8005998 + 8006942: 2800 cmp r0, #0 + 8006944: d161 bne.n 8006a0a + uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ + 8006946: 4632 mov r2, r6 + 8006948: 4621 mov r1, r4 + 800694a: a80a add r0, sp, #40 ; 0x28 + 800694c: f7ff f93b bl 8005bc6 + uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ + 8006950: 4633 mov r3, r6 + 8006952: aa0a add r2, sp, #40 ; 0x28 + 8006954: 4629 mov r1, r5 + 8006956: a802 add r0, sp, #8 + 8006958: f7ff f925 bl 8005ba6 + uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ + 800695c: 4632 mov r2, r6 + 800695e: 4629 mov r1, r5 + 8006960: 4628 mov r0, r5 + 8006962: f7ff f930 bl 8005bc6 + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ + 8006966: a90a add r1, sp, #40 ; 0x28 + 8006968: 4608 mov r0, r1 + 800696a: 4632 mov r2, r6 + 800696c: f7ff f92b bl 8005bc6 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 8006970: f04f 0808 mov.w r8, #8 + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + 8006974: 463a mov r2, r7 + 8006976: 4638 mov r0, r7 + 8006978: 4633 mov r3, r6 + 800697a: 4621 mov r1, r4 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 800697c: 1d37 adds r7, r6, #4 + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + 800697e: f7ff f912 bl 8005ba6 + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + 8006982: 463b mov r3, r7 + 8006984: 462a mov r2, r5 + 8006986: 4629 mov r1, r5 + 8006988: 4620 mov r0, r4 + 800698a: f8cd 8000 str.w r8, [sp] + 800698e: f7ff fce3 bl 8006358 + uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ + 8006992: 463b mov r3, r7 + 8006994: f8cd 8000 str.w r8, [sp] + 8006998: 462a mov r2, r5 + 800699a: 4621 mov r1, r4 + 800699c: 4620 mov r0, r4 + 800699e: f7ff fcdb bl 8006358 + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); + 80069a2: 6823 ldr r3, [r4, #0] + if (uECC_vli_testBit(Y1, 0)) { + 80069a4: 07db lsls r3, r3, #31 + 80069a6: d533 bpl.n 8006a10 + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + 80069a8: 463a mov r2, r7 + 80069aa: 4621 mov r1, r4 + 80069ac: 4620 mov r0, r4 + 80069ae: f7ff fa87 bl 8005ec0 + uECC_vli_rshift1(Y1, num_words_secp256k1); + 80069b2: 4641 mov r1, r8 + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + 80069b4: 4681 mov r9, r0 + uECC_vli_rshift1(Y1, num_words_secp256k1); + 80069b6: 4620 mov r0, r4 + 80069b8: f7ff f848 bl 8005a4c + Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); + 80069bc: 69e3 ldr r3, [r4, #28] + 80069be: ea43 73c9 orr.w r3, r3, r9, lsl #31 + 80069c2: 61e3 str r3, [r4, #28] + uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ + 80069c4: 4632 mov r2, r6 + 80069c6: 4621 mov r1, r4 + 80069c8: 4628 mov r0, r5 + 80069ca: f7ff f8fc bl 8005bc6 + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ + 80069ce: 463b mov r3, r7 + 80069d0: aa02 add r2, sp, #8 + 80069d2: 4629 mov r1, r5 + 80069d4: 4628 mov r0, r5 + 80069d6: f7ff fced bl 80063b4 + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ + 80069da: 463b mov r3, r7 + 80069dc: aa02 add r2, sp, #8 + 80069de: 4629 mov r1, r5 + 80069e0: 4628 mov r0, r5 + 80069e2: f7ff fce7 bl 80063b4 + uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ + 80069e6: a902 add r1, sp, #8 + 80069e8: 4608 mov r0, r1 + 80069ea: 463b mov r3, r7 + 80069ec: 462a mov r2, r5 + 80069ee: f7ff fce1 bl 80063b4 + uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ + 80069f2: 4633 mov r3, r6 + 80069f4: aa02 add r2, sp, #8 + 80069f6: 4621 mov r1, r4 + 80069f8: 4620 mov r0, r4 + 80069fa: f7ff f8d4 bl 8005ba6 + uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ + 80069fe: 463b mov r3, r7 + 8006a00: aa0a add r2, sp, #40 ; 0x28 + 8006a02: 4621 mov r1, r4 + 8006a04: 4620 mov r0, r4 + 8006a06: f7ff fcd5 bl 80063b4 +} + 8006a0a: b013 add sp, #76 ; 0x4c + 8006a0c: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + uECC_vli_rshift1(Y1, num_words_secp256k1); + 8006a10: 4641 mov r1, r8 + 8006a12: 4620 mov r0, r4 + 8006a14: f7ff f81a bl 8005a4c + 8006a18: e7d4 b.n 80069c4 + +08006a1a : +static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + 8006a1a: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8006a1e: b08a sub sp, #40 ; 0x28 + 8006a20: 4604 mov r4, r0 + 8006a22: 4615 mov r5, r2 + 8006a24: 460e mov r6, r1 + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 8006a26: 221c movs r2, #28 + 8006a28: 2100 movs r1, #0 + 8006a2a: a803 add r0, sp, #12 + 8006a2c: f006 ff7a bl 800d924 + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + 8006a30: 1d2f adds r7, r5, #4 + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 8006a32: 2303 movs r3, #3 + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 8006a34: 462a mov r2, r5 + 8006a36: 4631 mov r1, r6 + 8006a38: 4620 mov r0, r4 + wordcount_t num_words = curve->num_words; + 8006a3a: f995 8000 ldrsb.w r8, [r5] + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + 8006a3e: 9302 str r3, [sp, #8] + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + 8006a40: f7ff f8c1 bl 8005bc6 + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + 8006a44: 463b mov r3, r7 + 8006a46: aa02 add r2, sp, #8 + 8006a48: 4621 mov r1, r4 + 8006a4a: 4620 mov r0, r4 + 8006a4c: f7ff fcb2 bl 80063b4 + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + 8006a50: 462b mov r3, r5 + 8006a52: 4632 mov r2, r6 + 8006a54: 4621 mov r1, r4 + 8006a56: 4620 mov r0, r4 + 8006a58: f7ff f8a5 bl 8005ba6 + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */ + 8006a5c: f8cd 8000 str.w r8, [sp] + 8006a60: 463b mov r3, r7 + 8006a62: f105 0284 add.w r2, r5, #132 ; 0x84 + 8006a66: 4621 mov r1, r4 + 8006a68: 4620 mov r0, r4 + 8006a6a: f7ff fc75 bl 8006358 +} + 8006a6e: b00a add sp, #40 ; 0x28 + 8006a70: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +08006a74 : + uECC_Curve curve) { + 8006a74: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + wordcount_t num_words = curve->num_words; + 8006a78: f993 8000 ldrsb.w r8, [r3] + uECC_Curve curve) { + 8006a7c: b092 sub sp, #72 ; 0x48 + 8006a7e: 4604 mov r4, r0 + 8006a80: 4689 mov r9, r1 + if (uECC_vli_isZero(Z1, num_words)) { + 8006a82: 4610 mov r0, r2 + 8006a84: 4641 mov r1, r8 + uECC_Curve curve) { + 8006a86: 4615 mov r5, r2 + 8006a88: 461e mov r6, r3 + if (uECC_vli_isZero(Z1, num_words)) { + 8006a8a: f7fe ff85 bl 8005998 + 8006a8e: 2800 cmp r0, #0 + 8006a90: f040 808e bne.w 8006bb0 + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + 8006a94: 4632 mov r2, r6 + 8006a96: 4649 mov r1, r9 + 8006a98: a802 add r0, sp, #8 + 8006a9a: f7ff f894 bl 8005bc6 + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + 8006a9e: 4633 mov r3, r6 + 8006aa0: aa02 add r2, sp, #8 + 8006aa2: 4621 mov r1, r4 + 8006aa4: a80a add r0, sp, #40 ; 0x28 + 8006aa6: f7ff f87e bl 8005ba6 + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + 8006aaa: a902 add r1, sp, #8 + 8006aac: 4608 mov r0, r1 + 8006aae: 4632 mov r2, r6 + 8006ab0: f7ff f889 bl 8005bc6 + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + 8006ab4: 4633 mov r3, r6 + 8006ab6: 462a mov r2, r5 + 8006ab8: 4649 mov r1, r9 + 8006aba: 4648 mov r0, r9 + 8006abc: f7ff f873 bl 8005ba6 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + 8006ac0: 1d37 adds r7, r6, #4 + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + 8006ac2: 4632 mov r2, r6 + 8006ac4: 4629 mov r1, r5 + 8006ac6: 4628 mov r0, r5 + 8006ac8: f7ff f87d bl 8005bc6 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + 8006acc: 463b mov r3, r7 + 8006ace: 462a mov r2, r5 + 8006ad0: 4621 mov r1, r4 + 8006ad2: 4620 mov r0, r4 + 8006ad4: f8cd 8000 str.w r8, [sp] + 8006ad8: f7ff fc3e bl 8006358 + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ + 8006adc: 463b mov r3, r7 + 8006ade: 462a mov r2, r5 + 8006ae0: 4629 mov r1, r5 + 8006ae2: 4628 mov r0, r5 + 8006ae4: f8cd 8000 str.w r8, [sp] + 8006ae8: f7ff fc36 bl 8006358 + uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ + 8006aec: 463b mov r3, r7 + 8006aee: 462a mov r2, r5 + 8006af0: 4621 mov r1, r4 + 8006af2: 4628 mov r0, r5 + 8006af4: f7ff fc5e bl 80063b4 + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + 8006af8: 4633 mov r3, r6 + 8006afa: 462a mov r2, r5 + 8006afc: 4621 mov r1, r4 + 8006afe: 4620 mov r0, r4 + 8006b00: f7ff f851 bl 8005ba6 + uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ + 8006b04: 463b mov r3, r7 + 8006b06: 4622 mov r2, r4 + 8006b08: 4621 mov r1, r4 + 8006b0a: 4628 mov r0, r5 + 8006b0c: f8cd 8000 str.w r8, [sp] + 8006b10: f7ff fc22 bl 8006358 + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ + 8006b14: 463b mov r3, r7 + 8006b16: f8cd 8000 str.w r8, [sp] + 8006b1a: 462a mov r2, r5 + 8006b1c: 4621 mov r1, r4 + 8006b1e: 4620 mov r0, r4 + 8006b20: f7ff fc1a bl 8006358 + 8006b24: 6823 ldr r3, [r4, #0] + if (uECC_vli_testBit(X1, 0)) { + 8006b26: 07db lsls r3, r3, #31 + 8006b28: d545 bpl.n 8006bb6 + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + 8006b2a: 463a mov r2, r7 + 8006b2c: 4621 mov r1, r4 + 8006b2e: 4620 mov r0, r4 + 8006b30: f7ff f9c6 bl 8005ec0 + uECC_vli_rshift1(X1, num_words); + 8006b34: 4641 mov r1, r8 + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + 8006b36: 4682 mov sl, r0 + uECC_vli_rshift1(X1, num_words); + 8006b38: 4620 mov r0, r4 + 8006b3a: f7fe ff87 bl 8005a4c + X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + 8006b3e: f108 4380 add.w r3, r8, #1073741824 ; 0x40000000 + 8006b42: 3b01 subs r3, #1 + 8006b44: f854 2023 ldr.w r2, [r4, r3, lsl #2] + 8006b48: ea42 72ca orr.w r2, r2, sl, lsl #31 + 8006b4c: f844 2023 str.w r2, [r4, r3, lsl #2] + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + 8006b50: 4632 mov r2, r6 + 8006b52: 4621 mov r1, r4 + 8006b54: 4628 mov r0, r5 + 8006b56: f7ff f836 bl 8005bc6 + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ + 8006b5a: 463b mov r3, r7 + 8006b5c: aa0a add r2, sp, #40 ; 0x28 + 8006b5e: 4629 mov r1, r5 + 8006b60: 4628 mov r0, r5 + 8006b62: f7ff fc27 bl 80063b4 + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ + 8006b66: 463b mov r3, r7 + 8006b68: aa0a add r2, sp, #40 ; 0x28 + 8006b6a: 4629 mov r1, r5 + 8006b6c: 4628 mov r0, r5 + 8006b6e: f7ff fc21 bl 80063b4 + uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ + 8006b72: a90a add r1, sp, #40 ; 0x28 + 8006b74: 4608 mov r0, r1 + 8006b76: 463b mov r3, r7 + 8006b78: 462a mov r2, r5 + 8006b7a: f7ff fc1b bl 80063b4 + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + 8006b7e: 4633 mov r3, r6 + 8006b80: aa0a add r2, sp, #40 ; 0x28 + 8006b82: 4621 mov r1, r4 + 8006b84: 4620 mov r0, r4 + 8006b86: f7ff f80e bl 8005ba6 + uECC_vli_modSub(t4, X1, t4, curve->p, num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ + 8006b8a: aa02 add r2, sp, #8 + 8006b8c: 463b mov r3, r7 + 8006b8e: 4610 mov r0, r2 + 8006b90: 4621 mov r1, r4 + 8006b92: f7ff fc0f bl 80063b4 + uECC_vli_set(X1, Z1, num_words); + 8006b96: 4642 mov r2, r8 + 8006b98: 4629 mov r1, r5 + 8006b9a: 4620 mov r0, r4 + 8006b9c: f7fe ff35 bl 8005a0a + uECC_vli_set(Z1, Y1, num_words); + 8006ba0: 4649 mov r1, r9 + 8006ba2: 4628 mov r0, r5 + 8006ba4: f7fe ff31 bl 8005a0a + uECC_vli_set(Y1, t4, num_words); + 8006ba8: a902 add r1, sp, #8 + 8006baa: 4648 mov r0, r9 + 8006bac: f7fe ff2d bl 8005a0a +} + 8006bb0: b012 add sp, #72 ; 0x48 + 8006bb2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + uECC_vli_rshift1(X1, num_words); + 8006bb6: 4641 mov r1, r8 + 8006bb8: 4620 mov r0, r4 + 8006bba: f7fe ff47 bl 8005a4c + 8006bbe: e7c7 b.n 8006b50 + +08006bc0 : + g_rng_function = rng_function; + 8006bc0: 4b01 ldr r3, [pc, #4] ; (8006bc8 ) + 8006bc2: 6018 str r0, [r3, #0] +} + 8006bc4: 4770 bx lr + 8006bc6: bf00 nop + 8006bc8: 2009e2a4 .word 0x2009e2a4 + +08006bcc : +uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } + 8006bcc: 4800 ldr r0, [pc, #0] ; (8006bd0 ) + 8006bce: 4770 bx lr + 8006bd0: 080109a4 .word 0x080109a4 + +08006bd4 : +uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } + 8006bd4: 4800 ldr r0, [pc, #0] ; (8006bd8 ) + 8006bd6: 4770 bx lr + 8006bd8: 080108f0 .word 0x080108f0 + +08006bdc : + uECC_Curve curve) { + 8006bdc: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8006be0: 4605 mov r5, r0 + 8006be2: b098 sub sp, #96 ; 0x60 + 8006be4: 460f mov r7, r1 + 8006be6: 4614 mov r4, r2 + 8006be8: 2640 movs r6, #64 ; 0x40 + if (!uECC_generate_random_int(private, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + 8006bea: f102 0824 add.w r8, r2, #36 ; 0x24 + 8006bee: f9b4 3002 ldrsh.w r3, [r4, #2] + 8006bf2: f113 021f adds.w r2, r3, #31 + 8006bf6: bf48 it mi + 8006bf8: f103 023e addmi.w r2, r3, #62 ; 0x3e + 8006bfc: f342 1247 sbfx r2, r2, #5, #8 + 8006c00: 4641 mov r1, r8 + 8006c02: 4668 mov r0, sp + 8006c04: f7ff f920 bl 8005e48 + 8006c08: b330 cbz r0, 8006c58 + if (EccPoint_compute_public_key(public, private, curve)) { + 8006c0a: 4622 mov r2, r4 + 8006c0c: 4669 mov r1, sp + 8006c0e: a808 add r0, sp, #32 + 8006c10: f7ff fd8f bl 8006732 + 8006c14: b1f0 cbz r0, 8006c54 + uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), private); + 8006c16: f9b4 3002 ldrsh.w r3, [r4, #2] + 8006c1a: 1dd9 adds r1, r3, #7 + 8006c1c: bf48 it mi + 8006c1e: f103 010e addmi.w r1, r3, #14 + 8006c22: 466a mov r2, sp + 8006c24: 10c9 asrs r1, r1, #3 + 8006c26: 4638 mov r0, r7 + 8006c28: f7fe fff0 bl 8005c0c + uECC_vli_nativeToBytes(public_key, curve->num_bytes, public); + 8006c2c: f994 1001 ldrsb.w r1, [r4, #1] + 8006c30: aa08 add r2, sp, #32 + 8006c32: 4628 mov r0, r5 + 8006c34: f7fe ffea bl 8005c0c + public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words); + 8006c38: f994 1001 ldrsb.w r1, [r4, #1] + 8006c3c: f994 2000 ldrsb.w r2, [r4] + uECC_vli_nativeToBytes( + 8006c40: ab08 add r3, sp, #32 + 8006c42: 1868 adds r0, r5, r1 + 8006c44: eb03 0282 add.w r2, r3, r2, lsl #2 + 8006c48: f7fe ffe0 bl 8005c0c + return 1; + 8006c4c: 2001 movs r0, #1 +} + 8006c4e: b018 add sp, #96 ; 0x60 + 8006c50: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8006c54: 3e01 subs r6, #1 + 8006c56: d1ca bne.n 8006bee + return 0; + 8006c58: 2000 movs r0, #0 + 8006c5a: e7f8 b.n 8006c4e + +08006c5c : + uECC_Curve curve) { + 8006c5c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8006c60: 461c mov r4, r3 + wordcount_t num_bytes = curve->num_bytes; + 8006c62: f993 6001 ldrsb.w r6, [r3, #1] + wordcount_t num_words = curve->num_words; + 8006c66: f993 9000 ldrsb.w r9, [r3] + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006c6a: f9b3 3002 ldrsh.w r3, [r3, #2] + uECC_Curve curve) { + 8006c6e: b0a6 sub sp, #152 ; 0x98 + 8006c70: 4617 mov r7, r2 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006c72: 1dda adds r2, r3, #7 + 8006c74: bf48 it mi + 8006c76: f103 020e addmi.w r2, r3, #14 + uECC_word_t *p2[2] = {private, tmp}; + 8006c7a: f10d 0818 add.w r8, sp, #24 + uECC_Curve curve) { + 8006c7e: 4605 mov r5, r0 + uECC_word_t *p2[2] = {private, tmp}; + 8006c80: f10d 0a38 add.w sl, sp, #56 ; 0x38 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006c84: 10d2 asrs r2, r2, #3 + 8006c86: 4640 mov r0, r8 + uECC_word_t *p2[2] = {private, tmp}; + 8006c88: f8cd 8010 str.w r8, [sp, #16] + 8006c8c: f8cd a014 str.w sl, [sp, #20] + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006c90: f7fe ffd0 bl 8005c34 + uECC_vli_bytesToNative(public, public_key, num_bytes); + 8006c94: 4629 mov r1, r5 + 8006c96: 4632 mov r2, r6 + 8006c98: a816 add r0, sp, #88 ; 0x58 + 8006c9a: f7fe ffcb bl 8005c34 + uECC_vli_bytesToNative(public + num_words, public_key + num_bytes, num_bytes); + 8006c9e: ab16 add r3, sp, #88 ; 0x58 + 8006ca0: 19a9 adds r1, r5, r6 + 8006ca2: eb03 0089 add.w r0, r3, r9, lsl #2 + 8006ca6: 4632 mov r2, r6 + 8006ca8: f7fe ffc4 bl 8005c34 + carry = regularize_k(private, private, tmp, curve); + 8006cac: 4623 mov r3, r4 + 8006cae: 4652 mov r2, sl + 8006cb0: 4641 mov r1, r8 + 8006cb2: 4640 mov r0, r8 + 8006cb4: f7ff f929 bl 8005f0a + if (g_rng_function) { + 8006cb8: 4b19 ldr r3, [pc, #100] ; (8006d20 ) + 8006cba: 681b ldr r3, [r3, #0] + carry = regularize_k(private, private, tmp, curve); + 8006cbc: 4605 mov r5, r0 + if (g_rng_function) { + 8006cbe: b163 cbz r3, 8006cda + if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) { + 8006cc0: ab26 add r3, sp, #152 ; 0x98 + 8006cc2: eb03 0380 add.w r3, r3, r0, lsl #2 + 8006cc6: 464a mov r2, r9 + 8006cc8: f853 3c88 ldr.w r3, [r3, #-136] + 8006ccc: 9303 str r3, [sp, #12] + 8006cce: 4618 mov r0, r3 + 8006cd0: 1d21 adds r1, r4, #4 + 8006cd2: f7ff f8b9 bl 8005e48 + 8006cd6: 9b03 ldr r3, [sp, #12] + 8006cd8: b1f0 cbz r0, 8006d18 + EccPoint_mult(public, public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve); + 8006cda: fab5 f185 clz r1, r5 + 8006cde: aa26 add r2, sp, #152 ; 0x98 + 8006ce0: 0949 lsrs r1, r1, #5 + 8006ce2: eb02 0181 add.w r1, r2, r1, lsl #2 + 8006ce6: 8862 ldrh r2, [r4, #2] + 8006ce8: 9401 str r4, [sp, #4] + 8006cea: 3201 adds r2, #1 + 8006cec: b212 sxth r2, r2 + 8006cee: 9200 str r2, [sp, #0] + 8006cf0: f851 2c88 ldr.w r2, [r1, #-136] + 8006cf4: a916 add r1, sp, #88 ; 0x58 + 8006cf6: 4608 mov r0, r1 + 8006cf8: f7ff fc50 bl 800659c + uECC_vli_nativeToBytes(secret, num_bytes, public); + 8006cfc: aa16 add r2, sp, #88 ; 0x58 + 8006cfe: 4631 mov r1, r6 + 8006d00: 4638 mov r0, r7 + 8006d02: f7fe ff83 bl 8005c0c + return !EccPoint_isZero(public, curve); + 8006d06: 7821 ldrb r1, [r4, #0] + 8006d08: 0049 lsls r1, r1, #1 + 8006d0a: b249 sxtb r1, r1 + 8006d0c: 4610 mov r0, r2 + 8006d0e: f7fe fe43 bl 8005998 + 8006d12: fab0 f080 clz r0, r0 + 8006d16: 0940 lsrs r0, r0, #5 +} + 8006d18: b026 add sp, #152 ; 0x98 + 8006d1a: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 8006d1e: bf00 nop + 8006d20: 2009e2a4 .word 0x2009e2a4 + +08006d24 : +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve) { + 8006d24: b530 push {r4, r5, lr} + for (i = 0; i < curve->num_bytes; ++i) { + 8006d26: 2400 movs r4, #0 + 8006d28: f992 5001 ldrsb.w r5, [r2, #1] + 8006d2c: b263 sxtb r3, r4 + 8006d2e: 429d cmp r5, r3 + 8006d30: dc08 bgt.n 8006d44 + compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01); + 8006d32: eb00 0045 add.w r0, r0, r5, lsl #1 + 8006d36: f810 3c01 ldrb.w r3, [r0, #-1] + 8006d3a: f003 0301 and.w r3, r3, #1 + 8006d3e: 3302 adds r3, #2 + 8006d40: 700b strb r3, [r1, #0] +} + 8006d42: bd30 pop {r4, r5, pc} + compressed[i+1] = public_key[i]; + 8006d44: 5cc5 ldrb r5, [r0, r3] + 8006d46: 440b add r3, r1 + 8006d48: 3401 adds r4, #1 + 8006d4a: 705d strb r5, [r3, #1] + for (i = 0; i < curve->num_bytes; ++i) { + 8006d4c: e7ec b.n 8006d28 + +08006d4e : +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006d4e: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + uECC_word_t *y = point + curve->num_words; + 8006d52: f992 8000 ldrsb.w r8, [r2] +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006d56: b090 sub sp, #64 ; 0x40 + 8006d58: 4614 mov r4, r2 + 8006d5a: 4607 mov r7, r0 + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); + 8006d5c: f992 2001 ldrsb.w r2, [r2, #1] + uECC_word_t *y = point + curve->num_words; + 8006d60: eb0d 0588 add.w r5, sp, r8, lsl #2 +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { + 8006d64: 460e mov r6, r1 + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); + 8006d66: 1c41 adds r1, r0, #1 + 8006d68: 4668 mov r0, sp + 8006d6a: f7fe ff63 bl 8005c34 + curve->x_side(y, point, curve); + 8006d6e: 4622 mov r2, r4 + 8006d70: f8d4 30ac ldr.w r3, [r4, #172] ; 0xac + 8006d74: 4669 mov r1, sp + 8006d76: 4628 mov r0, r5 + 8006d78: 4798 blx r3 + curve->mod_sqrt(y, curve); + 8006d7a: f8d4 30a8 ldr.w r3, [r4, #168] ; 0xa8 + 8006d7e: 4621 mov r1, r4 + 8006d80: 4628 mov r0, r5 + 8006d82: 4798 blx r3 + if ((y[0] & 0x01) != (compressed[0] & 0x01)) { + 8006d84: 783b ldrb r3, [r7, #0] + 8006d86: f85d 2028 ldr.w r2, [sp, r8, lsl #2] + 8006d8a: 4053 eors r3, r2 + 8006d8c: 07db lsls r3, r3, #31 + 8006d8e: d504 bpl.n 8006d9a + uECC_vli_sub(y, curve->p, y, curve->num_words); + 8006d90: 462a mov r2, r5 + 8006d92: 1d21 adds r1, r4, #4 + 8006d94: 4628 mov r0, r5 + 8006d96: f7fe ffd1 bl 8005d3c + uECC_vli_nativeToBytes(public_key, curve->num_bytes, point); + 8006d9a: f994 1001 ldrsb.w r1, [r4, #1] + 8006d9e: 466a mov r2, sp + 8006da0: 4630 mov r0, r6 + 8006da2: f7fe ff33 bl 8005c0c + uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y); + 8006da6: f994 1001 ldrsb.w r1, [r4, #1] + 8006daa: 462a mov r2, r5 + 8006dac: 1870 adds r0, r6, r1 + 8006dae: f7fe ff2d bl 8005c0c +} + 8006db2: b010 add sp, #64 ; 0x40 + 8006db4: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +08006db8 : +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006db8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + if (EccPoint_isZero(point, curve)) { + 8006dbc: 780d ldrb r5, [r1, #0] + wordcount_t num_words = curve->num_words; + 8006dbe: f991 2000 ldrsb.w r2, [r1] +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006dc2: b092 sub sp, #72 ; 0x48 + 8006dc4: 460e mov r6, r1 + if (EccPoint_isZero(point, curve)) { + 8006dc6: 0069 lsls r1, r5, #1 + 8006dc8: b249 sxtb r1, r1 +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + 8006dca: 4607 mov r7, r0 + wordcount_t num_words = curve->num_words; + 8006dcc: 9201 str r2, [sp, #4] + if (EccPoint_isZero(point, curve)) { + 8006dce: f7fe fde3 bl 8005998 + 8006dd2: 4604 mov r4, r0 + 8006dd4: bb80 cbnz r0, 8006e38 + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + 8006dd6: f106 0804 add.w r8, r6, #4 + 8006dda: 9a01 ldr r2, [sp, #4] + 8006ddc: 4639 mov r1, r7 + 8006dde: 4640 mov r0, r8 + 8006de0: f7fe fe1f bl 8005a22 + 8006de4: 2801 cmp r0, #1 + 8006de6: d11a bne.n 8006e1e + uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) { + 8006de8: 9a01 ldr r2, [sp, #4] + 8006dea: 4640 mov r0, r8 + 8006dec: eb07 0182 add.w r1, r7, r2, lsl #2 + 8006df0: f7fe fe17 bl 8005a22 + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + 8006df4: 2801 cmp r0, #1 + 8006df6: d112 bne.n 8006e1e + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + 8006df8: 4632 mov r2, r6 + 8006dfa: a802 add r0, sp, #8 + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + 8006dfc: f10d 0828 add.w r8, sp, #40 ; 0x28 + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + 8006e00: f7fe fee1 bl 8005bc6 + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + 8006e04: f8d6 30ac ldr.w r3, [r6, #172] ; 0xac + 8006e08: 4632 mov r2, r6 + 8006e0a: 4639 mov r1, r7 + 8006e0c: 4640 mov r0, r8 + 8006e0e: 4798 blx r3 + for (i = num_words - 1; i >= 0; --i) { + 8006e10: 1e6b subs r3, r5, #1 + 8006e12: b25b sxtb r3, r3 + 8006e14: 061a lsls r2, r3, #24 + 8006e16: d506 bpl.n 8006e26 + return (diff == 0); + 8006e18: fab4 f484 clz r4, r4 + 8006e1c: 0964 lsrs r4, r4, #5 +} + 8006e1e: 4620 mov r0, r4 + 8006e20: b012 add sp, #72 ; 0x48 + 8006e22: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + diff |= (left[i] ^ right[i]); + 8006e26: aa02 add r2, sp, #8 + 8006e28: f858 1023 ldr.w r1, [r8, r3, lsl #2] + 8006e2c: f852 2023 ldr.w r2, [r2, r3, lsl #2] + 8006e30: 404a eors r2, r1 + 8006e32: 4314 orrs r4, r2 + for (i = num_words - 1; i >= 0; --i) { + 8006e34: 3b01 subs r3, #1 + 8006e36: e7ed b.n 8006e14 + return 0; + 8006e38: 2400 movs r4, #0 + 8006e3a: e7f0 b.n 8006e1e + +08006e3c : +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { + 8006e3c: b530 push {r4, r5, lr} + 8006e3e: 460c mov r4, r1 + 8006e40: b091 sub sp, #68 ; 0x44 + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8006e42: f991 2001 ldrsb.w r2, [r1, #1] +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { + 8006e46: 4605 mov r5, r0 + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8006e48: 4601 mov r1, r0 + 8006e4a: 4668 mov r0, sp + 8006e4c: f7fe fef2 bl 8005c34 + public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes); + 8006e50: f994 2001 ldrsb.w r2, [r4, #1] + 8006e54: f994 0000 ldrsb.w r0, [r4] + uECC_vli_bytesToNative( + 8006e58: 18a9 adds r1, r5, r2 + 8006e5a: eb0d 0080 add.w r0, sp, r0, lsl #2 + 8006e5e: f7fe fee9 bl 8005c34 + return uECC_valid_point(public, curve); + 8006e62: 4621 mov r1, r4 + 8006e64: 4668 mov r0, sp + 8006e66: f7ff ffa7 bl 8006db8 +} + 8006e6a: b011 add sp, #68 ; 0x44 + 8006e6c: bd30 pop {r4, r5, pc} + +08006e6e : +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006e6e: b570 push {r4, r5, r6, lr} + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006e70: f9b2 3002 ldrsh.w r3, [r2, #2] +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006e74: 4614 mov r4, r2 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006e76: 1dda adds r2, r3, #7 + 8006e78: bf48 it mi + 8006e7a: f103 020e addmi.w r2, r3, #14 +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006e7e: b098 sub sp, #96 ; 0x60 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006e80: 10d2 asrs r2, r2, #3 +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { + 8006e82: 460e mov r6, r1 + uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + 8006e84: 4601 mov r1, r0 + 8006e86: 4668 mov r0, sp + 8006e88: f7fe fed4 bl 8005c34 + if (uECC_vli_isZero(private, BITS_TO_WORDS(curve->num_n_bits))) { + 8006e8c: f9b4 3002 ldrsh.w r3, [r4, #2] + 8006e90: f113 021f adds.w r2, r3, #31 + 8006e94: bf48 it mi + 8006e96: f103 023e addmi.w r2, r3, #62 ; 0x3e + 8006e9a: f342 1147 sbfx r1, r2, #5, #8 + 8006e9e: 4668 mov r0, sp + 8006ea0: f7fe fd7a bl 8005998 + 8006ea4: b110 cbz r0, 8006eac + return 0; + 8006ea6: 2000 movs r0, #0 +} + 8006ea8: b018 add sp, #96 ; 0x60 + 8006eaa: bd70 pop {r4, r5, r6, pc} + if (uECC_vli_cmp(curve->n, private, BITS_TO_WORDS(curve->num_n_bits)) != 1) { + 8006eac: 460a mov r2, r1 + 8006eae: f104 0024 add.w r0, r4, #36 ; 0x24 + 8006eb2: 4669 mov r1, sp + 8006eb4: f7fe ffb0 bl 8005e18 + 8006eb8: 2801 cmp r0, #1 + 8006eba: 4605 mov r5, r0 + 8006ebc: d1f3 bne.n 8006ea6 + if (!EccPoint_compute_public_key(public, private, curve)) { + 8006ebe: 4622 mov r2, r4 + 8006ec0: 4669 mov r1, sp + 8006ec2: a808 add r0, sp, #32 + 8006ec4: f7ff fc35 bl 8006732 + 8006ec8: 2800 cmp r0, #0 + 8006eca: d0ec beq.n 8006ea6 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, public); + 8006ecc: f994 1001 ldrsb.w r1, [r4, #1] + 8006ed0: aa08 add r2, sp, #32 + 8006ed2: 4630 mov r0, r6 + 8006ed4: f7fe fe9a bl 8005c0c + public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words); + 8006ed8: f994 1001 ldrsb.w r1, [r4, #1] + 8006edc: f994 2000 ldrsb.w r2, [r4] + uECC_vli_nativeToBytes( + 8006ee0: ab08 add r3, sp, #32 + 8006ee2: 1870 adds r0, r6, r1 + 8006ee4: eb03 0282 add.w r2, r3, r2, lsl #2 + 8006ee8: f7fe fe90 bl 8005c0c + return 1; + 8006eec: 4628 mov r0, r5 + 8006eee: e7db b.n 8006ea8 + +08006ef0 : + uECC_Curve curve) { + 8006ef0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8006ef4: b08a sub sp, #40 ; 0x28 + 8006ef6: 4605 mov r5, r0 + 8006ef8: f8dd 9048 ldr.w r9, [sp, #72] ; 0x48 + 8006efc: 460e mov r6, r1 + 8006efe: 4617 mov r7, r2 + 8006f00: 4698 mov r8, r3 + 8006f02: 2440 movs r4, #64 ; 0x40 + if (!uECC_generate_random_int(k, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + 8006f04: f109 0a24 add.w sl, r9, #36 ; 0x24 + 8006f08: f9b9 3002 ldrsh.w r3, [r9, #2] + 8006f0c: f113 021f adds.w r2, r3, #31 + 8006f10: bf48 it mi + 8006f12: f103 023e addmi.w r2, r3, #62 ; 0x3e + 8006f16: f342 1247 sbfx r2, r2, #5, #8 + 8006f1a: 4651 mov r1, sl + 8006f1c: a802 add r0, sp, #8 + 8006f1e: f7fe ff93 bl 8005e48 + 8006f22: b150 cbz r0, 8006f3a + if (uECC_sign_with_k(private_key, message_hash, hash_size, k, signature, curve)) { + 8006f24: e9cd 8900 strd r8, r9, [sp] + 8006f28: ab02 add r3, sp, #8 + 8006f2a: 463a mov r2, r7 + 8006f2c: 4631 mov r1, r6 + 8006f2e: 4628 mov r0, r5 + 8006f30: f7ff fc2a bl 8006788 + 8006f34: b928 cbnz r0, 8006f42 + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 8006f36: 3c01 subs r4, #1 + 8006f38: d1e6 bne.n 8006f08 + return 0; + 8006f3a: 2000 movs r0, #0 +} + 8006f3c: b00a add sp, #40 ; 0x28 + 8006f3e: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + return 1; + 8006f42: 2001 movs r0, #1 + 8006f44: e7fa b.n 8006f3c + +08006f46 : +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve) { + 8006f46: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 8006f4a: b091 sub sp, #68 ; 0x44 + 8006f4c: 4693 mov fp, r2 + uint8_t *K = hash_context->tmp; + uint8_t *V = K + hash_context->result_size; + wordcount_t num_bytes = curve->num_bytes; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006f4e: 9a1b ldr r2, [sp, #108] ; 0x6c + 8006f50: f9b2 8002 ldrsh.w r8, [r2, #2] + uint8_t *V = K + hash_context->result_size; + 8006f54: e9d3 6504 ldrd r6, r5, [r3, #16] + uECC_Curve curve) { + 8006f58: 461c mov r4, r3 + wordcount_t num_bytes = curve->num_bytes; + 8006f5a: 9b1b ldr r3, [sp, #108] ; 0x6c + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006f5c: f118 071f adds.w r7, r8, #31 + 8006f60: bf48 it mi + 8006f62: f108 073e addmi.w r7, r8, #62 ; 0x3e + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t tries; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) { + 8006f66: 2200 movs r2, #0 + wordcount_t num_bytes = curve->num_bytes; + 8006f68: f993 3001 ldrsb.w r3, [r3, #1] + uECC_Curve curve) { + 8006f6c: 4681 mov r9, r0 + 8006f6e: 468a mov sl, r1 + uint8_t *V = K + hash_context->result_size; + 8006f70: 442e add r6, r5 + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 8006f72: f347 1747 sbfx r7, r7, #5, #8 + V[i] = 0x01; + 8006f76: 2001 movs r0, #1 + K[i] = 0; + 8006f78: 4694 mov ip, r2 + for (i = 0; i < hash_context->result_size; ++i) { + 8006f7a: 6921 ldr r1, [r4, #16] + 8006f7c: 4291 cmp r1, r2 + 8006f7e: f200 8086 bhi.w 800708e + } + + /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + 8006f82: 4629 mov r1, r5 + 8006f84: 4620 mov r0, r4 + 8006f86: 9303 str r3, [sp, #12] + 8006f88: f7fe fe74 bl 8005c74 + V[hash_context->result_size] = 0x00; + 8006f8c: 6922 ldr r2, [r4, #16] + 8006f8e: 2100 movs r1, #0 + 8006f90: 54b1 strb r1, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 8006f92: 6922 ldr r2, [r4, #16] + 8006f94: 4631 mov r1, r6 + 8006f96: 3201 adds r2, #1 + 8006f98: 4620 mov r0, r4 + 8006f9a: f7fe fe8c bl 8005cb6 + HMAC_update(hash_context, private_key, num_bytes); + 8006f9e: 9b03 ldr r3, [sp, #12] + 8006fa0: 4649 mov r1, r9 + 8006fa2: 461a mov r2, r3 + 8006fa4: 4620 mov r0, r4 + 8006fa6: f7fe fe86 bl 8005cb6 + HMAC_update(hash_context, message_hash, hash_size); + 8006faa: 465a mov r2, fp + 8006fac: 4651 mov r1, sl + 8006fae: 4620 mov r0, r4 + 8006fb0: f7fe fe81 bl 8005cb6 + HMAC_finish(hash_context, K, K); + 8006fb4: 462a mov r2, r5 + 8006fb6: 4629 mov r1, r5 + 8006fb8: 4620 mov r0, r4 + 8006fba: f7fe fe7e bl 8005cba + + update_V(hash_context, K, V); + 8006fbe: 4632 mov r2, r6 + 8006fc0: 4629 mov r1, r5 + 8006fc2: 4620 mov r0, r4 + 8006fc4: f7fe fea8 bl 8005d18 + + /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + 8006fc8: 4629 mov r1, r5 + 8006fca: 4620 mov r0, r4 + 8006fcc: f7fe fe52 bl 8005c74 + V[hash_context->result_size] = 0x01; + 8006fd0: 6922 ldr r2, [r4, #16] + 8006fd2: 2101 movs r1, #1 + 8006fd4: 54b1 strb r1, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 8006fd6: 6922 ldr r2, [r4, #16] + 8006fd8: 4620 mov r0, r4 + 8006fda: 440a add r2, r1 + 8006fdc: 4631 mov r1, r6 + 8006fde: f7fe fe6a bl 8005cb6 + HMAC_update(hash_context, private_key, num_bytes); + 8006fe2: 9b03 ldr r3, [sp, #12] + 8006fe4: 4649 mov r1, r9 + 8006fe6: 461a mov r2, r3 + 8006fe8: 4620 mov r0, r4 + 8006fea: f7fe fe64 bl 8005cb6 + HMAC_update(hash_context, message_hash, hash_size); + 8006fee: 465a mov r2, fp + 8006ff0: 4651 mov r1, sl + 8006ff2: 4620 mov r0, r4 + 8006ff4: f7fe fe5f bl 8005cb6 + HMAC_finish(hash_context, K, K); + 8006ff8: 462a mov r2, r5 + 8006ffa: 4629 mov r1, r5 + 8006ffc: 4620 mov r0, r4 + 8006ffe: f7fe fe5c bl 8005cba + + update_V(hash_context, K, V); + 8007002: 4632 mov r2, r6 + 8007004: 4629 mov r1, r5 + 8007006: 4620 mov r0, r4 + 8007008: f7fe fe86 bl 8005d18 + wordcount_t T_bytes = 0; + for (;;) { + update_V(hash_context, K, V); + for (i = 0; i < hash_context->result_size; ++i) { + T_ptr[T_bytes++] = V[i]; + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + 800700c: 00bb lsls r3, r7, #2 + 800700e: 9304 str r3, [sp, #16] + goto filled; + } + } + } + filled: + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + 8007010: 017b lsls r3, r7, #5 + 8007012: 9305 str r3, [sp, #20] + uECC_word_t mask = (uECC_word_t)-1; + T[num_n_words - 1] &= + mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits)); + 8007014: ebc8 1347 rsb r3, r8, r7, lsl #5 + 8007018: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800701c: b21b sxth r3, r3 + 800701e: fa22 f303 lsr.w r3, r2, r3 + 8007022: 9306 str r3, [sp, #24] + 8007024: 2340 movs r3, #64 ; 0x40 + 8007026: 9303 str r3, [sp, #12] + T[num_n_words - 1] &= + 8007028: 4417 add r7, r2 + 800702a: 446b add r3, sp + 800702c: eb03 0787 add.w r7, r3, r7, lsl #2 + wordcount_t T_bytes = 0; + 8007030: 2300 movs r3, #0 + update_V(hash_context, K, V); + 8007032: 4632 mov r2, r6 + 8007034: 4629 mov r1, r5 + 8007036: 4620 mov r0, r4 + 8007038: 9307 str r3, [sp, #28] + 800703a: f7fe fe6d bl 8005d18 + for (i = 0; i < hash_context->result_size; ++i) { + 800703e: 6920 ldr r0, [r4, #16] + 8007040: 9b07 ldr r3, [sp, #28] + 8007042: 4631 mov r1, r6 + 8007044: 4430 add r0, r6 + 8007046: 461a mov r2, r3 + T_ptr[T_bytes++] = V[i]; + 8007048: ab08 add r3, sp, #32 + 800704a: eb03 0c02 add.w ip, r3, r2 + for (i = 0; i < hash_context->result_size; ++i) { + 800704e: 4288 cmp r0, r1 + 8007050: 4613 mov r3, r2 + 8007052: f102 0201 add.w r2, r2, #1 + 8007056: b252 sxtb r2, r2 + 8007058: d0eb beq.n 8007032 + T_ptr[T_bytes++] = V[i]; + 800705a: f811 3b01 ldrb.w r3, [r1], #1 + 800705e: f88c 3000 strb.w r3, [ip] + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + 8007062: 9b04 ldr r3, [sp, #16] + 8007064: 4293 cmp r3, r2 + 8007066: dcef bgt.n 8007048 + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + 8007068: 9b05 ldr r3, [sp, #20] + 800706a: 4598 cmp r8, r3 + 800706c: db14 blt.n 8007098 + } + + if (uECC_sign_with_k(private_key, message_hash, hash_size, T, signature, curve)) { + 800706e: 9b1b ldr r3, [sp, #108] ; 0x6c + 8007070: 9301 str r3, [sp, #4] + 8007072: 9b1a ldr r3, [sp, #104] ; 0x68 + 8007074: 9300 str r3, [sp, #0] + 8007076: 465a mov r2, fp + 8007078: ab08 add r3, sp, #32 + 800707a: 4651 mov r1, sl + 800707c: 4648 mov r0, r9 + 800707e: f7ff fb83 bl 8006788 + 8007082: b180 cbz r0, 80070a6 + return 1; + 8007084: 2301 movs r3, #1 + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + } + return 0; +} + 8007086: 4618 mov r0, r3 + 8007088: b011 add sp, #68 ; 0x44 + 800708a: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + V[i] = 0x01; + 800708e: 54b0 strb r0, [r6, r2] + K[i] = 0; + 8007090: f805 c002 strb.w ip, [r5, r2] + for (i = 0; i < hash_context->result_size; ++i) { + 8007094: 3201 adds r2, #1 + 8007096: e770 b.n 8006f7a + T[num_n_words - 1] &= + 8007098: f857 3c20 ldr.w r3, [r7, #-32] + 800709c: 9a06 ldr r2, [sp, #24] + 800709e: 4013 ands r3, r2 + 80070a0: f847 3c20 str.w r3, [r7, #-32] + 80070a4: e7e3 b.n 800706e + 80070a6: 9007 str r0, [sp, #28] + HMAC_init(hash_context, K); + 80070a8: 4629 mov r1, r5 + 80070aa: 4620 mov r0, r4 + 80070ac: f7fe fde2 bl 8005c74 + V[hash_context->result_size] = 0x00; + 80070b0: 6922 ldr r2, [r4, #16] + 80070b2: 9b07 ldr r3, [sp, #28] + 80070b4: 54b3 strb r3, [r6, r2] + HMAC_update(hash_context, V, hash_context->result_size + 1); + 80070b6: 6922 ldr r2, [r4, #16] + 80070b8: 4631 mov r1, r6 + 80070ba: 3201 adds r2, #1 + 80070bc: 4620 mov r0, r4 + 80070be: f7fe fdfa bl 8005cb6 + HMAC_finish(hash_context, K, K); + 80070c2: 462a mov r2, r5 + 80070c4: 4629 mov r1, r5 + 80070c6: 4620 mov r0, r4 + 80070c8: f7fe fdf7 bl 8005cba + update_V(hash_context, K, V); + 80070cc: 4632 mov r2, r6 + 80070ce: 4629 mov r1, r5 + 80070d0: 4620 mov r0, r4 + 80070d2: f7fe fe21 bl 8005d18 + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + 80070d6: 9b03 ldr r3, [sp, #12] + 80070d8: 3b01 subs r3, #1 + 80070da: 9303 str r3, [sp, #12] + 80070dc: 9b07 ldr r3, [sp, #28] + 80070de: d1a7 bne.n 8007030 + 80070e0: e7d1 b.n 8007086 + +080070e2 : + +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve) { + 80070e2: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 80070e6: ed2d 8b02 vpush {d8} + 80070ea: b0fb sub sp, #492 ; 0x1ec + 80070ec: 461c mov r4, r3 + 80070ee: 9d86 ldr r5, [sp, #536] ; 0x218 + const uECC_word_t *point; + bitcount_t num_bits; + bitcount_t i; + uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 80070f0: f9b5 3002 ldrsh.w r3, [r5, #2] + wordcount_t num_words = curve->num_words; + 80070f4: f995 8000 ldrsb.w r8, [r5] + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + 80070f8: f113 061f adds.w r6, r3, #31 + 80070fc: bf48 it mi + 80070fe: f103 063e addmi.w r6, r3, #62 ; 0x3e + 8007102: f346 1647 sbfx r6, r6, #5, #8 + + rx[num_n_words - 1] = 0; + 8007106: f106 3aff add.w sl, r6, #4294967295 ; 0xffffffff + uECC_Curve curve) { + 800710a: 4691 mov r9, r2 + rx[num_n_words - 1] = 0; + 800710c: aa22 add r2, sp, #136 ; 0x88 + 800710e: 2300 movs r3, #0 + 8007110: f842 302a str.w r3, [r2, sl, lsl #2] + r[num_n_words - 1] = 0; + 8007114: aa7a add r2, sp, #488 ; 0x1e8 + 8007116: eb02 028a add.w r2, r2, sl, lsl #2 + uECC_Curve curve) { + 800711a: 4607 mov r7, r0 + r[num_n_words - 1] = 0; + 800711c: f842 3cc0 str.w r3, [r2, #-192] + s[num_n_words - 1] = 0; + 8007120: f842 3ca0 str.w r3, [r2, #-160] + uECC_Curve curve) { + 8007124: ee08 1a90 vmov s17, r1 + + uECC_vli_bytesToNative(public, public_key, curve->num_bytes); + 8007128: f995 2001 ldrsb.w r2, [r5, #1] + 800712c: 4601 mov r1, r0 + 800712e: a85a add r0, sp, #360 ; 0x168 + 8007130: f7fe fd80 bl 8005c34 + uECC_vli_bytesToNative( + public + num_words, public_key + curve->num_bytes, curve->num_bytes); + 8007134: ea4f 0388 mov.w r3, r8, lsl #2 + 8007138: f995 2001 ldrsb.w r2, [r5, #1] + 800713c: 9304 str r3, [sp, #16] + uECC_vli_bytesToNative( + 800713e: ab5a add r3, sp, #360 ; 0x168 + 8007140: eb03 0388 add.w r3, r3, r8, lsl #2 + 8007144: 4618 mov r0, r3 + 8007146: 18b9 adds r1, r7, r2 + 8007148: ee08 3a10 vmov s16, r3 + 800714c: f7fe fd72 bl 8005c34 + uECC_vli_bytesToNative(r, signature, curve->num_bytes); + 8007150: 4621 mov r1, r4 + 8007152: f995 2001 ldrsb.w r2, [r5, #1] + 8007156: a84a add r0, sp, #296 ; 0x128 + 8007158: f7fe fd6c bl 8005c34 + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes); + 800715c: f995 2001 ldrsb.w r2, [r5, #1] + 8007160: a852 add r0, sp, #328 ; 0x148 + 8007162: 18a1 adds r1, r4, r2 + 8007164: f7fe fd66 bl 8005c34 + + /* r, s must not be 0. */ + if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) { + 8007168: 4641 mov r1, r8 + 800716a: a84a add r0, sp, #296 ; 0x128 + 800716c: f7fe fc14 bl 8005998 + 8007170: 2300 movs r3, #0 + 8007172: 4604 mov r4, r0 + 8007174: 2800 cmp r0, #0 + 8007176: f040 812b bne.w 80073d0 + 800717a: a852 add r0, sp, #328 ; 0x148 + 800717c: f7fe fc0c bl 8005998 + 8007180: 9002 str r0, [sp, #8] + 8007182: 2800 cmp r0, #0 + 8007184: f040 8126 bne.w 80073d4 + return 0; + } + + /* r, s must be < n. */ + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 8007188: f105 0b24 add.w fp, r5, #36 ; 0x24 + 800718c: 4632 mov r2, r6 + 800718e: a94a add r1, sp, #296 ; 0x128 + 8007190: 4658 mov r0, fp + 8007192: f7fe fc46 bl 8005a22 + 8007196: 2801 cmp r0, #1 + 8007198: f040 811e bne.w 80073d8 + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + 800719c: 4632 mov r2, r6 + 800719e: a952 add r1, sp, #328 ; 0x148 + 80071a0: 4658 mov r0, fp + 80071a2: f7fe fc3e bl 8005a22 + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 80071a6: 2801 cmp r0, #1 + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + 80071a8: 9005 str r0, [sp, #20] + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + 80071aa: f040 8115 bne.w 80073d8 + return 0; + } + + /* Calculate u1 and u2. */ + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + 80071ae: ac1a add r4, sp, #104 ; 0x68 + u1[num_n_words - 1] = 0; + 80071b0: af0a add r7, sp, #40 ; 0x28 + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + 80071b2: 4633 mov r3, r6 + 80071b4: 465a mov r2, fp + 80071b6: 4620 mov r0, r4 + 80071b8: f7ff f84e bl 8006258 + u1[num_n_words - 1] = 0; + 80071bc: 9b02 ldr r3, [sp, #8] + 80071be: f847 302a str.w r3, [r7, sl, lsl #2] + bits2int(u1, message_hash, hash_size, curve); + 80071c2: 464a mov r2, r9 + 80071c4: 4638 mov r0, r7 + 80071c6: ee18 1a90 vmov r1, s17 + 80071ca: 462b mov r3, r5 + 80071cc: f7fe fddd bl 8005d8a + uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */ + 80071d0: 4639 mov r1, r7 + 80071d2: 4638 mov r0, r7 + 80071d4: 465b mov r3, fp + 80071d6: 4622 mov r2, r4 + 80071d8: 9600 str r6, [sp, #0] + 80071da: f7fe fc44 bl 8005a66 + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + + /* Calculate sum = G + Q. */ + uECC_vli_set(sum, public, num_words); + 80071de: f50d 7ad4 add.w sl, sp, #424 ; 0x1a8 + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + 80071e2: 465b mov r3, fp + 80071e4: 4622 mov r2, r4 + 80071e6: a94a add r1, sp, #296 ; 0x128 + 80071e8: a812 add r0, sp, #72 ; 0x48 + 80071ea: 9600 str r6, [sp, #0] + 80071ec: f7fe fc3b bl 8005a66 + uECC_vli_set(sum, public, num_words); + 80071f0: 4642 mov r2, r8 + 80071f2: 4650 mov r0, sl + 80071f4: a95a add r1, sp, #360 ; 0x168 + 80071f6: f7fe fc08 bl 8005a0a + uECC_vli_set(sum + num_words, public + num_words, num_words); + 80071fa: 9b04 ldr r3, [sp, #16] + 80071fc: eb0a 0903 add.w r9, sl, r3 + 8007200: ee18 1a10 vmov r1, s16 + 8007204: 4648 mov r0, r9 + 8007206: f7fe fc00 bl 8005a0a + uECC_vli_set(tx, curve->G, num_words); + 800720a: f105 0344 add.w r3, r5, #68 ; 0x44 + 800720e: 4619 mov r1, r3 + 8007210: a832 add r0, sp, #200 ; 0xc8 + 8007212: 9303 str r3, [sp, #12] + 8007214: f7fe fbf9 bl 8005a0a + uECC_vli_set(ty, curve->G + num_words, num_words); + 8007218: e9dd 3103 ldrd r3, r1, [sp, #12] + 800721c: a83a add r0, sp, #232 ; 0xe8 + 800721e: 1859 adds r1, r3, r1 + 8007220: f7fe fbf3 bl 8005a0a + uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */ + 8007224: 1d2b adds r3, r5, #4 + 8007226: ee08 3a10 vmov s16, r3 + 800722a: 4651 mov r1, sl + 800722c: aa32 add r2, sp, #200 ; 0xc8 + 800722e: 4620 mov r0, r4 + 8007230: f7ff f8c0 bl 80063b4 + XYcZ_add(tx, ty, sum, sum + num_words, curve); + 8007234: 464b mov r3, r9 + 8007236: 4652 mov r2, sl + 8007238: a93a add r1, sp, #232 ; 0xe8 + 800723a: a832 add r0, sp, #200 ; 0xc8 + 800723c: 9500 str r5, [sp, #0] + 800723e: f7ff f94d bl 80064dc + uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */ + 8007242: ee18 2a10 vmov r2, s16 + 8007246: 4643 mov r3, r8 + 8007248: 4621 mov r1, r4 + 800724a: 4620 mov r0, r4 + 800724c: f7ff f804 bl 8006258 + apply_z(sum, sum + num_words, z, curve); + 8007250: 462b mov r3, r5 + 8007252: 4649 mov r1, r9 + 8007254: 4650 mov r0, sl + 8007256: 4622 mov r2, r4 + 8007258: f7fe fcb9 bl 8005bce + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + points[0] = 0; + 800725c: 9a02 ldr r2, [sp, #8] + 800725e: 9206 str r2, [sp, #24] + points[1] = curve->G; + 8007260: 9a03 ldr r2, [sp, #12] + 8007262: 9207 str r2, [sp, #28] + points[2] = public; + points[3] = sum; + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 8007264: 4631 mov r1, r6 + points[2] = public; + 8007266: aa5a add r2, sp, #360 ; 0x168 + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 8007268: 4638 mov r0, r7 + points[3] = sum; + 800726a: e9cd 2a08 strd r2, sl, [sp, #32] + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + 800726e: f7fe fbac bl 80059ca + 8007272: 4631 mov r1, r6 + 8007274: 4682 mov sl, r0 + 8007276: a812 add r0, sp, #72 ; 0x48 + 8007278: f7fe fba7 bl 80059ca + return (a > b ? a : b); + 800727c: 4550 cmp r0, sl + 800727e: bfb8 it lt + 8007280: 4650 movlt r0, sl + uECC_vli_numBits(u2, num_n_words)); + + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8007282: fa1f f980 uxth.w r9, r0 + 8007286: f109 31ff add.w r1, r9, #4294967295 ; 0xffffffff + 800728a: b209 sxth r1, r1 + 800728c: 4638 mov r0, r7 + 800728e: 9103 str r1, [sp, #12] + 8007290: f7fe fb91 bl 80059b6 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 8007294: 9903 ldr r1, [sp, #12] + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 8007296: 1e07 subs r7, r0, #0 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 8007298: a812 add r0, sp, #72 ; 0x48 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 800729a: bf18 it ne + 800729c: 2701 movne r7, #1 + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + 800729e: f7fe fb8a bl 80059b6 + 80072a2: 2800 cmp r0, #0 + 80072a4: bf14 ite ne + 80072a6: 2002 movne r0, #2 + 80072a8: 2000 moveq r0, #0 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 80072aa: ab06 add r3, sp, #24 + 80072ac: 4307 orrs r7, r0 + uECC_vli_set(rx, point, num_words); + 80072ae: 4642 mov r2, r8 + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + 80072b0: f853 1027 ldr.w r1, [r3, r7, lsl #2] + uECC_vli_set(rx, point, num_words); + 80072b4: a822 add r0, sp, #136 ; 0x88 + 80072b6: f7fe fba8 bl 8005a0a + uECC_vli_set(ry, point + num_words, num_words); + 80072ba: 9b04 ldr r3, [sp, #16] + 80072bc: f10d 0aa8 add.w sl, sp, #168 ; 0xa8 + 80072c0: 4419 add r1, r3 + 80072c2: 4650 mov r0, sl + 80072c4: f7fe fba1 bl 8005a0a + uECC_vli_clear(z, num_words); + 80072c8: 4641 mov r1, r8 + 80072ca: 4620 mov r0, r4 + 80072cc: f7fe fb5e bl 800598c + z[0] = 1; + 80072d0: 9b05 ldr r3, [sp, #20] + 80072d2: 6023 str r3, [r4, #0] + + for (i = num_bits - 2; i >= 0; --i) { + 80072d4: f1a9 0902 sub.w r9, r9, #2 + 80072d8: ab22 add r3, sp, #136 ; 0x88 + 80072da: fa0f f989 sxth.w r9, r9 + 80072de: 9303 str r3, [sp, #12] + 80072e0: f1b9 0f00 cmp.w r9, #0 + 80072e4: da26 bge.n 8007334 + XYcZ_add(tx, ty, rx, ry, curve); + uECC_vli_modMult_fast(z, z, tz, curve); + } + } + + uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */ + 80072e6: ee18 2a10 vmov r2, s16 + 80072ea: 4643 mov r3, r8 + 80072ec: 4621 mov r1, r4 + 80072ee: 4620 mov r0, r4 + 80072f0: f7fe ffb2 bl 8006258 + apply_z(rx, ry, z, curve); + 80072f4: 9803 ldr r0, [sp, #12] + 80072f6: 462b mov r3, r5 + 80072f8: 4622 mov r2, r4 + 80072fa: 4651 mov r1, sl + 80072fc: f7fe fc67 bl 8005bce + + /* v = x1 (mod n) */ + if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) { + 8007300: 9903 ldr r1, [sp, #12] + 8007302: 4632 mov r2, r6 + 8007304: 4658 mov r0, fp + 8007306: f7fe fb8c bl 8005a22 + 800730a: 2801 cmp r0, #1 + 800730c: d003 beq.n 8007316 + uECC_vli_sub(rx, rx, curve->n, num_n_words); + 800730e: 465a mov r2, fp + 8007310: 4608 mov r0, r1 + 8007312: f7fe fd13 bl 8005d3c + for (i = num_words - 1; i >= 0; --i) { + 8007316: f108 33ff add.w r3, r8, #4294967295 ; 0xffffffff + 800731a: b25b sxtb r3, r3 + diff |= (left[i] ^ right[i]); + 800731c: a94a add r1, sp, #296 ; 0x128 + for (i = num_words - 1; i >= 0; --i) { + 800731e: 061a lsls r2, r3, #24 + 8007320: d54b bpl.n 80073ba + return (diff == 0); + 8007322: 9b02 ldr r3, [sp, #8] + 8007324: fab3 f083 clz r0, r3 + 8007328: 0940 lsrs r0, r0, #5 + } + + /* Accept only if v == r. */ + return (int)(uECC_vli_equal(rx, r, num_words)); +} + 800732a: b07b add sp, #492 ; 0x1ec + 800732c: ecbd 8b02 vpop {d8} + 8007330: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + curve->double_jacobian(rx, ry, z, curve); + 8007334: 462b mov r3, r5 + 8007336: 4622 mov r2, r4 + 8007338: f8d5 70a4 ldr.w r7, [r5, #164] ; 0xa4 + 800733c: 9803 ldr r0, [sp, #12] + 800733e: 4651 mov r1, sl + 8007340: 47b8 blx r7 + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); + 8007342: 4649 mov r1, r9 + 8007344: a80a add r0, sp, #40 ; 0x28 + 8007346: f7fe fb36 bl 80059b6 + 800734a: 4649 mov r1, r9 + 800734c: 1e07 subs r7, r0, #0 + 800734e: a812 add r0, sp, #72 ; 0x48 + 8007350: bf18 it ne + 8007352: 2701 movne r7, #1 + 8007354: f7fe fb2f bl 80059b6 + 8007358: 2800 cmp r0, #0 + 800735a: bf14 ite ne + 800735c: 2002 movne r0, #2 + 800735e: 2000 moveq r0, #0 + 8007360: 4307 orrs r7, r0 + point = points[index]; + 8007362: ab06 add r3, sp, #24 + 8007364: f853 1027 ldr.w r1, [r3, r7, lsl #2] + if (point) { + 8007368: b311 cbz r1, 80073b0 + uECC_vli_set(tx, point, num_words); + 800736a: 4642 mov r2, r8 + 800736c: a832 add r0, sp, #200 ; 0xc8 + 800736e: f7fe fb4c bl 8005a0a + uECC_vli_set(ty, point + num_words, num_words); + 8007372: 9b04 ldr r3, [sp, #16] + 8007374: a83a add r0, sp, #232 ; 0xe8 + 8007376: 4419 add r1, r3 + 8007378: f7fe fb47 bl 8005a0a + apply_z(tx, ty, z, curve); + 800737c: 4601 mov r1, r0 + 800737e: 462b mov r3, r5 + 8007380: 4622 mov r2, r4 + 8007382: a832 add r0, sp, #200 ; 0xc8 + 8007384: f7fe fc23 bl 8005bce + uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */ + 8007388: ee18 3a10 vmov r3, s16 + 800738c: 9903 ldr r1, [sp, #12] + 800738e: aa32 add r2, sp, #200 ; 0xc8 + 8007390: a842 add r0, sp, #264 ; 0x108 + 8007392: f7ff f80f bl 80063b4 + XYcZ_add(tx, ty, rx, ry, curve); + 8007396: 9a03 ldr r2, [sp, #12] + 8007398: 9500 str r5, [sp, #0] + 800739a: 4653 mov r3, sl + 800739c: a93a add r1, sp, #232 ; 0xe8 + 800739e: a832 add r0, sp, #200 ; 0xc8 + 80073a0: f7ff f89c bl 80064dc + uECC_vli_modMult_fast(z, z, tz, curve); + 80073a4: 462b mov r3, r5 + 80073a6: aa42 add r2, sp, #264 ; 0x108 + 80073a8: 4621 mov r1, r4 + 80073aa: 4620 mov r0, r4 + 80073ac: f7fe fbfb bl 8005ba6 + for (i = num_bits - 2; i >= 0; --i) { + 80073b0: f109 39ff add.w r9, r9, #4294967295 ; 0xffffffff + 80073b4: fa0f f989 sxth.w r9, r9 + 80073b8: e792 b.n 80072e0 + diff |= (left[i] ^ right[i]); + 80073ba: 9a03 ldr r2, [sp, #12] + 80073bc: f851 0023 ldr.w r0, [r1, r3, lsl #2] + 80073c0: f852 2023 ldr.w r2, [r2, r3, lsl #2] + 80073c4: 4042 eors r2, r0 + 80073c6: 9802 ldr r0, [sp, #8] + 80073c8: 4310 orrs r0, r2 + 80073ca: 9002 str r0, [sp, #8] + for (i = num_words - 1; i >= 0; --i) { + 80073cc: 3b01 subs r3, #1 + 80073ce: e7a6 b.n 800731e + return 0; + 80073d0: 4618 mov r0, r3 + 80073d2: e7aa b.n 800732a + 80073d4: 4620 mov r0, r4 + 80073d6: e7a8 b.n 800732a + 80073d8: 9802 ldr r0, [sp, #8] + 80073da: e7a6 b.n 800732a + +080073dc : +const uint32_t MSIRangeTable[12] = {100000, 200000, 400000, 800000, 1000000, 2000000, \ + 4000000, 8000000, 16000000, 24000000, 32000000, 48000000}; +uint32_t SystemCoreClock; + +// TODO: cleanup HAL stuff to not use this +uint32_t HAL_GetTick(void) { return 53; } + 80073dc: 2035 movs r0, #53 ; 0x35 + 80073de: 4770 bx lr + +080073e0 : +uint32_t uwTickPrio = 0; /* (1UL << __NVIC_PRIO_BITS); * Invalid priority */ + +// unwanted junk from stm32l4xx_hal_rcc.c +HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority) { return 0; } + 80073e0: 2000 movs r0, #0 + 80073e2: 4770 bx lr + +080073e4 : + * or PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when applicable) + */ +uint32_t HAL_PWREx_GetVoltageRange(void) +{ +#if defined(PWR_CR5_R1MODE) + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 80073e4: 4b07 ldr r3, [pc, #28] ; (8007404 ) + 80073e6: 6818 ldr r0, [r3, #0] + 80073e8: f400 60c0 and.w r0, r0, #1536 ; 0x600 + 80073ec: f5b0 6f80 cmp.w r0, #1024 ; 0x400 + 80073f0: d006 beq.n 8007400 + { + return PWR_REGULATOR_VOLTAGE_SCALE2; + } + else if (READ_BIT(PWR->CR5, PWR_CR5_R1MODE) == PWR_CR5_R1MODE) + 80073f2: f8d3 0080 ldr.w r0, [r3, #128] ; 0x80 + { + /* PWR_CR5_R1MODE bit set means that Range 1 Boost is disabled */ + return PWR_REGULATOR_VOLTAGE_SCALE1; + 80073f6: f410 7080 ands.w r0, r0, #256 ; 0x100 + 80073fa: bf18 it ne + 80073fc: f44f 7000 movne.w r0, #512 ; 0x200 + return PWR_REGULATOR_VOLTAGE_SCALE1_BOOST; + } +#else + return (PWR->CR1 & PWR_CR1_VOS); +#endif +} + 8007400: 4770 bx lr + 8007402: bf00 nop + 8007404: 40007000 .word 0x40007000 + +08007408 : + uint32_t wait_loop_index; + + assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling)); + +#if defined(PWR_CR5_R1MODE) + if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) + 8007408: 4b29 ldr r3, [pc, #164] ; (80074b0 ) + { + /* If current range is range 2 */ + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 800740a: 681a ldr r2, [r3, #0] + if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) + 800740c: bb30 cbnz r0, 800745c + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 800740e: f402 62c0 and.w r2, r2, #1536 ; 0x600 + 8007412: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + { + /* Make sure Range 1 Boost is enabled */ + CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); + 8007416: f8d3 2080 ldr.w r2, [r3, #128] ; 0x80 + 800741a: f422 7280 bic.w r2, r2, #256 ; 0x100 + 800741e: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007422: d11a bne.n 800745a + + /* Set Range 1 */ + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1); + 8007424: 681a ldr r2, [r3, #0] + 8007426: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 800742a: f442 7200 orr.w r2, r2, #512 ; 0x200 + 800742e: 601a str r2, [r3, #0] + + /* Wait until VOSF is cleared */ + wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1; + 8007430: 4a20 ldr r2, [pc, #128] ; (80074b4 ) + 8007432: 6812 ldr r2, [r2, #0] + 8007434: 2132 movs r1, #50 ; 0x32 + 8007436: 434a muls r2, r1 + 8007438: 491f ldr r1, [pc, #124] ; (80074b8 ) + 800743a: fbb2 f2f1 udiv r2, r2, r1 + 800743e: 3201 adds r2, #1 + while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U)) + 8007440: 6959 ldr r1, [r3, #20] + 8007442: 0549 lsls r1, r1, #21 + 8007444: d500 bpl.n 8007448 + 8007446: b922 cbnz r2, 8007452 + { + wait_loop_index--; + } + if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) + 8007448: 695b ldr r3, [r3, #20] + 800744a: 0558 lsls r0, r3, #21 + 800744c: d403 bmi.n 8007456 + /* No need to wait for VOSF to be cleared for this transition */ + } + } +#endif + + return HAL_OK; + 800744e: 2000 movs r0, #0 +} + 8007450: 4770 bx lr + wait_loop_index--; + 8007452: 3a01 subs r2, #1 + 8007454: e7f4 b.n 8007440 + return HAL_TIMEOUT; + 8007456: 2003 movs r0, #3 + 8007458: 4770 bx lr + CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); + 800745a: 4770 bx lr + else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1) + 800745c: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8007460: d11f bne.n 80074a2 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007462: f402 62c0 and.w r2, r2, #1536 ; 0x600 + 8007466: f5b2 6f80 cmp.w r2, #1024 ; 0x400 + SET_BIT(PWR->CR5, PWR_CR5_R1MODE); + 800746a: f8d3 2080 ldr.w r2, [r3, #128] ; 0x80 + 800746e: f442 7280 orr.w r2, r2, #256 ; 0x100 + 8007472: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2) + 8007476: d1ea bne.n 800744e + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1); + 8007478: 681a ldr r2, [r3, #0] + 800747a: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 800747e: f442 7200 orr.w r2, r2, #512 ; 0x200 + 8007482: 601a str r2, [r3, #0] + wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1; + 8007484: 4a0b ldr r2, [pc, #44] ; (80074b4 ) + 8007486: 6812 ldr r2, [r2, #0] + 8007488: 2132 movs r1, #50 ; 0x32 + 800748a: 434a muls r2, r1 + 800748c: 490a ldr r1, [pc, #40] ; (80074b8 ) + 800748e: fbb2 f2f1 udiv r2, r2, r1 + 8007492: 3201 adds r2, #1 + while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U)) + 8007494: 6959 ldr r1, [r3, #20] + 8007496: 0549 lsls r1, r1, #21 + 8007498: d5d6 bpl.n 8007448 + 800749a: 2a00 cmp r2, #0 + 800749c: d0d4 beq.n 8007448 + wait_loop_index--; + 800749e: 3a01 subs r2, #1 + 80074a0: e7f8 b.n 8007494 + MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2); + 80074a2: f422 62c0 bic.w r2, r2, #1536 ; 0x600 + 80074a6: f442 6280 orr.w r2, r2, #1024 ; 0x400 + 80074aa: 601a str r2, [r3, #0] + 80074ac: e7cf b.n 800744e + 80074ae: bf00 nop + 80074b0: 40007000 .word 0x40007000 + 80074b4: 2009e2ac .word 0x2009e2ac + 80074b8: 000f4240 .word 0x000f4240 + +080074bc : + +__weak void HAL_SDEx_DriveTransceiver_1_8V_Callback(FlagStatus status) +{ + // unused? +} + 80074bc: 4770 bx lr + ... + +080074c0 <__NVIC_SystemReset>: + 80074c0: f3bf 8f4f dsb sy + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80074c4: 4905 ldr r1, [pc, #20] ; (80074dc <__NVIC_SystemReset+0x1c>) + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80074c6: 4b06 ldr r3, [pc, #24] ; (80074e0 <__NVIC_SystemReset+0x20>) + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + 80074c8: 68ca ldr r2, [r1, #12] + 80074ca: f402 62e0 and.w r2, r2, #1792 ; 0x700 + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + 80074ce: 4313 orrs r3, r2 + 80074d0: 60cb str r3, [r1, #12] + 80074d2: f3bf 8f4f dsb sy + __NOP(); + 80074d6: bf00 nop + for(;;) /* wait until reset */ + 80074d8: e7fd b.n 80074d6 <__NVIC_SystemReset+0x16> + 80074da: bf00 nop + 80074dc: e000ed00 .word 0xe000ed00 + 80074e0: 05fa0004 .word 0x05fa0004 + +080074e4 : +{ + 80074e4: b510 push {r4, lr} + 80074e6: 3801 subs r0, #1 + 80074e8: 440a add r2, r1 + *(acc) ^= *(more); + 80074ea: f811 4b01 ldrb.w r4, [r1], #1 + 80074ee: f810 3f01 ldrb.w r3, [r0, #1]! + for(; len; len--, more++, acc++) { + 80074f2: 4291 cmp r1, r2 + *(acc) ^= *(more); + 80074f4: ea83 0304 eor.w r3, r3, r4 + 80074f8: 7003 strb r3, [r0, #0] + for(; len; len--, more++, acc++) { + 80074fa: d1f6 bne.n 80074ea + } +} + 80074fc: bd10 pop {r4, pc} + ... + +08007500 : + +// se2_write1() +// + static bool +se2_write1(uint8_t cmd, uint8_t arg) +{ + 8007500: b51f push {r0, r1, r2, r3, r4, lr} + uint8_t data[3] = { cmd, 1, arg }; + 8007502: 2301 movs r3, #1 + 8007504: f88d 300d strb.w r3, [sp, #13] + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 8007508: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + uint8_t data[3] = { cmd, 1, arg }; + 800750c: f88d 000c strb.w r0, [sp, #12] + 8007510: f88d 100e strb.w r1, [sp, #14] + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 8007514: 9300 str r3, [sp, #0] + 8007516: aa03 add r2, sp, #12 + 8007518: 2303 movs r3, #3 + 800751a: 2136 movs r1, #54 ; 0x36 + 800751c: 4804 ldr r0, [pc, #16] ; (8007530 ) + 800751e: f004 fb79 bl 800bc14 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 8007522: 3800 subs r0, #0 + 8007524: bf18 it ne + 8007526: 2001 movne r0, #1 + 8007528: b005 add sp, #20 + 800752a: f85d fb04 ldr.w pc, [sp], #4 + 800752e: bf00 nop + 8007530: 2009e3f0 .word 0x2009e3f0 + +08007534 : + +// se2_write2() +// + static bool +se2_write2(uint8_t cmd, uint8_t arg1, uint8_t arg2) +{ + 8007534: b51f push {r0, r1, r2, r3, r4, lr} + uint8_t data[4] = { cmd, 2, arg1, arg2 }; + 8007536: 2302 movs r3, #2 + 8007538: f88d 300d strb.w r3, [sp, #13] + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 800753c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + uint8_t data[4] = { cmd, 2, arg1, arg2 }; + 8007540: f88d 000c strb.w r0, [sp, #12] + 8007544: f88d 100e strb.w r1, [sp, #14] + 8007548: f88d 200f strb.w r2, [sp, #15] + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 800754c: 9300 str r3, [sp, #0] + 800754e: aa03 add r2, sp, #12 + 8007550: 2304 movs r3, #4 + 8007552: 2136 movs r1, #54 ; 0x36 + 8007554: 4804 ldr r0, [pc, #16] ; (8007568 ) + 8007556: f004 fb5d bl 800bc14 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 800755a: 3800 subs r0, #0 + 800755c: bf18 it ne + 800755e: 2001 movne r0, #1 + 8007560: b005 add sp, #20 + 8007562: f85d fb04 ldr.w pc, [sp], #4 + 8007566: bf00 nop + 8007568: 2009e3f0 .word 0x2009e3f0 + +0800756c : + +// se2_write_n() +// + static bool +se2_write_n(uint8_t cmd, uint8_t *param1, const uint8_t *data_in, uint8_t len) +{ + 800756c: b5f0 push {r4, r5, r6, r7, lr} + 800756e: 460d mov r5, r1 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007570: 2d00 cmp r5, #0 + 8007572: bf14 ite ne + 8007574: 2403 movne r4, #3 + 8007576: 2402 moveq r4, #2 + 8007578: 441c add r4, r3 +{ + 800757a: 4611 mov r1, r2 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 800757c: f104 0207 add.w r2, r4, #7 +{ + 8007580: b083 sub sp, #12 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007582: f402 727e and.w r2, r2, #1016 ; 0x3f8 +{ + 8007586: af02 add r7, sp, #8 + uint8_t data[2 + (param1?1:0) + len], *p = data; + 8007588: ebad 0d02 sub.w sp, sp, r2 + 800758c: ae02 add r6, sp, #8 + + *(p++) = cmd; + *(p++) = sizeof(data) - 2; + 800758e: f1a4 0202 sub.w r2, r4, #2 + *(p++) = cmd; + 8007592: f88d 0008 strb.w r0, [sp, #8] + *(p++) = sizeof(data) - 2; + 8007596: 7072 strb r2, [r6, #1] + if(param1) { + *(p++) = *param1; + 8007598: bf1b ittet ne + 800759a: 782a ldrbne r2, [r5, #0] + 800759c: 70b2 strbne r2, [r6, #2] + *(p++) = sizeof(data) - 2; + 800759e: f10d 000a addeq.w r0, sp, #10 + *(p++) = *param1; + 80075a2: f10d 000b addne.w r0, sp, #11 + } + if(len) { + 80075a6: b113 cbz r3, 80075ae + memcpy(p, data_in, len); + 80075a8: 461a mov r2, r3 + 80075aa: f006 f9ad bl 800d908 + } + + HAL_StatusTypeDef rv = HAL_I2C_Master_Transmit(&i2c_port, I2C_ADDR, + 80075ae: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 80075b2: 9300 str r3, [sp, #0] + 80075b4: 4632 mov r2, r6 + 80075b6: 4623 mov r3, r4 + 80075b8: 2136 movs r1, #54 ; 0x36 + 80075ba: 4804 ldr r0, [pc, #16] ; (80075cc ) + 80075bc: f004 fb2a bl 800bc14 + data, sizeof(data), HAL_MAX_DELAY); + + return (rv != HAL_OK); +} + 80075c0: 3800 subs r0, #0 + 80075c2: bf18 it ne + 80075c4: 2001 movne r0, #1 + 80075c6: 3704 adds r7, #4 + 80075c8: 46bd mov sp, r7 + 80075ca: bdf0 pop {r4, r5, r6, r7, pc} + 80075cc: 2009e3f0 .word 0x2009e3f0 + +080075d0 : + +// rng_for_uECC() +// + static int +rng_for_uECC(uint8_t *dest, unsigned size) +{ + 80075d0: b508 push {r3, lr} + 'dest' was filled with random data, or 0 if the random data could not be generated. + The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + + typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + */ + rng_buffer(dest, size); + 80075d2: f7fb f983 bl 80028dc + + return 1; +} + 80075d6: 2001 movs r0, #1 + 80075d8: bd08 pop {r3, pc} + ... + +080075dc : +{ + 80075dc: b508 push {r3, lr} + 80075de: 4602 mov r2, r0 + CALL_CHECK(se2_write_n(0x87, NULL, data, len)); + 80075e0: b2cb uxtb r3, r1 + 80075e2: 2087 movs r0, #135 ; 0x87 + 80075e4: 2100 movs r1, #0 + 80075e6: f7ff ffc1 bl 800756c + 80075ea: b118 cbz r0, 80075f4 + 80075ec: 4802 ldr r0, [pc, #8] ; (80075f8 ) + 80075ee: 21c1 movs r1, #193 ; 0xc1 + 80075f0: f006 f9a6 bl 800d940 +} + 80075f4: bd08 pop {r3, pc} + 80075f6: bf00 nop + 80075f8: 2009e394 .word 0x2009e394 + +080075fc : +{ + 80075fc: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + HAL_StatusTypeDef rv = HAL_I2C_Master_Receive(&i2c_port, I2C_ADDR, rx, len, HAL_MAX_DELAY); + 8007600: f8df 9044 ldr.w r9, [pc, #68] ; 8007648 +{ + 8007604: 4604 mov r4, r0 + 8007606: 460d mov r5, r1 + 8007608: f44f 7696 mov.w r6, #300 ; 0x12c + HAL_StatusTypeDef rv = HAL_I2C_Master_Receive(&i2c_port, I2C_ADDR, rx, len, HAL_MAX_DELAY); + 800760c: b287 uxth r7, r0 + 800760e: f04f 38ff mov.w r8, #4294967295 ; 0xffffffff + 8007612: f8cd 8000 str.w r8, [sp] + 8007616: 463b mov r3, r7 + 8007618: 462a mov r2, r5 + 800761a: 2136 movs r1, #54 ; 0x36 + 800761c: 4648 mov r0, r9 + 800761e: f004 fbad bl 800bd7c + if(rv == HAL_OK) { + 8007622: b938 cbnz r0, 8007634 + if(rx[0] != len-1) { + 8007624: 782b ldrb r3, [r5, #0] + 8007626: 3c01 subs r4, #1 + 8007628: 42a3 cmp r3, r4 + 800762a: d10a bne.n 8007642 + return rx[1]; + 800762c: 7868 ldrb r0, [r5, #1] +} + 800762e: b003 add sp, #12 + 8007630: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + delay_ms(1); + 8007634: 2001 movs r0, #1 + 8007636: f7fc fa25 bl 8003a84 + for(int tries=0; tries<300; tries++) { + 800763a: 3e01 subs r6, #1 + 800763c: d1e9 bne.n 8007612 + return RC_NO_ACK; + 800763e: 200f movs r0, #15 + 8007640: e7f5 b.n 800762e + return RC_WRONG_SIZE; + 8007642: 201f movs r0, #31 + 8007644: e7f3 b.n 800762e + 8007646: bf00 nop + 8007648: 2009e3f0 .word 0x2009e3f0 + +0800764c : +{ + 800764c: b507 push {r0, r1, r2, lr} + return se2_read_n(2, rx); + 800764e: 2002 movs r0, #2 + 8007650: a901 add r1, sp, #4 + 8007652: f7ff ffd3 bl 80075fc +} + 8007656: b003 add sp, #12 + 8007658: f85d fb04 ldr.w pc, [sp], #4 + +0800765c : +{ + 800765c: b507 push {r0, r1, r2, lr} + CALL_CHECK(se2_write_n(0x96, &page_num, data, 32)); + 800765e: 2320 movs r3, #32 +{ + 8007660: 460a mov r2, r1 + 8007662: f88d 0007 strb.w r0, [sp, #7] + CALL_CHECK(se2_write_n(0x96, &page_num, data, 32)); + 8007666: f10d 0107 add.w r1, sp, #7 + 800766a: 2096 movs r0, #150 ; 0x96 + 800766c: f7ff ff7e bl 800756c + 8007670: b118 cbz r0, 800767a + 8007672: 21cb movs r1, #203 ; 0xcb + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007674: 4805 ldr r0, [pc, #20] ; (800768c ) + 8007676: f006 f963 bl 800d940 + 800767a: f7ff ffe7 bl 800764c + 800767e: 28aa cmp r0, #170 ; 0xaa + 8007680: d001 beq.n 8007686 + 8007682: 21cd movs r1, #205 ; 0xcd + 8007684: e7f6 b.n 8007674 +} + 8007686: b003 add sp, #12 + 8007688: f85d fb04 ldr.w pc, [sp], #4 + 800768c: 2009e394 .word 0x2009e394 + +08007690 : + ASSERT(pubkey_num < 2); + 8007690: 2801 cmp r0, #1 +{ + 8007692: b508 push {r3, lr} + ASSERT(pubkey_num < 2); + 8007694: d902 bls.n 800769c + 8007696: 480a ldr r0, [pc, #40] ; (80076c0 ) + 8007698: f7f9 f9ce bl 8000a38 + CALL_CHECK(se2_write1(0xcb, (wpe <<6) | pubkey_num)); + 800769c: ea40 1181 orr.w r1, r0, r1, lsl #6 + 80076a0: b2c9 uxtb r1, r1 + 80076a2: 20cb movs r0, #203 ; 0xcb + 80076a4: f7ff ff2c bl 8007500 + 80076a8: b118 cbz r0, 80076b2 + 80076aa: 21d9 movs r1, #217 ; 0xd9 + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 80076ac: 4805 ldr r0, [pc, #20] ; (80076c4 ) + 80076ae: f006 f947 bl 800d940 + 80076b2: f7ff ffcb bl 800764c + 80076b6: 28aa cmp r0, #170 ; 0xaa + 80076b8: d001 beq.n 80076be + 80076ba: 21db movs r1, #219 ; 0xdb + 80076bc: e7f6 b.n 80076ac +} + 80076be: bd08 pop {r3, pc} + 80076c0: 0801046c .word 0x0801046c + 80076c4: 2009e394 .word 0x2009e394 + +080076c8 : +{ + 80076c8: b570 push {r4, r5, r6, lr} + 80076ca: b0dc sub sp, #368 ; 0x170 + 80076cc: 460d mov r5, r1 + 80076ce: f88d 0007 strb.w r0, [sp, #7] + rng_buffer(chal, sizeof(chal)); + 80076d2: 2120 movs r1, #32 + 80076d4: a802 add r0, sp, #8 +{ + 80076d6: 4616 mov r6, r2 + 80076d8: 461c mov r4, r3 + rng_buffer(chal, sizeof(chal)); + 80076da: f7fb f8ff bl 80028dc + se2_write_buffer(chal, sizeof(chal)); + 80076de: 2120 movs r1, #32 + 80076e0: a802 add r0, sp, #8 + 80076e2: f7ff ff7b bl 80075dc + CALL_CHECK(se2_write1(0xa5, (keynum<<5) | page_num)); + 80076e6: f89d 3007 ldrb.w r3, [sp, #7] + 80076ea: ea43 1146 orr.w r1, r3, r6, lsl #5 + 80076ee: b2c9 uxtb r1, r1 + 80076f0: 20a5 movs r0, #165 ; 0xa5 + 80076f2: f7ff ff05 bl 8007500 + 80076f6: b118 cbz r0, 8007700 + 80076f8: 21eb movs r1, #235 ; 0xeb + CHECK_RIGHT(se2_read_n(sizeof(check), check) == RC_SUCCESS); + 80076fa: 481e ldr r0, [pc, #120] ; (8007774 ) + 80076fc: f006 f920 bl 800d940 + 8007700: a912 add r1, sp, #72 ; 0x48 + 8007702: 2022 movs r0, #34 ; 0x22 + 8007704: f7ff ff7a bl 80075fc + 8007708: 28aa cmp r0, #170 ; 0xaa + 800770a: d001 beq.n 8007710 + 800770c: 21ee movs r1, #238 ; 0xee + 800770e: e7f4 b.n 80076fa + hmac_sha256_init(&ctx); + 8007710: a81b add r0, sp, #108 ; 0x6c + 8007712: f7fe f8bb bl 800588c + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 8007716: 4b18 ldr r3, [pc, #96] ; (8007778 ) + 8007718: 4918 ldr r1, [pc, #96] ; (800777c ) + 800771a: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 800771e: 33b0 adds r3, #176 ; 0xb0 + 8007720: 2aff cmp r2, #255 ; 0xff + 8007722: bf18 it ne + 8007724: 4619 movne r1, r3 + 8007726: a81b add r0, sp, #108 ; 0x6c + 8007728: 2208 movs r2, #8 + 800772a: 3160 adds r1, #96 ; 0x60 + 800772c: f7fe f8b4 bl 8005898 + hmac_sha256_update(&ctx, data, 32); + 8007730: 4629 mov r1, r5 + 8007732: a81b add r0, sp, #108 ; 0x6c + 8007734: 2220 movs r2, #32 + 8007736: f7fe f8af bl 8005898 + hmac_sha256_update(&ctx, chal, 32); + 800773a: a902 add r1, sp, #8 + 800773c: a81b add r0, sp, #108 ; 0x6c + 800773e: 2220 movs r2, #32 + 8007740: f7fe f8aa bl 8005898 + hmac_sha256_update(&ctx, &page_num, 1); + 8007744: f10d 0107 add.w r1, sp, #7 + 8007748: a81b add r0, sp, #108 ; 0x6c + 800774a: 2201 movs r2, #1 + 800774c: f7fe f8a4 bl 8005898 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 8007750: a81b add r0, sp, #108 ; 0x6c + 8007752: 490b ldr r1, [pc, #44] ; (8007780 ) + 8007754: 2202 movs r2, #2 + 8007756: f7fe f89f bl 8005898 + hmac_sha256_final(&ctx, secret, expect); + 800775a: aa0a add r2, sp, #40 ; 0x28 + 800775c: 4621 mov r1, r4 + 800775e: a81b add r0, sp, #108 ; 0x6c + 8007760: f7fe f8b0 bl 80058c4 + return check_equal(expect, check+2, 32); + 8007764: 2220 movs r2, #32 + 8007766: f10d 014a add.w r1, sp, #74 ; 0x4a + 800776a: a80a add r0, sp, #40 ; 0x28 + 800776c: f7fb f867 bl 800283e +} + 8007770: b05c add sp, #368 ; 0x170 + 8007772: bd70 pop {r4, r5, r6, pc} + 8007774: 2009e394 .word 0x2009e394 + 8007778: 0801c000 .word 0x0801c000 + 800777c: 2009e2b4 .word 0x2009e2b4 + 8007780: 08010ac0 .word 0x08010ac0 + +08007784 : +{ + 8007784: b570 push {r4, r5, r6, lr} + 8007786: 4604 mov r4, r0 + 8007788: b08a sub sp, #40 ; 0x28 + 800778a: 460d mov r5, r1 + CALL_CHECK(se2_write1(0x69, page_num)); + 800778c: 4601 mov r1, r0 + 800778e: 2069 movs r0, #105 ; 0x69 +{ + 8007790: 4616 mov r6, r2 + CALL_CHECK(se2_write1(0x69, page_num)); + 8007792: f7ff feb5 bl 8007500 + 8007796: b120 cbz r0, 80077a2 + 8007798: f44f 7185 mov.w r1, #266 ; 0x10a + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 800779c: 481c ldr r0, [pc, #112] ; (8007810 ) + 800779e: f006 f8cf bl 800d940 + 80077a2: a901 add r1, sp, #4 + 80077a4: 2022 movs r0, #34 ; 0x22 + 80077a6: f7ff ff29 bl 80075fc + 80077aa: 28aa cmp r0, #170 ; 0xaa + 80077ac: d002 beq.n 80077b4 + 80077ae: f240 110d movw r1, #269 ; 0x10d + 80077b2: e7f3 b.n 800779c + CHECK_RIGHT(rx[0] == 33); + 80077b4: f89d 3004 ldrb.w r3, [sp, #4] + 80077b8: 2b21 cmp r3, #33 ; 0x21 + 80077ba: d002 beq.n 80077c2 + 80077bc: f240 110f movw r1, #271 ; 0x10f + 80077c0: e7ec b.n 800779c + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 80077c2: f89d 3005 ldrb.w r3, [sp, #5] + 80077c6: 2baa cmp r3, #170 ; 0xaa + 80077c8: d002 beq.n 80077d0 + 80077ca: f44f 7188 mov.w r1, #272 ; 0x110 + 80077ce: e7e5 b.n 800779c + memcpy(data, rx+2, 32); + 80077d0: f10d 0306 add.w r3, sp, #6 + 80077d4: 462a mov r2, r5 + 80077d6: f10d 0126 add.w r1, sp, #38 ; 0x26 + 80077da: f853 0b04 ldr.w r0, [r3], #4 + 80077de: f842 0b04 str.w r0, [r2], #4 + 80077e2: 428b cmp r3, r1 + 80077e4: d1f9 bne.n 80077da + if(!verify) return; + 80077e6: b186 cbz r6, 800780a + CHECK_RIGHT(se2_verify_page(page_num, data, 0, SE2_SECRETS->pairing)); + 80077e8: 4b0a ldr r3, [pc, #40] ; (8007814 ) + 80077ea: 4a0b ldr r2, [pc, #44] ; (8007818 ) + 80077ec: f893 10b0 ldrb.w r1, [r3, #176] ; 0xb0 + 80077f0: 4b0a ldr r3, [pc, #40] ; (800781c ) + 80077f2: 4620 mov r0, r4 + 80077f4: 29ff cmp r1, #255 ; 0xff + 80077f6: bf18 it ne + 80077f8: 4613 movne r3, r2 + 80077fa: 2200 movs r2, #0 + 80077fc: 4629 mov r1, r5 + 80077fe: f7ff ff63 bl 80076c8 + 8007802: b910 cbnz r0, 800780a + 8007804: f44f 718b mov.w r1, #278 ; 0x116 + 8007808: e7c8 b.n 800779c +} + 800780a: b00a add sp, #40 ; 0x28 + 800780c: bd70 pop {r4, r5, r6, pc} + 800780e: bf00 nop + 8007810: 2009e394 .word 0x2009e394 + 8007814: 0801c000 .word 0x0801c000 + 8007818: 0801c0b0 .word 0x0801c0b0 + 800781c: 2009e2b4 .word 0x2009e2b4 + +08007820 : +{ + 8007820: b570 push {r4, r5, r6, lr} + 8007822: b0d6 sub sp, #344 ; 0x158 + 8007824: 461e mov r6, r3 + ASSERT((keynum == 0) || (keynum == 2)); + 8007826: f032 0302 bics.w r3, r2, #2 +{ + 800782a: 460c mov r4, r1 + 800782c: 4615 mov r5, r2 + 800782e: f88d 0007 strb.w r0, [sp, #7] + ASSERT((keynum == 0) || (keynum == 2)); + 8007832: d002 beq.n 800783a + 8007834: 4831 ldr r0, [pc, #196] ; (80078fc ) + 8007836: f7f9 f8ff bl 8000a38 + CALL_CHECK(se2_write1(0x4b, (keynum << 6) | page_num)); + 800783a: f89d 1007 ldrb.w r1, [sp, #7] + 800783e: ea41 1182 orr.w r1, r1, r2, lsl #6 + 8007842: b2c9 uxtb r1, r1 + 8007844: 204b movs r0, #75 ; 0x4b + 8007846: f7ff fe5b bl 8007500 + 800784a: b120 cbz r0, 8007856 + 800784c: f44f 71b3 mov.w r1, #358 ; 0x166 + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 8007850: 482b ldr r0, [pc, #172] ; (8007900 ) + 8007852: f006 f875 bl 800d940 + 8007856: a90a add r1, sp, #40 ; 0x28 + 8007858: 202a movs r0, #42 ; 0x2a + 800785a: f7ff fecf bl 80075fc + 800785e: 28aa cmp r0, #170 ; 0xaa + 8007860: d002 beq.n 8007868 + 8007862: f240 1169 movw r1, #361 ; 0x169 + 8007866: e7f3 b.n 8007850 + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 8007868: f89d 3029 ldrb.w r3, [sp, #41] ; 0x29 + 800786c: 2baa cmp r3, #170 ; 0xaa + 800786e: d002 beq.n 8007876 + 8007870: f240 116b movw r1, #363 ; 0x16b + 8007874: e7ec b.n 8007850 + memcpy(data, rx+2+8, 32); + 8007876: f10d 0332 add.w r3, sp, #50 ; 0x32 + 800787a: 4622 mov r2, r4 + 800787c: f10d 0152 add.w r1, sp, #82 ; 0x52 + 8007880: f853 0b04 ldr.w r0, [r3], #4 + 8007884: f842 0b04 str.w r0, [r2], #4 + 8007888: 428b cmp r3, r1 + 800788a: d1f9 bne.n 8007880 + hmac_sha256_init(&ctx); + 800788c: a815 add r0, sp, #84 ; 0x54 + 800788e: f7fd fffd bl 800588c + hmac_sha256_update(&ctx, chal, 8); + 8007892: 2208 movs r2, #8 + 8007894: f10d 012a add.w r1, sp, #42 ; 0x2a + 8007898: a815 add r0, sp, #84 ; 0x54 + 800789a: f7fd fffd bl 8005898 + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 800789e: 4b19 ldr r3, [pc, #100] ; (8007904 ) + 80078a0: 4919 ldr r1, [pc, #100] ; (8007908 ) + 80078a2: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80078a6: 33b0 adds r3, #176 ; 0xb0 + 80078a8: 2aff cmp r2, #255 ; 0xff + 80078aa: bf18 it ne + 80078ac: 4619 movne r1, r3 + 80078ae: 3160 adds r1, #96 ; 0x60 + 80078b0: 2208 movs r2, #8 + 80078b2: a815 add r0, sp, #84 ; 0x54 + 80078b4: f7fd fff0 bl 8005898 + hmac_sha256_update(&ctx, &page_num, 1); + 80078b8: 2201 movs r2, #1 + 80078ba: f10d 0107 add.w r1, sp, #7 + 80078be: a815 add r0, sp, #84 ; 0x54 + 80078c0: f7fd ffea bl 8005898 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 80078c4: 4911 ldr r1, [pc, #68] ; (800790c ) + 80078c6: 2202 movs r2, #2 + 80078c8: a815 add r0, sp, #84 ; 0x54 + 80078ca: f7fd ffe5 bl 8005898 + hmac_sha256_final(&ctx, secret, otp); + 80078ce: aa02 add r2, sp, #8 + 80078d0: 4631 mov r1, r6 + 80078d2: a815 add r0, sp, #84 ; 0x54 + 80078d4: f7fd fff6 bl 80058c4 + xor_mixin(data, otp, 32); + 80078d8: 2220 movs r2, #32 + 80078da: a902 add r1, sp, #8 + 80078dc: 4620 mov r0, r4 + 80078de: f7ff fe01 bl 80074e4 + CHECK_RIGHT(se2_verify_page(page_num, data, keynum, secret)); + 80078e2: f89d 0007 ldrb.w r0, [sp, #7] + 80078e6: 4633 mov r3, r6 + 80078e8: 462a mov r2, r5 + 80078ea: 4621 mov r1, r4 + 80078ec: f7ff feec bl 80076c8 + 80078f0: b910 cbnz r0, 80078f8 + 80078f2: f44f 71c0 mov.w r1, #384 ; 0x180 + 80078f6: e7ab b.n 8007850 +} + 80078f8: b056 add sp, #344 ; 0x158 + 80078fa: bd70 pop {r4, r5, r6, pc} + 80078fc: 0801046c .word 0x0801046c + 8007900: 2009e394 .word 0x2009e394 + 8007904: 0801c000 .word 0x0801c000 + 8007908: 2009e2b4 .word 0x2009e2b4 + 800790c: 08010ac0 .word 0x08010ac0 + +08007910 : +{ + 8007910: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8007914: 460e mov r6, r1 + ASSERT((keynum == 0) || (keynum == 2)); + 8007916: f032 0102 bics.w r1, r2, #2 +{ + 800791a: b0e4 sub sp, #400 ; 0x190 + 800791c: 4604 mov r4, r0 + 800791e: 4617 mov r7, r2 + 8007920: 4698 mov r8, r3 + ASSERT((keynum == 0) || (keynum == 2)); + 8007922: d002 beq.n 800792a + 8007924: 4849 ldr r0, [pc, #292] ; (8007a4c ) + 8007926: f7f9 f887 bl 8000a38 + se2_read_encrypted(page_num, old_data, keynum, secret); + 800792a: a901 add r1, sp, #4 + 800792c: f7ff ff78 bl 8007820 + uint8_t PGDV = page_num | 0x80; + 8007930: f064 037f orn r3, r4, #127 ; 0x7f + rng_buffer(&chal_check[32], 8); + 8007934: 2108 movs r1, #8 + 8007936: a821 add r0, sp, #132 ; 0x84 + uint8_t PGDV = page_num | 0x80; + 8007938: f88d 3002 strb.w r3, [sp, #2] + rng_buffer(&chal_check[32], 8); + 800793c: f7fa ffce bl 80028dc + hmac_sha256_init(&ctx); + 8007940: a823 add r0, sp, #140 ; 0x8c + 8007942: f7fd ffa3 bl 800588c + hmac_sha256_update(&ctx, &chal_check[32], 8); + 8007946: 2208 movs r2, #8 + 8007948: a921 add r1, sp, #132 ; 0x84 + 800794a: a823 add r0, sp, #140 ; 0x8c + 800794c: f7fd ffa4 bl 8005898 + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 8007950: 4b3f ldr r3, [pc, #252] ; (8007a50 ) + 8007952: 4940 ldr r1, [pc, #256] ; (8007a54 ) + 8007954: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 8007958: 33b0 adds r3, #176 ; 0xb0 + 800795a: 2aff cmp r2, #255 ; 0xff + 800795c: bf18 it ne + 800795e: 4619 movne r1, r3 + 8007960: 3160 adds r1, #96 ; 0x60 + 8007962: 2208 movs r2, #8 + 8007964: a823 add r0, sp, #140 ; 0x8c + 8007966: f7fd ff97 bl 8005898 + hmac_sha256_update(&ctx, &PGDV, 1); + 800796a: 2201 movs r2, #1 + 800796c: f10d 0102 add.w r1, sp, #2 + 8007970: a823 add r0, sp, #140 ; 0x8c + 8007972: f7fd ff91 bl 8005898 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 8007976: 4938 ldr r1, [pc, #224] ; (8007a58 ) + 8007978: 2202 movs r2, #2 + 800797a: a823 add r0, sp, #140 ; 0x8c + 800797c: f7fd ff8c bl 8005898 + ASSERT(ctx.num_pending == 19); + 8007980: 9b63 ldr r3, [sp, #396] ; 0x18c + 8007982: 2b13 cmp r3, #19 + 8007984: d1ce bne.n 8007924 + hmac_sha256_final(&ctx, secret, otp); + 8007986: aa09 add r2, sp, #36 ; 0x24 + 8007988: 4641 mov r1, r8 + 800798a: a823 add r0, sp, #140 ; 0x8c + 800798c: f7fd ff9a bl 80058c4 + memcpy(tmp, data, 32); + 8007990: 4635 mov r5, r6 + 8007992: aa11 add r2, sp, #68 ; 0x44 + 8007994: f106 0c20 add.w ip, r6, #32 + 8007998: 6828 ldr r0, [r5, #0] + 800799a: 6869 ldr r1, [r5, #4] + 800799c: 4613 mov r3, r2 + 800799e: c303 stmia r3!, {r0, r1} + 80079a0: 3508 adds r5, #8 + 80079a2: 4565 cmp r5, ip + 80079a4: 461a mov r2, r3 + 80079a6: d1f7 bne.n 8007998 + xor_mixin(tmp, otp, 32); + 80079a8: 2220 movs r2, #32 + 80079aa: a909 add r1, sp, #36 ; 0x24 + 80079ac: a811 add r0, sp, #68 ; 0x44 + 80079ae: f7ff fd99 bl 80074e4 + hmac_sha256_init(&ctx); + 80079b2: a823 add r0, sp, #140 ; 0x8c + 80079b4: f7fd ff6a bl 800588c + hmac_sha256_update(&ctx, SE2_SECRETS->romid, 8); + 80079b8: 4b25 ldr r3, [pc, #148] ; (8007a50 ) + 80079ba: 4926 ldr r1, [pc, #152] ; (8007a54 ) + 80079bc: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80079c0: 33b0 adds r3, #176 ; 0xb0 + 80079c2: 2aff cmp r2, #255 ; 0xff + 80079c4: bf18 it ne + 80079c6: 4619 movne r1, r3 + 80079c8: 3160 adds r1, #96 ; 0x60 + 80079ca: 2208 movs r2, #8 + 80079cc: a823 add r0, sp, #140 ; 0x8c + 80079ce: f7fd ff63 bl 8005898 + hmac_sha256_update(&ctx, old_data, 32); + 80079d2: 2220 movs r2, #32 + 80079d4: a901 add r1, sp, #4 + 80079d6: a823 add r0, sp, #140 ; 0x8c + 80079d8: f7fd ff5e bl 8005898 + hmac_sha256_update(&ctx, data, 32); + 80079dc: 2220 movs r2, #32 + 80079de: 4631 mov r1, r6 + 80079e0: a823 add r0, sp, #140 ; 0x8c + 80079e2: f7fd ff59 bl 8005898 + hmac_sha256_update(&ctx, &PGDV, 1); + 80079e6: 2201 movs r2, #1 + 80079e8: f10d 0102 add.w r1, sp, #2 + 80079ec: a823 add r0, sp, #140 ; 0x8c + 80079ee: f7fd ff53 bl 8005898 + hmac_sha256_update(&ctx, DEV_MANID, 2); + 80079f2: 4919 ldr r1, [pc, #100] ; (8007a58 ) + 80079f4: 2202 movs r2, #2 + 80079f6: a823 add r0, sp, #140 ; 0x8c + 80079f8: f7fd ff4e bl 8005898 + ASSERT(ctx.num_pending == 75); + 80079fc: 9b63 ldr r3, [sp, #396] ; 0x18c + 80079fe: 2b4b cmp r3, #75 ; 0x4b + 8007a00: d190 bne.n 8007924 + hmac_sha256_final(&ctx, secret, chal_check); + 8007a02: aa19 add r2, sp, #100 ; 0x64 + 8007a04: 4641 mov r1, r8 + 8007a06: a823 add r0, sp, #140 ; 0x8c + 8007a08: f7fd ff5c bl 80058c4 + se2_write_buffer(chal_check, sizeof(chal_check)); + 8007a0c: 2128 movs r1, #40 ; 0x28 + 8007a0e: a819 add r0, sp, #100 ; 0x64 + 8007a10: f7ff fde4 bl 80075dc + uint8_t pn = (keynum << 6) | page_num; + 8007a14: ea44 1487 orr.w r4, r4, r7, lsl #6 + CALL_CHECK(se2_write_n(0x99, &pn, tmp, 32)); + 8007a18: 2320 movs r3, #32 + 8007a1a: aa11 add r2, sp, #68 ; 0x44 + 8007a1c: f10d 0103 add.w r1, sp, #3 + 8007a20: 2099 movs r0, #153 ; 0x99 + uint8_t pn = (keynum << 6) | page_num; + 8007a22: f88d 4003 strb.w r4, [sp, #3] + CALL_CHECK(se2_write_n(0x99, &pn, tmp, 32)); + 8007a26: f7ff fda1 bl 800756c + 8007a2a: b120 cbz r0, 8007a36 + 8007a2c: f44f 71aa mov.w r1, #340 ; 0x154 + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007a30: 480a ldr r0, [pc, #40] ; (8007a5c ) + 8007a32: f005 ff85 bl 800d940 + 8007a36: f7ff fe09 bl 800764c + 8007a3a: 28aa cmp r0, #170 ; 0xaa + 8007a3c: d002 beq.n 8007a44 + 8007a3e: f44f 71ab mov.w r1, #342 ; 0x156 + 8007a42: e7f5 b.n 8007a30 +} + 8007a44: b064 add sp, #400 ; 0x190 + 8007a46: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + 8007a4a: bf00 nop + 8007a4c: 0801046c .word 0x0801046c + 8007a50: 0801c000 .word 0x0801c000 + 8007a54: 2009e2b4 .word 0x2009e2b4 + 8007a58: 08010ac0 .word 0x08010ac0 + 8007a5c: 2009e394 .word 0x2009e394 + +08007a60 : +{ + 8007a60: b508 push {r3, lr} + 8007a62: 4601 mov r1, r0 + CALL_CHECK(se2_write1(0xaa, page_num)); + 8007a64: 20aa movs r0, #170 ; 0xaa + 8007a66: f7ff fd4b bl 8007500 + 8007a6a: b120 cbz r0, 8007a76 + 8007a6c: 4804 ldr r0, [pc, #16] ; (8007a80 ) + 8007a6e: f240 118b movw r1, #395 ; 0x18b + 8007a72: f005 ff65 bl 800d940 +} + 8007a76: e8bd 4008 ldmia.w sp!, {r3, lr} + return se2_read1(); + 8007a7a: f7ff bde7 b.w 800764c + 8007a7e: bf00 nop + 8007a80: 2009e394 .word 0x2009e394 + +08007a84 : +{ + 8007a84: b538 push {r3, r4, r5, lr} + 8007a86: 460c mov r4, r1 + 8007a88: 4605 mov r5, r0 + if(se2_get_protection(page_num) == flags) { + 8007a8a: f7ff ffe9 bl 8007a60 + 8007a8e: 42a0 cmp r0, r4 + 8007a90: d011 beq.n 8007ab6 + CALL_CHECK(se2_write2(0xc3, page_num, flags)); + 8007a92: 4622 mov r2, r4 + 8007a94: 4629 mov r1, r5 + 8007a96: 20c3 movs r0, #195 ; 0xc3 + 8007a98: f7ff fd4c bl 8007534 + 8007a9c: b120 cbz r0, 8007aa8 + 8007a9e: f240 119b movw r1, #411 ; 0x19b + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007aa2: 4805 ldr r0, [pc, #20] ; (8007ab8 ) + 8007aa4: f005 ff4c bl 800d940 + 8007aa8: f7ff fdd0 bl 800764c + 8007aac: 28aa cmp r0, #170 ; 0xaa + 8007aae: d002 beq.n 8007ab6 + 8007ab0: f240 119d movw r1, #413 ; 0x19d + 8007ab4: e7f5 b.n 8007aa2 +} + 8007ab6: bd38 pop {r3, r4, r5, pc} + 8007ab8: 2009e394 .word 0x2009e394 + +08007abc : +{ + 8007abc: b500 push {lr} + if(setjmp(error_env)) { + 8007abe: 4812 ldr r0, [pc, #72] ; (8007b08 ) +{ + 8007ac0: b089 sub sp, #36 ; 0x24 + if(setjmp(error_env)) { + 8007ac2: f005 ff37 bl 800d934 + 8007ac6: b120 cbz r0, 8007ad2 + oled_show(screen_se2_issue); + 8007ac8: 4810 ldr r0, [pc, #64] ; (8007b0c ) + 8007aca: f7f9 fad3 bl 8001074 + LOCKUP_FOREVER(); + 8007ace: f7fc f8d3 bl 8003c78 + rng_delay(); + 8007ad2: f7fa ff19 bl 8002908 + if(rom_secrets->se2.pairing[0] == 0xff) { + 8007ad6: 4b0e ldr r3, [pc, #56] ; (8007b10 ) + 8007ad8: f893 30b0 ldrb.w r3, [r3, #176] ; 0xb0 + 8007adc: 2bff cmp r3, #255 ; 0xff + 8007ade: d00f beq.n 8007b00 + se2_read_page(PGN_ROM_OPTIONS, tmp, true); + 8007ae0: 2201 movs r2, #1 + 8007ae2: 4669 mov r1, sp + 8007ae4: 201c movs r0, #28 + 8007ae6: f7ff fe4d bl 8007784 + CHECK_RIGHT(check_equal(&tmp[24], rom_secrets->se2.romid, 8)); + 8007aea: 490a ldr r1, [pc, #40] ; (8007b14 ) + 8007aec: 2208 movs r2, #8 + 8007aee: a806 add r0, sp, #24 + 8007af0: f7fa fea5 bl 800283e + 8007af4: b920 cbnz r0, 8007b00 + 8007af6: 4804 ldr r0, [pc, #16] ; (8007b08 ) + 8007af8: f240 11b5 movw r1, #437 ; 0x1b5 + 8007afc: f005 ff20 bl 800d940 +} + 8007b00: b009 add sp, #36 ; 0x24 + 8007b02: f85d fb04 ldr.w pc, [sp], #4 + 8007b06: bf00 nop + 8007b08: 2009e394 .word 0x2009e394 + 8007b0c: 0800f3d7 .word 0x0800f3d7 + 8007b10: 0801c000 .word 0x0801c000 + 8007b14: 0801c110 .word 0x0801c110 + +08007b18 : +{ + 8007b18: b510 push {r4, lr} + if(setjmp(error_env)) fatal_mitm(); + 8007b1a: 4817 ldr r0, [pc, #92] ; (8007b78 ) +{ + 8007b1c: b088 sub sp, #32 + if(setjmp(error_env)) fatal_mitm(); + 8007b1e: f005 ff09 bl 800d934 + 8007b22: 4604 mov r4, r0 + 8007b24: b108 cbz r0, 8007b2a + 8007b26: f7f8 ff91 bl 8000a4c + uint8_t z32[32] = {0}; + 8007b2a: 221c movs r2, #28 + 8007b2c: 4601 mov r1, r0 + 8007b2e: 9000 str r0, [sp, #0] + 8007b30: a801 add r0, sp, #4 + 8007b32: f005 fef7 bl 800d924 + se2_write_page(PGN_PUBKEY_S+0, z32); + 8007b36: 4669 mov r1, sp + 8007b38: 201e movs r0, #30 + 8007b3a: f7ff fd8f bl 800765c + se2_write_page(PGN_PUBKEY_S+1, z32); + 8007b3e: 4669 mov r1, sp + 8007b40: 201f movs r0, #31 + 8007b42: f7ff fd8b bl 800765c + se2_write_buffer(z32, 32); + 8007b46: 2120 movs r1, #32 + 8007b48: 4668 mov r0, sp + 8007b4a: f7ff fd47 bl 80075dc + CALL_CHECK(se2_write2(0x3c, (2<<6), 0)); + 8007b4e: 4622 mov r2, r4 + 8007b50: 2180 movs r1, #128 ; 0x80 + 8007b52: 203c movs r0, #60 ; 0x3c + 8007b54: f7ff fcee bl 8007534 + 8007b58: b120 cbz r0, 8007b64 + 8007b5a: f240 11cd movw r1, #461 ; 0x1cd + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007b5e: 4806 ldr r0, [pc, #24] ; (8007b78 ) + 8007b60: f005 feee bl 800d940 + 8007b64: f7ff fd72 bl 800764c + 8007b68: 28aa cmp r0, #170 ; 0xaa + 8007b6a: d002 beq.n 8007b72 + 8007b6c: f44f 71e7 mov.w r1, #462 ; 0x1ce + 8007b70: e7f5 b.n 8007b5e +} + 8007b72: b008 add sp, #32 + 8007b74: bd10 pop {r4, pc} + 8007b76: bf00 nop + 8007b78: 2009e394 .word 0x2009e394 + +08007b7c : +{ + 8007b7c: b570 push {r4, r5, r6, lr} + if((setjmp(error_env))) { + 8007b7e: 485b ldr r0, [pc, #364] ; (8007cec ) +{ + 8007b80: b090 sub sp, #64 ; 0x40 + if((setjmp(error_env))) { + 8007b82: f005 fed7 bl 800d934 + 8007b86: 4604 mov r4, r0 + 8007b88: b120 cbz r0, 8007b94 + oled_show(screen_se2_issue); + 8007b8a: 4859 ldr r0, [pc, #356] ; (8007cf0 ) + 8007b8c: f7f9 fa72 bl 8001074 + LOCKUP_FOREVER(); + 8007b90: f7fc f872 bl 8003c78 + if(rom_secrets->se2.pairing[0] != 0xff) { + 8007b94: 4b57 ldr r3, [pc, #348] ; (8007cf4 ) + 8007b96: f893 10b0 ldrb.w r1, [r3, #176] ; 0xb0 + 8007b9a: 29ff cmp r1, #255 ; 0xff + 8007b9c: f040 80a0 bne.w 8007ce0 + memset(&_tbd, 0xff, sizeof(_tbd)); + 8007ba0: 4d55 ldr r5, [pc, #340] ; (8007cf8 ) + 8007ba2: 22e0 movs r2, #224 ; 0xe0 + 8007ba4: 4628 mov r0, r5 + 8007ba6: f005 febd bl 800d924 + rng_buffer(_tbd.tpin_key, 32); + 8007baa: 2120 movs r1, #32 + 8007bac: f105 0080 add.w r0, r5, #128 ; 0x80 + 8007bb0: f7fa fe94 bl 80028dc + se2_read_page(PGN_ROM_OPTIONS, tmp, false); + 8007bb4: 4622 mov r2, r4 + 8007bb6: 4669 mov r1, sp + 8007bb8: 201c movs r0, #28 + 8007bba: f7ff fde3 bl 8007784 + ASSERT(tmp[1] == 0x00); // check ANON is not set + 8007bbe: f89d 3001 ldrb.w r3, [sp, #1] + 8007bc2: b113 cbz r3, 8007bca + 8007bc4: 484d ldr r0, [pc, #308] ; (8007cfc ) + 8007bc6: f7f8 ff37 bl 8000a38 + memcpy(_tbd.romid, tmp+24, 8); + 8007bca: ab06 add r3, sp, #24 + 8007bcc: cb03 ldmia r3!, {r0, r1} + 8007bce: 6628 str r0, [r5, #96] ; 0x60 + 8007bd0: 6669 str r1, [r5, #100] ; 0x64 + rng_buffer(tmp, 32); + 8007bd2: 4668 mov r0, sp + 8007bd4: 2120 movs r1, #32 + 8007bd6: f7fa fe81 bl 80028dc + se2_write_page(PGN_SECRET_B, tmp); + 8007bda: 4669 mov r1, sp + 8007bdc: 201a movs r0, #26 + 8007bde: f7ff fd3d bl 800765c + se2_pick_keypair(0, true); + 8007be2: 2101 movs r1, #1 + 8007be4: 4620 mov r0, r4 + 8007be6: f7ff fd53 bl 8007690 + se2_read_page(PGN_PUBKEY_A, &_tbd.pubkey_A[0], false); + 8007bea: 4622 mov r2, r4 + 8007bec: f105 0120 add.w r1, r5, #32 + 8007bf0: 2010 movs r0, #16 + 8007bf2: f7ff fdc7 bl 8007784 + memset(tmp, 0, 32); + 8007bf6: 2620 movs r6, #32 + se2_read_page(PGN_PUBKEY_A+1, &_tbd.pubkey_A[32], false); + 8007bf8: 4622 mov r2, r4 + 8007bfa: f105 0140 add.w r1, r5, #64 ; 0x40 + 8007bfe: 2011 movs r0, #17 + 8007c00: f7ff fdc0 bl 8007784 + memset(tmp, 0, 32); + 8007c04: 4632 mov r2, r6 + 8007c06: 4621 mov r1, r4 + 8007c08: 4668 mov r0, sp + 8007c0a: f005 fe8b bl 800d924 + se2_write_page(PGN_PRIVKEY_B, tmp); + 8007c0e: 4669 mov r1, sp + 8007c10: 2017 movs r0, #23 + 8007c12: f7ff fd23 bl 800765c + se2_write_page(PGN_PRIVKEY_B+1, tmp); + 8007c16: 4669 mov r1, sp + 8007c18: 2018 movs r0, #24 + 8007c1a: f7ff fd1f bl 800765c + se2_write_page(PGN_PUBKEY_B, tmp); + 8007c1e: 4669 mov r1, sp + 8007c20: 2012 movs r0, #18 + 8007c22: f7ff fd1b bl 800765c + se2_write_page(PGN_PUBKEY_B+1, tmp); + 8007c26: 4669 mov r1, sp + 8007c28: 2013 movs r0, #19 + 8007c2a: f7ff fd17 bl 800765c + rng_buffer(_tbd.pairing, 32); + 8007c2e: 4631 mov r1, r6 + 8007c30: 4628 mov r0, r5 + 8007c32: f7fa fe53 bl 80028dc + } while(_tbd.pairing[0] == 0xff); + 8007c36: 782b ldrb r3, [r5, #0] + 8007c38: 2bff cmp r3, #255 ; 0xff + 8007c3a: d0f8 beq.n 8007c2e + se2_write_page(PGN_SECRET_A, _tbd.pairing); + 8007c3c: 4629 mov r1, r5 + 8007c3e: 2019 movs r0, #25 + rng_buffer(tmp, 32); + 8007c40: 466d mov r5, sp + se2_write_page(PGN_SECRET_A, _tbd.pairing); + 8007c42: f7ff fd0b bl 800765c + rng_buffer(tmp, 32); + 8007c46: 2120 movs r1, #32 + 8007c48: 4628 mov r0, r5 + 8007c4a: f7fa fe47 bl 80028dc + se2_write_page(PGN_SE2_EASY_KEY, tmp); + 8007c4e: 4629 mov r1, r5 + 8007c50: 200e movs r0, #14 + 8007c52: f7ff fd03 bl 800765c + memset(tmp, 0, 32); + 8007c56: 2220 movs r2, #32 + 8007c58: 2100 movs r1, #0 + 8007c5a: 4628 mov r0, r5 + 8007c5c: f005 fe62 bl 800d924 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007c60: 4626 mov r6, r4 + se2_write_page(pn, tmp); + 8007c62: b2f0 uxtb r0, r6 + 8007c64: 4629 mov r1, r5 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007c66: 3601 adds r6, #1 + se2_write_page(pn, tmp); + 8007c68: f7ff fcf8 bl 800765c + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007c6c: 2e0e cmp r6, #14 + 8007c6e: d1f8 bne.n 8007c62 + flash_save_se2_data(&_tbd); + 8007c70: 4821 ldr r0, [pc, #132] ; (8007cf8 ) + 8007c72: f7fa fb43 bl 80022fc + se2_set_protection(PGN_SECRET_A, PROT_WP); + 8007c76: 2102 movs r1, #2 + 8007c78: 2019 movs r0, #25 + 8007c7a: f7ff ff03 bl 8007a84 + se2_set_protection(PGN_SECRET_B, PROT_WP); + 8007c7e: 2102 movs r1, #2 + 8007c80: 201a movs r0, #26 + 8007c82: f7ff feff bl 8007a84 + se2_set_protection(PGN_PUBKEY_A, PROT_WP); + 8007c86: 2102 movs r1, #2 + 8007c88: 2010 movs r0, #16 + 8007c8a: f7ff fefb bl 8007a84 + se2_set_protection(PGN_PUBKEY_B, PROT_WP); + 8007c8e: 2102 movs r1, #2 + 8007c90: 2012 movs r0, #18 + 8007c92: f7ff fef7 bl 8007a84 + se2_set_protection(PGN_SE2_EASY_KEY, PROT_EPH); + 8007c96: 2110 movs r1, #16 + 8007c98: 4630 mov r0, r6 + 8007c9a: f7ff fef3 bl 8007a84 + se2_set_protection(pn, PROT_EPH); + 8007c9e: 2510 movs r5, #16 + 8007ca0: b2e0 uxtb r0, r4 + 8007ca2: 4629 mov r1, r5 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007ca4: 3401 adds r4, #1 + se2_set_protection(pn, PROT_EPH); + 8007ca6: f7ff feed bl 8007a84 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8007caa: 2c0e cmp r4, #14 + 8007cac: d1f8 bne.n 8007ca0 + se2_set_protection(PGN_ROM_OPTIONS, PROT_APH); // not planning to change + 8007cae: 2108 movs r1, #8 + 8007cb0: 201c movs r0, #28 + 8007cb2: f7ff fee7 bl 8007a84 + se2_read_page(PGN_DEC_COUNTER, tmp, false); + 8007cb6: 2200 movs r2, #0 + 8007cb8: a908 add r1, sp, #32 + 8007cba: 201b movs r0, #27 + 8007cbc: f7ff fd62 bl 8007784 + if(tmp[2] == 0xff) { + 8007cc0: f89d 3022 ldrb.w r3, [sp, #34] ; 0x22 + 8007cc4: 2bff cmp r3, #255 ; 0xff + 8007cc6: d10d bne.n 8007ce4 + tmp[0] = val & 0x0ff; + 8007cc8: 2380 movs r3, #128 ; 0x80 + 8007cca: f88d 3020 strb.w r3, [sp, #32] + se2_write_page(PGN_DEC_COUNTER, tmp); + 8007cce: a908 add r1, sp, #32 + tmp[1] = (val >> 8) & 0x0ff; + 8007cd0: 2300 movs r3, #0 + se2_write_page(PGN_DEC_COUNTER, tmp); + 8007cd2: 201b movs r0, #27 + tmp[1] = (val >> 8) & 0x0ff; + 8007cd4: f88d 3021 strb.w r3, [sp, #33] ; 0x21 + tmp[2] = (val >> 16) & 0x01; + 8007cd8: f88d 3022 strb.w r3, [sp, #34] ; 0x22 + se2_write_page(PGN_DEC_COUNTER, tmp); + 8007cdc: f7ff fcbe bl 800765c +} + 8007ce0: b010 add sp, #64 ; 0x40 + 8007ce2: bd70 pop {r4, r5, r6, pc} + puts("ctr set?"); // not expected, but keep going + 8007ce4: 4806 ldr r0, [pc, #24] ; (8007d00 ) + 8007ce6: f7fd f9bf bl 8005068 + 8007cea: e7f9 b.n 8007ce0 + 8007cec: 2009e394 .word 0x2009e394 + 8007cf0: 0800f3d7 .word 0x0800f3d7 + 8007cf4: 0801c000 .word 0x0801c000 + 8007cf8: 2009e2b4 .word 0x2009e2b4 + 8007cfc: 0801046c .word 0x0801046c + 8007d00: 08010aa0 .word 0x08010aa0 + +08007d04 : +{ + 8007d04: b510 push {r4, lr} + 8007d06: b08a sub sp, #40 ; 0x28 + 8007d08: 9001 str r0, [sp, #4] + if(setjmp(error_env)) fatal_mitm(); + 8007d0a: 481e ldr r0, [pc, #120] ; (8007d84 ) + 8007d0c: f005 fe12 bl 800d934 + 8007d10: b108 cbz r0, 8007d16 + 8007d12: f7f8 fe9b bl 8000a4c + ASSERT(check_all_ones(rom_secrets->se2.auth_pubkey, 64)); + 8007d16: 481c ldr r0, [pc, #112] ; (8007d88 ) + 8007d18: 2140 movs r1, #64 ; 0x40 + 8007d1a: f7fa fd77 bl 800280c + 8007d1e: b910 cbnz r0, 8007d26 + 8007d20: 481a ldr r0, [pc, #104] ; (8007d8c ) + 8007d22: f7f8 fe89 bl 8000a38 + memcpy(&_tbd, &rom_secrets->se2, sizeof(_tbd)); + 8007d26: 4c1a ldr r4, [pc, #104] ; (8007d90 ) + 8007d28: 491a ldr r1, [pc, #104] ; (8007d94 ) + 8007d2a: 22e0 movs r2, #224 ; 0xe0 + 8007d2c: 4620 mov r0, r4 + 8007d2e: f005 fdeb bl 800d908 + rng_buffer(tmp, 32); + 8007d32: 2120 movs r1, #32 + 8007d34: a802 add r0, sp, #8 + 8007d36: f7fa fdd1 bl 80028dc + se2_write_page(PGN_SE2_HARD_KEY, tmp); + 8007d3a: a902 add r1, sp, #8 + 8007d3c: 200f movs r0, #15 + 8007d3e: f7ff fc8d bl 800765c + se2_write_page(PGN_PUBKEY_C, &pubkey[0]); + 8007d42: 9901 ldr r1, [sp, #4] + 8007d44: 2014 movs r0, #20 + 8007d46: f7ff fc89 bl 800765c + se2_write_page(PGN_PUBKEY_C+1, &pubkey[32]); + 8007d4a: 9b01 ldr r3, [sp, #4] + 8007d4c: 2015 movs r0, #21 + 8007d4e: f103 0120 add.w r1, r3, #32 + 8007d52: f7ff fc83 bl 800765c + memcpy(_tbd.auth_pubkey, pubkey, 64); + 8007d56: 9b01 ldr r3, [sp, #4] + 8007d58: 34a0 adds r4, #160 ; 0xa0 + 8007d5a: f103 0240 add.w r2, r3, #64 ; 0x40 + 8007d5e: f853 1b04 ldr.w r1, [r3], #4 + 8007d62: f844 1b04 str.w r1, [r4], #4 + 8007d66: 4293 cmp r3, r2 + 8007d68: d1f9 bne.n 8007d5e + flash_save_se2_data(&_tbd); + 8007d6a: 4809 ldr r0, [pc, #36] ; (8007d90 ) + 8007d6c: f7fa fac6 bl 80022fc + se2_set_protection(PGN_SE2_HARD_KEY, PROT_WP | PROT_ECH | PROT_ECW); + 8007d70: 21c2 movs r1, #194 ; 0xc2 + 8007d72: 200f movs r0, #15 + 8007d74: f7ff fe86 bl 8007a84 + se2_set_protection(PGN_PUBKEY_C, PROT_WP | PROT_RP | PROT_AUTH); + 8007d78: 2123 movs r1, #35 ; 0x23 + 8007d7a: 2014 movs r0, #20 + 8007d7c: f7ff fe82 bl 8007a84 +} + 8007d80: b00a add sp, #40 ; 0x28 + 8007d82: bd10 pop {r4, pc} + 8007d84: 2009e394 .word 0x2009e394 + 8007d88: 0801c150 .word 0x0801c150 + 8007d8c: 0801046c .word 0x0801046c + 8007d90: 2009e2b4 .word 0x2009e2b4 + 8007d94: 0801c0b0 .word 0x0801c0b0 + +08007d98 : +{ + 8007d98: b530 push {r4, r5, lr} + 8007d9a: 4614 mov r4, r2 + ASSERT(pin_len >= 0); // 12-12 typical, but empty = blank PIN + 8007d9c: 1e0a subs r2, r1, #0 +{ + 8007d9e: b0c5 sub sp, #276 ; 0x114 + 8007da0: 4605 mov r5, r0 + ASSERT(pin_len >= 0); // 12-12 typical, but empty = blank PIN + 8007da2: da02 bge.n 8007daa + 8007da4: 4812 ldr r0, [pc, #72] ; (8007df0 ) + 8007da6: f7f8 fe47 bl 8000a38 + hmac_sha256_init(&ctx); + 8007daa: a803 add r0, sp, #12 + 8007dac: 9201 str r2, [sp, #4] + 8007dae: f7fd fd6d bl 800588c + hmac_sha256_update(&ctx, (uint8_t *)pin, pin_len); + 8007db2: 9a01 ldr r2, [sp, #4] + 8007db4: 4629 mov r1, r5 + 8007db6: a803 add r0, sp, #12 + 8007db8: f7fd fd6e bl 8005898 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, tpin_hash); + 8007dbc: 4b0d ldr r3, [pc, #52] ; (8007df4 ) + 8007dbe: 490e ldr r1, [pc, #56] ; (8007df8 ) + 8007dc0: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 8007dc4: 33b0 adds r3, #176 ; 0xb0 + 8007dc6: 2aff cmp r2, #255 ; 0xff + 8007dc8: bf18 it ne + 8007dca: 4619 movne r1, r3 + 8007dcc: a803 add r0, sp, #12 + 8007dce: 4622 mov r2, r4 + 8007dd0: 3180 adds r1, #128 ; 0x80 + 8007dd2: f7fd fd77 bl 80058c4 + sha256_single(tpin_hash, 32, tpin_hash); + 8007dd6: 4622 mov r2, r4 + 8007dd8: 4620 mov r0, r4 + 8007dda: 2120 movs r1, #32 + 8007ddc: f7fd fd36 bl 800584c + sha256_single(tpin_hash, 32, tpin_hash); + 8007de0: 4622 mov r2, r4 + 8007de2: 2120 movs r1, #32 + 8007de4: 4620 mov r0, r4 + 8007de6: f7fd fd31 bl 800584c +} + 8007dea: b045 add sp, #276 ; 0x114 + 8007dec: bd30 pop {r4, r5, pc} + 8007dee: bf00 nop + 8007df0: 0801046c .word 0x0801046c + 8007df4: 0801c000 .word 0x0801c000 + 8007df8: 2009e2b4 .word 0x2009e2b4 + +08007dfc : + +// p256_gen_keypair() +// + void +p256_gen_keypair(uint8_t privkey[32], uint8_t pubkey[64]) +{ + 8007dfc: b538 push {r3, r4, r5, lr} + 8007dfe: 4605 mov r5, r0 + uECC_set_rng(rng_for_uECC); + 8007e00: 4808 ldr r0, [pc, #32] ; (8007e24 ) +{ + 8007e02: 460c mov r4, r1 + uECC_set_rng(rng_for_uECC); + 8007e04: f7fe fedc bl 8006bc0 + + int ok = uECC_make_key(pubkey, privkey, uECC_secp256r1()); + 8007e08: f7fe fee0 bl 8006bcc + 8007e0c: 4629 mov r1, r5 + 8007e0e: 4602 mov r2, r0 + 8007e10: 4620 mov r0, r4 + 8007e12: f7fe fee3 bl 8006bdc + ASSERT(ok == 1); + 8007e16: 2801 cmp r0, #1 + 8007e18: d002 beq.n 8007e20 + 8007e1a: 4803 ldr r0, [pc, #12] ; (8007e28 ) + 8007e1c: f7f8 fe0c bl 8000a38 +} + 8007e20: bd38 pop {r3, r4, r5, pc} + 8007e22: bf00 nop + 8007e24: 080075d1 .word 0x080075d1 + 8007e28: 0801046c .word 0x0801046c + +08007e2c : + +// ps256_ecdh() +// + void +ps256_ecdh(const uint8_t pubkey[64], const uint8_t privkey[32], uint8_t result[32]) +{ + 8007e2c: b513 push {r0, r1, r4, lr} + 8007e2e: 4604 mov r4, r0 + uECC_set_rng(rng_for_uECC); + 8007e30: 4809 ldr r0, [pc, #36] ; (8007e58 ) +{ + 8007e32: e9cd 2100 strd r2, r1, [sp] + uECC_set_rng(rng_for_uECC); + 8007e36: f7fe fec3 bl 8006bc0 + + int ok = uECC_shared_secret(pubkey, privkey, result, uECC_secp256r1()); + 8007e3a: f7fe fec7 bl 8006bcc + 8007e3e: e9dd 2100 ldrd r2, r1, [sp] + 8007e42: 4603 mov r3, r0 + 8007e44: 4620 mov r0, r4 + 8007e46: f7fe ff09 bl 8006c5c + ASSERT(ok == 1); + 8007e4a: 2801 cmp r0, #1 + 8007e4c: d002 beq.n 8007e54 + 8007e4e: 4803 ldr r0, [pc, #12] ; (8007e5c ) + 8007e50: f7f8 fdf2 bl 8000a38 +} + 8007e54: b002 add sp, #8 + 8007e56: bd10 pop {r4, pc} + 8007e58: 080075d1 .word 0x080075d1 + 8007e5c: 0801046c .word 0x0801046c + +08007e60 : + +// se2_read_hard_secret() +// + static bool +se2_read_hard_secret(uint8_t hard_key[32], const uint8_t pin_digest[32]) +{ + 8007e60: b510 push {r4, lr} + 8007e62: b0e8 sub sp, #416 ; 0x1a0 + 8007e64: e9cd 0102 strd r0, r1, [sp, #8] + if(setjmp(error_env)) { + 8007e68: 4836 ldr r0, [pc, #216] ; (8007f44 ) + 8007e6a: f005 fd63 bl 800d934 + 8007e6e: 2800 cmp r0, #0 + 8007e70: d165 bne.n 8007f3e + // + SHA256_CTX ctx; + + // pick a temp key pair, share public part w/ SE2 + uint8_t tmp_privkey[32], tmp_pubkey[64]; + p256_gen_keypair(tmp_privkey, tmp_pubkey); + 8007e72: a925 add r1, sp, #148 ; 0x94 + 8007e74: a805 add r0, sp, #20 + 8007e76: f7ff ffc1 bl 8007dfc + + // - this can be mitm-ed, but we sign it next so doesn't matter + se2_write_page(PGN_PUBKEY_S, &tmp_pubkey[0]); + 8007e7a: a925 add r1, sp, #148 ; 0x94 + 8007e7c: 201e movs r0, #30 + 8007e7e: f7ff fbed bl 800765c + se2_write_page(PGN_PUBKEY_S+1, &tmp_pubkey[32]); + 8007e82: a92d add r1, sp, #180 ; 0xb4 + 8007e84: 201f movs r0, #31 + 8007e86: f7ff fbe9 bl 800765c + + // pick nonce + uint8_t chal[32+32]; + rng_buffer(chal, sizeof(chal)); + 8007e8a: 2140 movs r1, #64 ; 0x40 + 8007e8c: a835 add r0, sp, #212 ; 0xd4 + 8007e8e: f7fa fd25 bl 80028dc + se2_write_buffer(chal, sizeof(chal)); + 8007e92: 2140 movs r1, #64 ; 0x40 + 8007e94: a835 add r0, sp, #212 ; 0xd4 + 8007e96: f7ff fba1 bl 80075dc + + // md = ngu.hash.sha256s(T_pubkey + chal[0:32]) + sha256_init(&ctx); + 8007e9a: a855 add r0, sp, #340 ; 0x154 + 8007e9c: f7fd fc6e bl 800577c + sha256_update(&ctx, tmp_pubkey, 64); + 8007ea0: 2240 movs r2, #64 ; 0x40 + 8007ea2: a925 add r1, sp, #148 ; 0x94 + 8007ea4: a855 add r0, sp, #340 ; 0x154 + 8007ea6: f7fd fc77 bl 8005798 + sha256_update(&ctx, chal, 32); // only first 32 bytes + 8007eaa: 2220 movs r2, #32 + 8007eac: a935 add r1, sp, #212 ; 0xd4 + 8007eae: a855 add r0, sp, #340 ; 0x154 + 8007eb0: f7fd fc72 bl 8005798 + + uint8_t md[32]; + sha256_final(&ctx, md); + 8007eb4: a90d add r1, sp, #52 ; 0x34 + 8007eb6: a855 add r0, sp, #340 ; 0x154 + 8007eb8: f7fd fcb4 bl 8005824 + // Get that digest signed by SE1 now, and doing that requires + // the main pin, because the required slot requires auth by that key. + // - this is the critical step attackers would not be able to emulate w/o SE1 contents + // - fails here if PIN wrong + uint8_t signature[64]; + int arc = ae_sign_authed(KEYNUM_joiner_key, md, signature, KEYNUM_main_pin, pin_digest); + 8007ebc: 9b03 ldr r3, [sp, #12] + 8007ebe: 9300 str r3, [sp, #0] + 8007ec0: aa45 add r2, sp, #276 ; 0x114 + 8007ec2: 2303 movs r3, #3 + 8007ec4: a90d add r1, sp, #52 ; 0x34 + 8007ec6: 2007 movs r0, #7 + 8007ec8: f7fb f83e bl 8002f48 + CHECK_RIGHT(arc == 0); + 8007ecc: 4604 mov r4, r0 + 8007ece: b120 cbz r0, 8007eda + 8007ed0: f240 4152 movw r1, #1106 ; 0x452 + + // "Authenticate ECDSA Public Key" = 0xA8 + // cs_offset=32 ecdh_keynum=0=pubA ECDH=1 WR=0 + uint8_t param = ((32-1) << 3) | (0 << 2) | 0x2; + se2_write_n(0xA8, ¶m, signature, 64); + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007ed4: 481b ldr r0, [pc, #108] ; (8007f44 ) + 8007ed6: f005 fd33 bl 800d940 + uint8_t param = ((32-1) << 3) | (0 << 2) | 0x2; + 8007eda: 23fa movs r3, #250 ; 0xfa + 8007edc: f88d 3013 strb.w r3, [sp, #19] + se2_write_n(0xA8, ¶m, signature, 64); + 8007ee0: aa45 add r2, sp, #276 ; 0x114 + 8007ee2: 2340 movs r3, #64 ; 0x40 + 8007ee4: f10d 0113 add.w r1, sp, #19 + 8007ee8: 20a8 movs r0, #168 ; 0xa8 + 8007eea: f7ff fb3f bl 800756c + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8007eee: f7ff fbad bl 800764c + 8007ef2: 28aa cmp r0, #170 ; 0xaa + 8007ef4: d002 beq.n 8007efc + 8007ef6: f44f 618b mov.w r1, #1112 ; 0x458 + 8007efa: e7eb b.n 8007ed4 + + uint8_t shared_x[32], shared_secret[32]; + ps256_ecdh(rom_secrets->se2.pubkey_A, tmp_privkey, shared_x); + 8007efc: aa15 add r2, sp, #84 ; 0x54 + 8007efe: a905 add r1, sp, #20 + 8007f00: 4811 ldr r0, [pc, #68] ; (8007f48 ) + 8007f02: f7ff ff93 bl 8007e2c + + // shared secret S will be SHA over X of shared ECDH point + chal[32:] + // s = ngu.hash.sha256s(x + chal[32:]) + sha256_init(&ctx); + 8007f06: a855 add r0, sp, #340 ; 0x154 + 8007f08: f7fd fc38 bl 800577c + sha256_update(&ctx, shared_x, 32); + 8007f0c: 2220 movs r2, #32 + 8007f0e: a915 add r1, sp, #84 ; 0x54 + 8007f10: a855 add r0, sp, #340 ; 0x154 + 8007f12: f7fd fc41 bl 8005798 + sha256_update(&ctx, &chal[32], 32); // second half + 8007f16: 2220 movs r2, #32 + 8007f18: a93d add r1, sp, #244 ; 0xf4 + 8007f1a: a855 add r0, sp, #340 ; 0x154 + 8007f1c: f7fd fc3c bl 8005798 + sha256_final(&ctx, shared_secret); + 8007f20: a91d add r1, sp, #116 ; 0x74 + 8007f22: a855 add r0, sp, #340 ; 0x154 + 8007f24: f7fd fc7e bl 8005824 + + se2_read_encrypted(PGN_SE2_HARD_KEY, hard_key, 2, shared_secret); + 8007f28: 200f movs r0, #15 + 8007f2a: 9902 ldr r1, [sp, #8] + 8007f2c: ab1d add r3, sp, #116 ; 0x74 + 8007f2e: 2202 movs r2, #2 + 8007f30: f7ff fc76 bl 8007820 + + // CONCERN: secret "S" is retained in SE2's sram. No API to clear it. + // - but you'd need to see our copy of that value to make use of it + // - and PIN checked already to get here, so you could re-do anyway + se2_clear_volatile(); + 8007f34: f7ff fdf0 bl 8007b18 + + return false; + 8007f38: 4620 mov r0, r4 +} + 8007f3a: b068 add sp, #416 ; 0x1a0 + 8007f3c: bd10 pop {r4, pc} + return true; + 8007f3e: 2001 movs r0, #1 + 8007f40: e7fb b.n 8007f3a + 8007f42: bf00 nop + 8007f44: 2009e394 .word 0x2009e394 + 8007f48: 0801c0d0 .word 0x0801c0d0 + +08007f4c : + +// se2_calc_seed_key() +// + static bool +se2_calc_seed_key(uint8_t aes_key[32], const mcu_key_t *mcu_key, const uint8_t pin_digest[32]) +{ + 8007f4c: b570 push {r4, r5, r6, lr} + 8007f4e: b0d2 sub sp, #328 ; 0x148 + 8007f50: 4614 mov r4, r2 + // Gather key parts from all over. Combine them w/ HMAC into a AES-256 key + uint8_t se1_easy_key[32], se1_hard_key[32]; + se2_read_encrypted(PGN_SE2_EASY_KEY, se1_easy_key, 0, rom_secrets->se2.pairing); + 8007f52: 4b15 ldr r3, [pc, #84] ; (8007fa8 ) + 8007f54: 2200 movs r2, #0 +{ + 8007f56: 4605 mov r5, r0 + 8007f58: 460e mov r6, r1 + se2_read_encrypted(PGN_SE2_EASY_KEY, se1_easy_key, 0, rom_secrets->se2.pairing); + 8007f5a: 200e movs r0, #14 + 8007f5c: a901 add r1, sp, #4 + 8007f5e: f7ff fc5f bl 8007820 + + if(se2_read_hard_secret(se1_hard_key, pin_digest)) return true; + 8007f62: 4621 mov r1, r4 + 8007f64: a809 add r0, sp, #36 ; 0x24 + 8007f66: f7ff ff7b bl 8007e60 + 8007f6a: 4604 mov r4, r0 + 8007f6c: b9c8 cbnz r0, 8007fa2 + + HMAC_CTX ctx; + hmac_sha256_init(&ctx); + 8007f6e: a811 add r0, sp, #68 ; 0x44 + 8007f70: f7fd fc8c bl 800588c + hmac_sha256_update(&ctx, mcu_key->value, 32); + 8007f74: 2220 movs r2, #32 + 8007f76: 4631 mov r1, r6 + 8007f78: a811 add r0, sp, #68 ; 0x44 + 8007f7a: f7fd fc8d bl 8005898 + hmac_sha256_update(&ctx, se1_hard_key, 32); + 8007f7e: 2220 movs r2, #32 + 8007f80: a909 add r1, sp, #36 ; 0x24 + 8007f82: a811 add r0, sp, #68 ; 0x44 + 8007f84: f7fd fc88 bl 8005898 + hmac_sha256_update(&ctx, se1_easy_key, 32); + 8007f88: 2220 movs r2, #32 + 8007f8a: a901 add r1, sp, #4 + 8007f8c: a811 add r0, sp, #68 ; 0x44 + 8007f8e: f7fd fc83 bl 8005898 + + // combine them all using anther MCU key via HMAC-SHA256 + hmac_sha256_final(&ctx, rom_secrets->mcu_hmac_key, aes_key); + 8007f92: a811 add r0, sp, #68 ; 0x44 + 8007f94: 4905 ldr r1, [pc, #20] ; (8007fac ) + 8007f96: 462a mov r2, r5 + 8007f98: f7fd fc94 bl 80058c4 + hmac_sha256_init(&ctx); // clear secrets + 8007f9c: a811 add r0, sp, #68 ; 0x44 + 8007f9e: f7fd fc75 bl 800588c + + return false; +} + 8007fa2: 4620 mov r0, r4 + 8007fa4: b052 add sp, #328 ; 0x148 + 8007fa6: bd70 pop {r4, r5, r6, pc} + 8007fa8: 0801c0b0 .word 0x0801c0b0 + 8007fac: 0801c090 .word 0x0801c090 + +08007fb0 : +{ + 8007fb0: b5f0 push {r4, r5, r6, r7, lr} + if(i2c_port.Instance == I2C2) { + 8007fb2: 4e1b ldr r6, [pc, #108] ; (8008020 ) + 8007fb4: 4f1b ldr r7, [pc, #108] ; (8008024 ) + 8007fb6: 6833 ldr r3, [r6, #0] + 8007fb8: 42bb cmp r3, r7 +{ + 8007fba: b089 sub sp, #36 ; 0x24 + if(i2c_port.Instance == I2C2) { + 8007fbc: d02e beq.n 800801c + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8007fbe: 4b1a ldr r3, [pc, #104] ; (8008028 ) + GPIO_InitTypeDef setup = { + 8007fc0: 4d1a ldr r5, [pc, #104] ; (800802c ) + __HAL_RCC_GPIOB_CLK_ENABLE(); + 8007fc2: 6cda ldr r2, [r3, #76] ; 0x4c + 8007fc4: f042 0202 orr.w r2, r2, #2 + 8007fc8: 64da str r2, [r3, #76] ; 0x4c + 8007fca: 6cda ldr r2, [r3, #76] ; 0x4c + 8007fcc: f002 0202 and.w r2, r2, #2 + 8007fd0: 9201 str r2, [sp, #4] + 8007fd2: 9a01 ldr r2, [sp, #4] + __HAL_RCC_I2C2_CLK_ENABLE(); + 8007fd4: 6d9a ldr r2, [r3, #88] ; 0x58 + 8007fd6: f442 0280 orr.w r2, r2, #4194304 ; 0x400000 + 8007fda: 659a str r2, [r3, #88] ; 0x58 + 8007fdc: 6d9b ldr r3, [r3, #88] ; 0x58 + 8007fde: f403 0380 and.w r3, r3, #4194304 ; 0x400000 + 8007fe2: 9302 str r3, [sp, #8] + 8007fe4: 9b02 ldr r3, [sp, #8] + GPIO_InitTypeDef setup = { + 8007fe6: cd0f ldmia r5!, {r0, r1, r2, r3} + 8007fe8: ac03 add r4, sp, #12 + 8007fea: c40f stmia r4!, {r0, r1, r2, r3} + 8007fec: 682b ldr r3, [r5, #0] + HAL_GPIO_Init(GPIOB, &setup); + 8007fee: 4810 ldr r0, [pc, #64] ; (8008030 ) + GPIO_InitTypeDef setup = { + 8007ff0: 6023 str r3, [r4, #0] + HAL_GPIO_Init(GPIOB, &setup); + 8007ff2: a903 add r1, sp, #12 + 8007ff4: f7f9 f8fe bl 80011f4 + memset(&i2c_port, 0, sizeof(i2c_port)); + 8007ff8: 2244 movs r2, #68 ; 0x44 + 8007ffa: 2100 movs r1, #0 + 8007ffc: f106 0008 add.w r0, r6, #8 + 8008000: f005 fc90 bl 800d924 + i2c_port.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + 8008004: 2301 movs r3, #1 + 8008006: 60f3 str r3, [r6, #12] + HAL_StatusTypeDef rv = HAL_I2C_Init(&i2c_port); + 8008008: 4630 mov r0, r6 + i2c_port.Init.Timing = 0x00b03fb8; // 400khz "fast mode" in CubeMX @ 120Mhz (measured ok) + 800800a: 4b0a ldr r3, [pc, #40] ; (8008034 ) + i2c_port.Instance = I2C2; + 800800c: 6037 str r7, [r6, #0] + i2c_port.Init.Timing = 0x00b03fb8; // 400khz "fast mode" in CubeMX @ 120Mhz (measured ok) + 800800e: 6073 str r3, [r6, #4] + HAL_StatusTypeDef rv = HAL_I2C_Init(&i2c_port); + 8008010: f003 fdae bl 800bb70 + ASSERT(rv == HAL_OK); + 8008014: b110 cbz r0, 800801c + 8008016: 4808 ldr r0, [pc, #32] ; (8008038 ) + 8008018: f7f8 fd0e bl 8000a38 +} + 800801c: b009 add sp, #36 ; 0x24 + 800801e: bdf0 pop {r4, r5, r6, r7, pc} + 8008020: 2009e3f0 .word 0x2009e3f0 + 8008024: 40005800 .word 0x40005800 + 8008028: 40021000 .word 0x40021000 + 800802c: 08010aac .word 0x08010aac + 8008030: 48000400 .word 0x48000400 + 8008034: 00b03fb8 .word 0x00b03fb8 + 8008038: 0801046c .word 0x0801046c + +0800803c : +{ + 800803c: b5f0 push {r4, r5, r6, r7, lr} + 800803e: b089 sub sp, #36 ; 0x24 + se2_setup(); + 8008040: f7ff ffb6 bl 8007fb0 + if(setjmp(error_env)) fatal_mitm(); + 8008044: 480f ldr r0, [pc, #60] ; (8008084 ) + 8008046: f005 fc75 bl 800d934 + 800804a: 4604 mov r4, r0 + 800804c: b108 cbz r0, 8008052 + 800804e: f7f8 fcfd bl 8000a4c + uint8_t tmp[32] = {0}; + 8008052: 9000 str r0, [sp, #0] + 8008054: 4601 mov r1, r0 + 8008056: 221c movs r2, #28 + 8008058: a801 add r0, sp, #4 + 800805a: f005 fc63 bl 800d924 + se2_write_encrypted(pn, tmp, 0, SE2_SECRETS->pairing); + 800805e: 4f0a ldr r7, [pc, #40] ; (8008088 ) + 8008060: 4e0a ldr r6, [pc, #40] ; (800808c ) + 8008062: 4d0b ldr r5, [pc, #44] ; (8008090 ) + 8008064: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 8008068: b2e0 uxtb r0, r4 + 800806a: 2bff cmp r3, #255 ; 0xff + 800806c: bf0c ite eq + 800806e: 4633 moveq r3, r6 + 8008070: 462b movne r3, r5 + 8008072: 2200 movs r2, #0 + 8008074: 4669 mov r1, sp + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 8008076: 3401 adds r4, #1 + se2_write_encrypted(pn, tmp, 0, SE2_SECRETS->pairing); + 8008078: f7ff fc4a bl 8007910 + for(int pn=0; pn <= PGN_LAST_TRICK; pn++) { + 800807c: 2c0e cmp r4, #14 + 800807e: d1f1 bne.n 8008064 +} + 8008080: b009 add sp, #36 ; 0x24 + 8008082: bdf0 pop {r4, r5, r6, r7, pc} + 8008084: 2009e394 .word 0x2009e394 + 8008088: 0801c000 .word 0x0801c000 + 800808c: 2009e2b4 .word 0x2009e2b4 + 8008090: 0801c0b0 .word 0x0801c0b0 + +08008094 : +{ + 8008094: b5f0 push {r4, r5, r6, r7, lr} + 8008096: b087 sub sp, #28 + 8008098: e9cd 0102 strd r0, r1, [sp, #8] + if(setjmp(error_env)) fatal_mitm(); + 800809c: 4816 ldr r0, [pc, #88] ; (80080f8 ) +{ + 800809e: 9201 str r2, [sp, #4] + if(setjmp(error_env)) fatal_mitm(); + 80080a0: f005 fc48 bl 800d934 + 80080a4: b108 cbz r0, 80080aa + 80080a6: f7f8 fcd1 bl 8000a4c + se2_read_encrypted(slot_num+1, &data[0], 0, SE2_SECRETS->pairing); + 80080aa: 4f14 ldr r7, [pc, #80] ; (80080fc ) + 80080ac: 9005 str r0, [sp, #20] + se2_setup(); + 80080ae: f7ff ff7f bl 8007fb0 + se2_read_encrypted(slot_num+1, &data[0], 0, SE2_SECRETS->pairing); + 80080b2: f89d 4008 ldrb.w r4, [sp, #8] + 80080b6: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 80080ba: 4e11 ldr r6, [pc, #68] ; (8008100 ) + 80080bc: 4d11 ldr r5, [pc, #68] ; (8008104 ) + 80080be: 9a05 ldr r2, [sp, #20] + 80080c0: 9901 ldr r1, [sp, #4] + 80080c2: 9204 str r2, [sp, #16] + 80080c4: 1c60 adds r0, r4, #1 + 80080c6: 2bff cmp r3, #255 ; 0xff + 80080c8: bf0c ite eq + 80080ca: 4633 moveq r3, r6 + 80080cc: 462b movne r3, r5 + 80080ce: b2c0 uxtb r0, r0 + 80080d0: f7ff fba6 bl 8007820 + if(tc_flags & TC_XPRV_WALLET) { + 80080d4: 9b03 ldr r3, [sp, #12] + 80080d6: 051b lsls r3, r3, #20 + 80080d8: d50c bpl.n 80080f4 + se2_read_encrypted(slot_num+2, &data[32], 0, SE2_SECRETS->pairing); + 80080da: f897 30b0 ldrb.w r3, [r7, #176] ; 0xb0 + 80080de: 9901 ldr r1, [sp, #4] + 80080e0: 9a04 ldr r2, [sp, #16] + 80080e2: 3402 adds r4, #2 + 80080e4: 2bff cmp r3, #255 ; 0xff + 80080e6: bf0c ite eq + 80080e8: 4633 moveq r3, r6 + 80080ea: 462b movne r3, r5 + 80080ec: 3120 adds r1, #32 + 80080ee: b2e0 uxtb r0, r4 + 80080f0: f7ff fb96 bl 8007820 +} + 80080f4: b007 add sp, #28 + 80080f6: bdf0 pop {r4, r5, r6, r7, pc} + 80080f8: 2009e394 .word 0x2009e394 + 80080fc: 0801c000 .word 0x0801c000 + 8008100: 2009e2b4 .word 0x2009e2b4 + 8008104: 0801c0b0 .word 0x0801c0b0 + +08008108 : +{ + 8008108: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 800810c: b0fe sub sp, #504 ; 0x1f8 + 800810e: e9cd 1002 strd r1, r0, [sp, #8] + 8008112: e9cd 2300 strd r2, r3, [sp] + se2_setup(); + 8008116: f7ff ff4b bl 8007fb0 + if(setjmp(error_env)) { + 800811a: 4864 ldr r0, [pc, #400] ; (80082ac ) + 800811c: f005 fc0a bl 800d934 + 8008120: 4604 mov r4, r0 + 8008122: b138 cbz r0, 8008134 + if(!safety_mode) fatal_mitm(); + 8008124: 9b01 ldr r3, [sp, #4] + 8008126: b11b cbz r3, 8008130 + return false; + 8008128: 2000 movs r0, #0 +} + 800812a: b07e add sp, #504 ; 0x1f8 + 800812c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if(!safety_mode) fatal_mitm(); + 8008130: f7f8 fc8c bl 8000a4c + if(!pin_len) return false; + 8008134: 9b02 ldr r3, [sp, #8] + 8008136: 2b00 cmp r3, #0 + 8008138: d0f6 beq.n 8008128 + trick_pin_hash(pin, pin_len, tpin_hash); + 800813a: 9803 ldr r0, [sp, #12] + se2_read_encrypted(pn, slots[i], 0, SE2_SECRETS->pairing); + 800813c: f8df a174 ldr.w sl, [pc, #372] ; 80082b4 + 8008140: f8df 9174 ldr.w r9, [pc, #372] ; 80082b8 + 8008144: f8df 8174 ldr.w r8, [pc, #372] ; 80082bc + trick_pin_hash(pin, pin_len, tpin_hash); + 8008148: aa06 add r2, sp, #24 + 800814a: 4619 mov r1, r3 + 800814c: f7ff fe24 bl 8007d98 + 8008150: ad0e add r5, sp, #56 ; 0x38 + 8008152: 462f mov r7, r5 + int pn = PGN_TRICK(0); + 8008154: 4626 mov r6, r4 + se2_read_encrypted(pn, slots[i], 0, SE2_SECRETS->pairing); + 8008156: f89a 30b0 ldrb.w r3, [sl, #176] ; 0xb0 + 800815a: 4639 mov r1, r7 + 800815c: 2bff cmp r3, #255 ; 0xff + 800815e: bf0c ite eq + 8008160: 464b moveq r3, r9 + 8008162: 4643 movne r3, r8 + 8008164: b2f0 uxtb r0, r6 + 8008166: 2200 movs r2, #0 + for(int i=0; ipairing); + 800816a: f7ff fb59 bl 8007820 + for(int i=0; i + se2_clear_volatile(); + 8008176: f7ff fccf bl 8007b18 + uint32_t blank = 0; + 800817a: 2700 movs r7, #0 + int found = -1; + 800817c: f04f 36ff mov.w r6, #4294967295 ; 0xffffffff + if(check_equal(here, tpin_hash, 28)) { + 8008180: f04f 091c mov.w r9, #28 + blank |= (!!check_all_zeros(here, 32)) << i; + 8008184: f04f 0820 mov.w r8, #32 + if(check_equal(here, tpin_hash, 28)) { + 8008188: 464a mov r2, r9 + 800818a: a906 add r1, sp, #24 + 800818c: 4628 mov r0, r5 + 800818e: f7fa fb56 bl 800283e + blank |= (!!check_all_zeros(here, 32)) << i; + 8008192: 4641 mov r1, r8 + if(check_equal(here, tpin_hash, 28)) { + 8008194: 2800 cmp r0, #0 + 8008196: bf18 it ne + 8008198: 4626 movne r6, r4 + blank |= (!!check_all_zeros(here, 32)) << i; + 800819a: 4628 mov r0, r5 + 800819c: f7fa fb40 bl 8002820 + 80081a0: 40a0 lsls r0, r4 + for(int i=0; i + rng_delay(); + 80081b0: f7fa fbaa bl 8002908 + memset(found_slot, 0, sizeof(trick_slot_t)); + 80081b4: 9800 ldr r0, [sp, #0] + 80081b6: 2280 movs r2, #128 ; 0x80 + 80081b8: 2100 movs r1, #0 + 80081ba: f005 fbb3 bl 800d924 + if(safety_mode) { + 80081be: 9b01 ldr r3, [sp, #4] + 80081c0: b10b cbz r3, 80081c6 + found_slot->blank_slots = blank; + 80081c2: 9b00 ldr r3, [sp, #0] + 80081c4: 65df str r7, [r3, #92] ; 0x5c + if(found >= 0) { + 80081c6: 1c72 adds r2, r6, #1 + 80081c8: d069 beq.n 800829e + found_slot->slot_num = found; + 80081ca: 9b00 ldr r3, [sp, #0] + 80081cc: 0174 lsls r4, r6, #5 + 80081ce: 601e str r6, [r3, #0] + memcpy(meta, &slots[found][28], 4); + 80081d0: ab15 add r3, sp, #84 ; 0x54 + xor_mixin(meta, &tpin_hash[28], 4); + 80081d2: 2204 movs r2, #4 + memcpy(meta, &slots[found][28], 4); + 80081d4: 591b ldr r3, [r3, r4] + 80081d6: 9305 str r3, [sp, #20] + xor_mixin(meta, &tpin_hash[28], 4); + 80081d8: a90d add r1, sp, #52 ; 0x34 + 80081da: a805 add r0, sp, #20 + 80081dc: f7ff f982 bl 80074e4 + memcpy(&found_slot->tc_flags, &meta[0], 2); + 80081e0: 9b00 ldr r3, [sp, #0] + 80081e2: f8bd 5014 ldrh.w r5, [sp, #20] + memcpy(&found_slot->tc_arg, &meta[2], 2); + 80081e6: 9a00 ldr r2, [sp, #0] + memcpy(&found_slot->tc_flags, &meta[0], 2); + 80081e8: 809d strh r5, [r3, #4] + memcpy(&found_slot->tc_arg, &meta[2], 2); + 80081ea: f8bd 3016 ldrh.w r3, [sp, #22] + 80081ee: 80d3 strh r3, [r2, #6] + if(todo & TC_WORD_WALLET) { + 80081f0: 04eb lsls r3, r5, #19 + 80081f2: d513 bpl.n 800821c + if(found+1 < NUM_TRICKS) { + 80081f4: 2e0c cmp r6, #12 + 80081f6: dc0e bgt.n 8008216 + memcpy(found_slot->xdata, &slots[found+1][0], 32); + 80081f8: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 80081fc: eb0d 0403 add.w r4, sp, r3 + 8008200: f5a4 73d0 sub.w r3, r4, #416 ; 0x1a0 + 8008204: 3208 adds r2, #8 + 8008206: f5a4 74c0 sub.w r4, r4, #384 ; 0x180 + 800820a: f853 1b04 ldr.w r1, [r3], #4 + 800820e: f842 1b04 str.w r1, [r2], #4 + 8008212: 42a3 cmp r3, r4 + 8008214: d1f9 bne.n 800820a + if(!safety_mode && todo) { + 8008216: 9b01 ldr r3, [sp, #4] + 8008218: b33b cbz r3, 800826a + 800821a: e03e b.n 800829a + } else if(todo & TC_XPRV_WALLET) { + 800821c: 052f lsls r7, r5, #20 + 800821e: d521 bpl.n 8008264 + if(found+2 < NUM_TRICKS) { + 8008220: 2e0b cmp r6, #11 + 8008222: dcf8 bgt.n 8008216 + memcpy(&found_slot->xdata[0], &slots[found+1][0], 32); + 8008224: 9900 ldr r1, [sp, #0] + 8008226: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 800822a: 446b add r3, sp + 800822c: f5a3 72d0 sub.w r2, r3, #416 ; 0x1a0 + 8008230: 3108 adds r1, #8 + 8008232: f5a3 73c0 sub.w r3, r3, #384 ; 0x180 + 8008236: f852 0b04 ldr.w r0, [r2], #4 + 800823a: f841 0b04 str.w r0, [r1], #4 + 800823e: 429a cmp r2, r3 + 8008240: d1f9 bne.n 8008236 + memcpy(&found_slot->xdata[32], &slots[found+2][0], 32); + 8008242: f504 73fc add.w r3, r4, #504 ; 0x1f8 + 8008246: 9a00 ldr r2, [sp, #0] + 8008248: eb0d 0403 add.w r4, sp, r3 + 800824c: f5a4 73c0 sub.w r3, r4, #384 ; 0x180 + 8008250: 3228 adds r2, #40 ; 0x28 + 8008252: f5a4 74b0 sub.w r4, r4, #352 ; 0x160 + 8008256: f853 1b04 ldr.w r1, [r3], #4 + 800825a: f842 1b04 str.w r1, [r2], #4 + 800825e: 42a3 cmp r3, r4 + 8008260: d1f9 bne.n 8008256 + 8008262: e7d8 b.n 8008216 + if(!safety_mode && todo) { + 8008264: 9b01 ldr r3, [sp, #4] + 8008266: b9c3 cbnz r3, 800829a + 8008268: b1bd cbz r5, 800829a + if(todo & TC_WIPE) { + 800826a: 0428 lsls r0, r5, #16 + 800826c: d50a bpl.n 8008284 + mcu_key_clear(NULL); + 800826e: 2000 movs r0, #0 + 8008270: f7fa f9b8 bl 80025e4 + if(todo == TC_WIPE) { + 8008274: f5b5 4f00 cmp.w r5, #32768 ; 0x8000 + 8008278: d104 bne.n 8008284 + oled_show(screen_wiped); + 800827a: 480d ldr r0, [pc, #52] ; (80082b0 ) + 800827c: f7f8 fefa bl 8001074 + LOCKUP_FOREVER(); + 8008280: f7fb fcfa bl 8003c78 + if(todo & TC_BRICK) { + 8008284: 0469 lsls r1, r5, #17 + 8008286: d403 bmi.n 8008290 + if(todo & TC_REBOOT) { + 8008288: 05aa lsls r2, r5, #22 + 800828a: d504 bpl.n 8008296 + NVIC_SystemReset(); + 800828c: f7ff f918 bl 80074c0 <__NVIC_SystemReset> + fast_brick(); + 8008290: f7fa fa6c bl 800276c + 8008294: e7f8 b.n 8008288 + if(todo & TC_FAKE_OUT) { + 8008296: 04ab lsls r3, r5, #18 + 8008298: d401 bmi.n 800829e + return true; + 800829a: 2001 movs r0, #1 + 800829c: e745 b.n 800812a + found_slot->slot_num = -1; + 800829e: 9a00 ldr r2, [sp, #0] + 80082a0: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 80082a4: 6013 str r3, [r2, #0] + rng_delay(); + 80082a6: f7fa fb2f bl 8002908 + 80082aa: e73d b.n 8008128 + 80082ac: 2009e394 .word 0x2009e394 + 80082b0: 08010174 .word 0x08010174 + 80082b4: 0801c000 .word 0x0801c000 + 80082b8: 2009e2b4 .word 0x2009e2b4 + 80082bc: 0801c0b0 .word 0x0801c0b0 + +080082c0 : +{ + 80082c0: b510 push {r4, lr} + 80082c2: b0a2 sub sp, #136 ; 0x88 + 80082c4: 4604 mov r4, r0 + bool is_trick = se2_test_trick_pin("!p", 2, &slot, true); + 80082c6: 2301 movs r3, #1 + 80082c8: 481a ldr r0, [pc, #104] ; (8008334 ) + 80082ca: aa02 add r2, sp, #8 + 80082cc: 2102 movs r1, #2 + 80082ce: f7ff ff1b bl 8008108 + if(!is_trick) return; + 80082d2: b368 cbz r0, 8008330 + if(num_fails >= slot.tc_arg) { + 80082d4: f8bd 300e ldrh.w r3, [sp, #14] + 80082d8: 42a3 cmp r3, r4 + 80082da: dc29 bgt.n 8008330 + if(slot.tc_flags & TC_WIPE) { + 80082dc: f9bd 300c ldrsh.w r3, [sp, #12] + 80082e0: f8bd 000c ldrh.w r0, [sp, #12] + 80082e4: 2b00 cmp r3, #0 + 80082e6: da17 bge.n 8008318 + if(slot.tc_flags & TC_BRICK) { + 80082e8: f410 4080 ands.w r0, r0, #16384 ; 0x4000 + 80082ec: d00d beq.n 800830a + const mcu_key_t *cur = mcu_key_get(&valid); + 80082ee: f10d 0007 add.w r0, sp, #7 + 80082f2: f7fa f957 bl 80025a4 + if(valid) { + 80082f6: f89d 3007 ldrb.w r3, [sp, #7] + 80082fa: b16b cbz r3, 8008318 + mcu_key_clear(cur); + 80082fc: f7fa f972 bl 80025e4 + oled_show(screen_wiped); + 8008300: 480d ldr r0, [pc, #52] ; (8008338 ) + 8008302: f7f8 feb7 bl 8001074 + LOCKUP_FOREVER(); + 8008306: f7fb fcb7 bl 8003c78 + mcu_key_clear(NULL); // does valid key check + 800830a: f7fa f96b bl 80025e4 + if(slot.tc_flags == TC_WIPE) { + 800830e: f8bd 300c ldrh.w r3, [sp, #12] + 8008312: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + 8008316: d0f3 beq.n 8008300 + if(slot.tc_flags & TC_BRICK) { + 8008318: f8bd 300c ldrh.w r3, [sp, #12] + 800831c: 045a lsls r2, r3, #17 + 800831e: d501 bpl.n 8008324 + fast_brick(); + 8008320: f7fa fa24 bl 800276c + if(slot.tc_flags & TC_REBOOT) { + 8008324: f8bd 300c ldrh.w r3, [sp, #12] + 8008328: 059b lsls r3, r3, #22 + 800832a: d501 bpl.n 8008330 + NVIC_SystemReset(); + 800832c: f7ff f8c8 bl 80074c0 <__NVIC_SystemReset> +} + 8008330: b022 add sp, #136 ; 0x88 + 8008332: bd10 pop {r4, pc} + 8008334: 08010aa9 .word 0x08010aa9 + 8008338: 08010174 .word 0x08010174 + +0800833c : +{ + 800833c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 8008340: b094 sub sp, #80 ; 0x50 + 8008342: 9001 str r0, [sp, #4] + se2_setup(); + 8008344: f7ff fe34 bl 8007fb0 + if(setjmp(error_env)) { + 8008348: 4848 ldr r0, [pc, #288] ; (800846c ) + 800834a: f005 faf3 bl 800d934 + 800834e: 4604 mov r4, r0 + 8008350: 2800 cmp r0, #0 + 8008352: f040 8088 bne.w 8008466 + if((config->slot_num < 0) || (config->slot_num >= NUM_TRICKS) ) { + 8008356: 9b01 ldr r3, [sp, #4] + 8008358: 681b ldr r3, [r3, #0] + 800835a: 2b0d cmp r3, #13 + 800835c: d804 bhi.n 8008368 + if((config->slot_num >= NUM_TRICKS-1) && (config->tc_flags & TC_WORD_WALLET) ) { + 800835e: d106 bne.n 800836e + 8008360: 9b01 ldr r3, [sp, #4] + 8008362: 889b ldrh r3, [r3, #4] + 8008364: 04d9 lsls r1, r3, #19 + 8008366: d504 bpl.n 8008372 + return EPIN_RANGE_ERR; + 8008368: f06f 0466 mvn.w r4, #102 ; 0x66 + 800836c: e01f b.n 80083ae + if((config->slot_num >= NUM_TRICKS-2) && (config->tc_flags & TC_XPRV_WALLET) ) { + 800836e: 2b0c cmp r3, #12 + 8008370: d103 bne.n 800837a + 8008372: 9b01 ldr r3, [sp, #4] + 8008374: 889b ldrh r3, [r3, #4] + 8008376: 051a lsls r2, r3, #20 + 8008378: d4f6 bmi.n 8008368 + if(config->pin_len > sizeof(config->pin)) { + 800837a: 9b01 ldr r3, [sp, #4] + 800837c: 6d99 ldr r1, [r3, #88] ; 0x58 + 800837e: 2910 cmp r1, #16 + 8008380: d8f2 bhi.n 8008368 + if(config->blank_slots) { + 8008382: 6ddd ldr r5, [r3, #92] ; 0x5c + 8008384: b31d cbz r5, 80083ce + uint8_t zeros[32] = { 0 }; + 8008386: 2100 movs r1, #0 + 8008388: 221c movs r2, #28 + 800838a: a805 add r0, sp, #20 + 800838c: 9104 str r1, [sp, #16] + 800838e: f005 fac9 bl 800d924 + se2_write_encrypted(PGN_TRICK(i), zeros, 0, SE2_SECRETS->pairing); + 8008392: f8df 80e4 ldr.w r8, [pc, #228] ; 8008478 + 8008396: 4f36 ldr r7, [pc, #216] ; (8008470 ) + 8008398: 4e36 ldr r6, [pc, #216] ; (8008474 ) + for(int i=0; iblank_slots) { + 800839c: 9a01 ldr r2, [sp, #4] + uint32_t mask = (1 << i); + 800839e: 2301 movs r3, #1 + if(mask & config->blank_slots) { + 80083a0: 6dd2 ldr r2, [r2, #92] ; 0x5c + uint32_t mask = (1 << i); + 80083a2: 40ab lsls r3, r5 + if(mask & config->blank_slots) { + 80083a4: 4213 tst r3, r2 + 80083a6: d106 bne.n 80083b6 + for(int i=0; i +} + 80083ae: 4620 mov r0, r4 + 80083b0: b014 add sp, #80 ; 0x50 + 80083b2: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + se2_write_encrypted(PGN_TRICK(i), zeros, 0, SE2_SECRETS->pairing); + 80083b6: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + 80083ba: 2200 movs r2, #0 + 80083bc: 2bff cmp r3, #255 ; 0xff + 80083be: bf0c ite eq + 80083c0: 463b moveq r3, r7 + 80083c2: 4633 movne r3, r6 + 80083c4: a904 add r1, sp, #16 + 80083c6: b2e8 uxtb r0, r5 + 80083c8: f7ff faa2 bl 8007910 + 80083cc: e7ec b.n 80083a8 + trick_pin_hash(config->pin, config->pin_len, tpin_digest); + 80083ce: 9b01 ldr r3, [sp, #4] + se2_write_encrypted(PGN_TRICK(config->slot_num), tpin_digest, 0, SE2_SECRETS->pairing); + 80083d0: f8df 80a4 ldr.w r8, [pc, #164] ; 8008478 + 80083d4: 4f26 ldr r7, [pc, #152] ; (8008470 ) + 80083d6: 4e27 ldr r6, [pc, #156] ; (8008474 ) + trick_pin_hash(config->pin, config->pin_len, tpin_digest); + 80083d8: f103 0048 add.w r0, r3, #72 ; 0x48 + 80083dc: aa0c add r2, sp, #48 ; 0x30 + 80083de: f7ff fcdb bl 8007d98 + memcpy(&meta[0], &config->tc_flags, 2); + 80083e2: 9b01 ldr r3, [sp, #4] + 80083e4: 889b ldrh r3, [r3, #4] + 80083e6: f8ad 300c strh.w r3, [sp, #12] + memcpy(&meta[2], &config->tc_arg, 2); + 80083ea: 9b01 ldr r3, [sp, #4] + xor_mixin(&tpin_digest[28], meta, 4); + 80083ec: 2204 movs r2, #4 + memcpy(&meta[2], &config->tc_arg, 2); + 80083ee: 88db ldrh r3, [r3, #6] + 80083f0: f8ad 300e strh.w r3, [sp, #14] + xor_mixin(&tpin_digest[28], meta, 4); + 80083f4: a903 add r1, sp, #12 + 80083f6: a813 add r0, sp, #76 ; 0x4c + 80083f8: f7ff f874 bl 80074e4 + se2_write_encrypted(PGN_TRICK(config->slot_num), tpin_digest, 0, SE2_SECRETS->pairing); + 80083fc: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + 8008400: 9801 ldr r0, [sp, #4] + 8008402: 2bff cmp r3, #255 ; 0xff + 8008404: bf0c ite eq + 8008406: 463b moveq r3, r7 + 8008408: 4633 movne r3, r6 + 800840a: 7800 ldrb r0, [r0, #0] + 800840c: 462a mov r2, r5 + 800840e: a90c add r1, sp, #48 ; 0x30 + 8008410: f7ff fa7e bl 8007910 + if(config->tc_flags & (TC_WORD_WALLET | TC_XPRV_WALLET)) { + 8008414: 9b01 ldr r3, [sp, #4] + 8008416: 889b ldrh r3, [r3, #4] + 8008418: f403 53c0 and.w r3, r3, #6144 ; 0x1800 + 800841c: b9a3 cbnz r3, 8008448 + if(config->tc_flags & TC_XPRV_WALLET) { + 800841e: 9b01 ldr r3, [sp, #4] + 8008420: 889b ldrh r3, [r3, #4] + 8008422: 051b lsls r3, r3, #20 + 8008424: d5c3 bpl.n 80083ae + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 8008426: 9901 ldr r1, [sp, #4] + 0, SE2_SECRETS->pairing); + 8008428: 4b13 ldr r3, [pc, #76] ; (8008478 ) + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 800842a: f851 0b28 ldr.w r0, [r1], #40 + 0, SE2_SECRETS->pairing); + 800842e: f893 50b0 ldrb.w r5, [r3, #176] ; 0xb0 + se2_write_encrypted(PGN_TRICK(config->slot_num+2), &config->xdata[32], + 8008432: 4a10 ldr r2, [pc, #64] ; (8008474 ) + 8008434: 4b0e ldr r3, [pc, #56] ; (8008470 ) + 8008436: 3002 adds r0, #2 + 8008438: 2dff cmp r5, #255 ; 0xff + 800843a: bf18 it ne + 800843c: 4613 movne r3, r2 + 800843e: b2c0 uxtb r0, r0 + 8008440: 2200 movs r2, #0 + 8008442: f7ff fa65 bl 8007910 + 8008446: e7b2 b.n 80083ae + se2_write_encrypted(PGN_TRICK(config->slot_num+1), &config->xdata[0], + 8008448: 9901 ldr r1, [sp, #4] + 0, SE2_SECRETS->pairing); + 800844a: f898 30b0 ldrb.w r3, [r8, #176] ; 0xb0 + se2_write_encrypted(PGN_TRICK(config->slot_num+1), &config->xdata[0], + 800844e: f851 0b08 ldr.w r0, [r1], #8 + 8008452: 3001 adds r0, #1 + 8008454: 2bff cmp r3, #255 ; 0xff + 8008456: bf0c ite eq + 8008458: 463b moveq r3, r7 + 800845a: 4633 movne r3, r6 + 800845c: 462a mov r2, r5 + 800845e: b2c0 uxtb r0, r0 + 8008460: f7ff fa56 bl 8007910 + 8008464: e7db b.n 800841e + return EPIN_SE2_FAIL; + 8008466: f06f 0472 mvn.w r4, #114 ; 0x72 + 800846a: e7a0 b.n 80083ae + 800846c: 2009e394 .word 0x2009e394 + 8008470: 2009e2b4 .word 0x2009e2b4 + 8008474: 0801c0b0 .word 0x0801c0b0 + 8008478: 0801c000 .word 0x0801c000 + +0800847c : +// + bool +se2_encrypt_secret(const uint8_t secret[], int secret_len, int offset, + uint8_t main_slot[], uint8_t *check_value, + const uint8_t pin_digest[32]) +{ + 800847c: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 8008480: f5ad 7d10 sub.w sp, sp, #576 ; 0x240 + 8008484: 4699 mov r9, r3 + 8008486: 4682 mov sl, r0 + 8008488: 460f mov r7, r1 + 800848a: 4614 mov r4, r2 + 800848c: f8dd 8260 ldr.w r8, [sp, #608] ; 0x260 + se2_setup(); + 8008490: f7ff fd8e bl 8007fb0 + + bool is_valid; + const mcu_key_t *cur = mcu_key_get(&is_valid); + 8008494: f10d 000b add.w r0, sp, #11 + 8008498: f7fa f884 bl 80025a4 + + if(!is_valid) { + 800849c: f89d 300b ldrb.w r3, [sp, #11] + 80084a0: b953 cbnz r3, 80084b8 + if(!check_value) { + 80084a2: f1b8 0f00 cmp.w r8, #0 + 80084a6: d105 bne.n 80084b4 + // problem: we are not writing the check value but it would be changed. + // ie: change long secret before real secret--unlikely + return true; + 80084a8: 2501 movs r5, #1 + ctx.num_pending = 32; + aes_done(&ctx, check_value, 32, aes_key, nonce); + } + + return false; +} + 80084aa: 4628 mov r0, r5 + 80084ac: f50d 7d10 add.w sp, sp, #576 ; 0x240 + 80084b0: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + cur = mcu_key_pick(); + 80084b4: f7fa f8de bl 8002674 + if(se2_calc_seed_key(aes_key, cur, pin_digest)) return true; + 80084b8: 4601 mov r1, r0 + 80084ba: 9a99 ldr r2, [sp, #612] ; 0x264 + 80084bc: a807 add r0, sp, #28 + 80084be: f7ff fd45 bl 8007f4c + 80084c2: 4605 mov r5, r0 + 80084c4: 2800 cmp r0, #0 + 80084c6: d1ef bne.n 80084a8 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80084c8: 4b16 ldr r3, [pc, #88] ; (8008524 ) + 80084ca: cb0f ldmia r3, {r0, r1, r2, r3} + 80084cc: ae03 add r6, sp, #12 + 80084ce: 46b4 mov ip, r6 + 80084d0: e8ac 0007 stmia.w ip!, {r0, r1, r2} + nonce[15] = offset / AES_BLOCK_SIZE; + 80084d4: 2c00 cmp r4, #0 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80084d6: f82c 3b02 strh.w r3, [ip], #2 + nonce[15] = offset / AES_BLOCK_SIZE; + 80084da: bfb8 it lt + 80084dc: 340f addlt r4, #15 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 80084de: 0c1b lsrs r3, r3, #16 + 80084e0: f88c 3000 strb.w r3, [ip] + aes_init(&ctx); + 80084e4: a80f add r0, sp, #60 ; 0x3c + nonce[15] = offset / AES_BLOCK_SIZE; + 80084e6: 1124 asrs r4, r4, #4 + 80084e8: 73f4 strb r4, [r6, #15] + aes_init(&ctx); + 80084ea: f000 f92b bl 8008744 + aes_add(&ctx, secret, secret_len); + 80084ee: 463a mov r2, r7 + 80084f0: 4651 mov r1, sl + 80084f2: a80f add r0, sp, #60 ; 0x3c + 80084f4: f000 f92c bl 8008750 + aes_done(&ctx, main_slot, secret_len, aes_key, nonce); + 80084f8: 9600 str r6, [sp, #0] + 80084fa: ab07 add r3, sp, #28 + 80084fc: 463a mov r2, r7 + 80084fe: 4649 mov r1, r9 + 8008500: a80f add r0, sp, #60 ; 0x3c + 8008502: f000 f93b bl 800877c + if(check_value) { + 8008506: f1b8 0f00 cmp.w r8, #0 + 800850a: d0ce beq.n 80084aa + aes_init(&ctx); + 800850c: a80f add r0, sp, #60 ; 0x3c + 800850e: f000 f919 bl 8008744 + ctx.num_pending = 32; + 8008512: 2220 movs r2, #32 + aes_done(&ctx, check_value, 32, aes_key, nonce); + 8008514: 9600 str r6, [sp, #0] + 8008516: ab07 add r3, sp, #28 + 8008518: 4641 mov r1, r8 + 800851a: a80f add r0, sp, #60 ; 0x3c + ctx.num_pending = 32; + 800851c: 928f str r2, [sp, #572] ; 0x23c + aes_done(&ctx, check_value, 32, aes_key, nonce); + 800851e: f000 f92d bl 800877c + 8008522: e7c2 b.n 80084aa + 8008524: 0801c090 .word 0x0801c090 + +08008528 : +// + void +se2_decrypt_secret(uint8_t secret[], int secret_len, int offset, + const uint8_t main_slot[], const uint8_t *check_value, + const uint8_t pin_digest[32], bool *is_valid) +{ + 8008528: b530 push {r4, r5, lr} + 800852a: f5ad 7d1f sub.w sp, sp, #636 ; 0x27c + 800852e: e9cd 2306 strd r2, r3, [sp, #24] + 8008532: 9005 str r0, [sp, #20] + 8008534: 9103 str r1, [sp, #12] + se2_setup(); + 8008536: f7ff fd3b bl 8007fb0 + + const mcu_key_t *cur = mcu_key_get(is_valid); + 800853a: 98a4 ldr r0, [sp, #656] ; 0x290 + 800853c: f7fa f832 bl 80025a4 + if(!*is_valid) { + 8008540: 9ba4 ldr r3, [sp, #656] ; 0x290 + const mcu_key_t *cur = mcu_key_get(is_valid); + 8008542: 9004 str r0, [sp, #16] + if(!*is_valid) { + 8008544: 781b ldrb r3, [r3, #0] + 8008546: b133 cbz r3, 8008556 + // no key set? won't be able to decrypt. + return; + } + + int line_num; + if((line_num = setjmp(error_env))) { + 8008548: 4825 ldr r0, [pc, #148] ; (80085e0 ) + 800854a: f005 f9f3 bl 800d934 + 800854e: b128 cbz r0, 800855c + // internal failures / broken i2c buses will come here + *is_valid = false; + 8008550: 9aa4 ldr r2, [sp, #656] ; 0x290 + 8008552: 2300 movs r3, #0 + 8008554: 7013 strb r3, [r2, #0] + + // decrypt the real data + aes_init(&ctx); + aes_add(&ctx, main_slot, secret_len); + aes_done(&ctx, secret, secret_len, aes_key, nonce); +} + 8008556: f50d 7d1f add.w sp, sp, #636 ; 0x27c + 800855a: bd30 pop {r4, r5, pc} + if(se2_calc_seed_key(aes_key, cur, pin_digest)) { + 800855c: 9aa3 ldr r2, [sp, #652] ; 0x28c + 800855e: 9904 ldr r1, [sp, #16] + 8008560: a80d add r0, sp, #52 ; 0x34 + 8008562: f7ff fcf3 bl 8007f4c + 8008566: 2800 cmp r0, #0 + 8008568: d1f2 bne.n 8008550 + memcpy(nonce, rom_secrets->mcu_hmac_key, sizeof(nonce)-1); + 800856a: 4b1e ldr r3, [pc, #120] ; (80085e4 ) + 800856c: cb0f ldmia r3, {r0, r1, r2, r3} + 800856e: ad09 add r5, sp, #36 ; 0x24 + 8008570: 462c mov r4, r5 + 8008572: c407 stmia r4!, {r0, r1, r2} + 8008574: f824 3b02 strh.w r3, [r4], #2 + 8008578: 0c1b lsrs r3, r3, #16 + 800857a: 7023 strb r3, [r4, #0] + nonce[15] = offset / AES_BLOCK_SIZE; + 800857c: 9b06 ldr r3, [sp, #24] + 800857e: 2b00 cmp r3, #0 + 8008580: bfb8 it lt + 8008582: 330f addlt r3, #15 + 8008584: 111b asrs r3, r3, #4 + 8008586: 73eb strb r3, [r5, #15] + if(check_value) { + 8008588: 9ba2 ldr r3, [sp, #648] ; 0x288 + 800858a: b1bb cbz r3, 80085bc + aes_init(&ctx); + 800858c: a81d add r0, sp, #116 ; 0x74 + 800858e: f000 f8d9 bl 8008744 + aes_add(&ctx, check_value, 32); + 8008592: 99a2 ldr r1, [sp, #648] ; 0x288 + 8008594: 2220 movs r2, #32 + 8008596: a81d add r0, sp, #116 ; 0x74 + 8008598: f000 f8da bl 8008750 + aes_done(&ctx, got, 32, aes_key, nonce); + 800859c: ab09 add r3, sp, #36 ; 0x24 + 800859e: 9300 str r3, [sp, #0] + 80085a0: a915 add r1, sp, #84 ; 0x54 + 80085a2: a81d add r0, sp, #116 ; 0x74 + 80085a4: ab0d add r3, sp, #52 ; 0x34 + 80085a6: 2220 movs r2, #32 + 80085a8: f000 f8e8 bl 800877c + if(!check_all_zeros(got, 32)) { + 80085ac: 2120 movs r1, #32 + 80085ae: a815 add r0, sp, #84 ; 0x54 + 80085b0: f7fa f936 bl 8002820 + 80085b4: b910 cbnz r0, 80085bc + *is_valid = false; + 80085b6: 9ba4 ldr r3, [sp, #656] ; 0x290 + 80085b8: 7018 strb r0, [r3, #0] + return; + 80085ba: e7cc b.n 8008556 + aes_init(&ctx); + 80085bc: a81d add r0, sp, #116 ; 0x74 + 80085be: f000 f8c1 bl 8008744 + aes_add(&ctx, main_slot, secret_len); + 80085c2: 9a03 ldr r2, [sp, #12] + 80085c4: 9907 ldr r1, [sp, #28] + 80085c6: a81d add r0, sp, #116 ; 0x74 + 80085c8: f000 f8c2 bl 8008750 + aes_done(&ctx, secret, secret_len, aes_key, nonce); + 80085cc: ab09 add r3, sp, #36 ; 0x24 + 80085ce: 9300 str r3, [sp, #0] + 80085d0: 9a03 ldr r2, [sp, #12] + 80085d2: 9905 ldr r1, [sp, #20] + 80085d4: ab0d add r3, sp, #52 ; 0x34 + 80085d6: a81d add r0, sp, #116 ; 0x74 + 80085d8: f000 f8d0 bl 800877c + 80085dc: e7bb b.n 8008556 + 80085de: bf00 nop + 80085e0: 2009e394 .word 0x2009e394 + 80085e4: 0801c090 .word 0x0801c090 + +080085e8 : +// +// Hash up a PIN code for login attempt: to tie it into SE2's contents. +// + void +se2_pin_hash(uint8_t digest_io[32], uint32_t purpose) +{ + 80085e8: b5f0 push {r4, r5, r6, r7, lr} + if(purpose != PIN_PURPOSE_NORMAL) { + 80085ea: 4b41 ldr r3, [pc, #260] ; (80086f0 ) +{ + 80085ec: b0d5 sub sp, #340 ; 0x154 + if(purpose != PIN_PURPOSE_NORMAL) { + 80085ee: 4299 cmp r1, r3 +{ + 80085f0: e9cd 0100 strd r0, r1, [sp] + if(purpose != PIN_PURPOSE_NORMAL) { + 80085f4: d17a bne.n 80086ec + // do nothing except for real PIN case (ie. not for prefix words) + return; + } + + se2_setup(); + 80085f6: f7ff fcdb bl 8007fb0 + if((setjmp(error_env))) { + 80085fa: 483e ldr r0, [pc, #248] ; (80086f4 ) + 80085fc: f005 f99a bl 800d934 + 8008600: 4604 mov r4, r0 + 8008602: b120 cbz r0, 800860e + oled_show(screen_se2_issue); + 8008604: 483c ldr r0, [pc, #240] ; (80086f8 ) + 8008606: f7f8 fd35 bl 8001074 + + LOCKUP_FOREVER(); + 800860a: f7fb fb35 bl 8003c78 + uint8_t rx[34]; // 2 bytes of len+status, then 32 bytes of data + uint8_t tmp[32]; + HMAC_CTX ctx; + + // HMAC(key=tpin_key, msg=given hash so far) + hmac_sha256_init(&ctx); + 800860e: a813 add r0, sp, #76 ; 0x4c + 8008610: f7fd f93c bl 800588c + hmac_sha256_update(&ctx, digest_io, 32); + 8008614: 9900 ldr r1, [sp, #0] + 8008616: 2220 movs r2, #32 + 8008618: a813 add r0, sp, #76 ; 0x4c + 800861a: f7fd f93d bl 8005898 + hmac_sha256_update(&ctx, (uint8_t *)&purpose, 4); + 800861e: 2204 movs r2, #4 + 8008620: eb0d 0102 add.w r1, sp, r2 + 8008624: a813 add r0, sp, #76 ; 0x4c + 8008626: f7fd f937 bl 8005898 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, tmp); + 800862a: 4b34 ldr r3, [pc, #208] ; (80086fc ) + 800862c: 4934 ldr r1, [pc, #208] ; (8008700 ) + 800862e: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 8008632: 33b0 adds r3, #176 ; 0xb0 + 8008634: 2aff cmp r2, #255 ; 0xff + 8008636: bf18 it ne + 8008638: 4619 movne r1, r3 + 800863a: 3180 adds r1, #128 ; 0x80 + 800863c: aa02 add r2, sp, #8 + 800863e: a813 add r0, sp, #76 ; 0x4c + 8008640: f7fd f940 bl 80058c4 + + // NOTE: exposed as cleartext here + se2_write_buffer(tmp, 32); + 8008644: 2120 movs r1, #32 + 8008646: a802 add r0, sp, #8 + 8008648: f7fe ffc8 bl 80075dc + 800864c: 25aa movs r5, #170 ; 0xaa + se2_write_buffer(rx+2, 32); + } + + // HMAC(key=secret-B, msg=consts+easy_key+buffer+consts) + // - result put in secret-S (ram) + CALL_CHECK(se2_write2(0x3c, (2<<6) | (1<<4) | PGN_SE2_EASY_KEY, 0)); + 800864e: 269e movs r6, #158 ; 0x9e + 8008650: 273c movs r7, #60 ; 0x3c + 8008652: 4622 mov r2, r4 + 8008654: 4631 mov r1, r6 + 8008656: 4638 mov r0, r7 + 8008658: f7fe ff6c bl 8007534 + 800865c: b150 cbz r0, 8008674 + 800865e: f240 511d movw r1, #1309 ; 0x51d + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8008662: 4824 ldr r0, [pc, #144] ; (80086f4 ) + 8008664: f005 f96c bl 800d940 + se2_write_buffer(rx+2, 32); + 8008668: 2120 movs r1, #32 + 800866a: f10d 002a add.w r0, sp, #42 ; 0x2a + 800866e: f7fe ffb5 bl 80075dc + 8008672: e7ee b.n 8008652 + CHECK_RIGHT(se2_read1() == RC_SUCCESS); + 8008674: f7fe ffea bl 800764c + 8008678: 28aa cmp r0, #170 ; 0xaa + 800867a: d002 beq.n 8008682 + 800867c: f240 511e movw r1, #1310 ; 0x51e + 8008680: e7ef b.n 8008662 + + // HMAC(key=S, msg=counter+junk), so we have something to read out + // - not 100% clear what contents of 'buffer' are here, but seems + // to be deterministic and unchanged from prev command + CALL_CHECK(se2_write1(0xa5, (2<<5) | PGN_DEC_COUNTER)); + 8008682: 215b movs r1, #91 ; 0x5b + 8008684: 20a5 movs r0, #165 ; 0xa5 + 8008686: f7fe ff3b bl 8007500 + 800868a: b110 cbz r0, 8008692 + 800868c: f240 5123 movw r1, #1315 ; 0x523 + 8008690: e7e7 b.n 8008662 + + CHECK_RIGHT(se2_read_n(sizeof(rx), rx) == RC_SUCCESS); + 8008692: a90a add r1, sp, #40 ; 0x28 + 8008694: 2022 movs r0, #34 ; 0x22 + 8008696: f7fe ffb1 bl 80075fc + 800869a: 28aa cmp r0, #170 ; 0xaa + 800869c: d002 beq.n 80086a4 + 800869e: f240 5125 movw r1, #1317 ; 0x525 + 80086a2: e7de b.n 8008662 + CHECK_RIGHT(rx[1] == RC_SUCCESS); + 80086a4: f89d 3029 ldrb.w r3, [sp, #41] ; 0x29 + 80086a8: 2baa cmp r3, #170 ; 0xaa + 80086aa: d002 beq.n 80086b2 + 80086ac: f240 5126 movw r1, #1318 ; 0x526 + 80086b0: e7d7 b.n 8008662 + for(int i=0; i + } + + // one final HMAC because we had to read cleartext from bus + hmac_sha256_init(&ctx); + 80086b6: a813 add r0, sp, #76 ; 0x4c + 80086b8: f7fd f8e8 bl 800588c + hmac_sha256_update(&ctx, rx+2, 32); + 80086bc: 2220 movs r2, #32 + 80086be: f10d 012a add.w r1, sp, #42 ; 0x2a + 80086c2: a813 add r0, sp, #76 ; 0x4c + 80086c4: f7fd f8e8 bl 8005898 + hmac_sha256_update(&ctx, digest_io, 32); + 80086c8: 9900 ldr r1, [sp, #0] + 80086ca: 2220 movs r2, #32 + 80086cc: a813 add r0, sp, #76 ; 0x4c + 80086ce: f7fd f8e3 bl 8005898 + hmac_sha256_final(&ctx, SE2_SECRETS->tpin_key, digest_io); + 80086d2: 4b0a ldr r3, [pc, #40] ; (80086fc ) + 80086d4: 490a ldr r1, [pc, #40] ; (8008700 ) + 80086d6: f893 20b0 ldrb.w r2, [r3, #176] ; 0xb0 + 80086da: 33b0 adds r3, #176 ; 0xb0 + 80086dc: 2aff cmp r2, #255 ; 0xff + 80086de: bf18 it ne + 80086e0: 4619 movne r1, r3 + 80086e2: 3180 adds r1, #128 ; 0x80 + 80086e4: 9a00 ldr r2, [sp, #0] + 80086e6: a813 add r0, sp, #76 ; 0x4c + 80086e8: f7fd f8ec bl 80058c4 +} + 80086ec: b055 add sp, #340 ; 0x154 + 80086ee: bdf0 pop {r4, r5, r6, r7, pc} + 80086f0: 334d1858 .word 0x334d1858 + 80086f4: 2009e394 .word 0x2009e394 + 80086f8: 0800f3d7 .word 0x0800f3d7 + 80086fc: 0801c000 .word 0x0801c000 + 8008700: 2009e2b4 .word 0x2009e2b4 + +08008704 : +// +// Read some random bytes, which we know cannot be MitM'ed. +// + void +se2_read_rng(uint8_t value[8]) +{ + 8008704: b500 push {lr} + 8008706: b08b sub sp, #44 ; 0x2c + 8008708: 9001 str r0, [sp, #4] + // funny business means MitM here + se2_setup(); + 800870a: f7ff fc51 bl 8007fb0 + if(setjmp(error_env)) fatal_mitm(); + 800870e: 4809 ldr r0, [pc, #36] ; (8008734 ) + 8008710: f005 f910 bl 800d934 + 8008714: b108 cbz r0, 800871a + 8008716: f7f8 f999 bl 8000a4c + + // read a field with "RPS" bytes, and verify those were read true + uint8_t tmp[32]; + se2_read_page(PGN_ROM_OPTIONS, tmp, true); + 800871a: a902 add r1, sp, #8 + 800871c: 2201 movs r2, #1 + 800871e: 201c movs r0, #28 + 8008720: f7ff f830 bl 8007784 + + memcpy(value, &tmp[4], 8); + 8008724: ab03 add r3, sp, #12 + 8008726: cb03 ldmia r3!, {r0, r1} + 8008728: 9b01 ldr r3, [sp, #4] + 800872a: 6018 str r0, [r3, #0] + 800872c: 6059 str r1, [r3, #4] +} + 800872e: b00b add sp, #44 ; 0x2c + 8008730: f85d fb04 ldr.w pc, [sp], #4 + 8008734: 2009e394 .word 0x2009e394 + +08008738 : + uint32_t rv; + + if(((uint32_t)src) & 0x3) { + memcpy(&rv, *src, 4); + } else { + rv = *(uint32_t *)(*src); + 8008738: 6803 ldr r3, [r0, #0] + 800873a: f853 2b04 ldr.w r2, [r3], #4 + } + (*src) += 4; + 800873e: 6003 str r3, [r0, #0] + + return __REV(rv); +} + 8008740: ba10 rev r0, r2 + 8008742: 4770 bx lr + +08008744 : + memset(ctx, 0, sizeof(AES_CTX)); + 8008744: f44f 7201 mov.w r2, #516 ; 0x204 + 8008748: 2100 movs r1, #0 + 800874a: f005 b8eb b.w 800d924 + ... + +08008750 : +{ + 8008750: b538 push {r3, r4, r5, lr} + 8008752: 4605 mov r5, r0 + memcpy(ctx->pending+ctx->num_pending, data_in, len); + 8008754: f8d0 0200 ldr.w r0, [r0, #512] ; 0x200 + 8008758: 4428 add r0, r5 +{ + 800875a: 4614 mov r4, r2 + memcpy(ctx->pending+ctx->num_pending, data_in, len); + 800875c: f005 f8d4 bl 800d908 + ctx->num_pending += len; + 8008760: f8d5 2200 ldr.w r2, [r5, #512] ; 0x200 + 8008764: 4422 add r2, r4 + ASSERT(ctx->num_pending < sizeof(ctx->pending)); + 8008766: f5b2 7f00 cmp.w r2, #512 ; 0x200 + ctx->num_pending += len; + 800876a: f8c5 2200 str.w r2, [r5, #512] ; 0x200 + ASSERT(ctx->num_pending < sizeof(ctx->pending)); + 800876e: d302 bcc.n 8008776 + 8008770: 4801 ldr r0, [pc, #4] ; (8008778 ) + 8008772: f7f8 f961 bl 8000a38 +} + 8008776: bd38 pop {r3, r4, r5, pc} + 8008778: 0801046c .word 0x0801046c + +0800877c : +// +// Do the decryption. +// + void +aes_done(AES_CTX *ctx, uint8_t data_out[], uint32_t len, const uint8_t key[32], const uint8_t nonce[AES_BLOCK_SIZE]) +{ + 800877c: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + 8008780: 4688 mov r8, r1 + 8008782: 4611 mov r1, r2 + ASSERT(len <= ctx->num_pending); + 8008784: f8d0 2200 ldr.w r2, [r0, #512] ; 0x200 +{ + 8008788: b085 sub sp, #20 + ASSERT(len <= ctx->num_pending); + 800878a: 428a cmp r2, r1 +{ + 800878c: f8dd 9030 ldr.w r9, [sp, #48] ; 0x30 + 8008790: 4606 mov r6, r0 + ASSERT(len <= ctx->num_pending); + 8008792: d202 bcs.n 800879a + 8008794: 4858 ldr r0, [pc, #352] ; (80088f8 ) + 8008796: f7f8 f94f bl 8000a38 + + // enable clock to block + __HAL_RCC_AES_CLK_ENABLE(); + 800879a: 4d58 ldr r5, [pc, #352] ; (80088fc ) + + // most changes have to be made w/ module disabled + AES->CR &= ~AES_CR_EN; + 800879c: 4c58 ldr r4, [pc, #352] ; (8008900 ) + __HAL_RCC_AES_CLK_ENABLE(); + 800879e: 6cea ldr r2, [r5, #76] ; 0x4c + 80087a0: f442 3280 orr.w r2, r2, #65536 ; 0x10000 + 80087a4: 64ea str r2, [r5, #76] ; 0x4c + 80087a6: 6cea ldr r2, [r5, #76] ; 0x4c + 80087a8: f402 3280 and.w r2, r2, #65536 ; 0x10000 + 80087ac: 9201 str r2, [sp, #4] + 80087ae: 9a01 ldr r2, [sp, #4] + AES->CR &= ~AES_CR_EN; + 80087b0: 6822 ldr r2, [r4, #0] + 80087b2: f022 0201 bic.w r2, r2, #1 + 80087b6: 6022 str r2, [r4, #0] + + // set the key size and operation mode + MODIFY_REG(AES->CR, AES_CR_KEYSIZE, CRYP_KEYSIZE_256B); + 80087b8: 6822 ldr r2, [r4, #0] + 80087ba: f442 2280 orr.w r2, r2, #262144 ; 0x40000 + 80087be: 6022 str r2, [r4, #0] + MODIFY_REG(AES->CR, AES_CR_DATATYPE|AES_CR_MODE|AES_CR_CHMOD, + 80087c0: 6827 ldr r7, [r4, #0] + 80087c2: f427 3780 bic.w r7, r7, #65536 ; 0x10000 + 80087c6: f027 077e bic.w r7, r7, #126 ; 0x7e + 80087ca: f047 0744 orr.w r7, r7, #68 ; 0x44 + 80087ce: 6027 str r7, [r4, #0] + CRYP_DATATYPE_8B | CRYP_ALGOMODE_ENCRYPT | CRYP_CHAINMODE_AES_CTR); + + // load key and IV values + const uint8_t *K = key; + AES->KEYR7 = word_pump_bytes(&K); + 80087d0: a802 add r0, sp, #8 + const uint8_t *K = key; + 80087d2: 9302 str r3, [sp, #8] + AES->KEYR7 = word_pump_bytes(&K); + 80087d4: f7ff ffb0 bl 8008738 + 80087d8: 63e0 str r0, [r4, #60] ; 0x3c + AES->KEYR6 = word_pump_bytes(&K); + 80087da: a802 add r0, sp, #8 + 80087dc: f7ff ffac bl 8008738 + 80087e0: 63a0 str r0, [r4, #56] ; 0x38 + AES->KEYR5 = word_pump_bytes(&K); + 80087e2: a802 add r0, sp, #8 + 80087e4: f7ff ffa8 bl 8008738 + 80087e8: 6360 str r0, [r4, #52] ; 0x34 + AES->KEYR4 = word_pump_bytes(&K); + 80087ea: a802 add r0, sp, #8 + 80087ec: f7ff ffa4 bl 8008738 + 80087f0: 6320 str r0, [r4, #48] ; 0x30 + AES->KEYR3 = word_pump_bytes(&K); + 80087f2: a802 add r0, sp, #8 + 80087f4: f7ff ffa0 bl 8008738 + 80087f8: 61e0 str r0, [r4, #28] + AES->KEYR2 = word_pump_bytes(&K); + 80087fa: a802 add r0, sp, #8 + 80087fc: f7ff ff9c bl 8008738 + 8008800: 61a0 str r0, [r4, #24] + AES->KEYR1 = word_pump_bytes(&K); + 8008802: a802 add r0, sp, #8 + 8008804: f7ff ff98 bl 8008738 + 8008808: 6160 str r0, [r4, #20] + AES->KEYR0 = word_pump_bytes(&K); + 800880a: a802 add r0, sp, #8 + 800880c: f7ff ff94 bl 8008738 + 8008810: 6120 str r0, [r4, #16] + + if(nonce) { + 8008812: f1b9 0f00 cmp.w r9, #0 + 8008816: d045 beq.n 80088a4 + const uint8_t *N = nonce; + AES->IVR3 = word_pump_bytes(&N); + 8008818: a803 add r0, sp, #12 + const uint8_t *N = nonce; + 800881a: f8cd 900c str.w r9, [sp, #12] + AES->IVR3 = word_pump_bytes(&N); + 800881e: f7ff ff8b bl 8008738 + 8008822: 62e0 str r0, [r4, #44] ; 0x2c + AES->IVR2 = word_pump_bytes(&N); + 8008824: a803 add r0, sp, #12 + 8008826: f7ff ff87 bl 8008738 + 800882a: 62a0 str r0, [r4, #40] ; 0x28 + AES->IVR1 = word_pump_bytes(&N); + 800882c: a803 add r0, sp, #12 + 800882e: f7ff ff83 bl 8008738 + 8008832: 6260 str r0, [r4, #36] ; 0x24 + AES->IVR0 = word_pump_bytes(&N); + 8008834: a803 add r0, sp, #12 + 8008836: f7ff ff7f bl 8008738 + 800883a: 6220 str r0, [r4, #32] + AES->IVR1 = 0; + AES->IVR0 = 0; // maybe should be byte-swapped one, but whatever + } + + // Enable the Peripheral + AES->CR |= AES_CR_EN; + 800883c: 4b30 ldr r3, [pc, #192] ; (8008900 ) + 800883e: 681a ldr r2, [r3, #0] + + ASSERT((((uint32_t)&ctx->pending) & 3) == 0); // safe because of special attr + 8008840: 07b0 lsls r0, r6, #30 + AES->CR |= AES_CR_EN; + 8008842: f042 0201 orr.w r2, r2, #1 + 8008846: 601a str r2, [r3, #0] + ASSERT((((uint32_t)&ctx->pending) & 3) == 0); // safe because of special attr + 8008848: d1a4 bne.n 8008794 + + uint32_t *p = (uint32_t *)ctx->pending; + for(int i=0; i < ctx->num_pending; i += 16) { + 800884a: f06f 070f mvn.w r7, #15 + 800884e: f8d6 0200 ldr.w r0, [r6, #512] ; 0x200 + 8008852: f106 0410 add.w r4, r6, #16 + 8008856: 1bbf subs r7, r7, r6 + 8008858: 193a adds r2, r7, r4 + 800885a: 4282 cmp r2, r0 + 800885c: db2b blt.n 80088b6 + *out = AES->DOUTR; out++; + *out = AES->DOUTR; out++; + *out = AES->DOUTR; + } + + memcpy(data_out, ctx->pending, len); + 800885e: 460a mov r2, r1 + 8008860: 4640 mov r0, r8 + 8008862: 4631 mov r1, r6 + 8008864: f005 f850 bl 800d908 + + memset(ctx, 0, sizeof(AES_CTX)); + 8008868: f44f 7201 mov.w r2, #516 ; 0x204 + 800886c: 2100 movs r1, #0 + 800886e: 4630 mov r0, r6 + 8008870: f005 f858 bl 800d924 + + // reset state of chip block, and leave clock off as well + __HAL_RCC_AES_CLK_ENABLE(); + 8008874: 6ceb ldr r3, [r5, #76] ; 0x4c + 8008876: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 800887a: 64eb str r3, [r5, #76] ; 0x4c + 800887c: 6ceb ldr r3, [r5, #76] ; 0x4c + 800887e: f403 3380 and.w r3, r3, #65536 ; 0x10000 + 8008882: 9303 str r3, [sp, #12] + 8008884: 9b03 ldr r3, [sp, #12] + __HAL_RCC_AES_FORCE_RESET(); + 8008886: 6aeb ldr r3, [r5, #44] ; 0x2c + 8008888: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 800888c: 62eb str r3, [r5, #44] ; 0x2c + __HAL_RCC_AES_RELEASE_RESET(); + 800888e: 6aeb ldr r3, [r5, #44] ; 0x2c + 8008890: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 8008894: 62eb str r3, [r5, #44] ; 0x2c + __HAL_RCC_AES_CLK_DISABLE(); + 8008896: 6ceb ldr r3, [r5, #76] ; 0x4c + 8008898: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 800889c: 64eb str r3, [r5, #76] ; 0x4c +} + 800889e: b005 add sp, #20 + 80088a0: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + AES->IVR3 = 0; + 80088a4: f8c4 902c str.w r9, [r4, #44] ; 0x2c + AES->IVR2 = 0; + 80088a8: f8c4 9028 str.w r9, [r4, #40] ; 0x28 + AES->IVR1 = 0; + 80088ac: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + AES->IVR0 = 0; // maybe should be byte-swapped one, but whatever + 80088b0: f8c4 9020 str.w r9, [r4, #32] + 80088b4: e7c2 b.n 800883c + AES->DINR = *p; p++; + 80088b6: f854 2c10 ldr.w r2, [r4, #-16] + 80088ba: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80088bc: f854 2c0c ldr.w r2, [r4, #-12] + 80088c0: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80088c2: f854 2c08 ldr.w r2, [r4, #-8] + 80088c6: 609a str r2, [r3, #8] + AES->DINR = *p; p++; + 80088c8: f854 2c04 ldr.w r2, [r4, #-4] + 80088cc: 609a str r2, [r3, #8] + while(HAL_IS_BIT_CLR(AES->SR, AES_SR_CCF)) { + 80088ce: 685a ldr r2, [r3, #4] + 80088d0: 07d2 lsls r2, r2, #31 + 80088d2: d5fc bpl.n 80088ce + SET_BIT(AES->CR, CRYP_CCF_CLEAR); + 80088d4: 681a ldr r2, [r3, #0] + 80088d6: f042 0280 orr.w r2, r2, #128 ; 0x80 + 80088da: 601a str r2, [r3, #0] + *out = AES->DOUTR; out++; + 80088dc: 68da ldr r2, [r3, #12] + 80088de: f844 2c10 str.w r2, [r4, #-16] + *out = AES->DOUTR; out++; + 80088e2: 68da ldr r2, [r3, #12] + 80088e4: f844 2c0c str.w r2, [r4, #-12] + *out = AES->DOUTR; out++; + 80088e8: 68da ldr r2, [r3, #12] + 80088ea: f844 2c08 str.w r2, [r4, #-8] + *out = AES->DOUTR; + 80088ee: 68da ldr r2, [r3, #12] + 80088f0: f844 2c04 str.w r2, [r4, #-4] + for(int i=0; i < ctx->num_pending; i += 16) { + 80088f4: 3410 adds r4, #16 + 80088f6: e7af b.n 8008858 + 80088f8: 0801046c .word 0x0801046c + 80088fc: 40021000 .word 0x40021000 + 8008900: 50060000 .word 0x50060000 + +08008904 : + voltage range. + * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11 + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange) +{ + 8008904: b537 push {r0, r1, r2, r4, r5, lr} + uint32_t vos; + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + + if(__HAL_RCC_PWR_IS_CLK_ENABLED()) + 8008906: 4d1c ldr r5, [pc, #112] ; (8008978 ) + 8008908: 6dab ldr r3, [r5, #88] ; 0x58 + 800890a: 00da lsls r2, r3, #3 +{ + 800890c: 4604 mov r4, r0 + if(__HAL_RCC_PWR_IS_CLK_ENABLED()) + 800890e: d518 bpl.n 8008942 + { + vos = HAL_PWREx_GetVoltageRange(); + 8008910: f7fe fd68 bl 80073e4 + __HAL_RCC_PWR_CLK_ENABLE(); + vos = HAL_PWREx_GetVoltageRange(); + __HAL_RCC_PWR_CLK_DISABLE(); + } + + if(vos == PWR_REGULATOR_VOLTAGE_SCALE1) + 8008914: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8008918: d123 bne.n 8008962 + { + if(msirange > RCC_MSIRANGE_8) + 800891a: 2c80 cmp r4, #128 ; 0x80 + 800891c: d928 bls.n 8008970 + latency = FLASH_LATENCY_2; /* 2WS */ + } + else + { + /* MSI 24Mhz or 32Mhz */ + latency = FLASH_LATENCY_1; /* 1WS */ + 800891e: 2ca0 cmp r4, #160 ; 0xa0 + 8008920: bf8c ite hi + 8008922: 2002 movhi r0, #2 + 8008924: 2001 movls r0, #1 + /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */ + } +#endif + } + + __HAL_FLASH_SET_LATENCY(latency); + 8008926: 4a15 ldr r2, [pc, #84] ; (800897c ) + 8008928: 6813 ldr r3, [r2, #0] + 800892a: f023 030f bic.w r3, r3, #15 + 800892e: 4303 orrs r3, r0 + 8008930: 6013 str r3, [r2, #0] + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + if(__HAL_FLASH_GET_LATENCY() != latency) + 8008932: 6813 ldr r3, [r2, #0] + 8008934: f003 030f and.w r3, r3, #15 + { + return HAL_ERROR; + } + + return HAL_OK; +} + 8008938: 1a18 subs r0, r3, r0 + 800893a: bf18 it ne + 800893c: 2001 movne r0, #1 + 800893e: b003 add sp, #12 + 8008940: bd30 pop {r4, r5, pc} + __HAL_RCC_PWR_CLK_ENABLE(); + 8008942: 6dab ldr r3, [r5, #88] ; 0x58 + 8008944: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 8008948: 65ab str r3, [r5, #88] ; 0x58 + 800894a: 6dab ldr r3, [r5, #88] ; 0x58 + 800894c: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 8008950: 9301 str r3, [sp, #4] + 8008952: 9b01 ldr r3, [sp, #4] + vos = HAL_PWREx_GetVoltageRange(); + 8008954: f7fe fd46 bl 80073e4 + __HAL_RCC_PWR_CLK_DISABLE(); + 8008958: 6dab ldr r3, [r5, #88] ; 0x58 + 800895a: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800895e: 65ab str r3, [r5, #88] ; 0x58 + 8008960: e7d8 b.n 8008914 + if(msirange >= RCC_MSIRANGE_8) + 8008962: 2c7f cmp r4, #127 ; 0x7f + 8008964: d806 bhi.n 8008974 + if(msirange == RCC_MSIRANGE_7) + 8008966: f1a4 0370 sub.w r3, r4, #112 ; 0x70 + 800896a: 4258 negs r0, r3 + 800896c: 4158 adcs r0, r3 + 800896e: e7da b.n 8008926 + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + 8008970: 2000 movs r0, #0 + 8008972: e7d8 b.n 8008926 + latency = FLASH_LATENCY_2; /* 2WS */ + 8008974: 2002 movs r0, #2 + 8008976: e7d6 b.n 8008926 + 8008978: 40021000 .word 0x40021000 + 800897c: 40022000 .word 0x40022000 + +08008980 : +{ + 8008980: b5f8 push {r3, r4, r5, r6, r7, lr} + SET_BIT(RCC->CR, RCC_CR_MSION); + 8008982: 4c32 ldr r4, [pc, #200] ; (8008a4c ) + 8008984: 6823 ldr r3, [r4, #0] + 8008986: f043 0301 orr.w r3, r3, #1 + 800898a: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800898c: f7fe fd26 bl 80073dc + 8008990: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 8008992: 6823 ldr r3, [r4, #0] + 8008994: 079b lsls r3, r3, #30 + 8008996: d543 bpl.n 8008a20 + MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6); + 8008998: 6823 ldr r3, [r4, #0] + SystemCoreClock = MSI_VALUE; + 800899a: 4a2d ldr r2, [pc, #180] ; (8008a50 ) + MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6); + 800899c: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 80089a0: f043 0360 orr.w r3, r3, #96 ; 0x60 + 80089a4: 6023 str r3, [r4, #0] + CLEAR_REG(RCC->CFGR); + 80089a6: 2300 movs r3, #0 + 80089a8: 60a3 str r3, [r4, #8] + SystemCoreClock = MSI_VALUE; + 80089aa: 4b2a ldr r3, [pc, #168] ; (8008a54 ) + 80089ac: 601a str r2, [r3, #0] + if(HAL_InitTick(uwTickPrio) != HAL_OK) + 80089ae: 4b2a ldr r3, [pc, #168] ; (8008a58 ) + 80089b0: 6818 ldr r0, [r3, #0] + 80089b2: f7fe fd15 bl 80073e0 + 80089b6: 4605 mov r5, r0 + 80089b8: 2800 cmp r0, #0 + 80089ba: d145 bne.n 8008a48 + tickstart = HAL_GetTick(); + 80089bc: f7fe fd0e bl 80073dc + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 80089c0: f241 3788 movw r7, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 80089c4: 4606 mov r6, r0 + while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + 80089c6: 68a3 ldr r3, [r4, #8] + 80089c8: f013 0f0c tst.w r3, #12 + 80089cc: d130 bne.n 8008a30 + CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON); + 80089ce: 6822 ldr r2, [r4, #0] + 80089d0: 4b22 ldr r3, [pc, #136] ; (8008a5c ) + 80089d2: 4013 ands r3, r2 + 80089d4: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80089d6: f7fe fd01 bl 80073dc + 80089da: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U) + 80089dc: 6823 ldr r3, [r4, #0] + 80089de: f013 5328 ands.w r3, r3, #704643072 ; 0x2a000000 + 80089e2: d12b bne.n 8008a3c + CLEAR_REG(RCC->PLLCFGR); + 80089e4: 60e3 str r3, [r4, #12] + SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 ); + 80089e6: 68e2 ldr r2, [r4, #12] + 80089e8: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 80089ec: 60e2 str r2, [r4, #12] + CLEAR_REG(RCC->PLLSAI1CFGR); + 80089ee: 6123 str r3, [r4, #16] + SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 ); + 80089f0: 6922 ldr r2, [r4, #16] + 80089f2: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 80089f6: 6122 str r2, [r4, #16] + CLEAR_REG(RCC->PLLSAI2CFGR); + 80089f8: 6163 str r3, [r4, #20] + SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 ); + 80089fa: 6962 ldr r2, [r4, #20] + 80089fc: f442 5280 orr.w r2, r2, #4096 ; 0x1000 + 8008a00: 6162 str r2, [r4, #20] + CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); + 8008a02: 6822 ldr r2, [r4, #0] + 8008a04: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 8008a08: 6022 str r2, [r4, #0] + CLEAR_REG(RCC->CIER); + 8008a0a: 61a3 str r3, [r4, #24] + WRITE_REG(RCC->CICR, 0xFFFFFFFFU); + 8008a0c: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 8008a10: 6223 str r3, [r4, #32] + SET_BIT(RCC->CSR, RCC_CSR_RMVF); + 8008a12: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008a16: f443 0300 orr.w r3, r3, #8388608 ; 0x800000 + 8008a1a: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + return HAL_OK; + 8008a1e: e005 b.n 8008a2c + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 8008a20: f7fe fcdc bl 80073dc + 8008a24: 1b40 subs r0, r0, r5 + 8008a26: 2802 cmp r0, #2 + 8008a28: d9b3 bls.n 8008992 + return HAL_TIMEOUT; + 8008a2a: 2503 movs r5, #3 +} + 8008a2c: 4628 mov r0, r5 + 8008a2e: bdf8 pop {r3, r4, r5, r6, r7, pc} + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 8008a30: f7fe fcd4 bl 80073dc + 8008a34: 1b80 subs r0, r0, r6 + 8008a36: 42b8 cmp r0, r7 + 8008a38: d9c5 bls.n 80089c6 + 8008a3a: e7f6 b.n 8008a2a + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8008a3c: f7fe fcce bl 80073dc + 8008a40: 1b80 subs r0, r0, r6 + 8008a42: 2802 cmp r0, #2 + 8008a44: d9ca bls.n 80089dc + 8008a46: e7f0 b.n 8008a2a + return HAL_ERROR; + 8008a48: 2501 movs r5, #1 + 8008a4a: e7ef b.n 8008a2c + 8008a4c: 40021000 .word 0x40021000 + 8008a50: 003d0900 .word 0x003d0900 + 8008a54: 2009e2ac .word 0x2009e2ac + 8008a58: 2009e2b0 .word 0x2009e2b0 + 8008a5c: eafef4ff .word 0xeafef4ff + +08008a60 : +{ + 8008a60: b570 push {r4, r5, r6, lr} + __MCO1_CLK_ENABLE(); + 8008a62: 4c12 ldr r4, [pc, #72] ; (8008aac ) + 8008a64: 6ce3 ldr r3, [r4, #76] ; 0x4c + 8008a66: f043 0301 orr.w r3, r3, #1 + 8008a6a: 64e3 str r3, [r4, #76] ; 0x4c + 8008a6c: 6ce3 ldr r3, [r4, #76] ; 0x4c +{ + 8008a6e: b086 sub sp, #24 + __MCO1_CLK_ENABLE(); + 8008a70: f003 0301 and.w r3, r3, #1 + 8008a74: 9300 str r3, [sp, #0] + 8008a76: 9b00 ldr r3, [sp, #0] +{ + 8008a78: 4616 mov r6, r2 + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + 8008a7a: 2302 movs r3, #2 + 8008a7c: f44f 7280 mov.w r2, #256 ; 0x100 + 8008a80: e9cd 2301 strd r2, r3, [sp, #4] +{ + 8008a84: 460d mov r5, r1 + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + 8008a86: 9304 str r3, [sp, #16] + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 8008a88: a901 add r1, sp, #4 + GPIO_InitStruct.Pull = GPIO_NOPULL; + 8008a8a: 2300 movs r3, #0 + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 8008a8c: f04f 4090 mov.w r0, #1207959552 ; 0x48000000 + GPIO_InitStruct.Pull = GPIO_NOPULL; + 8008a90: 9303 str r3, [sp, #12] + GPIO_InitStruct.Alternate = GPIO_AF0_MCO; + 8008a92: 9305 str r3, [sp, #20] + HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); + 8008a94: f7f8 fbae bl 80011f4 + MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv )); + 8008a98: 68a3 ldr r3, [r4, #8] + 8008a9a: f023 43fe bic.w r3, r3, #2130706432 ; 0x7f000000 + 8008a9e: ea43 0206 orr.w r2, r3, r6 + 8008aa2: 432a orrs r2, r5 + 8008aa4: 60a2 str r2, [r4, #8] +} + 8008aa6: b006 add sp, #24 + 8008aa8: bd70 pop {r4, r5, r6, pc} + 8008aaa: bf00 nop + 8008aac: 40021000 .word 0x40021000 + +08008ab0 : + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008ab0: 4b22 ldr r3, [pc, #136] ; (8008b3c ) + 8008ab2: 689a ldr r2, [r3, #8] + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8008ab4: 68d9 ldr r1, [r3, #12] + if((sysclk_source == RCC_CFGR_SWS_MSI) || + 8008ab6: f012 020c ands.w r2, r2, #12 + 8008aba: d005 beq.n 8008ac8 + 8008abc: 2a0c cmp r2, #12 + 8008abe: d115 bne.n 8008aec + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8008ac0: f001 0103 and.w r1, r1, #3 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI))) + 8008ac4: 2901 cmp r1, #1 + 8008ac6: d118 bne.n 8008afa + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 8008ac8: 6819 ldr r1, [r3, #0] + msirange = MSIRangeTable[msirange]; + 8008aca: 481d ldr r0, [pc, #116] ; (8008b40 ) + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 8008acc: 0709 lsls r1, r1, #28 + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 8008ace: bf55 itete pl + 8008ad0: f8d3 1094 ldrpl.w r1, [r3, #148] ; 0x94 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 8008ad4: 6819 ldrmi r1, [r3, #0] + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 8008ad6: f3c1 2103 ubfxpl r1, r1, #8, #4 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 8008ada: f3c1 1103 ubfxmi r1, r1, #4, #4 + msirange = MSIRangeTable[msirange]; + 8008ade: f850 0021 ldr.w r0, [r0, r1, lsl #2] + if(sysclk_source == RCC_CFGR_SWS_MSI) + 8008ae2: b34a cbz r2, 8008b38 + if(sysclk_source == RCC_CFGR_SWS_PLL) + 8008ae4: 2a0c cmp r2, #12 + 8008ae6: d009 beq.n 8008afc + 8008ae8: 2000 movs r0, #0 + return sysclockfreq; + 8008aea: 4770 bx lr + else if(sysclk_source == RCC_CFGR_SWS_HSI) + 8008aec: 2a04 cmp r2, #4 + 8008aee: d022 beq.n 8008b36 + else if(sysclk_source == RCC_CFGR_SWS_HSE) + 8008af0: 2a08 cmp r2, #8 + 8008af2: 4814 ldr r0, [pc, #80] ; (8008b44 ) + 8008af4: bf18 it ne + 8008af6: 2000 movne r0, #0 + 8008af8: 4770 bx lr + uint32_t msirange = 0U, sysclockfreq = 0U; + 8008afa: 2000 movs r0, #0 + pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8008afc: 68da ldr r2, [r3, #12] + 8008afe: f002 0203 and.w r2, r2, #3 + switch (pllsource) + 8008b02: 2a02 cmp r2, #2 + 8008b04: d015 beq.n 8008b32 + 8008b06: 490f ldr r1, [pc, #60] ; (8008b44 ) + 8008b08: 2a03 cmp r2, #3 + 8008b0a: bf08 it eq + 8008b0c: 4608 moveq r0, r1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008b0e: 68d9 ldr r1, [r3, #12] + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 8008b10: 68da ldr r2, [r3, #12] + 8008b12: f3c2 2206 ubfx r2, r2, #8, #7 + 8008b16: 4342 muls r2, r0 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008b18: 68d8 ldr r0, [r3, #12] + 8008b1a: f3c0 6041 ubfx r0, r0, #25, #2 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008b1e: f3c1 1103 ubfx r1, r1, #4, #4 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008b22: 3001 adds r0, #1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 8008b24: 3101 adds r1, #1 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8008b26: 0040 lsls r0, r0, #1 + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 8008b28: fbb2 f2f1 udiv r2, r2, r1 + sysclockfreq = pllvco / pllr; + 8008b2c: fbb2 f0f0 udiv r0, r2, r0 + 8008b30: 4770 bx lr + pllvco = HSI_VALUE; + 8008b32: 4805 ldr r0, [pc, #20] ; (8008b48 ) + 8008b34: e7eb b.n 8008b0e + sysclockfreq = HSI_VALUE; + 8008b36: 4804 ldr r0, [pc, #16] ; (8008b48 ) +} + 8008b38: 4770 bx lr + 8008b3a: bf00 nop + 8008b3c: 40021000 .word 0x40021000 + 8008b40: 08010a70 .word 0x08010a70 + 8008b44: 007a1200 .word 0x007a1200 + 8008b48: 00f42400 .word 0x00f42400 + +08008b4c : +{ + 8008b4c: e92d 43f7 stmdb sp!, {r0, r1, r2, r4, r5, r6, r7, r8, r9, lr} + if(RCC_OscInitStruct == NULL) + 8008b50: 4605 mov r5, r0 + 8008b52: b908 cbnz r0, 8008b58 + return HAL_ERROR; + 8008b54: 2001 movs r0, #1 + 8008b56: e047 b.n 8008be8 + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008b58: 4c94 ldr r4, [pc, #592] ; (8008dac ) + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 8008b5a: 6803 ldr r3, [r0, #0] + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008b5c: 68a6 ldr r6, [r4, #8] + pll_config = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8008b5e: 68e7 ldr r7, [r4, #12] + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 8008b60: 06db lsls r3, r3, #27 + sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); + 8008b62: f006 060c and.w r6, r6, #12 + pll_config = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8008b66: f007 0703 and.w r7, r7, #3 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + 8008b6a: d575 bpl.n 8008c58 + if((sysclk_source == RCC_CFGR_SWS_MSI) || + 8008b6c: b11e cbz r6, 8008b76 + 8008b6e: 2e0c cmp r6, #12 + 8008b70: d154 bne.n 8008c1c + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_MSI))) + 8008b72: 2f01 cmp r7, #1 + 8008b74: d152 bne.n 8008c1c + if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)) + 8008b76: 6823 ldr r3, [r4, #0] + 8008b78: 0798 lsls r0, r3, #30 + 8008b7a: d502 bpl.n 8008b82 + 8008b7c: 69ab ldr r3, [r5, #24] + 8008b7e: 2b00 cmp r3, #0 + 8008b80: d0e8 beq.n 8008b54 + if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE()) + 8008b82: 6823 ldr r3, [r4, #0] + 8008b84: 6a28 ldr r0, [r5, #32] + 8008b86: 0719 lsls r1, r3, #28 + 8008b88: bf56 itet pl + 8008b8a: f8d4 3094 ldrpl.w r3, [r4, #148] ; 0x94 + 8008b8e: 6823 ldrmi r3, [r4, #0] + 8008b90: 091b lsrpl r3, r3, #4 + 8008b92: f003 03f0 and.w r3, r3, #240 ; 0xf0 + 8008b96: 4298 cmp r0, r3 + 8008b98: d929 bls.n 8008bee + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + 8008b9a: f7ff feb3 bl 8008904 + 8008b9e: 2800 cmp r0, #0 + 8008ba0: d1d8 bne.n 8008b54 + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 8008ba2: 6823 ldr r3, [r4, #0] + 8008ba4: f043 0308 orr.w r3, r3, #8 + 8008ba8: 6023 str r3, [r4, #0] + 8008baa: 6823 ldr r3, [r4, #0] + 8008bac: 6a2a ldr r2, [r5, #32] + 8008bae: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008bb2: 4313 orrs r3, r2 + 8008bb4: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 8008bb6: 6863 ldr r3, [r4, #4] + 8008bb8: 69ea ldr r2, [r5, #28] + 8008bba: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 8008bbe: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008bc2: 6063 str r3, [r4, #4] + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); + 8008bc4: f7ff ff74 bl 8008ab0 + 8008bc8: 68a3 ldr r3, [r4, #8] + 8008bca: 4a79 ldr r2, [pc, #484] ; (8008db0 ) + 8008bcc: f3c3 1303 ubfx r3, r3, #4, #4 + 8008bd0: 5cd3 ldrb r3, [r2, r3] + 8008bd2: f003 031f and.w r3, r3, #31 + 8008bd6: 40d8 lsrs r0, r3 + 8008bd8: 4b76 ldr r3, [pc, #472] ; (8008db4 ) + 8008bda: 6018 str r0, [r3, #0] + status = HAL_InitTick(uwTickPrio); + 8008bdc: 4b76 ldr r3, [pc, #472] ; (8008db8 ) + 8008bde: 6818 ldr r0, [r3, #0] + 8008be0: f7fe fbfe bl 80073e0 + if(status != HAL_OK) + 8008be4: 2800 cmp r0, #0 + 8008be6: d037 beq.n 8008c58 +} + 8008be8: b003 add sp, #12 + 8008bea: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 8008bee: 6823 ldr r3, [r4, #0] + 8008bf0: f043 0308 orr.w r3, r3, #8 + 8008bf4: 6023 str r3, [r4, #0] + 8008bf6: 6823 ldr r3, [r4, #0] + 8008bf8: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008bfc: 4303 orrs r3, r0 + 8008bfe: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 8008c00: 6863 ldr r3, [r4, #4] + 8008c02: 69ea ldr r2, [r5, #28] + 8008c04: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 8008c08: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008c0c: 6063 str r3, [r4, #4] + if(sysclk_source == RCC_CFGR_SWS_MSI) + 8008c0e: 2e00 cmp r6, #0 + 8008c10: d1d8 bne.n 8008bc4 + if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + 8008c12: f7ff fe77 bl 8008904 + 8008c16: 2800 cmp r0, #0 + 8008c18: d0d4 beq.n 8008bc4 + 8008c1a: e79b b.n 8008b54 + if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF) + 8008c1c: 69ab ldr r3, [r5, #24] + 8008c1e: 2b00 cmp r3, #0 + 8008c20: d03a beq.n 8008c98 + __HAL_RCC_MSI_ENABLE(); + 8008c22: 6823 ldr r3, [r4, #0] + 8008c24: f043 0301 orr.w r3, r3, #1 + 8008c28: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008c2a: f7fe fbd7 bl 80073dc + 8008c2e: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 8008c30: 6823 ldr r3, [r4, #0] + 8008c32: 079a lsls r2, r3, #30 + 8008c34: d528 bpl.n 8008c88 + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + 8008c36: 6823 ldr r3, [r4, #0] + 8008c38: f043 0308 orr.w r3, r3, #8 + 8008c3c: 6023 str r3, [r4, #0] + 8008c3e: 6823 ldr r3, [r4, #0] + 8008c40: 6a2a ldr r2, [r5, #32] + 8008c42: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8008c46: 4313 orrs r3, r2 + 8008c48: 6023 str r3, [r4, #0] + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + 8008c4a: 6863 ldr r3, [r4, #4] + 8008c4c: 69ea ldr r2, [r5, #28] + 8008c4e: f423 437f bic.w r3, r3, #65280 ; 0xff00 + 8008c52: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008c56: 6063 str r3, [r4, #4] + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + 8008c58: 682b ldr r3, [r5, #0] + 8008c5a: 07d8 lsls r0, r3, #31 + 8008c5c: d42d bmi.n 8008cba + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) + 8008c5e: 682b ldr r3, [r5, #0] + 8008c60: 0799 lsls r1, r3, #30 + 8008c62: d46b bmi.n 8008d3c + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) + 8008c64: 682b ldr r3, [r5, #0] + 8008c66: 0718 lsls r0, r3, #28 + 8008c68: f100 80a8 bmi.w 8008dbc + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + 8008c6c: 682b ldr r3, [r5, #0] + 8008c6e: 0759 lsls r1, r3, #29 + 8008c70: f100 80ce bmi.w 8008e10 + if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) + 8008c74: 682b ldr r3, [r5, #0] + 8008c76: 069f lsls r7, r3, #26 + 8008c78: f100 8137 bmi.w 8008eea + if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE) + 8008c7c: 6aab ldr r3, [r5, #40] ; 0x28 + 8008c7e: 2b00 cmp r3, #0 + 8008c80: f040 815d bne.w 8008f3e + return HAL_OK; + 8008c84: 2000 movs r0, #0 + 8008c86: e7af b.n 8008be8 + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 8008c88: f7fe fba8 bl 80073dc + 8008c8c: eba0 0008 sub.w r0, r0, r8 + 8008c90: 2802 cmp r0, #2 + 8008c92: d9cd bls.n 8008c30 + return HAL_TIMEOUT; + 8008c94: 2003 movs r0, #3 + 8008c96: e7a7 b.n 8008be8 + __HAL_RCC_MSI_DISABLE(); + 8008c98: 6823 ldr r3, [r4, #0] + 8008c9a: f023 0301 bic.w r3, r3, #1 + 8008c9e: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008ca0: f7fe fb9c bl 80073dc + 8008ca4: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) + 8008ca6: 6823 ldr r3, [r4, #0] + 8008ca8: 079b lsls r3, r3, #30 + 8008caa: d5d5 bpl.n 8008c58 + if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + 8008cac: f7fe fb96 bl 80073dc + 8008cb0: eba0 0008 sub.w r0, r0, r8 + 8008cb4: 2802 cmp r0, #2 + 8008cb6: d9f6 bls.n 8008ca6 + 8008cb8: e7ec b.n 8008c94 + if((sysclk_source == RCC_CFGR_SWS_HSE) || + 8008cba: 2e08 cmp r6, #8 + 8008cbc: d003 beq.n 8008cc6 + 8008cbe: 2e0c cmp r6, #12 + 8008cc0: d108 bne.n 8008cd4 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSE))) + 8008cc2: 2f03 cmp r7, #3 + 8008cc4: d106 bne.n 8008cd4 + if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) + 8008cc6: 6823 ldr r3, [r4, #0] + 8008cc8: 039a lsls r2, r3, #14 + 8008cca: d5c8 bpl.n 8008c5e + 8008ccc: 686b ldr r3, [r5, #4] + 8008cce: 2b00 cmp r3, #0 + 8008cd0: d1c5 bne.n 8008c5e + 8008cd2: e73f b.n 8008b54 + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 8008cd4: 686b ldr r3, [r5, #4] + 8008cd6: f5b3 3f80 cmp.w r3, #65536 ; 0x10000 + 8008cda: d110 bne.n 8008cfe + 8008cdc: 6823 ldr r3, [r4, #0] + 8008cde: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8008ce2: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008ce4: f7fe fb7a bl 80073dc + 8008ce8: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + 8008cea: 6823 ldr r3, [r4, #0] + 8008cec: 039b lsls r3, r3, #14 + 8008cee: d4b6 bmi.n 8008c5e + if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + 8008cf0: f7fe fb74 bl 80073dc + 8008cf4: eba0 0008 sub.w r0, r0, r8 + 8008cf8: 2864 cmp r0, #100 ; 0x64 + 8008cfa: d9f6 bls.n 8008cea + 8008cfc: e7ca b.n 8008c94 + __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); + 8008cfe: f5b3 2fa0 cmp.w r3, #327680 ; 0x50000 + 8008d02: d104 bne.n 8008d0e + 8008d04: 6823 ldr r3, [r4, #0] + 8008d06: f443 2380 orr.w r3, r3, #262144 ; 0x40000 + 8008d0a: 6023 str r3, [r4, #0] + 8008d0c: e7e6 b.n 8008cdc + 8008d0e: 6822 ldr r2, [r4, #0] + 8008d10: f422 3280 bic.w r2, r2, #65536 ; 0x10000 + 8008d14: 6022 str r2, [r4, #0] + 8008d16: 6822 ldr r2, [r4, #0] + 8008d18: f422 2280 bic.w r2, r2, #262144 ; 0x40000 + 8008d1c: 6022 str r2, [r4, #0] + if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) + 8008d1e: 2b00 cmp r3, #0 + 8008d20: d1e0 bne.n 8008ce4 + tickstart = HAL_GetTick(); + 8008d22: f7fe fb5b bl 80073dc + 8008d26: 4680 mov r8, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) + 8008d28: 6823 ldr r3, [r4, #0] + 8008d2a: 0398 lsls r0, r3, #14 + 8008d2c: d597 bpl.n 8008c5e + if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + 8008d2e: f7fe fb55 bl 80073dc + 8008d32: eba0 0008 sub.w r0, r0, r8 + 8008d36: 2864 cmp r0, #100 ; 0x64 + 8008d38: d9f6 bls.n 8008d28 + 8008d3a: e7ab b.n 8008c94 + if((sysclk_source == RCC_CFGR_SWS_HSI) || + 8008d3c: 2e04 cmp r6, #4 + 8008d3e: d003 beq.n 8008d48 + 8008d40: 2e0c cmp r6, #12 + 8008d42: d110 bne.n 8008d66 + ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSI))) + 8008d44: 2f02 cmp r7, #2 + 8008d46: d10e bne.n 8008d66 + if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)) + 8008d48: 6823 ldr r3, [r4, #0] + 8008d4a: 0559 lsls r1, r3, #21 + 8008d4c: d503 bpl.n 8008d56 + 8008d4e: 68eb ldr r3, [r5, #12] + 8008d50: 2b00 cmp r3, #0 + 8008d52: f43f aeff beq.w 8008b54 + __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); + 8008d56: 6863 ldr r3, [r4, #4] + 8008d58: 692a ldr r2, [r5, #16] + 8008d5a: f023 43fe bic.w r3, r3, #2130706432 ; 0x7f000000 + 8008d5e: ea43 6302 orr.w r3, r3, r2, lsl #24 + 8008d62: 6063 str r3, [r4, #4] + 8008d64: e77e b.n 8008c64 + if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + 8008d66: 68eb ldr r3, [r5, #12] + 8008d68: b17b cbz r3, 8008d8a + __HAL_RCC_HSI_ENABLE(); + 8008d6a: 6823 ldr r3, [r4, #0] + 8008d6c: f443 7380 orr.w r3, r3, #256 ; 0x100 + 8008d70: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008d72: f7fe fb33 bl 80073dc + 8008d76: 4607 mov r7, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 8008d78: 6823 ldr r3, [r4, #0] + 8008d7a: 055a lsls r2, r3, #21 + 8008d7c: d4eb bmi.n 8008d56 + if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + 8008d7e: f7fe fb2d bl 80073dc + 8008d82: 1bc0 subs r0, r0, r7 + 8008d84: 2802 cmp r0, #2 + 8008d86: d9f7 bls.n 8008d78 + 8008d88: e784 b.n 8008c94 + __HAL_RCC_HSI_DISABLE(); + 8008d8a: 6823 ldr r3, [r4, #0] + 8008d8c: f423 7380 bic.w r3, r3, #256 ; 0x100 + 8008d90: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008d92: f7fe fb23 bl 80073dc + 8008d96: 4607 mov r7, r0 + while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) + 8008d98: 6823 ldr r3, [r4, #0] + 8008d9a: 055b lsls r3, r3, #21 + 8008d9c: f57f af62 bpl.w 8008c64 + if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + 8008da0: f7fe fb1c bl 80073dc + 8008da4: 1bc0 subs r0, r0, r7 + 8008da6: 2802 cmp r0, #2 + 8008da8: d9f6 bls.n 8008d98 + 8008daa: e773 b.n 8008c94 + 8008dac: 40021000 .word 0x40021000 + 8008db0: 08010a58 .word 0x08010a58 + 8008db4: 2009e2ac .word 0x2009e2ac + 8008db8: 2009e2b0 .word 0x2009e2b0 + if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + 8008dbc: 696b ldr r3, [r5, #20] + 8008dbe: b19b cbz r3, 8008de8 + __HAL_RCC_LSI_ENABLE(); + 8008dc0: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008dc4: f043 0301 orr.w r3, r3, #1 + 8008dc8: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + tickstart = HAL_GetTick(); + 8008dcc: f7fe fb06 bl 80073dc + 8008dd0: 4607 mov r7, r0 + while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U) + 8008dd2: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008dd6: 079a lsls r2, r3, #30 + 8008dd8: f53f af48 bmi.w 8008c6c + if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + 8008ddc: f7fe fafe bl 80073dc + 8008de0: 1bc0 subs r0, r0, r7 + 8008de2: 2802 cmp r0, #2 + 8008de4: d9f5 bls.n 8008dd2 + 8008de6: e755 b.n 8008c94 + __HAL_RCC_LSI_DISABLE(); + 8008de8: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008dec: f023 0301 bic.w r3, r3, #1 + 8008df0: f8c4 3094 str.w r3, [r4, #148] ; 0x94 + tickstart = HAL_GetTick(); + 8008df4: f7fe faf2 bl 80073dc + 8008df8: 4607 mov r7, r0 + while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) + 8008dfa: f8d4 3094 ldr.w r3, [r4, #148] ; 0x94 + 8008dfe: 079b lsls r3, r3, #30 + 8008e00: f57f af34 bpl.w 8008c6c + if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) + 8008e04: f7fe faea bl 80073dc + 8008e08: 1bc0 subs r0, r0, r7 + 8008e0a: 2802 cmp r0, #2 + 8008e0c: d9f5 bls.n 8008dfa + 8008e0e: e741 b.n 8008c94 + if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN)) + 8008e10: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008e12: 00df lsls r7, r3, #3 + 8008e14: d429 bmi.n 8008e6a + __HAL_RCC_PWR_CLK_ENABLE(); + 8008e16: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008e18: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 8008e1c: 65a3 str r3, [r4, #88] ; 0x58 + 8008e1e: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008e20: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 8008e24: 9301 str r3, [sp, #4] + 8008e26: 9b01 ldr r3, [sp, #4] + pwrclkchanged = SET; + 8008e28: f04f 0801 mov.w r8, #1 + if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) + 8008e2c: 4f9c ldr r7, [pc, #624] ; (80090a0 ) + 8008e2e: 683b ldr r3, [r7, #0] + 8008e30: 05d8 lsls r0, r3, #23 + 8008e32: d51d bpl.n 8008e70 + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8008e34: 68ab ldr r3, [r5, #8] + 8008e36: 2b01 cmp r3, #1 + 8008e38: d12b bne.n 8008e92 + 8008e3a: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008e3e: f043 0301 orr.w r3, r3, #1 + 8008e42: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + tickstart = HAL_GetTick(); + 8008e46: f7fe fac9 bl 80073dc + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008e4a: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8008e4e: 4607 mov r7, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + 8008e50: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008e54: 079a lsls r2, r3, #30 + 8008e56: d542 bpl.n 8008ede + if(pwrclkchanged == SET) + 8008e58: f1b8 0f00 cmp.w r8, #0 + 8008e5c: f43f af0a beq.w 8008c74 + __HAL_RCC_PWR_CLK_DISABLE(); + 8008e60: 6da3 ldr r3, [r4, #88] ; 0x58 + 8008e62: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8008e66: 65a3 str r3, [r4, #88] ; 0x58 + 8008e68: e704 b.n 8008c74 + FlagStatus pwrclkchanged = RESET; + 8008e6a: f04f 0800 mov.w r8, #0 + 8008e6e: e7dd b.n 8008e2c + SET_BIT(PWR->CR1, PWR_CR1_DBP); + 8008e70: 683b ldr r3, [r7, #0] + 8008e72: f443 7380 orr.w r3, r3, #256 ; 0x100 + 8008e76: 603b str r3, [r7, #0] + tickstart = HAL_GetTick(); + 8008e78: f7fe fab0 bl 80073dc + 8008e7c: 4681 mov r9, r0 + while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) + 8008e7e: 683b ldr r3, [r7, #0] + 8008e80: 05d9 lsls r1, r3, #23 + 8008e82: d4d7 bmi.n 8008e34 + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 8008e84: f7fe faaa bl 80073dc + 8008e88: eba0 0009 sub.w r0, r0, r9 + 8008e8c: 2802 cmp r0, #2 + 8008e8e: d9f6 bls.n 8008e7e + 8008e90: e700 b.n 8008c94 + __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); + 8008e92: 2b05 cmp r3, #5 + 8008e94: d106 bne.n 8008ea4 + 8008e96: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008e9a: f043 0304 orr.w r3, r3, #4 + 8008e9e: f8c4 3090 str.w r3, [r4, #144] ; 0x90 + 8008ea2: e7ca b.n 8008e3a + 8008ea4: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8008ea8: f022 0201 bic.w r2, r2, #1 + 8008eac: f8c4 2090 str.w r2, [r4, #144] ; 0x90 + 8008eb0: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8008eb4: f022 0204 bic.w r2, r2, #4 + 8008eb8: f8c4 2090 str.w r2, [r4, #144] ; 0x90 + if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) + 8008ebc: 2b00 cmp r3, #0 + 8008ebe: d1c2 bne.n 8008e46 + tickstart = HAL_GetTick(); + 8008ec0: f7fe fa8c bl 80073dc + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008ec4: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8008ec8: 4607 mov r7, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) + 8008eca: f8d4 3090 ldr.w r3, [r4, #144] ; 0x90 + 8008ece: 079b lsls r3, r3, #30 + 8008ed0: d5c2 bpl.n 8008e58 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008ed2: f7fe fa83 bl 80073dc + 8008ed6: 1bc0 subs r0, r0, r7 + 8008ed8: 4548 cmp r0, r9 + 8008eda: d9f6 bls.n 8008eca + 8008edc: e6da b.n 8008c94 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8008ede: f7fe fa7d bl 80073dc + 8008ee2: 1bc0 subs r0, r0, r7 + 8008ee4: 4548 cmp r0, r9 + 8008ee6: d9b3 bls.n 8008e50 + 8008ee8: e6d4 b.n 8008c94 + if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) + 8008eea: 6a6b ldr r3, [r5, #36] ; 0x24 + 8008eec: b19b cbz r3, 8008f16 + __HAL_RCC_HSI48_ENABLE(); + 8008eee: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008ef2: f043 0301 orr.w r3, r3, #1 + 8008ef6: f8c4 3098 str.w r3, [r4, #152] ; 0x98 + tickstart = HAL_GetTick(); + 8008efa: f7fe fa6f bl 80073dc + 8008efe: 4607 mov r7, r0 + while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U) + 8008f00: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008f04: 0798 lsls r0, r3, #30 + 8008f06: f53f aeb9 bmi.w 8008c7c + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8008f0a: f7fe fa67 bl 80073dc + 8008f0e: 1bc0 subs r0, r0, r7 + 8008f10: 2802 cmp r0, #2 + 8008f12: d9f5 bls.n 8008f00 + 8008f14: e6be b.n 8008c94 + __HAL_RCC_HSI48_DISABLE(); + 8008f16: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008f1a: f023 0301 bic.w r3, r3, #1 + 8008f1e: f8c4 3098 str.w r3, [r4, #152] ; 0x98 + tickstart = HAL_GetTick(); + 8008f22: f7fe fa5b bl 80073dc + 8008f26: 4607 mov r7, r0 + while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U) + 8008f28: f8d4 3098 ldr.w r3, [r4, #152] ; 0x98 + 8008f2c: 0799 lsls r1, r3, #30 + 8008f2e: f57f aea5 bpl.w 8008c7c + if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) + 8008f32: f7fe fa53 bl 80073dc + 8008f36: 1bc0 subs r0, r0, r7 + 8008f38: 2802 cmp r0, #2 + 8008f3a: d9f5 bls.n 8008f28 + 8008f3c: e6aa b.n 8008c94 + if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON) + 8008f3e: 2b02 cmp r3, #2 + 8008f40: f040 808c bne.w 800905c + pll_config = RCC->PLLCFGR; + 8008f44: 68e3 ldr r3, [r4, #12] + if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8008f46: 6aea ldr r2, [r5, #44] ; 0x2c + 8008f48: f003 0103 and.w r1, r3, #3 + 8008f4c: 4291 cmp r1, r2 + 8008f4e: d122 bne.n 8008f96 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) || + 8008f50: 6b29 ldr r1, [r5, #48] ; 0x30 + 8008f52: f003 02f0 and.w r2, r3, #240 ; 0xf0 + 8008f56: 3901 subs r1, #1 + if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + 8008f58: ebb2 1f01 cmp.w r2, r1, lsl #4 + 8008f5c: d11b bne.n 8008f96 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) || + 8008f5e: 6b69 ldr r1, [r5, #52] ; 0x34 + 8008f60: f403 42fe and.w r2, r3, #32512 ; 0x7f00 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) || + 8008f64: ebb2 2f01 cmp.w r2, r1, lsl #8 + 8008f68: d115 bne.n 8008f96 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) || + 8008f6a: 6ba9 ldr r1, [r5, #56] ; 0x38 + 8008f6c: f003 4278 and.w r2, r3, #4160749568 ; 0xf8000000 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) || + 8008f70: ebb2 6fc1 cmp.w r2, r1, lsl #27 + 8008f74: d10f bne.n 8008f96 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) || + 8008f76: 6bea ldr r2, [r5, #60] ; 0x3c + 8008f78: 0852 lsrs r2, r2, #1 + 8008f7a: f403 01c0 and.w r1, r3, #6291456 ; 0x600000 + 8008f7e: 3a01 subs r2, #1 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) || + 8008f80: ebb1 5f42 cmp.w r1, r2, lsl #21 + 8008f84: d107 bne.n 8008f96 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos))) + 8008f86: 6c2a ldr r2, [r5, #64] ; 0x40 + 8008f88: 0852 lsrs r2, r2, #1 + 8008f8a: f003 63c0 and.w r3, r3, #100663296 ; 0x6000000 + 8008f8e: 3a01 subs r2, #1 + (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) || + 8008f90: ebb3 6f42 cmp.w r3, r2, lsl #25 + 8008f94: d049 beq.n 800902a + if(sysclk_source != RCC_CFGR_SWS_PLL) + 8008f96: 2e0c cmp r6, #12 + 8008f98: f43f addc beq.w 8008b54 + if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U) + 8008f9c: 6823 ldr r3, [r4, #0] + 8008f9e: 015a lsls r2, r3, #5 + 8008fa0: f53f add8 bmi.w 8008b54 + || (READ_BIT(RCC->CR, RCC_CR_PLLSAI2ON) != 0U) + 8008fa4: 6823 ldr r3, [r4, #0] + 8008fa6: 00db lsls r3, r3, #3 + 8008fa8: f53f add4 bmi.w 8008b54 + __HAL_RCC_PLL_DISABLE(); + 8008fac: 6823 ldr r3, [r4, #0] + 8008fae: f023 7380 bic.w r3, r3, #16777216 ; 0x1000000 + 8008fb2: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 8008fb4: f7fe fa12 bl 80073dc + 8008fb8: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) + 8008fba: 6823 ldr r3, [r4, #0] + 8008fbc: 019f lsls r7, r3, #6 + 8008fbe: d42e bmi.n 800901e + __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, + 8008fc0: 68e2 ldr r2, [r4, #12] + 8008fc2: 4b38 ldr r3, [pc, #224] ; (80090a4 ) + 8008fc4: 4013 ands r3, r2 + 8008fc6: 6aea ldr r2, [r5, #44] ; 0x2c + 8008fc8: 4313 orrs r3, r2 + 8008fca: 6b6a ldr r2, [r5, #52] ; 0x34 + 8008fcc: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8008fd0: 6baa ldr r2, [r5, #56] ; 0x38 + 8008fd2: ea43 63c2 orr.w r3, r3, r2, lsl #27 + 8008fd6: 6b2a ldr r2, [r5, #48] ; 0x30 + 8008fd8: 3a01 subs r2, #1 + 8008fda: ea43 1302 orr.w r3, r3, r2, lsl #4 + 8008fde: 6bea ldr r2, [r5, #60] ; 0x3c + 8008fe0: 0852 lsrs r2, r2, #1 + 8008fe2: 3a01 subs r2, #1 + 8008fe4: ea43 5342 orr.w r3, r3, r2, lsl #21 + 8008fe8: 6c2a ldr r2, [r5, #64] ; 0x40 + 8008fea: 0852 lsrs r2, r2, #1 + 8008fec: 3a01 subs r2, #1 + 8008fee: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8008ff2: 60e3 str r3, [r4, #12] + __HAL_RCC_PLL_ENABLE(); + 8008ff4: 6823 ldr r3, [r4, #0] + 8008ff6: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8008ffa: 6023 str r3, [r4, #0] + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + 8008ffc: 68e3 ldr r3, [r4, #12] + 8008ffe: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8009002: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8009004: f7fe f9ea bl 80073dc + 8009008: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 800900a: 6823 ldr r3, [r4, #0] + 800900c: 0198 lsls r0, r3, #6 + 800900e: f53f ae39 bmi.w 8008c84 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8009012: f7fe f9e3 bl 80073dc + 8009016: 1b40 subs r0, r0, r5 + 8009018: 2802 cmp r0, #2 + 800901a: d9f6 bls.n 800900a + 800901c: e63a b.n 8008c94 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 800901e: f7fe f9dd bl 80073dc + 8009022: 1b80 subs r0, r0, r6 + 8009024: 2802 cmp r0, #2 + 8009026: d9c8 bls.n 8008fba + 8009028: e634 b.n 8008c94 + if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 800902a: 6823 ldr r3, [r4, #0] + 800902c: 0199 lsls r1, r3, #6 + 800902e: f53f ae29 bmi.w 8008c84 + __HAL_RCC_PLL_ENABLE(); + 8009032: 6823 ldr r3, [r4, #0] + 8009034: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8009038: 6023 str r3, [r4, #0] + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + 800903a: 68e3 ldr r3, [r4, #12] + 800903c: f043 7380 orr.w r3, r3, #16777216 ; 0x1000000 + 8009040: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8009042: f7fe f9cb bl 80073dc + 8009046: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 8009048: 6823 ldr r3, [r4, #0] + 800904a: 019a lsls r2, r3, #6 + 800904c: f53f ae1a bmi.w 8008c84 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8009050: f7fe f9c4 bl 80073dc + 8009054: 1b40 subs r0, r0, r5 + 8009056: 2802 cmp r0, #2 + 8009058: d9f6 bls.n 8009048 + 800905a: e61b b.n 8008c94 + if(sysclk_source != RCC_CFGR_SWS_PLL) + 800905c: 2e0c cmp r6, #12 + 800905e: f43f ad79 beq.w 8008b54 + __HAL_RCC_PLL_DISABLE(); + 8009062: 6823 ldr r3, [r4, #0] + 8009064: f023 7380 bic.w r3, r3, #16777216 ; 0x1000000 + 8009068: 6023 str r3, [r4, #0] + if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U) + 800906a: 6823 ldr r3, [r4, #0] + 800906c: f013 5f20 tst.w r3, #671088640 ; 0x28000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 8009070: bf02 ittt eq + 8009072: 68e3 ldreq r3, [r4, #12] + 8009074: f023 0303 biceq.w r3, r3, #3 + 8009078: 60e3 streq r3, [r4, #12] + __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK); + 800907a: 68e3 ldr r3, [r4, #12] + 800907c: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 8009080: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 8009084: 60e3 str r3, [r4, #12] + tickstart = HAL_GetTick(); + 8009086: f7fe f9a9 bl 80073dc + 800908a: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) + 800908c: 6823 ldr r3, [r4, #0] + 800908e: 019b lsls r3, r3, #6 + 8009090: f57f adf8 bpl.w 8008c84 + if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + 8009094: f7fe f9a2 bl 80073dc + 8009098: 1b40 subs r0, r0, r5 + 800909a: 2802 cmp r0, #2 + 800909c: d9f6 bls.n 800908c + 800909e: e5f9 b.n 8008c94 + 80090a0: 40007000 .word 0x40007000 + 80090a4: 019d800c .word 0x019d800c + +080090a8 : +{ + 80090a8: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 80090ac: 460e mov r6, r1 + if(RCC_ClkInitStruct == NULL) + 80090ae: 4605 mov r5, r0 + 80090b0: b910 cbnz r0, 80090b8 + return HAL_ERROR; + 80090b2: 2001 movs r0, #1 +} + 80090b4: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + if(FLatency > __HAL_FLASH_GET_LATENCY()) + 80090b8: 4a6f ldr r2, [pc, #444] ; (8009278 ) + 80090ba: 6813 ldr r3, [r2, #0] + 80090bc: f003 030f and.w r3, r3, #15 + 80090c0: 428b cmp r3, r1 + 80090c2: d335 bcc.n 8009130 + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) + 80090c4: 6829 ldr r1, [r5, #0] + 80090c6: f011 0701 ands.w r7, r1, #1 + 80090ca: d13c bne.n 8009146 + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + 80090cc: 682a ldr r2, [r5, #0] + 80090ce: 0791 lsls r1, r2, #30 + 80090d0: f140 80b7 bpl.w 8009242 + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); + 80090d4: 4969 ldr r1, [pc, #420] ; (800927c ) + 80090d6: 68a8 ldr r0, [r5, #8] + 80090d8: 688b ldr r3, [r1, #8] + 80090da: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 80090de: 4303 orrs r3, r0 + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + 80090e0: 608b str r3, [r1, #8] + if(FLatency < __HAL_FLASH_GET_LATENCY()) + 80090e2: 4965 ldr r1, [pc, #404] ; (8009278 ) + 80090e4: 680b ldr r3, [r1, #0] + 80090e6: f003 030f and.w r3, r3, #15 + 80090ea: 42b3 cmp r3, r6 + 80090ec: f200 80b1 bhi.w 8009252 + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + 80090f0: f012 0f04 tst.w r2, #4 + 80090f4: 4c61 ldr r4, [pc, #388] ; (800927c ) + 80090f6: f040 80b8 bne.w 800926a + if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + 80090fa: 0713 lsls r3, r2, #28 + 80090fc: d506 bpl.n 800910c + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U)); + 80090fe: 68a3 ldr r3, [r4, #8] + 8009100: 692a ldr r2, [r5, #16] + 8009102: f423 5360 bic.w r3, r3, #14336 ; 0x3800 + 8009106: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 800910a: 60a3 str r3, [r4, #8] + SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); + 800910c: f7ff fcd0 bl 8008ab0 + 8009110: 68a3 ldr r3, [r4, #8] + 8009112: 4a5b ldr r2, [pc, #364] ; (8009280 ) + 8009114: f3c3 1303 ubfx r3, r3, #4, #4 + 8009118: 5cd3 ldrb r3, [r2, r3] + 800911a: f003 031f and.w r3, r3, #31 + 800911e: 40d8 lsrs r0, r3 + 8009120: 4b58 ldr r3, [pc, #352] ; (8009284 ) + 8009122: 6018 str r0, [r3, #0] + status = HAL_InitTick(uwTickPrio); + 8009124: 4b58 ldr r3, [pc, #352] ; (8009288 ) + 8009126: 6818 ldr r0, [r3, #0] +} + 8009128: e8bd 43f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + status = HAL_InitTick(uwTickPrio); + 800912c: f7fe b958 b.w 80073e0 + __HAL_FLASH_SET_LATENCY(FLatency); + 8009130: 6813 ldr r3, [r2, #0] + 8009132: f023 030f bic.w r3, r3, #15 + 8009136: 430b orrs r3, r1 + 8009138: 6013 str r3, [r2, #0] + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 800913a: 6813 ldr r3, [r2, #0] + 800913c: f003 030f and.w r3, r3, #15 + 8009140: 428b cmp r3, r1 + 8009142: d1b6 bne.n 80090b2 + 8009144: e7be b.n 80090c4 + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) + 8009146: 686b ldr r3, [r5, #4] + 8009148: 4c4c ldr r4, [pc, #304] ; (800927c ) + 800914a: 2b03 cmp r3, #3 + 800914c: d163 bne.n 8009216 + if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + 800914e: 6823 ldr r3, [r4, #0] + 8009150: 019b lsls r3, r3, #6 + 8009152: d5ae bpl.n 80090b2 +static uint32_t RCC_GetSysClockFreqFromPLLSource(void) +{ + uint32_t msirange = 0U; + uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */ + + if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI) + 8009154: 68e3 ldr r3, [r4, #12] + 8009156: f003 0303 and.w r3, r3, #3 + 800915a: 2b01 cmp r3, #1 + 800915c: d145 bne.n 80091ea + { + /* Get MSI range source */ + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 800915e: 6823 ldr r3, [r4, #0] + else + { /* MSIRANGE from RCC_CR applies */ + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + 8009160: 4a4a ldr r2, [pc, #296] ; (800928c ) + if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) + 8009162: 071f lsls r7, r3, #28 + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 8009164: bf55 itete pl + 8009166: f8d4 3094 ldrpl.w r3, [r4, #148] ; 0x94 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 800916a: 6823 ldrmi r3, [r4, #0] + msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; + 800916c: f3c3 2303 ubfxpl r3, r3, #8, #4 + msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; + 8009170: f3c3 1303 ubfxmi r3, r3, #4, #4 + msirange = MSIRangeTable[msirange]; + 8009174: f852 2023 ldr.w r2, [r2, r3, lsl #2] + } + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM + SYSCLK = PLL_VCO / PLLR + */ + pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8009178: 68e3 ldr r3, [r4, #12] + 800917a: f003 0303 and.w r3, r3, #3 + + switch (pllsource) + 800917e: 2b02 cmp r3, #2 + 8009180: d035 beq.n 80091ee + 8009182: 4843 ldr r0, [pc, #268] ; (8009290 ) + 8009184: 2b03 cmp r3, #3 + 8009186: bf08 it eq + 8009188: 4602 moveq r2, r0 + case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ + default: + pllvco = msirange; + break; + } + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 800918a: 68e0 ldr r0, [r4, #12] + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 800918c: 68e3 ldr r3, [r4, #12] + 800918e: f3c3 2306 ubfx r3, r3, #8, #7 + 8009192: 4353 muls r3, r2 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 8009194: 68e2 ldr r2, [r4, #12] + 8009196: f3c2 6241 ubfx r2, r2, #25, #2 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 800919a: f3c0 1003 ubfx r0, r0, #4, #4 + pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; + 800919e: 3201 adds r2, #1 + 80091a0: 0052 lsls r2, r2, #1 + pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; + 80091a2: 3001 adds r0, #1 + pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; + 80091a4: fbb3 f3f0 udiv r3, r3, r0 + sysclockfreq = pllvco / pllr; + 80091a8: fbb3 f3f2 udiv r3, r3, r2 + if(RCC_GetSysClockFreqFromPLLSource() > 80000000U) + 80091ac: 4a39 ldr r2, [pc, #228] ; (8009294 ) + 80091ae: 4293 cmp r3, r2 + 80091b0: d81f bhi.n 80091f2 + uint32_t hpre = RCC_SYSCLK_DIV1; + 80091b2: 2700 movs r7, #0 + MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); + 80091b4: 68a3 ldr r3, [r4, #8] + 80091b6: 686a ldr r2, [r5, #4] + 80091b8: f023 0303 bic.w r3, r3, #3 + 80091bc: 4313 orrs r3, r2 + 80091be: 60a3 str r3, [r4, #8] + tickstart = HAL_GetTick(); + 80091c0: f7fe f90c bl 80073dc + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 80091c4: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 80091c8: 4680 mov r8, r0 + while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) + 80091ca: 68a3 ldr r3, [r4, #8] + 80091cc: 686a ldr r2, [r5, #4] + 80091ce: f003 030c and.w r3, r3, #12 + 80091d2: ebb3 0f82 cmp.w r3, r2, lsl #2 + 80091d6: f43f af79 beq.w 80090cc + if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + 80091da: f7fe f8ff bl 80073dc + 80091de: eba0 0008 sub.w r0, r0, r8 + 80091e2: 4548 cmp r0, r9 + 80091e4: d9f1 bls.n 80091ca + return HAL_TIMEOUT; + 80091e6: 2003 movs r0, #3 + 80091e8: e764 b.n 80090b4 + uint32_t msirange = 0U; + 80091ea: 2200 movs r2, #0 + 80091ec: e7c4 b.n 8009178 + pllvco = HSI_VALUE; + 80091ee: 4a2a ldr r2, [pc, #168] ; (8009298 ) + 80091f0: e7cb b.n 800918a + if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1) + 80091f2: 68a3 ldr r3, [r4, #8] + 80091f4: f013 0ff0 tst.w r3, #240 ; 0xf0 + 80091f8: d107 bne.n 800920a + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2); + 80091fa: 68a3 ldr r3, [r4, #8] + 80091fc: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8009200: f043 0380 orr.w r3, r3, #128 ; 0x80 + 8009204: 60a3 str r3, [r4, #8] + hpre = RCC_SYSCLK_DIV2; + 8009206: 2780 movs r7, #128 ; 0x80 + 8009208: e7d4 b.n 80091b4 + else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1)) + 800920a: 0788 lsls r0, r1, #30 + 800920c: d5d1 bpl.n 80091b2 + 800920e: 68ab ldr r3, [r5, #8] + 8009210: 2b00 cmp r3, #0 + 8009212: d1ce bne.n 80091b2 + 8009214: e7f1 b.n 80091fa + if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) + 8009216: 2b02 cmp r3, #2 + 8009218: d10a bne.n 8009230 + if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) + 800921a: 6823 ldr r3, [r4, #0] + 800921c: f413 3f00 tst.w r3, #131072 ; 0x20000 + if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 8009220: f43f af47 beq.w 80090b2 + if(HAL_RCC_GetSysClockFreq() > 80000000U) + 8009224: f7ff fc44 bl 8008ab0 + 8009228: 4b1a ldr r3, [pc, #104] ; (8009294 ) + 800922a: 4298 cmp r0, r3 + 800922c: d9c1 bls.n 80091b2 + 800922e: e7e4 b.n 80091fa + else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) + 8009230: b91b cbnz r3, 800923a + if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) + 8009232: 6823 ldr r3, [r4, #0] + 8009234: f013 0f02 tst.w r3, #2 + 8009238: e7f2 b.n 8009220 + if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) + 800923a: 6823 ldr r3, [r4, #0] + 800923c: f413 6f80 tst.w r3, #1024 ; 0x400 + 8009240: e7ee b.n 8009220 + if(hpre == RCC_SYSCLK_DIV2) + 8009242: 2f80 cmp r7, #128 ; 0x80 + 8009244: f47f af4d bne.w 80090e2 + MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); + 8009248: 490c ldr r1, [pc, #48] ; (800927c ) + 800924a: 688b ldr r3, [r1, #8] + 800924c: f023 03f0 bic.w r3, r3, #240 ; 0xf0 + 8009250: e746 b.n 80090e0 + __HAL_FLASH_SET_LATENCY(FLatency); + 8009252: 680b ldr r3, [r1, #0] + 8009254: f023 030f bic.w r3, r3, #15 + 8009258: 4333 orrs r3, r6 + 800925a: 600b str r3, [r1, #0] + if(__HAL_FLASH_GET_LATENCY() != FLatency) + 800925c: 680b ldr r3, [r1, #0] + 800925e: f003 030f and.w r3, r3, #15 + 8009262: 42b3 cmp r3, r6 + 8009264: f47f af25 bne.w 80090b2 + 8009268: e742 b.n 80090f0 + MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider); + 800926a: 68a3 ldr r3, [r4, #8] + 800926c: 68e9 ldr r1, [r5, #12] + 800926e: f423 63e0 bic.w r3, r3, #1792 ; 0x700 + 8009272: 430b orrs r3, r1 + 8009274: 60a3 str r3, [r4, #8] + 8009276: e740 b.n 80090fa + 8009278: 40022000 .word 0x40022000 + 800927c: 40021000 .word 0x40021000 + 8009280: 08010a58 .word 0x08010a58 + 8009284: 2009e2ac .word 0x2009e2ac + 8009288: 2009e2b0 .word 0x2009e2b0 + 800928c: 08010a70 .word 0x08010a70 + 8009290: 007a1200 .word 0x007a1200 + 8009294: 04c4b400 .word 0x04c4b400 + 8009298: 00f42400 .word 0x00f42400 + +0800929c : +} + 800929c: 4b01 ldr r3, [pc, #4] ; (80092a4 ) + 800929e: 6818 ldr r0, [r3, #0] + 80092a0: 4770 bx lr + 80092a2: bf00 nop + 80092a4: 2009e2ac .word 0x2009e2ac + +080092a8 : + return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU)); + 80092a8: 4b05 ldr r3, [pc, #20] ; (80092c0 ) + 80092aa: 4a06 ldr r2, [pc, #24] ; (80092c4 ) + 80092ac: 689b ldr r3, [r3, #8] + 80092ae: f3c3 2302 ubfx r3, r3, #8, #3 + 80092b2: 5cd3 ldrb r3, [r2, r3] + 80092b4: 4a04 ldr r2, [pc, #16] ; (80092c8 ) + 80092b6: 6810 ldr r0, [r2, #0] + 80092b8: f003 031f and.w r3, r3, #31 +} + 80092bc: 40d8 lsrs r0, r3 + 80092be: 4770 bx lr + 80092c0: 40021000 .word 0x40021000 + 80092c4: 08010a68 .word 0x08010a68 + 80092c8: 2009e2ac .word 0x2009e2ac + +080092cc : + return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU)); + 80092cc: 4b05 ldr r3, [pc, #20] ; (80092e4 ) + 80092ce: 4a06 ldr r2, [pc, #24] ; (80092e8 ) + 80092d0: 689b ldr r3, [r3, #8] + 80092d2: f3c3 23c2 ubfx r3, r3, #11, #3 + 80092d6: 5cd3 ldrb r3, [r2, r3] + 80092d8: 4a04 ldr r2, [pc, #16] ; (80092ec ) + 80092da: 6810 ldr r0, [r2, #0] + 80092dc: f003 031f and.w r3, r3, #31 +} + 80092e0: 40d8 lsrs r0, r3 + 80092e2: 4770 bx lr + 80092e4: 40021000 .word 0x40021000 + 80092e8: 08010a68 .word 0x08010a68 + 80092ec: 2009e2ac .word 0x2009e2ac + +080092f0 : + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \ + 80092f0: 233f movs r3, #63 ; 0x3f + 80092f2: 6003 str r3, [r0, #0] + if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP) + 80092f4: 4b2e ldr r3, [pc, #184] ; (80093b0 ) + 80092f6: 681a ldr r2, [r3, #0] + 80092f8: 0351 lsls r1, r2, #13 + 80092fa: d54a bpl.n 8009392 + RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; + 80092fc: f44f 22a0 mov.w r2, #327680 ; 0x50000 + RCC_OscInitStruct->HSEState = RCC_HSE_OFF; + 8009300: 6042 str r2, [r0, #4] + if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION) + 8009302: 681a ldr r2, [r3, #0] + 8009304: f002 0201 and.w r2, r2, #1 + 8009308: 6182 str r2, [r0, #24] + RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos; + 800930a: 685a ldr r2, [r3, #4] + 800930c: f3c2 2207 ubfx r2, r2, #8, #8 + 8009310: 61c2 str r2, [r0, #28] + RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE); + 8009312: 681a ldr r2, [r3, #0] + 8009314: f002 02f0 and.w r2, r2, #240 ; 0xf0 + 8009318: 6202 str r2, [r0, #32] + if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION) + 800931a: 681a ldr r2, [r3, #0] + RCC_OscInitStruct->HSIState = RCC_HSI_ON; + 800931c: f402 7280 and.w r2, r2, #256 ; 0x100 + 8009320: 60c2 str r2, [r0, #12] + RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos; + 8009322: 685a ldr r2, [r3, #4] + 8009324: f3c2 6206 ubfx r2, r2, #24, #7 + 8009328: 6102 str r2, [r0, #16] + if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) + 800932a: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800932e: 0752 lsls r2, r2, #29 + 8009330: d536 bpl.n 80093a0 + RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + 8009332: 2205 movs r2, #5 + RCC_OscInitStruct->LSEState = RCC_LSE_OFF; + 8009334: 6082 str r2, [r0, #8] + if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION) + 8009336: f8d3 2094 ldr.w r2, [r3, #148] ; 0x94 + 800933a: f002 0201 and.w r2, r2, #1 + 800933e: 6142 str r2, [r0, #20] + if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON) + 8009340: f8d3 2098 ldr.w r2, [r3, #152] ; 0x98 + 8009344: f002 0201 and.w r2, r2, #1 + 8009348: 6242 str r2, [r0, #36] ; 0x24 + if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON) + 800934a: 681a ldr r2, [r3, #0] + RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; + 800934c: f012 7f80 tst.w r2, #16777216 ; 0x1000000 + 8009350: bf14 ite ne + 8009352: 2202 movne r2, #2 + 8009354: 2201 moveq r2, #1 + 8009356: 6282 str r2, [r0, #40] ; 0x28 + RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); + 8009358: 68da ldr r2, [r3, #12] + 800935a: f002 0203 and.w r2, r2, #3 + 800935e: 62c2 str r2, [r0, #44] ; 0x2c + RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U; + 8009360: 68da ldr r2, [r3, #12] + 8009362: f3c2 1203 ubfx r2, r2, #4, #4 + 8009366: 3201 adds r2, #1 + 8009368: 6302 str r2, [r0, #48] ; 0x30 + RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 800936a: 68da ldr r2, [r3, #12] + 800936c: f3c2 2206 ubfx r2, r2, #8, #7 + 8009370: 6342 str r2, [r0, #52] ; 0x34 + RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U); + 8009372: 68da ldr r2, [r3, #12] + 8009374: f3c2 5241 ubfx r2, r2, #21, #2 + 8009378: 3201 adds r2, #1 + 800937a: 0052 lsls r2, r2, #1 + 800937c: 63c2 str r2, [r0, #60] ; 0x3c + RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U); + 800937e: 68da ldr r2, [r3, #12] + 8009380: f3c2 6241 ubfx r2, r2, #25, #2 + 8009384: 3201 adds r2, #1 + 8009386: 0052 lsls r2, r2, #1 + 8009388: 6402 str r2, [r0, #64] ; 0x40 + RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 800938a: 68db ldr r3, [r3, #12] + 800938c: 0edb lsrs r3, r3, #27 + 800938e: 6383 str r3, [r0, #56] ; 0x38 +} + 8009390: 4770 bx lr + else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON) + 8009392: 681a ldr r2, [r3, #0] + 8009394: f412 3280 ands.w r2, r2, #65536 ; 0x10000 + RCC_OscInitStruct->HSEState = RCC_HSE_ON; + 8009398: bf18 it ne + 800939a: f44f 3280 movne.w r2, #65536 ; 0x10000 + 800939e: e7af b.n 8009300 + else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON) + 80093a0: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 80093a4: f012 0201 ands.w r2, r2, #1 + RCC_OscInitStruct->LSEState = RCC_LSE_ON; + 80093a8: bf18 it ne + 80093aa: 2201 movne r2, #1 + 80093ac: e7c2 b.n 8009334 + 80093ae: bf00 nop + 80093b0: 40021000 .word 0x40021000 + +080093b4 : + RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + 80093b4: 230f movs r3, #15 + 80093b6: 6003 str r3, [r0, #0] + RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW); + 80093b8: 4b0b ldr r3, [pc, #44] ; (80093e8 ) + 80093ba: 689a ldr r2, [r3, #8] + 80093bc: f002 0203 and.w r2, r2, #3 + 80093c0: 6042 str r2, [r0, #4] + RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE); + 80093c2: 689a ldr r2, [r3, #8] + 80093c4: f002 02f0 and.w r2, r2, #240 ; 0xf0 + 80093c8: 6082 str r2, [r0, #8] + RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1); + 80093ca: 689a ldr r2, [r3, #8] + 80093cc: f402 62e0 and.w r2, r2, #1792 ; 0x700 + 80093d0: 60c2 str r2, [r0, #12] + RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U); + 80093d2: 689b ldr r3, [r3, #8] + 80093d4: 08db lsrs r3, r3, #3 + 80093d6: f403 63e0 and.w r3, r3, #1792 ; 0x700 + 80093da: 6103 str r3, [r0, #16] + *pFLatency = __HAL_FLASH_GET_LATENCY(); + 80093dc: 4b03 ldr r3, [pc, #12] ; (80093ec ) + 80093de: 681b ldr r3, [r3, #0] + 80093e0: f003 030f and.w r3, r3, #15 + 80093e4: 600b str r3, [r1, #0] +} + 80093e6: 4770 bx lr + 80093e8: 40021000 .word 0x40021000 + 80093ec: 40022000 .word 0x40022000 + +080093f0 : + SET_BIT(RCC->CR, RCC_CR_CSSON) ; + 80093f0: 4a02 ldr r2, [pc, #8] ; (80093fc ) + 80093f2: 6813 ldr r3, [r2, #0] + 80093f4: f443 2300 orr.w r3, r3, #524288 ; 0x80000 + 80093f8: 6013 str r3, [r2, #0] +} + 80093fa: 4770 bx lr + 80093fc: 40021000 .word 0x40021000 + +08009400 : +} + 8009400: 4770 bx lr + ... + +08009404 : +{ + 8009404: b510 push {r4, lr} + if(__HAL_RCC_GET_IT(RCC_IT_CSS)) + 8009406: 4c05 ldr r4, [pc, #20] ; (800941c ) + 8009408: 69e3 ldr r3, [r4, #28] + 800940a: 05db lsls r3, r3, #23 + 800940c: d504 bpl.n 8009418 + HAL_RCC_CSSCallback(); + 800940e: f7ff fff7 bl 8009400 + __HAL_RCC_CLEAR_IT(RCC_IT_CSS); + 8009412: f44f 7380 mov.w r3, #256 ; 0x100 + 8009416: 6223 str r3, [r4, #32] +} + 8009418: bd10 pop {r4, pc} + 800941a: bf00 nop + 800941c: 40021000 .word 0x40021000 + +08009420 : +#if defined(RCC_PLLP_SUPPORT) + uint32_t pllp = 0U; +#endif /* RCC_PLLP_SUPPORT */ + + /* Handle SAIs */ + if(PeriphClk == RCC_PERIPHCLK_SAI1) + 8009420: f5b0 6f00 cmp.w r0, #2048 ; 0x800 + 8009424: 4a3d ldr r2, [pc, #244] ; (800951c ) + 8009426: d108 bne.n 800943a + { + srcclk = __HAL_RCC_GET_SAI1_SOURCE(); + 8009428: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 800942c: f003 03e0 and.w r3, r3, #224 ; 0xe0 + if(srcclk == RCC_SAI1CLKSOURCE_PIN) + 8009430: 2b60 cmp r3, #96 ; 0x60 + 8009432: d12d bne.n 8009490 + { + frequency = EXTERNAL_SAI1_CLOCK_VALUE; + 8009434: f64b 3080 movw r0, #48000 ; 0xbb80 + 8009438: 4770 bx lr + /* Else, PLL clock output to check below */ + } +#if defined(SAI2) + else + { + if(PeriphClk == RCC_PERIPHCLK_SAI2) + 800943a: f5b0 5f80 cmp.w r0, #4096 ; 0x1000 + 800943e: d12a bne.n 8009496 + { + srcclk = __HAL_RCC_GET_SAI2_SOURCE(); + 8009440: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009444: f403 63e0 and.w r3, r3, #1792 ; 0x700 + if(srcclk == RCC_SAI2CLKSOURCE_PIN) + 8009448: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 800944c: d0f2 beq.n 8009434 + if(frequency == 0U) + { + pllvco = InputFrequency; + +#if defined(SAI2) + if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL)) + 800944e: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 8009452: d15c bne.n 800950e + { + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != 0U)) + 8009454: 6810 ldr r0, [r2, #0] + 8009456: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 800945a: d05d beq.n 8009518 + 800945c: 68d0 ldr r0, [r2, #12] + 800945e: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 8009462: d059 beq.n 8009518 + { + /* f(PLL Source) / PLLM */ + pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009464: 68d0 ldr r0, [r2, #12] + 8009466: f3c0 1003 ubfx r0, r0, #4, #4 + 800946a: 3001 adds r0, #1 + 800946c: fbb1 f0f0 udiv r0, r1, r0 + /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */ + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009470: 68d1 ldr r1, [r2, #12] +#if defined(RCC_PLLP_DIV_2_31_SUPPORT) + pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 8009472: 68d3 ldr r3, [r2, #12] +#endif + if(pllp == 0U) + 8009474: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009476: f3c1 2106 ubfx r1, r1, #8, #7 + if(pllp == 0U) + 800947a: d105 bne.n 8009488 + { + if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U) + 800947c: 68d3 ldr r3, [r2, #12] + { + pllp = 17U; + } + else + { + pllp = 7U; + 800947e: f413 3f00 tst.w r3, #131072 ; 0x20000 + 8009482: bf14 ite ne + 8009484: 2311 movne r3, #17 + 8009486: 2307 moveq r3, #7 + } + } + frequency = (pllvco * plln) / pllp; + 8009488: 4348 muls r0, r1 + 800948a: fbb0 f0f3 udiv r0, r0, r3 + 800948e: 4770 bx lr + if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL)) + 8009490: 2b40 cmp r3, #64 ; 0x40 + 8009492: d0df beq.n 8009454 + else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */ + 8009494: b9ab cbnz r3, 80094c2 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)) + 8009496: 6810 ldr r0, [r2, #0] + 8009498: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 800949c: d03c beq.n 8009518 + 800949e: 6910 ldr r0, [r2, #16] + 80094a0: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 80094a4: d038 beq.n 8009518 + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 80094a6: 6913 ldr r3, [r2, #16] + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 80094a8: 6910 ldr r0, [r2, #16] + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 80094aa: f3c3 1303 ubfx r3, r3, #4, #4 + 80094ae: 3301 adds r3, #1 + 80094b0: fbb1 f1f3 udiv r1, r1, r3 + pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos; + 80094b4: 6913 ldr r3, [r2, #16] + if(pllp == 0U) + 80094b6: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 80094b8: f3c0 2006 ubfx r0, r0, #8, #7 + if(pllp == 0U) + 80094bc: d1e4 bne.n 8009488 + if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U) + 80094be: 6913 ldr r3, [r2, #16] + 80094c0: e7dd b.n 800947e + else if((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI)) + 80094c2: 2b80 cmp r3, #128 ; 0x80 + 80094c4: d106 bne.n 80094d4 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 80094c6: 6810 ldr r0, [r2, #0] + frequency = HSI_VALUE; + 80094c8: 4b15 ldr r3, [pc, #84] ; (8009520 ) + 80094ca: f410 6080 ands.w r0, r0, #1024 ; 0x400 + 80094ce: bf18 it ne + 80094d0: 4618 movne r0, r3 + 80094d2: 4770 bx lr + else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2)) + 80094d4: 2b20 cmp r3, #32 + 80094d6: d002 beq.n 80094de + 80094d8: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 80094dc: d115 bne.n 800950a + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI2RDY) && (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != 0U)) + 80094de: 6810 ldr r0, [r2, #0] + 80094e0: f010 5000 ands.w r0, r0, #536870912 ; 0x20000000 + 80094e4: d018 beq.n 8009518 + 80094e6: 6950 ldr r0, [r2, #20] + 80094e8: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 80094ec: d014 beq.n 8009518 + pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U)); + 80094ee: 6953 ldr r3, [r2, #20] + 80094f0: f3c3 1303 ubfx r3, r3, #4, #4 + 80094f4: 3301 adds r3, #1 + 80094f6: fbb1 f0f3 udiv r0, r1, r3 + plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 80094fa: 6951 ldr r1, [r2, #20] + pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos; + 80094fc: 6953 ldr r3, [r2, #20] + if(pllp == 0U) + 80094fe: 0edb lsrs r3, r3, #27 + plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 8009500: f3c1 2106 ubfx r1, r1, #8, #7 + if(pllp == 0U) + 8009504: d1c0 bne.n 8009488 + if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != 0U) + 8009506: 6953 ldr r3, [r2, #20] + 8009508: e7b9 b.n 800947e + 800950a: 2000 movs r0, #0 + /* No clock source, frequency default init at 0 */ + } + } + + + return frequency; + 800950c: 4770 bx lr + else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */ + 800950e: 2b00 cmp r3, #0 + 8009510: d0c1 beq.n 8009496 + else if((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI)) + 8009512: f5b3 6f80 cmp.w r3, #1024 ; 0x400 + 8009516: e7d5 b.n 80094c4 +} + 8009518: 4770 bx lr + 800951a: bf00 nop + 800951c: 40021000 .word 0x40021000 + 8009520: 00f42400 .word 0x00f42400 + +08009524 : +{ + 8009524: b5f8 push {r3, r4, r5, r6, r7, lr} + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009526: 4c3c ldr r4, [pc, #240] ; (8009618 ) + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source) + 8009528: 6803 ldr r3, [r0, #0] + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800952a: 68e2 ldr r2, [r4, #12] +{ + 800952c: 4605 mov r5, r0 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800952e: 0790 lsls r0, r2, #30 +{ + 8009530: 460f mov r7, r1 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009532: d023 beq.n 800957c + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source) + 8009534: 68e2 ldr r2, [r4, #12] + 8009536: f002 0203 and.w r2, r2, #3 + 800953a: 429a cmp r2, r3 + 800953c: d16a bne.n 8009614 + || + 800953e: 2a00 cmp r2, #0 + 8009540: d068 beq.n 8009614 + __HAL_RCC_PLLSAI1_DISABLE(); + 8009542: 6823 ldr r3, [r4, #0] + 8009544: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 8009548: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800954a: f7fd ff47 bl 80073dc + 800954e: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 8009550: 6823 ldr r3, [r4, #0] + 8009552: 011a lsls r2, r3, #4 + 8009554: d42d bmi.n 80095b2 + MODIFY_REG(RCC->PLLSAI1CFGR, + 8009556: 68ab ldr r3, [r5, #8] + 8009558: 021e lsls r6, r3, #8 + 800955a: 686b ldr r3, [r5, #4] + 800955c: 3b01 subs r3, #1 + 800955e: 0118 lsls r0, r3, #4 + if(Divider == DIVIDER_P_UPDATE) + 8009560: b377 cbz r7, 80095c0 + else if(Divider == DIVIDER_Q_UPDATE) + 8009562: 2f01 cmp r7, #1 + 8009564: d145 bne.n 80095f2 + MODIFY_REG(RCC->PLLSAI1CFGR, + 8009566: 692b ldr r3, [r5, #16] + 8009568: 6927 ldr r7, [r4, #16] + 800956a: 085b lsrs r3, r3, #1 + 800956c: 1e59 subs r1, r3, #1 + 800956e: 4b2b ldr r3, [pc, #172] ; (800961c ) + 8009570: 403b ands r3, r7 + 8009572: 4333 orrs r3, r6 + 8009574: 4303 orrs r3, r0 + 8009576: ea43 5341 orr.w r3, r3, r1, lsl #21 + 800957a: e029 b.n 80095d0 + switch(PllSai1->PLLSAI1Source) + 800957c: 2b02 cmp r3, #2 + 800957e: d00d beq.n 800959c + 8009580: 2b03 cmp r3, #3 + 8009582: d00f beq.n 80095a4 + 8009584: 2b01 cmp r3, #1 + 8009586: d145 bne.n 8009614 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) + 8009588: 6822 ldr r2, [r4, #0] + 800958a: f012 0f02 tst.w r2, #2 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 800958e: d041 beq.n 8009614 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai1->PLLSAI1Source); + 8009590: 68e0 ldr r0, [r4, #12] + 8009592: f020 0003 bic.w r0, r0, #3 + 8009596: 4318 orrs r0, r3 + 8009598: 60e0 str r0, [r4, #12] + if(status == HAL_OK) + 800959a: e7d2 b.n 8009542 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) + 800959c: 6822 ldr r2, [r4, #0] + 800959e: f412 6f80 tst.w r2, #1024 ; 0x400 + 80095a2: e7f4 b.n 800958e + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY)) + 80095a4: 6822 ldr r2, [r4, #0] + 80095a6: 0391 lsls r1, r2, #14 + 80095a8: d4f2 bmi.n 8009590 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80095aa: 6822 ldr r2, [r4, #0] + 80095ac: f412 2f80 tst.w r2, #262144 ; 0x40000 + 80095b0: e7ed b.n 800958e + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 80095b2: f7fd ff13 bl 80073dc + 80095b6: 1b80 subs r0, r0, r6 + 80095b8: 2802 cmp r0, #2 + 80095ba: d9c9 bls.n 8009550 + status = HAL_TIMEOUT; + 80095bc: 2003 movs r0, #3 +} + 80095be: bdf8 pop {r3, r4, r5, r6, r7, pc} + MODIFY_REG(RCC->PLLSAI1CFGR, + 80095c0: 68e9 ldr r1, [r5, #12] + 80095c2: 6922 ldr r2, [r4, #16] + 80095c4: ea46 63c1 orr.w r3, r6, r1, lsl #27 + 80095c8: 4915 ldr r1, [pc, #84] ; (8009620 ) + 80095ca: 4011 ands r1, r2 + 80095cc: 430b orrs r3, r1 + 80095ce: 4303 orrs r3, r0 + MODIFY_REG(RCC->PLLSAI1CFGR, + 80095d0: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1_ENABLE(); + 80095d2: 6823 ldr r3, [r4, #0] + 80095d4: f043 6380 orr.w r3, r3, #67108864 ; 0x4000000 + 80095d8: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 80095da: f7fd feff bl 80073dc + 80095de: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 80095e0: 6823 ldr r3, [r4, #0] + 80095e2: 011b lsls r3, r3, #4 + 80095e4: d510 bpl.n 8009608 + __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut); + 80095e6: 6923 ldr r3, [r4, #16] + 80095e8: 69aa ldr r2, [r5, #24] + 80095ea: 4313 orrs r3, r2 + 80095ec: 6123 str r3, [r4, #16] + 80095ee: 2000 movs r0, #0 + return status; + 80095f0: e7e5 b.n 80095be + MODIFY_REG(RCC->PLLSAI1CFGR, + 80095f2: 696b ldr r3, [r5, #20] + 80095f4: 6921 ldr r1, [r4, #16] + 80095f6: 085b lsrs r3, r3, #1 + 80095f8: 1e5a subs r2, r3, #1 + 80095fa: 4b0a ldr r3, [pc, #40] ; (8009624 ) + 80095fc: 400b ands r3, r1 + 80095fe: 4333 orrs r3, r6 + 8009600: 4303 orrs r3, r0 + 8009602: ea43 6342 orr.w r3, r3, r2, lsl #25 + 8009606: e7e3 b.n 80095d0 + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 8009608: f7fd fee8 bl 80073dc + 800960c: 1b80 subs r0, r0, r6 + 800960e: 2802 cmp r0, #2 + 8009610: d9e6 bls.n 80095e0 + 8009612: e7d3 b.n 80095bc + status = HAL_ERROR; + 8009614: 2001 movs r0, #1 + 8009616: e7d2 b.n 80095be + 8009618: 40021000 .word 0x40021000 + 800961c: ff9f800f .word 0xff9f800f + 8009620: 07ff800f .word 0x07ff800f + 8009624: f9ff800f .word 0xf9ff800f + +08009628 : +static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider) + 8009628: b570 push {r4, r5, r6, lr} + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800962a: 4c2f ldr r4, [pc, #188] ; (80096e8 ) + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source) + 800962c: 6803 ldr r3, [r0, #0] + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 800962e: 68e2 ldr r2, [r4, #12] +static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider) + 8009630: 4605 mov r5, r0 + if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) + 8009632: 0790 lsls r0, r2, #30 + 8009634: d026 beq.n 8009684 + if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source) + 8009636: 68e2 ldr r2, [r4, #12] + 8009638: f002 0203 and.w r2, r2, #3 + 800963c: 429a cmp r2, r3 + 800963e: d151 bne.n 80096e4 + || + 8009640: 2a00 cmp r2, #0 + 8009642: d04f beq.n 80096e4 + __HAL_RCC_PLLSAI2_DISABLE(); + 8009644: 6823 ldr r3, [r4, #0] + 8009646: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800964a: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800964c: f7fd fec6 bl 80073dc + 8009650: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 8009652: 6823 ldr r3, [r4, #0] + 8009654: 009a lsls r2, r3, #2 + 8009656: d430 bmi.n 80096ba + MODIFY_REG(RCC->PLLSAI2CFGR, + 8009658: e9d5 2302 ldrd r2, r3, [r5, #8] + 800965c: 06db lsls r3, r3, #27 + 800965e: 6961 ldr r1, [r4, #20] + 8009660: ea43 2302 orr.w r3, r3, r2, lsl #8 + 8009664: 4a21 ldr r2, [pc, #132] ; (80096ec ) + 8009666: 400a ands r2, r1 + 8009668: 4313 orrs r3, r2 + 800966a: 686a ldr r2, [r5, #4] + 800966c: 3a01 subs r2, #1 + 800966e: ea43 1302 orr.w r3, r3, r2, lsl #4 + 8009672: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2_ENABLE(); + 8009674: 6823 ldr r3, [r4, #0] + 8009676: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800967a: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800967c: f7fd feae bl 80073dc + 8009680: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 8009682: e026 b.n 80096d2 + switch(PllSai2->PLLSAI2Source) + 8009684: 2b02 cmp r3, #2 + 8009686: d00d beq.n 80096a4 + 8009688: 2b03 cmp r3, #3 + 800968a: d00f beq.n 80096ac + 800968c: 2b01 cmp r3, #1 + 800968e: d129 bne.n 80096e4 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) + 8009690: 6822 ldr r2, [r4, #0] + 8009692: f012 0f02 tst.w r2, #2 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 8009696: d025 beq.n 80096e4 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PllSai2->PLLSAI2Source); + 8009698: 68e0 ldr r0, [r4, #12] + 800969a: f020 0003 bic.w r0, r0, #3 + 800969e: 4318 orrs r0, r3 + 80096a0: 60e0 str r0, [r4, #12] + if(status == HAL_OK) + 80096a2: e7cf b.n 8009644 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) + 80096a4: 6822 ldr r2, [r4, #0] + 80096a6: f412 6f80 tst.w r2, #1024 ; 0x400 + 80096aa: e7f4 b.n 8009696 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY)) + 80096ac: 6822 ldr r2, [r4, #0] + 80096ae: 0391 lsls r1, r2, #14 + 80096b0: d4f2 bmi.n 8009698 + if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) + 80096b2: 6822 ldr r2, [r4, #0] + 80096b4: f412 2f80 tst.w r2, #262144 ; 0x40000 + 80096b8: e7ed b.n 8009696 + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 80096ba: f7fd fe8f bl 80073dc + 80096be: 1b80 subs r0, r0, r6 + 80096c0: 2802 cmp r0, #2 + 80096c2: d9c6 bls.n 8009652 + status = HAL_TIMEOUT; + 80096c4: 2003 movs r0, #3 +} + 80096c6: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 80096c8: f7fd fe88 bl 80073dc + 80096cc: 1b80 subs r0, r0, r6 + 80096ce: 2802 cmp r0, #2 + 80096d0: d8f8 bhi.n 80096c4 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 80096d2: 6823 ldr r3, [r4, #0] + 80096d4: 009b lsls r3, r3, #2 + 80096d6: d5f7 bpl.n 80096c8 + __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut); + 80096d8: 6963 ldr r3, [r4, #20] + 80096da: 69aa ldr r2, [r5, #24] + 80096dc: 4313 orrs r3, r2 + 80096de: 6163 str r3, [r4, #20] + 80096e0: 2000 movs r0, #0 + return status; + 80096e2: e7f0 b.n 80096c6 + status = HAL_ERROR; + 80096e4: 2001 movs r0, #1 + 80096e6: e7ee b.n 80096c6 + 80096e8: 40021000 .word 0x40021000 + 80096ec: 07ff800f .word 0x07ff800f + +080096f0 : +{ + 80096f0: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)) + 80096f4: 6806 ldr r6, [r0, #0] + 80096f6: f416 6600 ands.w r6, r6, #2048 ; 0x800 +{ + 80096fa: 4604 mov r4, r0 + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)) + 80096fc: d007 beq.n 800970e + switch(PeriphClkInit->Sai1ClockSelection) + 80096fe: 6ec1 ldr r1, [r0, #108] ; 0x6c + 8009700: 2940 cmp r1, #64 ; 0x40 + 8009702: d022 beq.n 800974a + 8009704: d812 bhi.n 800972c + 8009706: b331 cbz r1, 8009756 + 8009708: 2920 cmp r1, #32 + 800970a: d02b beq.n 8009764 + 800970c: 2601 movs r6, #1 + if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2)) + 800970e: 6823 ldr r3, [r4, #0] + 8009710: 04db lsls r3, r3, #19 + 8009712: d509 bpl.n 8009728 + switch(PeriphClkInit->Sai2ClockSelection) + 8009714: 6f21 ldr r1, [r4, #112] ; 0x70 + 8009716: f5b1 7f00 cmp.w r1, #512 ; 0x200 + 800971a: d02f beq.n 800977c + 800971c: d826 bhi.n 800976c + 800971e: b399 cbz r1, 8009788 + 8009720: f5b1 7f80 cmp.w r1, #256 ; 0x100 + 8009724: d073 beq.n 800980e + 8009726: 2601 movs r6, #1 + 8009728: 4635 mov r5, r6 + 800972a: e03c b.n 80097a6 + switch(PeriphClkInit->Sai1ClockSelection) + 800972c: 2960 cmp r1, #96 ; 0x60 + 800972e: d001 beq.n 8009734 + 8009730: 2980 cmp r1, #128 ; 0x80 + 8009732: d1eb bne.n 800970c + __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); + 8009734: 4a3b ldr r2, [pc, #236] ; (8009824 ) + 8009736: 6ee1 ldr r1, [r4, #108] ; 0x6c + 8009738: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 800973c: f023 03e0 bic.w r3, r3, #224 ; 0xe0 + 8009740: 430b orrs r3, r1 + 8009742: f8c2 309c str.w r3, [r2, #156] ; 0x9c + 8009746: 2600 movs r6, #0 + 8009748: e7e1 b.n 800970e + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 800974a: 4a36 ldr r2, [pc, #216] ; (8009824 ) + 800974c: 68d3 ldr r3, [r2, #12] + 800974e: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8009752: 60d3 str r3, [r2, #12] + if(ret == HAL_OK) + 8009754: e7ee b.n 8009734 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); + 8009756: 3004 adds r0, #4 + 8009758: f7ff fee4 bl 8009524 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 800975c: 4606 mov r6, r0 + if(ret == HAL_OK) + 800975e: 2800 cmp r0, #0 + 8009760: d1d5 bne.n 800970e + 8009762: e7e7 b.n 8009734 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 8009764: 3020 adds r0, #32 + 8009766: f7ff ff5f bl 8009628 + 800976a: e7f7 b.n 800975c + switch(PeriphClkInit->Sai2ClockSelection) + 800976c: f5b1 7f40 cmp.w r1, #768 ; 0x300 + 8009770: d002 beq.n 8009778 + 8009772: f5b1 6f80 cmp.w r1, #1024 ; 0x400 + 8009776: d1d6 bne.n 8009726 + 8009778: 4635 mov r5, r6 + 800977a: e009 b.n 8009790 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 800977c: 4a29 ldr r2, [pc, #164] ; (8009824 ) + 800977e: 68d3 ldr r3, [r2, #12] + 8009780: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8009784: 60d3 str r3, [r2, #12] + break; + 8009786: e7f7 b.n 8009778 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); + 8009788: 1d20 adds r0, r4, #4 + 800978a: f7ff fecb bl 8009524 + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 800978e: 4605 mov r5, r0 + if(ret == HAL_OK) + 8009790: 2d00 cmp r5, #0 + 8009792: d141 bne.n 8009818 + __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); + 8009794: 4a23 ldr r2, [pc, #140] ; (8009824 ) + 8009796: 6f21 ldr r1, [r4, #112] ; 0x70 + 8009798: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 800979c: f423 63e0 bic.w r3, r3, #1792 ; 0x700 + 80097a0: 430b orrs r3, r1 + 80097a2: f8c2 309c str.w r3, [r2, #156] ; 0x9c + if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) + 80097a6: 6823 ldr r3, [r4, #0] + 80097a8: 039f lsls r7, r3, #14 + 80097aa: f140 817d bpl.w 8009aa8 + if(__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U) + 80097ae: 4f1d ldr r7, [pc, #116] ; (8009824 ) + 80097b0: 6dbb ldr r3, [r7, #88] ; 0x58 + 80097b2: 00d8 lsls r0, r3, #3 + 80097b4: d432 bmi.n 800981c + __HAL_RCC_PWR_CLK_ENABLE(); + 80097b6: 6dbb ldr r3, [r7, #88] ; 0x58 + 80097b8: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 80097bc: 65bb str r3, [r7, #88] ; 0x58 + 80097be: 6dbb ldr r3, [r7, #88] ; 0x58 + 80097c0: f003 5380 and.w r3, r3, #268435456 ; 0x10000000 + 80097c4: 9301 str r3, [sp, #4] + 80097c6: 9b01 ldr r3, [sp, #4] + pwrclkchanged = SET; + 80097c8: f04f 0801 mov.w r8, #1 + SET_BIT(PWR->CR1, PWR_CR1_DBP); + 80097cc: f8df 9058 ldr.w r9, [pc, #88] ; 8009828 + 80097d0: f8d9 3000 ldr.w r3, [r9] + 80097d4: f443 7380 orr.w r3, r3, #256 ; 0x100 + 80097d8: f8c9 3000 str.w r3, [r9] + tickstart = HAL_GetTick(); + 80097dc: f7fd fdfe bl 80073dc + 80097e0: 4682 mov sl, r0 + while(READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U) + 80097e2: f8d9 3000 ldr.w r3, [r9] + 80097e6: 05d9 lsls r1, r3, #23 + 80097e8: d520 bpl.n 800982c + if(ret == HAL_OK) + 80097ea: bb35 cbnz r5, 800983a + tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL); + 80097ec: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + if((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection)) + 80097f0: f413 7340 ands.w r3, r3, #768 ; 0x300 + 80097f4: f040 812e bne.w 8009a54 + __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); + 80097f8: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 80097fc: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8009800: f423 7340 bic.w r3, r3, #768 ; 0x300 + 8009804: 4313 orrs r3, r2 + 8009806: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + 800980a: 4635 mov r5, r6 + 800980c: e015 b.n 800983a + ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); + 800980e: f104 0020 add.w r0, r4, #32 + 8009812: f7ff ff09 bl 8009628 + 8009816: e7ba b.n 800978e + 8009818: 462e mov r6, r5 + 800981a: e7c4 b.n 80097a6 + FlagStatus pwrclkchanged = RESET; + 800981c: f04f 0800 mov.w r8, #0 + 8009820: e7d4 b.n 80097cc + 8009822: bf00 nop + 8009824: 40021000 .word 0x40021000 + 8009828: 40007000 .word 0x40007000 + if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) + 800982c: f7fd fdd6 bl 80073dc + 8009830: eba0 000a sub.w r0, r0, sl + 8009834: 2802 cmp r0, #2 + 8009836: d9d4 bls.n 80097e2 + ret = HAL_TIMEOUT; + 8009838: 2503 movs r5, #3 + if(pwrclkchanged == SET) + 800983a: f1b8 0f00 cmp.w r8, #0 + 800983e: d003 beq.n 8009848 + __HAL_RCC_PWR_CLK_DISABLE(); + 8009840: 6dbb ldr r3, [r7, #88] ; 0x58 + 8009842: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 8009846: 65bb str r3, [r7, #88] ; 0x58 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) + 8009848: 6823 ldr r3, [r4, #0] + 800984a: 07d8 lsls r0, r3, #31 + 800984c: d508 bpl.n 8009860 + __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); + 800984e: 49b2 ldr r1, [pc, #712] ; (8009b18 ) + 8009850: 6be0 ldr r0, [r4, #60] ; 0x3c + 8009852: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009856: f022 0203 bic.w r2, r2, #3 + 800985a: 4302 orrs r2, r0 + 800985c: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) + 8009860: 0799 lsls r1, r3, #30 + 8009862: d508 bpl.n 8009876 + __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); + 8009864: 49ac ldr r1, [pc, #688] ; (8009b18 ) + 8009866: 6c20 ldr r0, [r4, #64] ; 0x40 + 8009868: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 800986c: f022 020c bic.w r2, r2, #12 + 8009870: 4302 orrs r2, r0 + 8009872: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3) + 8009876: 075a lsls r2, r3, #29 + 8009878: d508 bpl.n 800988c + __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); + 800987a: 49a7 ldr r1, [pc, #668] ; (8009b18 ) + 800987c: 6c60 ldr r0, [r4, #68] ; 0x44 + 800987e: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009882: f022 0230 bic.w r2, r2, #48 ; 0x30 + 8009886: 4302 orrs r2, r0 + 8009888: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4) + 800988c: 071f lsls r7, r3, #28 + 800988e: d508 bpl.n 80098a2 + __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection); + 8009890: 49a1 ldr r1, [pc, #644] ; (8009b18 ) + 8009892: 6ca0 ldr r0, [r4, #72] ; 0x48 + 8009894: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009898: f022 02c0 bic.w r2, r2, #192 ; 0xc0 + 800989c: 4302 orrs r2, r0 + 800989e: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5) + 80098a2: 06de lsls r6, r3, #27 + 80098a4: d508 bpl.n 80098b8 + __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection); + 80098a6: 499c ldr r1, [pc, #624] ; (8009b18 ) + 80098a8: 6ce0 ldr r0, [r4, #76] ; 0x4c + 80098aa: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80098ae: f422 7240 bic.w r2, r2, #768 ; 0x300 + 80098b2: 4302 orrs r2, r0 + 80098b4: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) + 80098b8: 0698 lsls r0, r3, #26 + 80098ba: d508 bpl.n 80098ce + __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection); + 80098bc: 4996 ldr r1, [pc, #600] ; (8009b18 ) + 80098be: 6d20 ldr r0, [r4, #80] ; 0x50 + 80098c0: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80098c4: f422 6240 bic.w r2, r2, #3072 ; 0xc00 + 80098c8: 4302 orrs r2, r0 + 80098ca: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1)) + 80098ce: 0599 lsls r1, r3, #22 + 80098d0: d508 bpl.n 80098e4 + __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); + 80098d2: 4991 ldr r1, [pc, #580] ; (8009b18 ) + 80098d4: 6e60 ldr r0, [r4, #100] ; 0x64 + 80098d6: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80098da: f422 2240 bic.w r2, r2, #786432 ; 0xc0000 + 80098de: 4302 orrs r2, r0 + 80098e0: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2)) + 80098e4: 055a lsls r2, r3, #21 + 80098e6: d508 bpl.n 80098fa + __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection); + 80098e8: 498b ldr r1, [pc, #556] ; (8009b18 ) + 80098ea: 6ea0 ldr r0, [r4, #104] ; 0x68 + 80098ec: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 80098f0: f422 1240 bic.w r2, r2, #3145728 ; 0x300000 + 80098f4: 4302 orrs r2, r0 + 80098f6: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) + 80098fa: 065f lsls r7, r3, #25 + 80098fc: d508 bpl.n 8009910 + __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); + 80098fe: 4986 ldr r1, [pc, #536] ; (8009b18 ) + 8009900: 6d60 ldr r0, [r4, #84] ; 0x54 + 8009902: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009906: f422 5240 bic.w r2, r2, #12288 ; 0x3000 + 800990a: 4302 orrs r2, r0 + 800990c: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2) + 8009910: 061e lsls r6, r3, #24 + 8009912: d508 bpl.n 8009926 + __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection); + 8009914: 4980 ldr r1, [pc, #512] ; (8009b18 ) + 8009916: 6da0 ldr r0, [r4, #88] ; 0x58 + 8009918: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 800991c: f422 4240 bic.w r2, r2, #49152 ; 0xc000 + 8009920: 4302 orrs r2, r0 + 8009922: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3) + 8009926: 05d8 lsls r0, r3, #23 + 8009928: d508 bpl.n 800993c + __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection); + 800992a: 497b ldr r1, [pc, #492] ; (8009b18 ) + 800992c: 6de0 ldr r0, [r4, #92] ; 0x5c + 800992e: f8d1 2088 ldr.w r2, [r1, #136] ; 0x88 + 8009932: f422 3240 bic.w r2, r2, #196608 ; 0x30000 + 8009936: 4302 orrs r2, r0 + 8009938: f8c1 2088 str.w r2, [r1, #136] ; 0x88 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4) + 800993c: 02d9 lsls r1, r3, #11 + 800993e: d508 bpl.n 8009952 + __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection); + 8009940: 4975 ldr r1, [pc, #468] ; (8009b18 ) + 8009942: 6e20 ldr r0, [r4, #96] ; 0x60 + 8009944: f8d1 209c ldr.w r2, [r1, #156] ; 0x9c + 8009948: f022 0203 bic.w r2, r2, #3 + 800994c: 4302 orrs r2, r0 + 800994e: f8c1 209c str.w r2, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB)) + 8009952: 049a lsls r2, r3, #18 + 8009954: d510 bpl.n 8009978 + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8009956: 4a70 ldr r2, [pc, #448] ; (8009b18 ) + 8009958: 6f61 ldr r1, [r4, #116] ; 0x74 + 800995a: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 800995e: f023 6340 bic.w r3, r3, #201326592 ; 0xc000000 + 8009962: 430b orrs r3, r1 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL) + 8009964: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); + 8009968: f8c2 3088 str.w r3, [r2, #136] ; 0x88 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL) + 800996c: f040 809e bne.w 8009aac + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 8009970: 68d3 ldr r3, [r2, #12] + 8009972: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 8009976: 60d3 str r3, [r2, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1)) + 8009978: 6823 ldr r3, [r4, #0] + 800997a: 031b lsls r3, r3, #12 + 800997c: d50f bpl.n 800999e + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 800997e: 6fa1 ldr r1, [r4, #120] ; 0x78 + 8009980: 4b65 ldr r3, [pc, #404] ; (8009b18 ) + 8009982: f5b1 4f80 cmp.w r1, #16384 ; 0x4000 + 8009986: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 800998a: f040 809b bne.w 8009ac4 + 800998e: f442 4280 orr.w r2, r2, #16384 ; 0x4000 + 8009992: f8c3 209c str.w r2, [r3, #156] ; 0x9c + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); + 8009996: 68da ldr r2, [r3, #12] + 8009998: f442 3280 orr.w r2, r2, #65536 ; 0x10000 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 800999c: 60da str r2, [r3, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG)) + 800999e: 6823 ldr r3, [r4, #0] + 80099a0: 035f lsls r7, r3, #13 + 80099a2: d510 bpl.n 80099c6 + __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection); + 80099a4: 4a5c ldr r2, [pc, #368] ; (8009b18 ) + 80099a6: 6fe1 ldr r1, [r4, #124] ; 0x7c + 80099a8: f8d2 3088 ldr.w r3, [r2, #136] ; 0x88 + 80099ac: f023 6340 bic.w r3, r3, #201326592 ; 0xc000000 + 80099b0: 430b orrs r3, r1 + if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL) + 80099b2: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection); + 80099b6: f8c2 3088 str.w r3, [r2, #136] ; 0x88 + if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL) + 80099ba: f040 80a1 bne.w 8009b00 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 80099be: 68d3 ldr r3, [r2, #12] + 80099c0: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 80099c4: 60d3 str r3, [r2, #12] + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC) + 80099c6: 6823 ldr r3, [r4, #0] + 80099c8: 045e lsls r6, r3, #17 + 80099ca: d513 bpl.n 80099f4 + __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); + 80099cc: 4952 ldr r1, [pc, #328] ; (8009b18 ) + 80099ce: f8d4 2080 ldr.w r2, [r4, #128] ; 0x80 + 80099d2: f8d1 3088 ldr.w r3, [r1, #136] ; 0x88 + 80099d6: f023 5340 bic.w r3, r3, #805306368 ; 0x30000000 + 80099da: 4313 orrs r3, r2 + if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1) + 80099dc: f1b2 5f80 cmp.w r2, #268435456 ; 0x10000000 + __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); + 80099e0: f8c1 3088 str.w r3, [r1, #136] ; 0x88 + if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1) + 80099e4: d106 bne.n 80099f4 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE); + 80099e6: 2102 movs r1, #2 + 80099e8: 1d20 adds r0, r4, #4 + 80099ea: f7ff fd9b bl 8009524 + if(ret != HAL_OK) + 80099ee: 2800 cmp r0, #0 + 80099f0: bf18 it ne + 80099f2: 4605 movne r5, r0 + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1) + 80099f4: 6822 ldr r2, [r4, #0] + 80099f6: 03d0 lsls r0, r2, #15 + 80099f8: d509 bpl.n 8009a0e + __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection); + 80099fa: 4947 ldr r1, [pc, #284] ; (8009b18 ) + 80099fc: f8d4 0084 ldr.w r0, [r4, #132] ; 0x84 + 8009a00: f8d1 309c ldr.w r3, [r1, #156] ; 0x9c + 8009a04: f023 0304 bic.w r3, r3, #4 + 8009a08: 4303 orrs r3, r0 + 8009a0a: f8c1 309c str.w r3, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1AUDIO) == RCC_PERIPHCLK_DFSDM1AUDIO) + 8009a0e: 0291 lsls r1, r2, #10 + 8009a10: d509 bpl.n 8009a26 + __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection); + 8009a12: 4941 ldr r1, [pc, #260] ; (8009b18 ) + 8009a14: f8d4 0088 ldr.w r0, [r4, #136] ; 0x88 + 8009a18: f8d1 309c ldr.w r3, [r1, #156] ; 0x9c + 8009a1c: f023 0318 bic.w r3, r3, #24 + 8009a20: 4303 orrs r3, r0 + 8009a22: f8c1 309c str.w r3, [r1, #156] ; 0x9c + if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI) + 8009a26: 01d3 lsls r3, r2, #7 + 8009a28: d510 bpl.n 8009a4c + __HAL_RCC_OSPI_CONFIG(PeriphClkInit->OspiClockSelection); + 8009a2a: 4a3b ldr r2, [pc, #236] ; (8009b18 ) + 8009a2c: f8d4 108c ldr.w r1, [r4, #140] ; 0x8c + 8009a30: f8d2 309c ldr.w r3, [r2, #156] ; 0x9c + 8009a34: f423 1340 bic.w r3, r3, #3145728 ; 0x300000 + 8009a38: 430b orrs r3, r1 + 8009a3a: f8c2 309c str.w r3, [r2, #156] ; 0x9c + if(PeriphClkInit->OspiClockSelection == RCC_OSPICLKSOURCE_PLL) + 8009a3e: f5b1 1f00 cmp.w r1, #2097152 ; 0x200000 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 8009a42: bf02 ittt eq + 8009a44: 68d3 ldreq r3, [r2, #12] + 8009a46: f443 1380 orreq.w r3, r3, #1048576 ; 0x100000 + 8009a4a: 60d3 streq r3, [r2, #12] +} + 8009a4c: 4628 mov r0, r5 + 8009a4e: b002 add sp, #8 + 8009a50: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection)) + 8009a54: f8d4 2090 ldr.w r2, [r4, #144] ; 0x90 + 8009a58: 429a cmp r2, r3 + 8009a5a: f43f aecd beq.w 80097f8 + tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + 8009a5e: f8d7 2090 ldr.w r2, [r7, #144] ; 0x90 + __HAL_RCC_BACKUPRESET_FORCE(); + 8009a62: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 8009a66: f443 3380 orr.w r3, r3, #65536 ; 0x10000 + 8009a6a: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + __HAL_RCC_BACKUPRESET_RELEASE(); + 8009a6e: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); + 8009a72: f422 7140 bic.w r1, r2, #768 ; 0x300 + __HAL_RCC_BACKUPRESET_RELEASE(); + 8009a76: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) + 8009a7a: 07d2 lsls r2, r2, #31 + __HAL_RCC_BACKUPRESET_RELEASE(); + 8009a7c: f8c7 3090 str.w r3, [r7, #144] ; 0x90 + RCC->BDCR = tmpregister; + 8009a80: f8c7 1090 str.w r1, [r7, #144] ; 0x90 + if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) + 8009a84: f57f aeb8 bpl.w 80097f8 + tickstart = HAL_GetTick(); + 8009a88: f7fd fca8 bl 80073dc + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8009a8c: f241 3988 movw r9, #5000 ; 0x1388 + tickstart = HAL_GetTick(); + 8009a90: 4605 mov r5, r0 + while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) + 8009a92: f8d7 3090 ldr.w r3, [r7, #144] ; 0x90 + 8009a96: 079b lsls r3, r3, #30 + 8009a98: f53f aeae bmi.w 80097f8 + if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + 8009a9c: f7fd fc9e bl 80073dc + 8009aa0: 1b40 subs r0, r0, r5 + 8009aa2: 4548 cmp r0, r9 + 8009aa4: d9f5 bls.n 8009a92 + 8009aa6: e6c7 b.n 8009838 + 8009aa8: 4635 mov r5, r6 + 8009aaa: e6cd b.n 8009848 + if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1) + 8009aac: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 8009ab0: f47f af62 bne.w 8009978 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 8009ab4: 2101 movs r1, #1 + 8009ab6: 1d20 adds r0, r4, #4 + 8009ab8: f7ff fd34 bl 8009524 + if(ret != HAL_OK) + 8009abc: 2800 cmp r0, #0 + 8009abe: bf18 it ne + 8009ac0: 4605 movne r5, r0 + 8009ac2: e759 b.n 8009978 + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 8009ac4: f422 4280 bic.w r2, r2, #16384 ; 0x4000 + 8009ac8: f8c3 209c str.w r2, [r3, #156] ; 0x9c + 8009acc: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009ad0: f022 6240 bic.w r2, r2, #201326592 ; 0xc000000 + 8009ad4: 430a orrs r2, r1 + if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) /* PLL "Q" ? */ + 8009ad6: f1b1 6f00 cmp.w r1, #134217728 ; 0x8000000 + __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); + 8009ada: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) /* PLL "Q" ? */ + 8009ade: d103 bne.n 8009ae8 + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); + 8009ae0: 68da ldr r2, [r3, #12] + 8009ae2: f442 1280 orr.w r2, r2, #1048576 ; 0x100000 + 8009ae6: e759 b.n 800999c + else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1) + 8009ae8: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 8009aec: f47f af57 bne.w 800999e + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 8009af0: 2101 movs r1, #1 + 8009af2: 1d20 adds r0, r4, #4 + 8009af4: f7ff fd16 bl 8009524 + if(ret != HAL_OK) + 8009af8: 2800 cmp r0, #0 + 8009afa: bf18 it ne + 8009afc: 4605 movne r5, r0 + 8009afe: e74e b.n 800999e + else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1) + 8009b00: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 8009b04: f47f af5f bne.w 80099c6 + ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); + 8009b08: 2101 movs r1, #1 + 8009b0a: 1d20 adds r0, r4, #4 + 8009b0c: f7ff fd0a bl 8009524 + if(ret != HAL_OK) + 8009b10: 2800 cmp r0, #0 + 8009b12: bf18 it ne + 8009b14: 4605 movne r5, r0 + 8009b16: e756 b.n 80099c6 + 8009b18: 40021000 .word 0x40021000 + +08009b1c : + PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \ + 8009b1c: 4b5b ldr r3, [pc, #364] ; (8009c8c ) + 8009b1e: 6003 str r3, [r0, #0] + PeriphClkInit->PLLSAI1.PLLSAI1Source = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC) >> RCC_PLLCFGR_PLLSRC_Pos; + 8009b20: 4b5b ldr r3, [pc, #364] ; (8009c90 ) + 8009b22: 68d9 ldr r1, [r3, #12] + 8009b24: f001 0103 and.w r1, r1, #3 + 8009b28: 6041 str r1, [r0, #4] + PeriphClkInit->PLLSAI1.PLLSAI1M = (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U; + 8009b2a: 691a ldr r2, [r3, #16] + 8009b2c: f3c2 1203 ubfx r2, r2, #4, #4 + 8009b30: 3201 adds r2, #1 + 8009b32: 6082 str r2, [r0, #8] + PeriphClkInit->PLLSAI1.PLLSAI1N = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009b34: 691a ldr r2, [r3, #16] + 8009b36: f3c2 2206 ubfx r2, r2, #8, #7 + 8009b3a: 60c2 str r2, [r0, #12] + PeriphClkInit->PLLSAI1.PLLSAI1P = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) >> RCC_PLLSAI1CFGR_PLLSAI1P_Pos) << 4U) + 7U; + 8009b3c: 691a ldr r2, [r3, #16] + 8009b3e: 0b52 lsrs r2, r2, #13 + 8009b40: f002 0210 and.w r2, r2, #16 + 8009b44: 3207 adds r2, #7 + 8009b46: 6102 str r2, [r0, #16] + PeriphClkInit->PLLSAI1.PLLSAI1Q = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) * 2U; + 8009b48: 691a ldr r2, [r3, #16] + 8009b4a: f3c2 5241 ubfx r2, r2, #21, #2 + 8009b4e: 3201 adds r2, #1 + 8009b50: 0052 lsls r2, r2, #1 + 8009b52: 6142 str r2, [r0, #20] + PeriphClkInit->PLLSAI1.PLLSAI1R = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U; + 8009b54: 691a ldr r2, [r3, #16] + PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source; + 8009b56: 6201 str r1, [r0, #32] + PeriphClkInit->PLLSAI1.PLLSAI1R = ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U; + 8009b58: f3c2 6241 ubfx r2, r2, #25, #2 + 8009b5c: 3201 adds r2, #1 + 8009b5e: 0052 lsls r2, r2, #1 + 8009b60: 6182 str r2, [r0, #24] + PeriphClkInit->PLLSAI2.PLLSAI2M = (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U; + 8009b62: 695a ldr r2, [r3, #20] + 8009b64: f3c2 1203 ubfx r2, r2, #4, #4 + 8009b68: 3201 adds r2, #1 + 8009b6a: 6242 str r2, [r0, #36] ; 0x24 + PeriphClkInit->PLLSAI2.PLLSAI2N = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos; + 8009b6c: 695a ldr r2, [r3, #20] + 8009b6e: f3c2 2206 ubfx r2, r2, #8, #7 + 8009b72: 6282 str r2, [r0, #40] ; 0x28 + PeriphClkInit->PLLSAI2.PLLSAI2P = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) >> RCC_PLLSAI2CFGR_PLLSAI2P_Pos) << 4U) + 7U; + 8009b74: 695a ldr r2, [r3, #20] + 8009b76: 0b52 lsrs r2, r2, #13 + 8009b78: f002 0210 and.w r2, r2, #16 + 8009b7c: 3207 adds r2, #7 + 8009b7e: 62c2 str r2, [r0, #44] ; 0x2c + PeriphClkInit->PLLSAI2.PLLSAI2Q = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2Q) >> RCC_PLLSAI2CFGR_PLLSAI2Q_Pos) + 1U) * 2U; + 8009b80: 695a ldr r2, [r3, #20] + 8009b82: f3c2 5241 ubfx r2, r2, #21, #2 + 8009b86: 3201 adds r2, #1 + 8009b88: 0052 lsls r2, r2, #1 + 8009b8a: 6302 str r2, [r0, #48] ; 0x30 + PeriphClkInit->PLLSAI2.PLLSAI2R = ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R)>> RCC_PLLSAI2CFGR_PLLSAI2R_Pos) + 1U) * 2U; + 8009b8c: 695a ldr r2, [r3, #20] + 8009b8e: f3c2 6241 ubfx r2, r2, #25, #2 + 8009b92: 3201 adds r2, #1 + 8009b94: 0052 lsls r2, r2, #1 + 8009b96: 6342 str r2, [r0, #52] ; 0x34 + PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); + 8009b98: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009b9c: f002 0203 and.w r2, r2, #3 + 8009ba0: 63c2 str r2, [r0, #60] ; 0x3c + PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); + 8009ba2: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009ba6: f002 020c and.w r2, r2, #12 + 8009baa: 6402 str r2, [r0, #64] ; 0x40 + PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE(); + 8009bac: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bb0: f002 0230 and.w r2, r2, #48 ; 0x30 + 8009bb4: 6442 str r2, [r0, #68] ; 0x44 + PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE(); + 8009bb6: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bba: f002 02c0 and.w r2, r2, #192 ; 0xc0 + 8009bbe: 6482 str r2, [r0, #72] ; 0x48 + PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE(); + 8009bc0: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bc4: f402 7240 and.w r2, r2, #768 ; 0x300 + 8009bc8: 64c2 str r2, [r0, #76] ; 0x4c + PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); + 8009bca: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bce: f402 6240 and.w r2, r2, #3072 ; 0xc00 + 8009bd2: 6502 str r2, [r0, #80] ; 0x50 + PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); + 8009bd4: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bd8: f402 5240 and.w r2, r2, #12288 ; 0x3000 + 8009bdc: 6542 str r2, [r0, #84] ; 0x54 + PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE(); + 8009bde: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009be2: f402 4240 and.w r2, r2, #49152 ; 0xc000 + 8009be6: 6582 str r2, [r0, #88] ; 0x58 + PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE(); + 8009be8: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009bec: f402 3240 and.w r2, r2, #196608 ; 0x30000 + 8009bf0: 65c2 str r2, [r0, #92] ; 0x5c + PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE(); + 8009bf2: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009bf6: f002 0203 and.w r2, r2, #3 + 8009bfa: 6602 str r2, [r0, #96] ; 0x60 + PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); + 8009bfc: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009c00: f402 2240 and.w r2, r2, #786432 ; 0xc0000 + 8009c04: 6642 str r2, [r0, #100] ; 0x64 + PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE(); + 8009c06: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009c0a: f402 1240 and.w r2, r2, #3145728 ; 0x300000 + 8009c0e: 6682 str r2, [r0, #104] ; 0x68 + PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); + 8009c10: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009c14: f002 02e0 and.w r2, r2, #224 ; 0xe0 + 8009c18: 66c2 str r2, [r0, #108] ; 0x6c + PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); + 8009c1a: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009c1e: f402 62e0 and.w r2, r2, #1792 ; 0x700 + 8009c22: 6702 str r2, [r0, #112] ; 0x70 + PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); + 8009c24: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 8009c28: f402 7240 and.w r2, r2, #768 ; 0x300 + 8009c2c: f8c0 2090 str.w r2, [r0, #144] ; 0x90 + PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); + 8009c30: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009c34: f002 6240 and.w r2, r2, #201326592 ; 0xc000000 + 8009c38: 6742 str r2, [r0, #116] ; 0x74 + PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE(); + 8009c3a: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009c3e: 0452 lsls r2, r2, #17 + 8009c40: bf56 itet pl + 8009c42: f8d3 2088 ldrpl.w r2, [r3, #136] ; 0x88 + 8009c46: f44f 4280 movmi.w r2, #16384 ; 0x4000 + 8009c4a: f002 6240 andpl.w r2, r2, #201326592 ; 0xc000000 + 8009c4e: 6782 str r2, [r0, #120] ; 0x78 + PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE(); + 8009c50: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009c54: f002 6240 and.w r2, r2, #201326592 ; 0xc000000 + 8009c58: 67c2 str r2, [r0, #124] ; 0x7c + PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE(); + 8009c5a: f8d3 2088 ldr.w r2, [r3, #136] ; 0x88 + 8009c5e: f002 5240 and.w r2, r2, #805306368 ; 0x30000000 + 8009c62: f8c0 2080 str.w r2, [r0, #128] ; 0x80 + PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE(); + 8009c66: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009c6a: f002 0204 and.w r2, r2, #4 + 8009c6e: f8c0 2084 str.w r2, [r0, #132] ; 0x84 + PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); + 8009c72: f8d3 209c ldr.w r2, [r3, #156] ; 0x9c + 8009c76: f002 0218 and.w r2, r2, #24 + 8009c7a: f8c0 2088 str.w r2, [r0, #136] ; 0x88 + PeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE(); + 8009c7e: f8d3 309c ldr.w r3, [r3, #156] ; 0x9c + 8009c82: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + 8009c86: f8c0 308c str.w r3, [r0, #140] ; 0x8c +} + 8009c8a: 4770 bx lr + 8009c8c: 013f7fff .word 0x013f7fff + 8009c90: 40021000 .word 0x40021000 + +08009c94 : + if(PeriphClk == RCC_PERIPHCLK_RTC) + 8009c94: f5b0 3f00 cmp.w r0, #131072 ; 0x20000 +{ + 8009c98: b4f0 push {r4, r5, r6, r7} + 8009c9a: 4d9a ldr r5, [pc, #616] ; (8009f04 ) + if(PeriphClk == RCC_PERIPHCLK_RTC) + 8009c9c: d11c bne.n 8009cd8 + srcclk = __HAL_RCC_GET_RTC_SOURCE(); + 8009c9e: f8d5 3090 ldr.w r3, [r5, #144] ; 0x90 + 8009ca2: f403 7340 and.w r3, r3, #768 ; 0x300 + switch(srcclk) + 8009ca6: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 8009caa: f000 8085 beq.w 8009db8 + 8009cae: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 8009cb2: d00a beq.n 8009cca + 8009cb4: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 8009cb8: d154 bne.n 8009d64 + if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) + 8009cba: f8d5 0090 ldr.w r0, [r5, #144] ; 0x90 + frequency = LSE_VALUE; + 8009cbe: f010 0002 ands.w r0, r0, #2 + 8009cc2: bf18 it ne + 8009cc4: f44f 4000 movne.w r0, #32768 ; 0x8000 + 8009cc8: e11a b.n 8009f00 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) + 8009cca: 6828 ldr r0, [r5, #0] + frequency = HSE_VALUE / 32U; + 8009ccc: 4b8e ldr r3, [pc, #568] ; (8009f08 ) + 8009cce: f410 3000 ands.w r0, r0, #131072 ; 0x20000 + frequency = HSI_VALUE; + 8009cd2: bf18 it ne + 8009cd4: 4618 movne r0, r3 + 8009cd6: e113 b.n 8009f00 + pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); + 8009cd8: 68eb ldr r3, [r5, #12] + 8009cda: f003 0303 and.w r3, r3, #3 + switch(pll_oscsource) + 8009cde: 2b02 cmp r3, #2 + 8009ce0: d02f beq.n 8009d42 + 8009ce2: 2b03 cmp r3, #3 + 8009ce4: d034 beq.n 8009d50 + 8009ce6: 2b01 cmp r3, #1 + 8009ce8: d137 bne.n 8009d5a + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) + 8009cea: 6829 ldr r1, [r5, #0] + 8009cec: f011 0102 ands.w r1, r1, #2 + 8009cf0: d00c beq.n 8009d0c + pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)]; + 8009cf2: 682b ldr r3, [r5, #0] + 8009cf4: 4a85 ldr r2, [pc, #532] ; (8009f0c ) + 8009cf6: 0719 lsls r1, r3, #28 + 8009cf8: bf4b itete mi + 8009cfa: 682b ldrmi r3, [r5, #0] + 8009cfc: f8d5 3094 ldrpl.w r3, [r5, #148] ; 0x94 + 8009d00: f3c3 1303 ubfxmi r3, r3, #4, #4 + 8009d04: f3c3 2303 ubfxpl r3, r3, #8, #4 + 8009d08: f852 1023 ldr.w r1, [r2, r3, lsl #2] + switch(PeriphClk) + 8009d0c: f5b0 6f80 cmp.w r0, #1024 ; 0x400 + 8009d10: f000 8226 beq.w 800a160 + 8009d14: d858 bhi.n 8009dc8 + 8009d16: 2820 cmp r0, #32 + 8009d18: f000 81be beq.w 800a098 + 8009d1c: d824 bhi.n 8009d68 + 8009d1e: 2808 cmp r0, #8 + 8009d20: d81d bhi.n 8009d5e + 8009d22: 2800 cmp r0, #0 + 8009d24: f000 80ec beq.w 8009f00 + 8009d28: 3801 subs r0, #1 + 8009d2a: 2807 cmp r0, #7 + 8009d2c: d81a bhi.n 8009d64 + 8009d2e: e8df f010 tbh [pc, r0, lsl #1] + 8009d32: 0164 .short 0x0164 + 8009d34: 00190177 .word 0x00190177 + 8009d38: 00190189 .word 0x00190189 + 8009d3c: 00190019 .word 0x00190019 + 8009d40: 0196 .short 0x0196 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 8009d42: 6829 ldr r1, [r5, #0] + pllvco = HSI_VALUE; + 8009d44: 4b72 ldr r3, [pc, #456] ; (8009f10 ) + 8009d46: f411 6180 ands.w r1, r1, #1024 ; 0x400 + pllvco = HSE_VALUE; + 8009d4a: bf18 it ne + 8009d4c: 4619 movne r1, r3 + 8009d4e: e7dd b.n 8009d0c + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) + 8009d50: 6829 ldr r1, [r5, #0] + pllvco = HSE_VALUE; + 8009d52: 4b70 ldr r3, [pc, #448] ; (8009f14 ) + 8009d54: f411 3100 ands.w r1, r1, #131072 ; 0x20000 + 8009d58: e7f7 b.n 8009d4a + switch(pll_oscsource) + 8009d5a: 2100 movs r1, #0 + 8009d5c: e7d6 b.n 8009d0c + switch(PeriphClk) + 8009d5e: 2810 cmp r0, #16 + 8009d60: f000 818a beq.w 800a078 + 8009d64: 2000 movs r0, #0 + 8009d66: e0cb b.n 8009f00 + 8009d68: f5b0 7f80 cmp.w r0, #256 ; 0x100 + 8009d6c: f000 81ea beq.w 800a144 + 8009d70: d80f bhi.n 8009d92 + 8009d72: 2840 cmp r0, #64 ; 0x40 + 8009d74: f000 81d5 beq.w 800a122 + 8009d78: 2880 cmp r0, #128 ; 0x80 + 8009d7a: d1f3 bne.n 8009d64 + srcclk = __HAL_RCC_GET_I2C2_SOURCE(); + 8009d7c: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d80: f403 4340 and.w r3, r3, #49152 ; 0xc000 + switch(srcclk) + 8009d84: f5b3 4f80 cmp.w r3, #16384 ; 0x4000 + 8009d88: f000 8157 beq.w 800a03a + 8009d8c: f5b3 4f00 cmp.w r3, #32768 ; 0x8000 + 8009d90: e1d0 b.n 800a134 + switch(PeriphClk) + 8009d92: f5b0 7f00 cmp.w r0, #512 ; 0x200 + 8009d96: d1e5 bne.n 8009d64 + srcclk = __HAL_RCC_GET_LPTIM1_SOURCE(); + 8009d98: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009d9c: f403 2340 and.w r3, r3, #786432 ; 0xc0000 + switch(srcclk) + 8009da0: f5b3 2f00 cmp.w r3, #524288 ; 0x80000 + 8009da4: f000 8137 beq.w 800a016 + 8009da8: f200 81d7 bhi.w 800a15a + 8009dac: 2b00 cmp r3, #0 + 8009dae: f000 81c6 beq.w 800a13e + 8009db2: f5b3 2f80 cmp.w r3, #262144 ; 0x40000 + 8009db6: d1d5 bne.n 8009d64 + if(HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) + 8009db8: f8d5 0094 ldr.w r0, [r5, #148] ; 0x94 + frequency = LSI_VALUE; + 8009dbc: f010 0002 ands.w r0, r0, #2 + 8009dc0: bf18 it ne + 8009dc2: f44f 40fa movne.w r0, #32000 ; 0x7d00 + 8009dc6: e09b b.n 8009f00 + switch(PeriphClk) + 8009dc8: f5b0 2f80 cmp.w r0, #262144 ; 0x40000 + 8009dcc: d040 beq.n 8009e50 + 8009dce: d819 bhi.n 8009e04 + 8009dd0: f5b0 5f00 cmp.w r0, #8192 ; 0x2000 + 8009dd4: d03c beq.n 8009e50 + 8009dd6: d808 bhi.n 8009dea + 8009dd8: f5b0 6f00 cmp.w r0, #2048 ; 0x800 + 8009ddc: d002 beq.n 8009de4 + 8009dde: f5b0 5f80 cmp.w r0, #4096 ; 0x1000 + 8009de2: d1bf bne.n 8009d64 +} + 8009de4: bcf0 pop {r4, r5, r6, r7} + frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco); + 8009de6: f7ff bb1b b.w 8009420 + switch(PeriphClk) + 8009dea: f5b0 4f80 cmp.w r0, #16384 ; 0x4000 + 8009dee: f000 8163 beq.w 800a0b8 + 8009df2: f5b0 3f80 cmp.w r0, #65536 ; 0x10000 + 8009df6: d1b5 bne.n 8009d64 + srcclk = __HAL_RCC_GET_DFSDM1_SOURCE(); + 8009df8: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK2) + 8009dfc: 075a lsls r2, r3, #29 + 8009dfe: f100 811c bmi.w 800a03a + 8009e02: e105 b.n 800a010 + switch(PeriphClk) + 8009e04: f5b0 1f00 cmp.w r0, #2097152 ; 0x200000 + 8009e08: f000 817c beq.w 800a104 + 8009e0c: d80f bhi.n 8009e2e + 8009e0e: f5b0 2f00 cmp.w r0, #524288 ; 0x80000 + 8009e12: f000 8081 beq.w 8009f18 + 8009e16: f5b0 1f80 cmp.w r0, #1048576 ; 0x100000 + 8009e1a: d1a3 bne.n 8009d64 + srcclk = __HAL_RCC_GET_I2C4_SOURCE(); + 8009e1c: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 8009e20: f003 0303 and.w r3, r3, #3 + switch(srcclk) + 8009e24: 2b01 cmp r3, #1 + 8009e26: f000 8108 beq.w 800a03a + 8009e2a: 2b02 cmp r3, #2 + 8009e2c: e182 b.n 800a134 + switch(PeriphClk) + 8009e2e: f1b0 7f80 cmp.w r0, #16777216 ; 0x1000000 + 8009e32: d197 bne.n 8009d64 + srcclk = __HAL_RCC_GET_OSPI_SOURCE(); + 8009e34: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 8009e38: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + switch(srcclk) + 8009e3c: f5b3 1f80 cmp.w r3, #1048576 ; 0x100000 + 8009e40: d033 beq.n 8009eaa + 8009e42: f5b3 1f00 cmp.w r3, #2097152 ; 0x200000 + 8009e46: f000 819c beq.w 800a182 + 8009e4a: 2b00 cmp r3, #0 + 8009e4c: d18a bne.n 8009d64 + 8009e4e: e0f4 b.n 800a03a + srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL); + 8009e50: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009e54: f003 6340 and.w r3, r3, #201326592 ; 0xc000000 + switch(srcclk) + 8009e58: f1b3 6f00 cmp.w r3, #134217728 ; 0x8000000 + 8009e5c: d037 beq.n 8009ece + 8009e5e: d820 bhi.n 8009ea2 + 8009e60: 2b00 cmp r3, #0 + 8009e62: f000 80c4 beq.w 8009fee + 8009e66: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + 8009e6a: f47f af7b bne.w 8009d64 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY)) + 8009e6e: 6828 ldr r0, [r5, #0] + 8009e70: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 8009e74: d044 beq.n 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN)) + 8009e76: 6928 ldr r0, [r5, #16] + 8009e78: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009e7c: d040 beq.n 8009f00 + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009e7e: 692f ldr r7, [r5, #16] + 8009e80: f3c7 2706 ubfx r7, r7, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e84: 4379 muls r1, r7 + 8009e86: 692f ldr r7, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009e88: 6928 ldr r0, [r5, #16] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009e8a: f3c7 1703 ubfx r7, r7, #4, #4 + 8009e8e: 3701 adds r7, #1 + 8009e90: fbb1 f1f7 udiv r1, r1, r7 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009e94: f3c0 5041 ubfx r0, r0, #21, #2 + 8009e98: 3001 adds r0, #1 + 8009e9a: 0040 lsls r0, r0, #1 + 8009e9c: fbb1 f0f0 udiv r0, r1, r0 + 8009ea0: e02e b.n 8009f00 + 8009ea2: f1b3 6f40 cmp.w r3, #201326592 ; 0xc000000 + 8009ea6: f47f af5d bne.w 8009d64 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) + 8009eaa: 6828 ldr r0, [r5, #0] + 8009eac: f010 0002 ands.w r0, r0, #2 + 8009eb0: d026 beq.n 8009f00 + frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)]; + 8009eb2: 682b ldr r3, [r5, #0] + 8009eb4: 4a15 ldr r2, [pc, #84] ; (8009f0c ) + 8009eb6: 071b lsls r3, r3, #28 + 8009eb8: bf4b itete mi + 8009eba: 682b ldrmi r3, [r5, #0] + 8009ebc: f8d5 3094 ldrpl.w r3, [r5, #148] ; 0x94 + 8009ec0: f3c3 1303 ubfxmi r3, r3, #4, #4 + 8009ec4: f3c3 2303 ubfxpl r3, r3, #8, #4 + 8009ec8: f852 0023 ldr.w r0, [r2, r3, lsl #2] + 8009ecc: e018 b.n 8009f00 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009ece: 6828 ldr r0, [r5, #0] + 8009ed0: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009ed4: d014 beq.n 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 8009ed6: 68e8 ldr r0, [r5, #12] + 8009ed8: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009edc: d010 beq.n 8009f00 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009ede: 68e8 ldr r0, [r5, #12] + 8009ee0: f3c0 2006 ubfx r0, r0, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009ee4: 4348 muls r0, r1 + 8009ee6: 68e9 ldr r1, [r5, #12] + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009ee8: 68ed ldr r5, [r5, #12] + 8009eea: f3c5 5541 ubfx r5, r5, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009eee: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009ef2: 3501 adds r5, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009ef4: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009ef6: 006d lsls r5, r5, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009ef8: fbb0 f0f1 udiv r0, r0, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009efc: fbb0 f0f5 udiv r0, r0, r5 +} + 8009f00: bcf0 pop {r4, r5, r6, r7} + 8009f02: 4770 bx lr + 8009f04: 40021000 .word 0x40021000 + 8009f08: 0003d090 .word 0x0003d090 + 8009f0c: 08010a70 .word 0x08010a70 + 8009f10: 00f42400 .word 0x00f42400 + 8009f14: 007a1200 .word 0x007a1200 + if(HAL_IS_BIT_SET(RCC->CCIPR2, RCC_CCIPR2_SDMMCSEL)) /* PLL "P" ? */ + 8009f18: f8d5 009c ldr.w r0, [r5, #156] ; 0x9c + 8009f1c: f410 4080 ands.w r0, r0, #16384 ; 0x4000 + 8009f20: d01f beq.n 8009f62 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009f22: 6828 ldr r0, [r5, #0] + 8009f24: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009f28: d0ea beq.n 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN)) + 8009f2a: 68e8 ldr r0, [r5, #12] + 8009f2c: f410 3080 ands.w r0, r0, #65536 ; 0x10000 + 8009f30: d0e6 beq.n 8009f00 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009f32: 68ee ldr r6, [r5, #12] + 8009f34: f3c6 2606 ubfx r6, r6, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009f38: fb01 f006 mul.w r0, r1, r6 + 8009f3c: 68ee ldr r6, [r5, #12] + pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; + 8009f3e: 68eb ldr r3, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009f40: f3c6 1603 ubfx r6, r6, #4, #4 + if(pllp == 0U) + 8009f44: 0edb lsrs r3, r3, #27 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009f46: f106 0601 add.w r6, r6, #1 + 8009f4a: fbb0 f0f6 udiv r0, r0, r6 + if(pllp == 0U) + 8009f4e: d105 bne.n 8009f5c + if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U) + 8009f50: 68eb ldr r3, [r5, #12] + pllp = 7U; + 8009f52: f413 3f00 tst.w r3, #131072 ; 0x20000 + 8009f56: bf14 ite ne + 8009f58: 2311 movne r3, #17 + 8009f5a: 2307 moveq r3, #7 + frequency = (pllvco / pllp); + 8009f5c: fbb0 f0f3 udiv r0, r0, r3 + 8009f60: e7ce b.n 8009f00 + srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL); + 8009f62: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009f66: f003 6340 and.w r3, r3, #201326592 ; 0xc000000 + switch(srcclk) + 8009f6a: f1b3 6f00 cmp.w r3, #134217728 ; 0x8000000 + 8009f6e: d024 beq.n 8009fba + 8009f70: d81e bhi.n 8009fb0 + 8009f72: 2b00 cmp r3, #0 + 8009f74: d03b beq.n 8009fee + 8009f76: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + 8009f7a: d1c1 bne.n 8009f00 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY)) + 8009f7c: 6828 ldr r0, [r5, #0] + 8009f7e: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 8009f82: d0bd beq.n 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN)) + 8009f84: 6928 ldr r0, [r5, #16] + 8009f86: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009f8a: d0b9 beq.n 8009f00 + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 8009f8c: 692a ldr r2, [r5, #16] + 8009f8e: f3c2 2206 ubfx r2, r2, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009f92: 434a muls r2, r1 + 8009f94: 6929 ldr r1, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009f96: 6928 ldr r0, [r5, #16] + 8009f98: f3c0 5041 ubfx r0, r0, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009f9c: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009fa0: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009fa2: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009fa4: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 8009fa6: fbb2 f2f1 udiv r2, r2, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U)); + 8009faa: fbb2 f0f0 udiv r0, r2, r0 + 8009fae: e7a7 b.n 8009f00 + 8009fb0: f1b3 6f40 cmp.w r3, #201326592 ; 0xc000000 + 8009fb4: f43f af79 beq.w 8009eaa + 8009fb8: e7a2 b.n 8009f00 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 8009fba: 6828 ldr r0, [r5, #0] + 8009fbc: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 8009fc0: d09e beq.n 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 8009fc2: 68e8 ldr r0, [r5, #12] + 8009fc4: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 8009fc8: d09a beq.n 8009f00 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 8009fca: 68ec ldr r4, [r5, #12] + 8009fcc: f3c4 2406 ubfx r4, r4, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009fd0: 434c muls r4, r1 + 8009fd2: 68e9 ldr r1, [r5, #12] + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009fd4: 68e8 ldr r0, [r5, #12] + 8009fd6: f3c0 5041 ubfx r0, r0, #21, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009fda: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009fde: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009fe0: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009fe2: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 8009fe4: fbb4 f4f1 udiv r4, r4, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 8009fe8: fbb4 f0f0 udiv r0, r4, r0 + 8009fec: e788 b.n 8009f00 + if(HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */ + 8009fee: f8d5 0098 ldr.w r0, [r5, #152] ; 0x98 + frequency = HSI48_VALUE; + 8009ff2: 4b6f ldr r3, [pc, #444] ; (800a1b0 ) + 8009ff4: f010 0002 ands.w r0, r0, #2 + 8009ff8: e66b b.n 8009cd2 + srcclk = __HAL_RCC_GET_USART1_SOURCE(); + 8009ffa: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 8009ffe: f003 0303 and.w r3, r3, #3 + switch(srcclk) + 800a002: 2b02 cmp r3, #2 + 800a004: d007 beq.n 800a016 + 800a006: 2b03 cmp r3, #3 + 800a008: f43f ae57 beq.w 8009cba + 800a00c: 2b01 cmp r3, #1 + 800a00e: d014 beq.n 800a03a +} + 800a010: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetPCLK2Freq(); + 800a012: f7ff b95b b.w 80092cc + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) + 800a016: 6828 ldr r0, [r5, #0] + frequency = HSI_VALUE; + 800a018: 4b66 ldr r3, [pc, #408] ; (800a1b4 ) + 800a01a: f410 6080 ands.w r0, r0, #1024 ; 0x400 + 800a01e: e658 b.n 8009cd2 + srcclk = __HAL_RCC_GET_USART2_SOURCE(); + 800a020: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a024: f003 030c and.w r3, r3, #12 + switch(srcclk) + 800a028: 2b08 cmp r3, #8 + 800a02a: d0f4 beq.n 800a016 + 800a02c: d808 bhi.n 800a040 + 800a02e: 2b00 cmp r3, #0 + 800a030: f000 8085 beq.w 800a13e + 800a034: 2b04 cmp r3, #4 + 800a036: f47f ae95 bne.w 8009d64 +} + 800a03a: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetSysClockFreq(); + 800a03c: f7fe bd38 b.w 8008ab0 + 800a040: 2b0c cmp r3, #12 + 800a042: e639 b.n 8009cb8 + srcclk = __HAL_RCC_GET_USART3_SOURCE(); + 800a044: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a048: f003 0330 and.w r3, r3, #48 ; 0x30 + switch(srcclk) + 800a04c: 2b20 cmp r3, #32 + 800a04e: d0e2 beq.n 800a016 + 800a050: d803 bhi.n 800a05a + 800a052: 2b00 cmp r3, #0 + 800a054: d073 beq.n 800a13e + 800a056: 2b10 cmp r3, #16 + 800a058: e7ed b.n 800a036 + 800a05a: 2b30 cmp r3, #48 ; 0x30 + 800a05c: e62c b.n 8009cb8 + srcclk = __HAL_RCC_GET_UART4_SOURCE(); + 800a05e: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a062: f003 03c0 and.w r3, r3, #192 ; 0xc0 + switch(srcclk) + 800a066: 2b80 cmp r3, #128 ; 0x80 + 800a068: d0d5 beq.n 800a016 + 800a06a: d803 bhi.n 800a074 + 800a06c: 2b00 cmp r3, #0 + 800a06e: d066 beq.n 800a13e + 800a070: 2b40 cmp r3, #64 ; 0x40 + 800a072: e7e0 b.n 800a036 + 800a074: 2bc0 cmp r3, #192 ; 0xc0 + 800a076: e61f b.n 8009cb8 + srcclk = __HAL_RCC_GET_UART5_SOURCE(); + 800a078: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a07c: f403 7340 and.w r3, r3, #768 ; 0x300 + switch(srcclk) + 800a080: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800a084: d0c7 beq.n 800a016 + 800a086: d804 bhi.n 800a092 + 800a088: 2b00 cmp r3, #0 + 800a08a: d058 beq.n 800a13e + 800a08c: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800a090: e7d1 b.n 800a036 + 800a092: f5b3 7f40 cmp.w r3, #768 ; 0x300 + 800a096: e60f b.n 8009cb8 + srcclk = __HAL_RCC_GET_LPUART1_SOURCE(); + 800a098: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a09c: f403 6340 and.w r3, r3, #3072 ; 0xc00 + switch(srcclk) + 800a0a0: f5b3 6f00 cmp.w r3, #2048 ; 0x800 + 800a0a4: d0b7 beq.n 800a016 + 800a0a6: d804 bhi.n 800a0b2 + 800a0a8: 2b00 cmp r3, #0 + 800a0aa: d048 beq.n 800a13e + 800a0ac: f5b3 6f80 cmp.w r3, #1024 ; 0x400 + 800a0b0: e7c1 b.n 800a036 + 800a0b2: f5b3 6f40 cmp.w r3, #3072 ; 0xc00 + 800a0b6: e5ff b.n 8009cb8 + srcclk = __HAL_RCC_GET_ADC_SOURCE(); + 800a0b8: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a0bc: f003 5340 and.w r3, r3, #805306368 ; 0x30000000 + switch(srcclk) + 800a0c0: f1b3 5f80 cmp.w r3, #268435456 ; 0x10000000 + 800a0c4: d002 beq.n 800a0cc + 800a0c6: f1b3 5f40 cmp.w r3, #805306368 ; 0x30000000 + 800a0ca: e7b4 b.n 800a036 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != 0U)) + 800a0cc: 6828 ldr r0, [r5, #0] + 800a0ce: f010 6000 ands.w r0, r0, #134217728 ; 0x8000000 + 800a0d2: f43f af15 beq.w 8009f00 + 800a0d6: 6928 ldr r0, [r5, #16] + 800a0d8: f010 7080 ands.w r0, r0, #16777216 ; 0x1000000 + 800a0dc: f43f af10 beq.w 8009f00 + plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos; + 800a0e0: 692b ldr r3, [r5, #16] + 800a0e2: f3c3 2306 ubfx r3, r3, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 800a0e6: 434b muls r3, r1 + 800a0e8: 6929 ldr r1, [r5, #16] + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 800a0ea: 6928 ldr r0, [r5, #16] + 800a0ec: f3c0 6041 ubfx r0, r0, #25, #2 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 800a0f0: f3c1 1103 ubfx r1, r1, #4, #4 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 800a0f4: 3001 adds r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 800a0f6: 3101 adds r1, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 800a0f8: 0040 lsls r0, r0, #1 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U)); + 800a0fa: fbb3 f3f1 udiv r3, r3, r1 + frequency = (pllvco / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U)); + 800a0fe: fbb3 f0f0 udiv r0, r3, r0 + 800a102: e6fd b.n 8009f00 + srcclk = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); + 800a104: f8d5 309c ldr.w r3, [r5, #156] ; 0x9c + 800a108: f003 0318 and.w r3, r3, #24 + switch(srcclk) + 800a10c: 2b08 cmp r3, #8 + 800a10e: d082 beq.n 800a016 + 800a110: 2b10 cmp r3, #16 + 800a112: f43f aeca beq.w 8009eaa + 800a116: 2b00 cmp r3, #0 + 800a118: f47f ae24 bne.w 8009d64 + frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco); + 800a11c: f44f 6000 mov.w r0, #2048 ; 0x800 + 800a120: e660 b.n 8009de4 + srcclk = __HAL_RCC_GET_I2C1_SOURCE(); + 800a122: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a126: f403 5340 and.w r3, r3, #12288 ; 0x3000 + switch(srcclk) + 800a12a: f5b3 5f80 cmp.w r3, #4096 ; 0x1000 + 800a12e: d084 beq.n 800a03a + 800a130: f5b3 5f00 cmp.w r3, #8192 ; 0x2000 + 800a134: f43f af6f beq.w 800a016 + 800a138: 2b00 cmp r3, #0 + 800a13a: f47f ae13 bne.w 8009d64 +} + 800a13e: bcf0 pop {r4, r5, r6, r7} + frequency = HAL_RCC_GetPCLK1Freq(); + 800a140: f7ff b8b2 b.w 80092a8 + srcclk = __HAL_RCC_GET_I2C3_SOURCE(); + 800a144: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a148: f403 3340 and.w r3, r3, #196608 ; 0x30000 + switch(srcclk) + 800a14c: f5b3 3f80 cmp.w r3, #65536 ; 0x10000 + 800a150: f43f af73 beq.w 800a03a + 800a154: f5b3 3f00 cmp.w r3, #131072 ; 0x20000 + 800a158: e7ec b.n 800a134 + 800a15a: f5b3 2f40 cmp.w r3, #786432 ; 0xc0000 + 800a15e: e5ab b.n 8009cb8 + srcclk = __HAL_RCC_GET_LPTIM2_SOURCE(); + 800a160: f8d5 3088 ldr.w r3, [r5, #136] ; 0x88 + 800a164: f403 1340 and.w r3, r3, #3145728 ; 0x300000 + switch(srcclk) + 800a168: f5b3 1f00 cmp.w r3, #2097152 ; 0x200000 + 800a16c: f43f af53 beq.w 800a016 + 800a170: d804 bhi.n 800a17c + 800a172: 2b00 cmp r3, #0 + 800a174: d0e3 beq.n 800a13e + 800a176: f5b3 1f80 cmp.w r3, #1048576 ; 0x100000 + 800a17a: e61c b.n 8009db6 + 800a17c: f5b3 1f40 cmp.w r3, #3145728 ; 0x300000 + 800a180: e59a b.n 8009cb8 + if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)) + 800a182: 6828 ldr r0, [r5, #0] + 800a184: f010 7000 ands.w r0, r0, #33554432 ; 0x2000000 + 800a188: f43f aeba beq.w 8009f00 + if(HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) + 800a18c: 68e8 ldr r0, [r5, #12] + 800a18e: f410 1080 ands.w r0, r0, #1048576 ; 0x100000 + 800a192: f43f aeb5 beq.w 8009f00 + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 800a196: 68e8 ldr r0, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 800a198: 68eb ldr r3, [r5, #12] + plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; + 800a19a: f3c0 2006 ubfx r0, r0, #8, #7 + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 800a19e: f3c3 1303 ubfx r3, r3, #4, #4 + 800a1a2: 4341 muls r1, r0 + 800a1a4: 3301 adds r3, #1 + frequency = (pllvco / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U)); + 800a1a6: 68e8 ldr r0, [r5, #12] + pllvco = ((pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U)); + 800a1a8: fbb1 f1f3 udiv r1, r1, r3 + 800a1ac: e672 b.n 8009e94 + 800a1ae: bf00 nop + 800a1b0: 02dc6c00 .word 0x02dc6c00 + 800a1b4: 00f42400 .word 0x00f42400 + +0800a1b8 : +{ + 800a1b8: b570 push {r4, r5, r6, lr} + __HAL_RCC_PLLSAI1_DISABLE(); + 800a1ba: 4c20 ldr r4, [pc, #128] ; (800a23c ) + 800a1bc: 6823 ldr r3, [r4, #0] + 800a1be: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 800a1c2: 6023 str r3, [r4, #0] +{ + 800a1c4: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 800a1c6: f7fd f909 bl 80073dc + 800a1ca: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 800a1cc: 6823 ldr r3, [r4, #0] + 800a1ce: 011a lsls r2, r3, #4 + 800a1d0: d423 bmi.n 800a21a + __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1M, PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R); + 800a1d2: e9d5 2302 ldrd r2, r3, [r5, #8] + 800a1d6: 06db lsls r3, r3, #27 + 800a1d8: 6921 ldr r1, [r4, #16] + 800a1da: ea43 2302 orr.w r3, r3, r2, lsl #8 + 800a1de: 4a18 ldr r2, [pc, #96] ; (800a240 ) + 800a1e0: 400a ands r2, r1 + 800a1e2: 4313 orrs r3, r2 + 800a1e4: 686a ldr r2, [r5, #4] + 800a1e6: 3a01 subs r2, #1 + 800a1e8: ea43 1302 orr.w r3, r3, r2, lsl #4 + 800a1ec: 692a ldr r2, [r5, #16] + 800a1ee: 0852 lsrs r2, r2, #1 + 800a1f0: 3a01 subs r2, #1 + 800a1f2: ea43 5342 orr.w r3, r3, r2, lsl #21 + 800a1f6: 696a ldr r2, [r5, #20] + 800a1f8: 0852 lsrs r2, r2, #1 + 800a1fa: 3a01 subs r2, #1 + 800a1fc: ea43 6342 orr.w r3, r3, r2, lsl #25 + 800a200: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut); + 800a202: 6923 ldr r3, [r4, #16] + 800a204: 69aa ldr r2, [r5, #24] + 800a206: 4313 orrs r3, r2 + 800a208: 6123 str r3, [r4, #16] + __HAL_RCC_PLLSAI1_ENABLE(); + 800a20a: 6823 ldr r3, [r4, #0] + 800a20c: f043 6380 orr.w r3, r3, #67108864 ; 0x4000000 + 800a210: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a212: f7fd f8e3 bl 80073dc + 800a216: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 800a218: e00b b.n 800a232 + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 800a21a: f7fd f8df bl 80073dc + 800a21e: 1b80 subs r0, r0, r6 + 800a220: 2802 cmp r0, #2 + 800a222: d9d3 bls.n 800a1cc + status = HAL_TIMEOUT; + 800a224: 2003 movs r0, #3 +} + 800a226: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 800a228: f7fd f8d8 bl 80073dc + 800a22c: 1b40 subs r0, r0, r5 + 800a22e: 2802 cmp r0, #2 + 800a230: d8f8 bhi.n 800a224 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) + 800a232: 6823 ldr r3, [r4, #0] + 800a234: 011b lsls r3, r3, #4 + 800a236: d5f7 bpl.n 800a228 + 800a238: 2000 movs r0, #0 + return status; + 800a23a: e7f4 b.n 800a226 + 800a23c: 40021000 .word 0x40021000 + 800a240: 019d800f .word 0x019d800f + +0800a244 : +{ + 800a244: b538 push {r3, r4, r5, lr} + __HAL_RCC_PLLSAI1_DISABLE(); + 800a246: 4c11 ldr r4, [pc, #68] ; (800a28c ) + 800a248: 6823 ldr r3, [r4, #0] + 800a24a: f023 6380 bic.w r3, r3, #67108864 ; 0x4000000 + 800a24e: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a250: f7fd f8c4 bl 80073dc + 800a254: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U) + 800a256: 6823 ldr r3, [r4, #0] + 800a258: f013 6300 ands.w r3, r3, #134217728 ; 0x8000000 + 800a25c: d10f bne.n 800a27e + HAL_StatusTypeDef status = HAL_OK; + 800a25e: 4618 mov r0, r3 + __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN); + 800a260: 6923 ldr r3, [r4, #16] + 800a262: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 800a266: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 800a26a: 6123 str r3, [r4, #16] + if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI2RDY)) == 0U) + 800a26c: 6823 ldr r3, [r4, #0] + 800a26e: f013 5f08 tst.w r3, #570425344 ; 0x22000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 800a272: bf02 ittt eq + 800a274: 68e3 ldreq r3, [r4, #12] + 800a276: f023 0303 biceq.w r3, r3, #3 + 800a27a: 60e3 streq r3, [r4, #12] +} + 800a27c: bd38 pop {r3, r4, r5, pc} + if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + 800a27e: f7fd f8ad bl 80073dc + 800a282: 1b40 subs r0, r0, r5 + 800a284: 2802 cmp r0, #2 + 800a286: d9e6 bls.n 800a256 + status = HAL_TIMEOUT; + 800a288: 2003 movs r0, #3 + 800a28a: e7e9 b.n 800a260 + 800a28c: 40021000 .word 0x40021000 + +0800a290 : +{ + 800a290: b570 push {r4, r5, r6, lr} + __HAL_RCC_PLLSAI2_DISABLE(); + 800a292: 4c20 ldr r4, [pc, #128] ; (800a314 ) + 800a294: 6823 ldr r3, [r4, #0] + 800a296: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800a29a: 6023 str r3, [r4, #0] +{ + 800a29c: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 800a29e: f7fd f89d bl 80073dc + 800a2a2: 4606 mov r6, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 800a2a4: 6823 ldr r3, [r4, #0] + 800a2a6: 009a lsls r2, r3, #2 + 800a2a8: d423 bmi.n 800a2f2 + __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2Q, PLLSAI2Init->PLLSAI2R); + 800a2aa: e9d5 2302 ldrd r2, r3, [r5, #8] + 800a2ae: 06db lsls r3, r3, #27 + 800a2b0: 6961 ldr r1, [r4, #20] + 800a2b2: ea43 2302 orr.w r3, r3, r2, lsl #8 + 800a2b6: 4a18 ldr r2, [pc, #96] ; (800a318 ) + 800a2b8: 400a ands r2, r1 + 800a2ba: 4313 orrs r3, r2 + 800a2bc: 686a ldr r2, [r5, #4] + 800a2be: 3a01 subs r2, #1 + 800a2c0: ea43 1302 orr.w r3, r3, r2, lsl #4 + 800a2c4: 692a ldr r2, [r5, #16] + 800a2c6: 0852 lsrs r2, r2, #1 + 800a2c8: 3a01 subs r2, #1 + 800a2ca: ea43 5342 orr.w r3, r3, r2, lsl #21 + 800a2ce: 696a ldr r2, [r5, #20] + 800a2d0: 0852 lsrs r2, r2, #1 + 800a2d2: 3a01 subs r2, #1 + 800a2d4: ea43 6342 orr.w r3, r3, r2, lsl #25 + 800a2d8: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut); + 800a2da: 6963 ldr r3, [r4, #20] + 800a2dc: 69aa ldr r2, [r5, #24] + 800a2de: 4313 orrs r3, r2 + 800a2e0: 6163 str r3, [r4, #20] + __HAL_RCC_PLLSAI2_ENABLE(); + 800a2e2: 6823 ldr r3, [r4, #0] + 800a2e4: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800a2e8: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a2ea: f7fd f877 bl 80073dc + 800a2ee: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 800a2f0: e00b b.n 800a30a + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a2f2: f7fd f873 bl 80073dc + 800a2f6: 1b80 subs r0, r0, r6 + 800a2f8: 2802 cmp r0, #2 + 800a2fa: d9d3 bls.n 800a2a4 + status = HAL_TIMEOUT; + 800a2fc: 2003 movs r0, #3 +} + 800a2fe: bd70 pop {r4, r5, r6, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a300: f7fd f86c bl 80073dc + 800a304: 1b40 subs r0, r0, r5 + 800a306: 2802 cmp r0, #2 + 800a308: d8f8 bhi.n 800a2fc + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U) + 800a30a: 6823 ldr r3, [r4, #0] + 800a30c: 009b lsls r3, r3, #2 + 800a30e: d5f7 bpl.n 800a300 + 800a310: 2000 movs r0, #0 + return status; + 800a312: e7f4 b.n 800a2fe + 800a314: 40021000 .word 0x40021000 + 800a318: 019d800f .word 0x019d800f + +0800a31c : +{ + 800a31c: b538 push {r3, r4, r5, lr} + __HAL_RCC_PLLSAI2_DISABLE(); + 800a31e: 4c11 ldr r4, [pc, #68] ; (800a364 ) + 800a320: 6823 ldr r3, [r4, #0] + 800a322: f023 5380 bic.w r3, r3, #268435456 ; 0x10000000 + 800a326: 6023 str r3, [r4, #0] + tickstart = HAL_GetTick(); + 800a328: f7fd f858 bl 80073dc + 800a32c: 4605 mov r5, r0 + while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U) + 800a32e: 6823 ldr r3, [r4, #0] + 800a330: f013 5300 ands.w r3, r3, #536870912 ; 0x20000000 + 800a334: d10f bne.n 800a356 + HAL_StatusTypeDef status = HAL_OK; + 800a336: 4618 mov r0, r3 + __HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2QEN|RCC_PLLSAI2CFGR_PLLSAI2REN); + 800a338: 6963 ldr r3, [r4, #20] + 800a33a: f023 7388 bic.w r3, r3, #17825792 ; 0x1100000 + 800a33e: f423 3380 bic.w r3, r3, #65536 ; 0x10000 + 800a342: 6163 str r3, [r4, #20] + if(READ_BIT(RCC->CR, (RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY)) == 0U) + 800a344: 6823 ldr r3, [r4, #0] + 800a346: f013 6f20 tst.w r3, #167772160 ; 0xa000000 + MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); + 800a34a: bf02 ittt eq + 800a34c: 68e3 ldreq r3, [r4, #12] + 800a34e: f023 0303 biceq.w r3, r3, #3 + 800a352: 60e3 streq r3, [r4, #12] +} + 800a354: bd38 pop {r3, r4, r5, pc} + if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) + 800a356: f7fd f841 bl 80073dc + 800a35a: 1b40 subs r0, r0, r5 + 800a35c: 2802 cmp r0, #2 + 800a35e: d9e6 bls.n 800a32e + status = HAL_TIMEOUT; + 800a360: 2003 movs r0, #3 + 800a362: e7e9 b.n 800a338 + 800a364: 40021000 .word 0x40021000 + +0800a368 : + __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk); + 800a368: 4a03 ldr r2, [pc, #12] ; (800a378 ) + 800a36a: 6893 ldr r3, [r2, #8] + 800a36c: f423 4300 bic.w r3, r3, #32768 ; 0x8000 + 800a370: 4318 orrs r0, r3 + 800a372: 6090 str r0, [r2, #8] +} + 800a374: 4770 bx lr + 800a376: bf00 nop + 800a378: 40021000 .word 0x40021000 + +0800a37c : + __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange); + 800a37c: 4a04 ldr r2, [pc, #16] ; (800a390 ) + 800a37e: f8d2 3094 ldr.w r3, [r2, #148] ; 0x94 + 800a382: f423 6370 bic.w r3, r3, #3840 ; 0xf00 + 800a386: ea43 1000 orr.w r0, r3, r0, lsl #4 + 800a38a: f8c2 0094 str.w r0, [r2, #148] ; 0x94 +} + 800a38e: 4770 bx lr + 800a390: 40021000 .word 0x40021000 + +0800a394 : + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON); + 800a394: 4a03 ldr r2, [pc, #12] ; (800a3a4 ) + 800a396: f8d2 3090 ldr.w r3, [r2, #144] ; 0x90 + 800a39a: f043 0320 orr.w r3, r3, #32 + 800a39e: f8c2 3090 str.w r3, [r2, #144] ; 0x90 +} + 800a3a2: 4770 bx lr + 800a3a4: 40021000 .word 0x40021000 + +0800a3a8 : + CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + 800a3a8: 4b05 ldr r3, [pc, #20] ; (800a3c0 ) + 800a3aa: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800a3ae: f022 0220 bic.w r2, r2, #32 + 800a3b2: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS); + 800a3b6: 699a ldr r2, [r3, #24] + 800a3b8: f422 7200 bic.w r2, r2, #512 ; 0x200 + 800a3bc: 619a str r2, [r3, #24] +} + 800a3be: 4770 bx lr + 800a3c0: 40021000 .word 0x40021000 + +0800a3c4 : + SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; + 800a3c4: 4b0a ldr r3, [pc, #40] ; (800a3f0 ) + 800a3c6: f8d3 2090 ldr.w r2, [r3, #144] ; 0x90 + 800a3ca: f042 0220 orr.w r2, r2, #32 + 800a3ce: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS); + 800a3d2: 699a ldr r2, [r3, #24] + 800a3d4: f442 7200 orr.w r2, r2, #512 ; 0x200 + 800a3d8: 619a str r2, [r3, #24] + __HAL_RCC_LSECSS_EXTI_ENABLE_IT(); + 800a3da: f5a3 3386 sub.w r3, r3, #68608 ; 0x10c00 + 800a3de: 681a ldr r2, [r3, #0] + 800a3e0: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 800a3e4: 601a str r2, [r3, #0] + __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE(); + 800a3e6: 689a ldr r2, [r3, #8] + 800a3e8: f442 2200 orr.w r2, r2, #524288 ; 0x80000 + 800a3ec: 609a str r2, [r3, #8] +} + 800a3ee: 4770 bx lr + 800a3f0: 40021000 .word 0x40021000 + +0800a3f4 : +} + 800a3f4: 4770 bx lr + ... + +0800a3f8 : +{ + 800a3f8: b510 push {r4, lr} + if(__HAL_RCC_GET_IT(RCC_IT_LSECSS)) + 800a3fa: 4c05 ldr r4, [pc, #20] ; (800a410 ) + 800a3fc: 69e3 ldr r3, [r4, #28] + 800a3fe: 059b lsls r3, r3, #22 + 800a400: d504 bpl.n 800a40c + HAL_RCCEx_LSECSS_Callback(); + 800a402: f7ff fff7 bl 800a3f4 + __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS); + 800a406: f44f 7300 mov.w r3, #512 ; 0x200 + 800a40a: 6223 str r3, [r4, #32] +} + 800a40c: bd10 pop {r4, pc} + 800a40e: bf00 nop + 800a410: 40021000 .word 0x40021000 + +0800a414 : + SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; + 800a414: 4a02 ldr r2, [pc, #8] ; (800a420 ) + 800a416: 6813 ldr r3, [r2, #0] + 800a418: f043 0304 orr.w r3, r3, #4 + 800a41c: 6013 str r3, [r2, #0] +} + 800a41e: 4770 bx lr + 800a420: 40021000 .word 0x40021000 + +0800a424 : + CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; + 800a424: 4a02 ldr r2, [pc, #8] ; (800a430 ) + 800a426: 6813 ldr r3, [r2, #0] + 800a428: f023 0304 bic.w r3, r3, #4 + 800a42c: 6013 str r3, [r2, #0] +} + 800a42e: 4770 bx lr + 800a430: 40021000 .word 0x40021000 + +0800a434 : + MODIFY_REG(RCC->DLYCFGR, RCC_DLYCFGR_OCTOSPI1_DLY|RCC_DLYCFGR_OCTOSPI2_DLY, (Delay1 | (Delay2 << RCC_DLYCFGR_OCTOSPI2_DLY_Pos))) ; + 800a434: 4a05 ldr r2, [pc, #20] ; (800a44c ) + 800a436: f8d2 30a4 ldr.w r3, [r2, #164] ; 0xa4 + 800a43a: f023 03ff bic.w r3, r3, #255 ; 0xff + 800a43e: 4318 orrs r0, r3 + 800a440: ea40 1101 orr.w r1, r0, r1, lsl #4 + 800a444: f8c2 10a4 str.w r1, [r2, #164] ; 0xa4 +} + 800a448: 4770 bx lr + 800a44a: bf00 nop + 800a44c: 40021000 .word 0x40021000 + +0800a450 : + __HAL_RCC_CRS_FORCE_RESET(); + 800a450: 4b10 ldr r3, [pc, #64] ; (800a494 ) + 800a452: 6b9a ldr r2, [r3, #56] ; 0x38 + 800a454: f042 7280 orr.w r2, r2, #16777216 ; 0x1000000 + 800a458: 639a str r2, [r3, #56] ; 0x38 + __HAL_RCC_CRS_RELEASE_RESET(); + 800a45a: 6b9a ldr r2, [r3, #56] ; 0x38 + 800a45c: f022 7280 bic.w r2, r2, #16777216 ; 0x1000000 + 800a460: 639a str r2, [r3, #56] ; 0x38 + value = (pInit->Prescaler | pInit->Source | pInit->Polarity); + 800a462: e9d0 3200 ldrd r3, r2, [r0] + 800a466: 4313 orrs r3, r2 + 800a468: 6882 ldr r2, [r0, #8] + 800a46a: 4313 orrs r3, r2 + value |= pInit->ReloadValue; + 800a46c: 68c2 ldr r2, [r0, #12] + 800a46e: 4313 orrs r3, r2 + value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos); + 800a470: 6902 ldr r2, [r0, #16] + 800a472: ea43 4302 orr.w r3, r3, r2, lsl #16 + WRITE_REG(CRS->CFGR, value); + 800a476: 4a08 ldr r2, [pc, #32] ; (800a498 ) + 800a478: 6053 str r3, [r2, #4] + MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos)); + 800a47a: 6813 ldr r3, [r2, #0] + 800a47c: 6941 ldr r1, [r0, #20] + 800a47e: f423 537c bic.w r3, r3, #16128 ; 0x3f00 + 800a482: ea43 2301 orr.w r3, r3, r1, lsl #8 + 800a486: 6013 str r3, [r2, #0] + SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); + 800a488: 6813 ldr r3, [r2, #0] + 800a48a: f043 0360 orr.w r3, r3, #96 ; 0x60 + 800a48e: 6013 str r3, [r2, #0] +} + 800a490: 4770 bx lr + 800a492: bf00 nop + 800a494: 40021000 .word 0x40021000 + 800a498: 40006000 .word 0x40006000 + +0800a49c : + SET_BIT(CRS->CR, CRS_CR_SWSYNC); + 800a49c: 4a02 ldr r2, [pc, #8] ; (800a4a8 ) + 800a49e: 6813 ldr r3, [r2, #0] + 800a4a0: f043 0380 orr.w r3, r3, #128 ; 0x80 + 800a4a4: 6013 str r3, [r2, #0] +} + 800a4a6: 4770 bx lr + 800a4a8: 40006000 .word 0x40006000 + +0800a4ac : + pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); + 800a4ac: 4b07 ldr r3, [pc, #28] ; (800a4cc ) + 800a4ae: 685a ldr r2, [r3, #4] + 800a4b0: b292 uxth r2, r2 + 800a4b2: 6002 str r2, [r0, #0] + pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos); + 800a4b4: 681a ldr r2, [r3, #0] + 800a4b6: f3c2 2205 ubfx r2, r2, #8, #6 + 800a4ba: 6042 str r2, [r0, #4] + pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos); + 800a4bc: 689a ldr r2, [r3, #8] + 800a4be: 0c12 lsrs r2, r2, #16 + 800a4c0: 6082 str r2, [r0, #8] + pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); + 800a4c2: 689b ldr r3, [r3, #8] + 800a4c4: f403 4300 and.w r3, r3, #32768 ; 0x8000 + 800a4c8: 60c3 str r3, [r0, #12] +} + 800a4ca: 4770 bx lr + 800a4cc: 40006000 .word 0x40006000 + +0800a4d0 : +{ + 800a4d0: b5f8 push {r3, r4, r5, r6, r7, lr} + 800a4d2: 4605 mov r5, r0 + tickstart = HAL_GetTick(); + 800a4d4: f7fc ff82 bl 80073dc + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + 800a4d8: 4c1e ldr r4, [pc, #120] ; (800a554 ) + tickstart = HAL_GetTick(); + 800a4da: 4606 mov r6, r0 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + 800a4dc: 2701 movs r7, #1 + if(Timeout != HAL_MAX_DELAY) + 800a4de: 1c68 adds r0, r5, #1 + 800a4e0: d12f bne.n 800a542 + crsstatus = RCC_CRS_TIMEOUT; + 800a4e2: 2000 movs r0, #0 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) + 800a4e4: 68a2 ldr r2, [r4, #8] + 800a4e6: 07d1 lsls r1, r2, #31 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); + 800a4e8: bf48 it mi + 800a4ea: 60e7 strmi r7, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + 800a4ec: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCOK; + 800a4ee: bf48 it mi + 800a4f0: f040 0002 orrmi.w r0, r0, #2 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) + 800a4f4: 0792 lsls r2, r2, #30 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN); + 800a4f6: bf44 itt mi + 800a4f8: 2202 movmi r2, #2 + 800a4fa: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + 800a4fc: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCWARN; + 800a4fe: bf48 it mi + 800a500: f040 0004 orrmi.w r0, r0, #4 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) + 800a504: 0553 lsls r3, r2, #21 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF); + 800a506: bf44 itt mi + 800a508: 2204 movmi r2, #4 + 800a50a: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + 800a50c: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_TRIMOVF; + 800a50e: bf48 it mi + 800a510: f040 0020 orrmi.w r0, r0, #32 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) + 800a514: 05d1 lsls r1, r2, #23 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR); + 800a516: bf44 itt mi + 800a518: 2204 movmi r2, #4 + 800a51a: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + 800a51c: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCERR; + 800a51e: bf48 it mi + 800a520: f040 0008 orrmi.w r0, r0, #8 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) + 800a524: 0592 lsls r2, r2, #22 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS); + 800a526: bf44 itt mi + 800a528: 2204 movmi r2, #4 + 800a52a: 60e2 strmi r2, [r4, #12] + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + 800a52c: 68a2 ldr r2, [r4, #8] + crsstatus |= RCC_CRS_SYNCMISS; + 800a52e: bf48 it mi + 800a530: f040 0010 orrmi.w r0, r0, #16 + if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) + 800a534: 0713 lsls r3, r2, #28 + __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); + 800a536: bf44 itt mi + 800a538: 2208 movmi r2, #8 + 800a53a: 60e2 strmi r2, [r4, #12] + } while(RCC_CRS_NONE == crsstatus); + 800a53c: 2800 cmp r0, #0 + 800a53e: d0ce beq.n 800a4de +} + 800a540: bdf8 pop {r3, r4, r5, r6, r7, pc} + if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) + 800a542: f7fc ff4b bl 80073dc + 800a546: 1b80 subs r0, r0, r6 + 800a548: 42a8 cmp r0, r5 + 800a54a: d801 bhi.n 800a550 + 800a54c: 2d00 cmp r5, #0 + 800a54e: d1c8 bne.n 800a4e2 + crsstatus = RCC_CRS_TIMEOUT; + 800a550: 2001 movs r0, #1 + 800a552: e7c7 b.n 800a4e4 + 800a554: 40006000 .word 0x40006000 + +0800a558 : + 800a558: 4770 bx lr + +0800a55a : + 800a55a: 4770 bx lr + +0800a55c : + 800a55c: 4770 bx lr + +0800a55e : +} + 800a55e: 4770 bx lr + +0800a560 : + uint32_t itflags = READ_REG(CRS->ISR); + 800a560: 491b ldr r1, [pc, #108] ; (800a5d0 ) +{ + 800a562: b508 push {r3, lr} + uint32_t itflags = READ_REG(CRS->ISR); + 800a564: 688b ldr r3, [r1, #8] + uint32_t itsources = READ_REG(CRS->CR); + 800a566: 680a ldr r2, [r1, #0] + if(((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U)) + 800a568: 07d8 lsls r0, r3, #31 + 800a56a: d506 bpl.n 800a57a + 800a56c: 07d0 lsls r0, r2, #31 + 800a56e: d504 bpl.n 800a57a + WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); + 800a570: 2301 movs r3, #1 + 800a572: 60cb str r3, [r1, #12] + HAL_RCCEx_CRS_SyncOkCallback(); + 800a574: f7ff fff0 bl 800a558 +} + 800a578: bd08 pop {r3, pc} + else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U)) + 800a57a: 0798 lsls r0, r3, #30 + 800a57c: d507 bpl.n 800a58e + 800a57e: 0791 lsls r1, r2, #30 + 800a580: d505 bpl.n 800a58e + WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); + 800a582: 4b13 ldr r3, [pc, #76] ; (800a5d0 ) + 800a584: 2202 movs r2, #2 + 800a586: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_SyncWarnCallback(); + 800a588: f7ff ffe7 bl 800a55a + 800a58c: e7f4 b.n 800a578 + else if(((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U)) + 800a58e: 0718 lsls r0, r3, #28 + 800a590: d507 bpl.n 800a5a2 + 800a592: 0711 lsls r1, r2, #28 + 800a594: d505 bpl.n 800a5a2 + WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); + 800a596: 4b0e ldr r3, [pc, #56] ; (800a5d0 ) + 800a598: 2208 movs r2, #8 + 800a59a: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_ExpectedSyncCallback(); + 800a59c: f7ff ffde bl 800a55c + 800a5a0: e7ea b.n 800a578 + if(((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U)) + 800a5a2: 0758 lsls r0, r3, #29 + 800a5a4: d5e8 bpl.n 800a578 + 800a5a6: 0751 lsls r1, r2, #29 + 800a5a8: d5e6 bpl.n 800a578 + crserror |= RCC_CRS_SYNCERR; + 800a5aa: f413 7080 ands.w r0, r3, #256 ; 0x100 + 800a5ae: bf18 it ne + 800a5b0: 2008 movne r0, #8 + if((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U) + 800a5b2: 059a lsls r2, r3, #22 + crserror |= RCC_CRS_SYNCMISS; + 800a5b4: bf48 it mi + 800a5b6: f040 0010 orrmi.w r0, r0, #16 + if((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U) + 800a5ba: 055b lsls r3, r3, #21 + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + 800a5bc: 4b04 ldr r3, [pc, #16] ; (800a5d0 ) + 800a5be: f04f 0204 mov.w r2, #4 + crserror |= RCC_CRS_TRIMOVF; + 800a5c2: bf48 it mi + 800a5c4: f040 0020 orrmi.w r0, r0, #32 + WRITE_REG(CRS->ICR, CRS_ICR_ERRC); + 800a5c8: 60da str r2, [r3, #12] + HAL_RCCEx_CRS_ErrorCallback(crserror); + 800a5ca: f7ff ffc8 bl 800a55e +} + 800a5ce: e7d3 b.n 800a578 + 800a5d0: 40006000 .word 0x40006000 + +0800a5d4 : + * processing is suspended when possible and the Peripheral feeding point reached at + * suspension time is stored in the handle for resumption later on. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WriteData(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size) +{ + 800a5d4: b573 push {r0, r1, r4, r5, r6, lr} + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + + for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U) + { + /* Write input data 4 bytes at a time */ + HASH->DIN = *(uint32_t*)inputaddr; + 800a5d6: 4d1e ldr r5, [pc, #120] ; (800a650 ) + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800a5d8: 9101 str r1, [sp, #4] +{ + 800a5da: 4604 mov r4, r0 + for(buffercounter = 0U; buffercounter < Size; buffercounter+=4U) + 800a5dc: 2100 movs r1, #0 + 800a5de: 4291 cmp r1, r2 + 800a5e0: d221 bcs.n 800a626 + HASH->DIN = *(uint32_t*)inputaddr; + 800a5e2: 9b01 ldr r3, [sp, #4] + 800a5e4: 681b ldr r3, [r3, #0] + 800a5e6: 606b str r3, [r5, #4] + inputaddr+=4U; + 800a5e8: 9b01 ldr r3, [sp, #4] + + /* If the suspension flag has been raised and if the processing is not about + to end, suspend processing */ + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a5ea: f894 0036 ldrb.w r0, [r4, #54] ; 0x36 + inputaddr+=4U; + 800a5ee: 3304 adds r3, #4 + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a5f0: 2801 cmp r0, #1 + inputaddr+=4U; + 800a5f2: 9301 str r3, [sp, #4] + if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4U) < Size)) + 800a5f4: f101 0304 add.w r3, r1, #4 + 800a5f8: d127 bne.n 800a64a + 800a5fa: 4293 cmp r3, r2 + 800a5fc: d225 bcs.n 800a64a + { + /* Wait for DINIS = 1, which occurs when 16 32-bit locations are free + in the input buffer */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800a5fe: 6a6e ldr r6, [r5, #36] ; 0x24 + 800a600: 07f6 lsls r6, r6, #31 + 800a602: d522 bpl.n 800a64a + /* Reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + + /* Depending whether the key or the input data were fed to the Peripheral, the feeding point + reached at suspension time is not saved in the same handle fields */ + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a604: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a608: 2500 movs r5, #0 + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a60a: 2b02 cmp r3, #2 + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a60c: f884 5036 strb.w r5, [r4, #54] ; 0x36 + if ((hhash->Phase == HAL_HASH_PHASE_PROCESS) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2)) + 800a610: d001 beq.n 800a616 + 800a612: 2b04 cmp r3, #4 + 800a614: d109 bne.n 800a62a + { + /* Save current reading and writing locations of Input and Output buffers */ + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + /* Save the number of bytes that remain to be processed at this point */ + hhash->HashInCount = Size - (buffercounter + 4U); + 800a616: 3a04 subs r2, #4 + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + 800a618: 9b01 ldr r3, [sp, #4] + 800a61a: 60e3 str r3, [r4, #12] + hhash->HashInCount = Size - (buffercounter + 4U); + 800a61c: 1a52 subs r2, r2, r1 + 800a61e: 6222 str r2, [r4, #32] + __HAL_UNLOCK(hhash); + return HAL_ERROR; + } + + /* Set the HASH state to Suspended and exit to stop entering data */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a620: 2308 movs r3, #8 + 800a622: f884 3035 strb.w r3, [r4, #53] ; 0x35 + } /* if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) */ + } /* if ((hhash->SuspendRequest == HAL_HASH_SUSPEND) && ((buffercounter+4) < Size)) */ + } /* for(buffercounter = 0; buffercounter < Size; buffercounter+=4) */ + + /* At this point, all the data have been entered to the Peripheral: exit */ + return HAL_OK; + 800a626: 2000 movs r0, #0 + 800a628: e00d b.n 800a646 + else if ((hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) || (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3)) + 800a62a: 2b03 cmp r3, #3 + 800a62c: d001 beq.n 800a632 + 800a62e: 2b05 cmp r3, #5 + 800a630: d105 bne.n 800a63e + hhash->HashKeyCount = Size - (buffercounter + 4U); + 800a632: 3a04 subs r2, #4 + hhash->pHashKeyBuffPtr = (uint8_t *)inputaddr; + 800a634: 9b01 ldr r3, [sp, #4] + 800a636: 6163 str r3, [r4, #20] + hhash->HashKeyCount = Size - (buffercounter + 4U); + 800a638: 1a52 subs r2, r2, r1 + 800a63a: 62a2 str r2, [r4, #40] ; 0x28 + 800a63c: e7f0 b.n 800a620 + hhash->State = HAL_HASH_STATE_READY; + 800a63e: f884 0035 strb.w r0, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800a642: f884 5034 strb.w r5, [r4, #52] ; 0x34 +} + 800a646: b002 add sp, #8 + 800a648: bd70 pop {r4, r5, r6, pc} + 800a64a: 4619 mov r1, r3 + 800a64c: e7c7 b.n 800a5de + 800a64e: bf00 nop + 800a650: 50060400 .word 0x50060400 + +0800a654 : + */ +static void HASH_GetDigest(uint8_t *pMsgDigest, uint8_t Size) +{ + uint32_t msgdigest = (uint32_t)pMsgDigest; + + switch(Size) + 800a654: 291c cmp r1, #28 + 800a656: d027 beq.n 800a6a8 + 800a658: d804 bhi.n 800a664 + 800a65a: 2910 cmp r1, #16 + 800a65c: d005 beq.n 800a66a + 800a65e: 2914 cmp r1, #20 + 800a660: d011 beq.n 800a686 + 800a662: 4770 bx lr + 800a664: 2920 cmp r1, #32 + 800a666: d037 beq.n 800a6d8 + 800a668: 4770 bx lr + { + /* Read the message digest */ + case 16: /* MD5 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a66a: 4b29 ldr r3, [pc, #164] ; (800a710 ) + 800a66c: 68da ldr r2, [r3, #12] + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); + 800a66e: ba12 rev r2, r2 + 800a670: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a672: 691a ldr r2, [r3, #16] + 800a674: ba12 rev r2, r2 + 800a676: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a678: 695a ldr r2, [r3, #20] + 800a67a: ba12 rev r2, r2 + 800a67c: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a67e: 699b ldr r3, [r3, #24] + 800a680: ba1b rev r3, r3 + 800a682: 60c3 str r3, [r0, #12] + break; + 800a684: 4770 bx lr + case 20: /* SHA1 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a686: 4b22 ldr r3, [pc, #136] ; (800a710 ) + 800a688: 68da ldr r2, [r3, #12] + 800a68a: ba12 rev r2, r2 + 800a68c: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a68e: 691a ldr r2, [r3, #16] + 800a690: ba12 rev r2, r2 + 800a692: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a694: 695a ldr r2, [r3, #20] + 800a696: ba12 rev r2, r2 + 800a698: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a69a: 699a ldr r2, [r3, #24] + 800a69c: ba12 rev r2, r2 + 800a69e: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a6a0: 69db ldr r3, [r3, #28] + 800a6a2: ba1b rev r3, r3 + 800a6a4: 6103 str r3, [r0, #16] + break; + 800a6a6: 4770 bx lr + case 28: /* SHA224 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a6a8: 4b19 ldr r3, [pc, #100] ; (800a710 ) + 800a6aa: 68da ldr r2, [r3, #12] + 800a6ac: ba12 rev r2, r2 + 800a6ae: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a6b0: 691a ldr r2, [r3, #16] + 800a6b2: ba12 rev r2, r2 + 800a6b4: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a6b6: 695a ldr r2, [r3, #20] + 800a6b8: ba12 rev r2, r2 + 800a6ba: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a6bc: 699a ldr r2, [r3, #24] + 800a6be: ba12 rev r2, r2 + 800a6c0: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a6c2: 69db ldr r3, [r3, #28] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a6c4: 4a13 ldr r2, [pc, #76] ; (800a714 ) + 800a6c6: ba1b rev r3, r3 + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a6c8: 6103 str r3, [r0, #16] + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a6ca: 6a53 ldr r3, [r2, #36] ; 0x24 + 800a6cc: ba1b rev r3, r3 + 800a6ce: 6143 str r3, [r0, #20] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + 800a6d0: 6a93 ldr r3, [r2, #40] ; 0x28 + 800a6d2: ba1b rev r3, r3 + 800a6d4: 6183 str r3, [r0, #24] + break; + 800a6d6: 4770 bx lr + case 32: /* SHA256 */ + *(uint32_t*)(msgdigest) = __REV(HASH->HR[0]); + 800a6d8: 4b0d ldr r3, [pc, #52] ; (800a710 ) + 800a6da: 68da ldr r2, [r3, #12] + 800a6dc: ba12 rev r2, r2 + 800a6de: 6002 str r2, [r0, #0] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[1]); + 800a6e0: 691a ldr r2, [r3, #16] + 800a6e2: ba12 rev r2, r2 + 800a6e4: 6042 str r2, [r0, #4] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[2]); + 800a6e6: 695a ldr r2, [r3, #20] + 800a6e8: ba12 rev r2, r2 + 800a6ea: 6082 str r2, [r0, #8] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[3]); + 800a6ec: 699a ldr r2, [r3, #24] + 800a6ee: ba12 rev r2, r2 + 800a6f0: 60c2 str r2, [r0, #12] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH->HR[4]); + 800a6f2: 69db ldr r3, [r3, #28] + 800a6f4: ba1b rev r3, r3 + 800a6f6: 6103 str r3, [r0, #16] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[5]); + 800a6f8: 4b06 ldr r3, [pc, #24] ; (800a714 ) + 800a6fa: 6a5a ldr r2, [r3, #36] ; 0x24 + 800a6fc: ba12 rev r2, r2 + 800a6fe: 6142 str r2, [r0, #20] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[6]); + 800a700: 6a9a ldr r2, [r3, #40] ; 0x28 + 800a702: ba12 rev r2, r2 + 800a704: 6182 str r2, [r0, #24] + msgdigest+=4U; + *(uint32_t*)(msgdigest) = __REV(HASH_DIGEST->HR[7]); + 800a706: 6adb ldr r3, [r3, #44] ; 0x2c + 800a708: ba1b rev r3, r3 + 800a70a: 61c3 str r3, [r0, #28] + break; + default: + break; + } +} + 800a70c: 4770 bx lr + 800a70e: bf00 nop + 800a710: 50060400 .word 0x50060400 + 800a714: 50060700 .word 0x50060700 + +0800a718 : + * @param Status the Flag status (SET or RESET). + * @param Timeout Timeout duration. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_WaitOnFlagUntilTimeout(HASH_HandleTypeDef *hhash, uint32_t Flag, FlagStatus Status, uint32_t Timeout) +{ + 800a718: e92d 43f8 stmdb sp!, {r3, r4, r5, r6, r7, r8, r9, lr} + 800a71c: 4604 mov r4, r0 + 800a71e: 460e mov r6, r1 + 800a720: 4691 mov r9, r2 + 800a722: 461d mov r5, r3 + uint32_t tickstart = HAL_GetTick(); + 800a724: f7fc fe5a bl 80073dc + 800a728: f8df 805c ldr.w r8, [pc, #92] ; 800a788 + 800a72c: 4607 mov r7, r0 + + /* Wait until flag is set */ + if(Status == RESET) + 800a72e: f1b9 0f00 cmp.w r9, #0 + 800a732: d021 beq.n 800a778 + } + } + } + else + { + while(__HAL_HASH_GET_FLAG(Flag) != RESET) + 800a734: f8d8 3024 ldr.w r3, [r8, #36] ; 0x24 + 800a738: ea36 0303 bics.w r3, r6, r3 + 800a73c: d121 bne.n 800a782 + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + 800a73e: 1c6b adds r3, r5, #1 + 800a740: d0f8 beq.n 800a734 + { + if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U)) + 800a742: f7fc fe4b bl 80073dc + 800a746: 1bc0 subs r0, r0, r7 + 800a748: 42a8 cmp r0, r5 + 800a74a: d80a bhi.n 800a762 + 800a74c: 2d00 cmp r5, #0 + 800a74e: d1f1 bne.n 800a734 + 800a750: e007 b.n 800a762 + if(Timeout != HAL_MAX_DELAY) + 800a752: 1c6a adds r2, r5, #1 + 800a754: d010 beq.n 800a778 + if(((HAL_GetTick()-tickstart) > Timeout) || (Timeout == 0U)) + 800a756: f7fc fe41 bl 80073dc + 800a75a: 1bc0 subs r0, r0, r7 + 800a75c: 42a8 cmp r0, r5 + 800a75e: d800 bhi.n 800a762 + 800a760: b955 cbnz r5, 800a778 + { + /* Set State to Ready to be able to restart later on */ + hhash->State = HAL_HASH_STATE_READY; + 800a762: 2301 movs r3, #1 + 800a764: f884 3035 strb.w r3, [r4, #53] ; 0x35 + /* Store time out issue in handle status */ + hhash->Status = HAL_TIMEOUT; + + /* Process Unlocked */ + __HAL_UNLOCK(hhash); + 800a768: 2200 movs r2, #0 + hhash->Status = HAL_TIMEOUT; + 800a76a: 2303 movs r3, #3 + 800a76c: f884 302c strb.w r3, [r4, #44] ; 0x2c + __HAL_UNLOCK(hhash); + 800a770: f884 2034 strb.w r2, [r4, #52] ; 0x34 + + return HAL_TIMEOUT; + 800a774: 4618 mov r0, r3 + 800a776: e005 b.n 800a784 + while(__HAL_HASH_GET_FLAG(Flag) == RESET) + 800a778: f8d8 3024 ldr.w r3, [r8, #36] ; 0x24 + 800a77c: ea36 0303 bics.w r3, r6, r3 + 800a780: d1e7 bne.n 800a752 + } + } + } + } + return HAL_OK; + 800a782: 2000 movs r0, #0 +} + 800a784: e8bd 83f8 ldmia.w sp!, {r3, r4, r5, r6, r7, r8, r9, pc} + 800a788: 50060400 .word 0x50060400 + +0800a78c : +} + 800a78c: 4770 bx lr + ... + +0800a790 : +{ + 800a790: b538 push {r3, r4, r5, lr} + if(hhash == NULL) + 800a792: 4604 mov r4, r0 + 800a794: b328 cbz r0, 800a7e2 + if(hhash->State == HAL_HASH_STATE_RESET) + 800a796: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + 800a79a: f003 02ff and.w r2, r3, #255 ; 0xff + 800a79e: b91b cbnz r3, 800a7a8 + hhash->Lock = HAL_UNLOCKED; + 800a7a0: f880 2034 strb.w r2, [r0, #52] ; 0x34 + HAL_HASH_MspInit(hhash); + 800a7a4: f7ff fff2 bl 800a78c + hhash->HashInCount = 0; + 800a7a8: 2000 movs r0, #0 + MODIFY_REG(HASH->CR, HASH_CR_DATATYPE, hhash->Init.DataType); + 800a7aa: 4a0f ldr r2, [pc, #60] ; (800a7e8 ) + hhash->HashBuffSize = 0; + 800a7ac: 61e0 str r0, [r4, #28] + hhash->State = HAL_HASH_STATE_BUSY; + 800a7ae: 2302 movs r3, #2 + hhash->Phase = HAL_HASH_PHASE_READY; + 800a7b0: 2101 movs r1, #1 + hhash->State = HAL_HASH_STATE_BUSY; + 800a7b2: f884 3035 strb.w r3, [r4, #53] ; 0x35 + hhash->Phase = HAL_HASH_PHASE_READY; + 800a7b6: f884 102d strb.w r1, [r4, #45] ; 0x2d + hhash->HashInCount = 0; + 800a7ba: 6220 str r0, [r4, #32] + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a7bc: 86e0 strh r0, [r4, #54] ; 0x36 + hhash->HashITCounter = 0; + 800a7be: 6260 str r0, [r4, #36] ; 0x24 + hhash->NbWordsAlreadyPushed = 0; + 800a7c0: 63a0 str r0, [r4, #56] ; 0x38 + MODIFY_REG(HASH->CR, HASH_CR_DATATYPE, hhash->Init.DataType); + 800a7c2: 6813 ldr r3, [r2, #0] + 800a7c4: 6825 ldr r5, [r4, #0] + 800a7c6: f023 0330 bic.w r3, r3, #48 ; 0x30 + 800a7ca: 432b orrs r3, r5 + 800a7cc: 6013 str r3, [r2, #0] +__HAL_HASH_RESET_MDMAT(); + 800a7ce: 6813 ldr r3, [r2, #0] + 800a7d0: f423 5300 bic.w r3, r3, #8192 ; 0x2000 + 800a7d4: 6013 str r3, [r2, #0] + hhash->State = HAL_HASH_STATE_READY; + 800a7d6: f884 1035 strb.w r1, [r4, #53] ; 0x35 + hhash->Status = HAL_OK; + 800a7da: f884 002c strb.w r0, [r4, #44] ; 0x2c + hhash->ErrorCode = HAL_HASH_ERROR_NONE; + 800a7de: 63e0 str r0, [r4, #60] ; 0x3c +} + 800a7e0: bd38 pop {r3, r4, r5, pc} + return HAL_ERROR; + 800a7e2: 2001 movs r0, #1 + 800a7e4: e7fc b.n 800a7e0 + 800a7e6: bf00 nop + 800a7e8: 50060400 .word 0x50060400 + +0800a7ec : + 800a7ec: 4770 bx lr + +0800a7ee : + 800a7ee: 4770 bx lr + +0800a7f0 : + 800a7f0: 4770 bx lr + +0800a7f2 : + 800a7f2: 4770 bx lr + +0800a7f4 : +{ + 800a7f4: b570 push {r4, r5, r6, lr} + * suspension time is stored in the handle for resumption later on. + * @retval HAL status + */ +static HAL_StatusTypeDef HASH_IT(HASH_HandleTypeDef *hhash) +{ + if (hhash->State == HAL_HASH_STATE_BUSY) + 800a7f6: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + 800a7fa: 2b02 cmp r3, #2 +{ + 800a7fc: 4604 mov r4, r0 + if (hhash->State == HAL_HASH_STATE_BUSY) + 800a7fe: b2da uxtb r2, r3 + 800a800: f040 80e7 bne.w 800a9d2 + { + /* ITCounter must not be equal to 0 at this point. Report an error if this is the case. */ + if(hhash->HashITCounter == 0U) + 800a804: 6a43 ldr r3, [r0, #36] ; 0x24 + 800a806: 4d74 ldr r5, [pc, #464] ; (800a9d8 ) + 800a808: b94b cbnz r3, 800a81e + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a80a: 6a2b ldr r3, [r5, #32] + 800a80c: f023 0303 bic.w r3, r3, #3 + 800a810: 622b str r3, [r5, #32] + /* HASH state set back to Ready to prevent any issue in user code + present in HAL_HASH_ErrorCallback() */ + hhash->State = HAL_HASH_STATE_READY; + 800a812: 2301 movs r3, #1 + 800a814: f880 3035 strb.w r3, [r0, #53] ; 0x35 + hhash->Status = HASH_IT(hhash); + 800a818: f884 302c strb.w r3, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800a81c: e099 b.n 800a952 + return HAL_ERROR; + } + else if (hhash->HashITCounter == 1U) + 800a81e: 6a43 ldr r3, [r0, #36] ; 0x24 + 800a820: 2b01 cmp r3, #1 + } + else + { + /* Cruise speed reached, HashITCounter remains equal to 3 until the end of + the HASH processing or the end of the current step for HMAC processing. */ + hhash->HashITCounter = 3U; + 800a822: bf16 itet ne + 800a824: 2303 movne r3, #3 + hhash->HashITCounter = 2U; + 800a826: 6242 streq r2, [r0, #36] ; 0x24 + hhash->HashITCounter = 3U; + 800a828: 6243 strne r3, [r0, #36] ; 0x24 + } + + /* If digest is ready */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DCIS)) + 800a82a: 6a6b ldr r3, [r5, #36] ; 0x24 + 800a82c: f013 0302 ands.w r3, r3, #2 + 800a830: d022 beq.n 800a878 + { + /* Read the digest */ + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800a832: 682a ldr r2, [r5, #0] + 800a834: 4b69 ldr r3, [pc, #420] ; (800a9dc ) + 800a836: 6900 ldr r0, [r0, #16] + 800a838: 421a tst r2, r3 + 800a83a: d019 beq.n 800a870 + 800a83c: 682a ldr r2, [r5, #0] + 800a83e: 401a ands r2, r3 + 800a840: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800a844: d016 beq.n 800a874 + 800a846: 682a ldr r2, [r5, #0] + 800a848: 4393 bics r3, r2 + 800a84a: bf0c ite eq + 800a84c: 2120 moveq r1, #32 + 800a84e: 2110 movne r1, #16 + 800a850: f7ff ff00 bl 800a654 + + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a854: 6a2b ldr r3, [r5, #32] + 800a856: f023 0303 bic.w r3, r3, #3 + 800a85a: 622b str r3, [r5, #32] + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_READY; + 800a85c: 2301 movs r3, #1 + 800a85e: f884 3035 strb.w r3, [r4, #53] ; 0x35 + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + 800a862: f884 302d strb.w r3, [r4, #45] ; 0x2d + /* Call digest computation complete call back */ +#if (USE_HAL_HASH_REGISTER_CALLBACKS == 1) + hhash->DgstCpltCallback(hhash); +#else + HAL_HASH_DgstCpltCallback(hhash); + 800a866: 4620 mov r0, r4 + 800a868: f7ff ffc2 bl 800a7f0 + hhash->Status = HAL_OK; + 800a86c: 2300 movs r3, #0 + 800a86e: e015 b.n 800a89c + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800a870: 2114 movs r1, #20 + 800a872: e7ed b.n 800a850 + 800a874: 211c movs r1, #28 + 800a876: e7eb b.n 800a850 + + return HAL_OK; + } + + /* If Peripheral ready to accept new data */ + if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800a878: 6a6a ldr r2, [r5, #36] ; 0x24 + 800a87a: 07d2 lsls r2, r2, #31 + 800a87c: d5f6 bpl.n 800a86c + { + + /* If the suspension flag has been raised and if the processing is not about + to end, suspend processing */ + if ( (hhash->HashInCount != 0U) && (hhash->SuspendRequest == HAL_HASH_SUSPEND)) + 800a87e: 6a02 ldr r2, [r0, #32] + 800a880: b17a cbz r2, 800a8a2 + 800a882: f890 2036 ldrb.w r2, [r0, #54] ; 0x36 + 800a886: 2a01 cmp r2, #1 + 800a888: d10b bne.n 800a8a2 + { + /* Disable Interrupts */ + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a88a: 6a2a ldr r2, [r5, #32] + 800a88c: f022 0203 bic.w r2, r2, #3 + 800a890: 622a str r2, [r5, #32] + + /* Reset SuspendRequest */ + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + + /* Change the HASH state */ + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a892: 2208 movs r2, #8 + hhash->SuspendRequest = HAL_HASH_SUSPEND_NONE; + 800a894: f880 3036 strb.w r3, [r0, #54] ; 0x36 + hhash->State = HAL_HASH_STATE_SUSPENDED; + 800a898: f880 2035 strb.w r2, [r0, #53] ; 0x35 + hhash->Status = HAL_OK; + 800a89c: f884 302c strb.w r3, [r4, #44] ; 0x2c +} + 800a8a0: e076 b.n 800a990 + uint32_t buffercounter; + uint32_t inputcounter; + uint32_t ret = HASH_DIGEST_CALCULATION_NOT_STARTED; + + /* If there are more than 64 bytes remaining to be entered */ + if(hhash->HashInCount > 64U) + 800a8a2: 6a21 ldr r1, [r4, #32] + { + inputaddr = (uint32_t)hhash->pHashInBuffPtr; + 800a8a4: 68e3 ldr r3, [r4, #12] + if(hhash->HashInCount > 64U) + 800a8a6: 2940 cmp r1, #64 ; 0x40 + inputaddr = (uint32_t)hhash->pHashInBuffPtr; + 800a8a8: 461a mov r2, r3 + if(hhash->HashInCount > 64U) + 800a8aa: d91c bls.n 800a8e6 + 800a8ac: f103 0140 add.w r1, r3, #64 ; 0x40 + /* Write the Input block in the Data IN register + (16 32-bit words, or 64 bytes are entered) */ + for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) + { + HASH->DIN = *(uint32_t*)inputaddr; + 800a8b0: f853 0b04 ldr.w r0, [r3], #4 + 800a8b4: 6068 str r0, [r5, #4] + for(buffercounter = 0U; buffercounter < 64U; buffercounter+=4U) + 800a8b6: 4299 cmp r1, r3 + 800a8b8: d1fa bne.n 800a8b0 + inputaddr+=4U; + } + /* If this is the start of input data entering, an additional word + must be entered to start up the HASH processing */ + if(hhash->HashITCounter == 2U) + 800a8ba: 6a63 ldr r3, [r4, #36] ; 0x24 + 800a8bc: 2b02 cmp r3, #2 + 800a8be: d10d bne.n 800a8dc + { + HASH->DIN = *(uint32_t*)inputaddr; + 800a8c0: 680b ldr r3, [r1, #0] + 800a8c2: 606b str r3, [r5, #4] + if(hhash->HashInCount >= 68U) + 800a8c4: 6a23 ldr r3, [r4, #32] + 800a8c6: 2b43 cmp r3, #67 ; 0x43 + 800a8c8: d905 bls.n 800a8d6 + { + /* There are still data waiting to be entered in the Peripheral. + Decrement buffer counter and set pointer to the proper + memory location for the next data entering round. */ + hhash->HashInCount -= 68U; + 800a8ca: 6a23 ldr r3, [r4, #32] + 800a8cc: 3b44 subs r3, #68 ; 0x44 + 800a8ce: 6223 str r3, [r4, #32] + hhash->pHashInBuffPtr+= 68U; + 800a8d0: 3244 adds r2, #68 ; 0x44 + { + /* 64 bytes have been entered and there are still some remaining: + Decrement buffer counter and set pointer to the proper + memory location for the next data entering round.*/ + hhash->HashInCount -= 64U; + hhash->pHashInBuffPtr+= 64U; + 800a8d2: 60e2 str r2, [r4, #12] + /* Reset buffer counter */ + hhash->HashInCount = 0; + } + + /* Return whether or digest calculation has started */ + return ret; + 800a8d4: e7ca b.n 800a86c + hhash->HashInCount = 0U; + 800a8d6: 2300 movs r3, #0 + 800a8d8: 6223 str r3, [r4, #32] + return ret; + 800a8da: e7c7 b.n 800a86c + hhash->HashInCount -= 64U; + 800a8dc: 6a23 ldr r3, [r4, #32] + 800a8de: 3b40 subs r3, #64 ; 0x40 + 800a8e0: 6223 str r3, [r4, #32] + hhash->pHashInBuffPtr+= 64U; + 800a8e2: 3240 adds r2, #64 ; 0x40 + 800a8e4: e7f5 b.n 800a8d2 + inputcounter = hhash->HashInCount; + 800a8e6: 6a22 ldr r2, [r4, #32] + __HAL_HASH_DISABLE_IT(HASH_IT_DINI); + 800a8e8: 6a29 ldr r1, [r5, #32] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a8ea: 3203 adds r2, #3 + __HAL_HASH_DISABLE_IT(HASH_IT_DINI); + 800a8ec: f021 0101 bic.w r1, r1, #1 + 800a8f0: f022 0203 bic.w r2, r2, #3 + 800a8f4: 6229 str r1, [r5, #32] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a8f6: 441a add r2, r3 + 800a8f8: 4293 cmp r3, r2 + 800a8fa: d10b bne.n 800a914 + if (hhash->Accumulation == 1U) + 800a8fc: 6c23 ldr r3, [r4, #64] ; 0x40 + 800a8fe: 2b01 cmp r3, #1 + 800a900: d10c bne.n 800a91c + hhash->Accumulation = 0U; + 800a902: 2500 movs r5, #0 + 800a904: 6425 str r5, [r4, #64] ; 0x40 + HAL_HASH_InCpltCallback(hhash); + 800a906: 4620 mov r0, r4 + hhash->State = HAL_HASH_STATE_READY; + 800a908: f884 3035 strb.w r3, [r4, #53] ; 0x35 + HAL_HASH_InCpltCallback(hhash); + 800a90c: f7ff ff6f bl 800a7ee + hhash->HashInCount = 0; + 800a910: 6225 str r5, [r4, #32] + return ret; + 800a912: e7ab b.n 800a86c + HASH->DIN = *(uint32_t*)inputaddr; + 800a914: f853 1b04 ldr.w r1, [r3], #4 + 800a918: 6069 str r1, [r5, #4] + for(buffercounter = 0U; buffercounter < ((inputcounter+3U)/4U); buffercounter++) + 800a91a: e7ed b.n 800a8f8 + __HAL_HASH_START_DIGEST(); + 800a91c: 68ab ldr r3, [r5, #8] + 800a91e: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800a922: 60ab str r3, [r5, #8] + hhash->HashInCount = 0; + 800a924: 2300 movs r3, #0 + 800a926: 6223 str r3, [r4, #32] + HAL_HASH_InCpltCallback(hhash); + 800a928: 4620 mov r0, r4 + 800a92a: f7ff ff60 bl 800a7ee + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) + 800a92e: f894 602d ldrb.w r6, [r4, #45] ; 0x2d + 800a932: 2e03 cmp r6, #3 + 800a934: d12d bne.n 800a992 + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK) + 800a936: f44f 737a mov.w r3, #1000 ; 0x3e8 + 800a93a: 2201 movs r2, #1 + 800a93c: 2108 movs r1, #8 + 800a93e: 4620 mov r0, r4 + 800a940: f7ff feea bl 800a718 + 800a944: b168 cbz r0, 800a962 + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a946: 6a2b ldr r3, [r5, #32] + 800a948: f023 0303 bic.w r3, r3, #3 + 800a94c: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a94e: f884 602c strb.w r6, [r4, #44] ; 0x2c + hhash->ErrorCode |= HAL_HASH_ERROR_IT; + 800a952: 6be3 ldr r3, [r4, #60] ; 0x3c + 800a954: f043 0301 orr.w r3, r3, #1 + 800a958: 63e3 str r3, [r4, #60] ; 0x3c + HAL_HASH_ErrorCallback(hhash); + 800a95a: 4620 mov r0, r4 + 800a95c: f7ff ff49 bl 800a7f2 + 800a960: e784 b.n 800a86c + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; /* Move phase from Step 1 to Step 2 */ + 800a962: 2304 movs r3, #4 + 800a964: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); /* Set NBLW for the input message */ + 800a968: 68ab ldr r3, [r5, #8] + 800a96a: 69e2 ldr r2, [r4, #28] + 800a96c: f023 031f bic.w r3, r3, #31 + 800a970: f002 0103 and.w r1, r2, #3 + 800a974: ea43 03c1 orr.w r3, r3, r1, lsl #3 + 800a978: 60ab str r3, [r5, #8] + hhash->pHashInBuffPtr = hhash->pHashMsgBuffPtr; /* Set the input data address */ + 800a97a: 69a3 ldr r3, [r4, #24] + hhash->HashInCount = hhash->HashBuffSize; /* Set the input data size (in bytes) */ + 800a97c: 6222 str r2, [r4, #32] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a97e: 60e3 str r3, [r4, #12] + hhash->HashITCounter = 1; /* Set ITCounter to 1 to indicate the start of a new phase */ + 800a980: 2301 movs r3, #1 + 800a982: 6263 str r3, [r4, #36] ; 0x24 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI); /* Enable IT (was disabled in HASH_Write_Block_Data) */ + 800a984: 6a2b ldr r3, [r5, #32] + 800a986: f043 0301 orr.w r3, r3, #1 + 800a98a: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a98c: f884 002c strb.w r0, [r4, #44] ; 0x2c +} + 800a990: bd70 pop {r4, r5, r6, pc} + else if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) + 800a992: 2e04 cmp r6, #4 + 800a994: f47f af6a bne.w 800a86c + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, HASH_TIMEOUTVALUE) != HAL_OK) + 800a998: f44f 737a mov.w r3, #1000 ; 0x3e8 + 800a99c: 2201 movs r2, #1 + 800a99e: 2108 movs r1, #8 + 800a9a0: 4620 mov r0, r4 + 800a9a2: f7ff feb9 bl 800a718 + 800a9a6: b128 cbz r0, 800a9b4 + __HAL_HASH_DISABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800a9a8: 6a2b ldr r3, [r5, #32] + 800a9aa: f023 0303 bic.w r3, r3, #3 + 800a9ae: 622b str r3, [r5, #32] + hhash->Status = HASH_IT(hhash); + 800a9b0: 2303 movs r3, #3 + 800a9b2: e731 b.n 800a818 + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; /* Move phase from Step 2 to Step 3 */ + 800a9b4: 2305 movs r3, #5 + 800a9b6: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); /* Set NBLW for the key */ + 800a9ba: 68ab ldr r3, [r5, #8] + 800a9bc: 6862 ldr r2, [r4, #4] + 800a9be: f023 031f bic.w r3, r3, #31 + 800a9c2: f002 0103 and.w r1, r2, #3 + 800a9c6: ea43 03c1 orr.w r3, r3, r1, lsl #3 + 800a9ca: 60ab str r3, [r5, #8] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a9cc: 68a3 ldr r3, [r4, #8] + hhash->HashInCount = hhash->Init.KeySize; /* Set the key size (in bytes) */ + 800a9ce: 6222 str r2, [r4, #32] + hhash->pHashInBuffPtr = hhash->Init.pKey; /* Set the key address */ + 800a9d0: e7d5 b.n 800a97e + hhash->Status = HASH_IT(hhash); + 800a9d2: 2302 movs r3, #2 + 800a9d4: e720 b.n 800a818 + 800a9d6: bf00 nop + 800a9d8: 50060400 .word 0x50060400 + 800a9dc: 00040080 .word 0x00040080 + +0800a9e0 : + return hhash->State; + 800a9e0: f890 0035 ldrb.w r0, [r0, #53] ; 0x35 +} + 800a9e4: 4770 bx lr + +0800a9e6 : +} + 800a9e6: f890 002c ldrb.w r0, [r0, #44] ; 0x2c + 800a9ea: 4770 bx lr + +0800a9ec : + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->IMR,HASH_IT_DINI|HASH_IT_DCI); + 800a9ec: 4b0e ldr r3, [pc, #56] ; (800aa28 ) + 800a9ee: 6a1a ldr r2, [r3, #32] + 800a9f0: f002 0203 and.w r2, r2, #3 + 800a9f4: 600a str r2, [r1, #0] + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->STR,HASH_STR_NBLW); + 800a9f6: 689a ldr r2, [r3, #8] + 800a9f8: f002 021f and.w r2, r2, #31 + 800a9fc: 604a str r2, [r1, #4] + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->CR,HASH_CR_DMAE|HASH_CR_DATATYPE|HASH_CR_MODE|HASH_CR_ALGO|HASH_CR_LKEY|HASH_CR_MDMAT); + 800a9fe: 681b ldr r3, [r3, #0] + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800aa00: 4a0a ldr r2, [pc, #40] ; (800aa2c ) + *(uint32_t*)(mem_ptr) = READ_BIT(HASH->CR,HASH_CR_DMAE|HASH_CR_DATATYPE|HASH_CR_MODE|HASH_CR_ALGO|HASH_CR_LKEY|HASH_CR_MDMAT); + 800aa02: f023 437f bic.w r3, r3, #4278190080 ; 0xff000000 + 800aa06: f423 037a bic.w r3, r3, #16384000 ; 0xfa0000 + 800aa0a: f423 435f bic.w r3, r3, #57088 ; 0xdf00 + 800aa0e: f023 0307 bic.w r3, r3, #7 + 800aa12: 608b str r3, [r1, #8] + uint32_t csr_ptr = (uint32_t)HASH->CSR; + 800aa14: 4b06 ldr r3, [pc, #24] ; (800aa30 ) + mem_ptr+=4U; + 800aa16: 310c adds r1, #12 + *(uint32_t*)(mem_ptr) = *(uint32_t*)(csr_ptr); + 800aa18: f853 0b04 ldr.w r0, [r3], #4 + 800aa1c: f841 0b04 str.w r0, [r1], #4 + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800aa20: 4293 cmp r3, r2 + 800aa22: d1f9 bne.n 800aa18 +} + 800aa24: 4770 bx lr + 800aa26: bf00 nop + 800aa28: 50060400 .word 0x50060400 + 800aa2c: 500605d0 .word 0x500605d0 + 800aa30: 500604f8 .word 0x500604f8 + +0800aa34 : + WRITE_REG(HASH->IMR, (*(uint32_t*)(mem_ptr))); + 800aa34: 4b0a ldr r3, [pc, #40] ; (800aa60 ) + 800aa36: 680a ldr r2, [r1, #0] + 800aa38: 621a str r2, [r3, #32] + WRITE_REG(HASH->STR, (*(uint32_t*)(mem_ptr))); + 800aa3a: 684a ldr r2, [r1, #4] + 800aa3c: 609a str r2, [r3, #8] + WRITE_REG(HASH->CR, (*(uint32_t*)(mem_ptr))); + 800aa3e: 688a ldr r2, [r1, #8] + 800aa40: 601a str r2, [r3, #0] + __HAL_HASH_INIT(); + 800aa42: 681a ldr r2, [r3, #0] + 800aa44: f042 0204 orr.w r2, r2, #4 + 800aa48: 601a str r2, [r3, #0] + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800aa4a: 4a06 ldr r2, [pc, #24] ; (800aa64 ) + mem_ptr+=4U; + 800aa4c: 310c adds r1, #12 + uint32_t csr_ptr = (uint32_t)HASH->CSR; + 800aa4e: 33f8 adds r3, #248 ; 0xf8 + WRITE_REG((*(uint32_t*)(csr_ptr)), (*(uint32_t*)(mem_ptr))); + 800aa50: f851 0b04 ldr.w r0, [r1], #4 + 800aa54: f843 0b04 str.w r0, [r3], #4 + for (i = HASH_NUMBER_OF_CSR_REGISTERS; i >0U; i--) + 800aa58: 4293 cmp r3, r2 + 800aa5a: d1f9 bne.n 800aa50 +} + 800aa5c: 4770 bx lr + 800aa5e: bf00 nop + 800aa60: 50060400 .word 0x50060400 + 800aa64: 500605d0 .word 0x500605d0 + +0800aa68 : + hhash->SuspendRequest = HAL_HASH_SUSPEND; + 800aa68: 2301 movs r3, #1 + 800aa6a: f880 3036 strb.w r3, [r0, #54] ; 0x36 +} + 800aa6e: 4770 bx lr + +0800aa70 : + return hhash->ErrorCode; + 800aa70: 6bc0 ldr r0, [r0, #60] ; 0x3c +} + 800aa72: 4770 bx lr + +0800aa74 : + * @param Timeout Timeout value. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout, uint32_t Algorithm) +{ + 800aa74: b5f8 push {r3, r4, r5, r6, r7, lr} + 800aa76: 461e mov r6, r3 + uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */ + uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */ + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800aa78: f890 3035 ldrb.w r3, [r0, #53] ; 0x35 + + + /* Initiate HASH processing in case of start or resumption */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800aa7c: 2b01 cmp r3, #1 +{ + 800aa7e: 4604 mov r4, r0 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800aa80: b2d8 uxtb r0, r3 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800aa82: d001 beq.n 800aa88 + 800aa84: 2808 cmp r0, #8 + 800aa86: d17a bne.n 800ab7e + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (pOutBuffer == NULL)) + 800aa88: b101 cbz r1, 800aa8c + 800aa8a: b926 cbnz r6, 800aa96 + { + hhash->State = HAL_HASH_STATE_READY; + 800aa8c: 2501 movs r5, #1 + 800aa8e: f884 5035 strb.w r5, [r4, #53] ; 0x35 + } + else + { + return HAL_BUSY; + } +} + 800aa92: 4628 mov r0, r5 + 800aa94: bdf8 pop {r3, r4, r5, r6, r7, pc} + __HAL_LOCK(hhash); + 800aa96: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800aa9a: 2b01 cmp r3, #1 + 800aa9c: d06f beq.n 800ab7e + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aa9e: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + __HAL_LOCK(hhash); + 800aaa2: 2501 movs r5, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aaa4: 42ab cmp r3, r5 + __HAL_LOCK(hhash); + 800aaa6: f884 5034 strb.w r5, [r4, #52] ; 0x34 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800aaaa: d148 bne.n 800ab3e + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800aaac: 4f36 ldr r7, [pc, #216] ; (800ab88 ) + 800aaae: 9b07 ldr r3, [sp, #28] + hhash->State = HAL_HASH_STATE_BUSY; + 800aab0: f04f 0c02 mov.w ip, #2 + 800aab4: f884 c035 strb.w ip, [r4, #53] ; 0x35 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800aab8: 683d ldr r5, [r7, #0] + 800aaba: f425 25a0 bic.w r5, r5, #327680 ; 0x50000 + 800aabe: f025 05c4 bic.w r5, r5, #196 ; 0xc4 + 800aac2: 431d orrs r5, r3 + 800aac4: f045 0504 orr.w r5, r5, #4 + 800aac8: 603d str r5, [r7, #0] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800aaca: 68b8 ldr r0, [r7, #8] + 800aacc: f002 0303 and.w r3, r2, #3 + 800aad0: f020 001f bic.w r0, r0, #31 + 800aad4: ea40 03c3 orr.w r3, r0, r3, lsl #3 + 800aad8: 60bb str r3, [r7, #8] + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800aada: f884 c02d strb.w ip, [r4, #45] ; 0x2d + hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp); + 800aade: 4620 mov r0, r4 + 800aae0: f7ff fd78 bl 800a5d4 + 800aae4: 4605 mov r5, r0 + 800aae6: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800aaea: 2800 cmp r0, #0 + 800aaec: d1d1 bne.n 800aa92 + if (hhash->State != HAL_HASH_STATE_SUSPENDED) + 800aaee: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800aaf2: 2b08 cmp r3, #8 + 800aaf4: d03b beq.n 800ab6e + __HAL_HASH_START_DIGEST(); + 800aaf6: 4f24 ldr r7, [pc, #144] ; (800ab88 ) + 800aaf8: 68bb ldr r3, [r7, #8] + 800aafa: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800aafe: 60bb str r3, [r7, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800ab00: 4602 mov r2, r0 + 800ab02: 9b06 ldr r3, [sp, #24] + 800ab04: 2102 movs r1, #2 + 800ab06: 4620 mov r0, r4 + 800ab08: f7ff fe06 bl 800a718 + 800ab0c: 2800 cmp r0, #0 + 800ab0e: d138 bne.n 800ab82 + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800ab10: 683a ldr r2, [r7, #0] + 800ab12: 4b1e ldr r3, [pc, #120] ; (800ab8c ) + 800ab14: 421a tst r2, r3 + 800ab16: d02e beq.n 800ab76 + 800ab18: 683a ldr r2, [r7, #0] + 800ab1a: 401a ands r2, r3 + 800ab1c: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800ab20: d02b beq.n 800ab7a + 800ab22: 683a ldr r2, [r7, #0] + 800ab24: 4393 bics r3, r2 + 800ab26: bf0c ite eq + 800ab28: 2120 moveq r1, #32 + 800ab2a: 2110 movne r1, #16 + 800ab2c: 4630 mov r0, r6 + 800ab2e: f7ff fd91 bl 800a654 + hhash->State = HAL_HASH_STATE_READY; + 800ab32: 2301 movs r3, #1 + 800ab34: f884 3035 strb.w r3, [r4, #53] ; 0x35 + hhash->Phase = HAL_HASH_PHASE_READY; + 800ab38: f884 302d strb.w r3, [r4, #45] ; 0x2d + 800ab3c: e017 b.n 800ab6e + else if (hhash->Phase == HAL_HASH_PHASE_PROCESS) + 800ab3e: 2b02 cmp r3, #2 + 800ab40: d113 bne.n 800ab6a + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800ab42: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800ab46: 2b08 cmp r3, #8 + __HAL_HASH_SET_NBVALIDBITS(Size); + 800ab48: bf15 itete ne + 800ab4a: 4d0f ldrne r5, [pc, #60] ; (800ab88 ) + Size_tmp = hhash->HashInCount; + 800ab4c: 6a22 ldreq r2, [r4, #32] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800ab4e: 68a8 ldrne r0, [r5, #8] + pInBuffer_tmp = hhash->pHashInBuffPtr; + 800ab50: 68e1 ldreq r1, [r4, #12] + __HAL_HASH_SET_NBVALIDBITS(Size); + 800ab52: bf1f itttt ne + 800ab54: f002 0303 andne.w r3, r2, #3 + 800ab58: f020 001f bicne.w r0, r0, #31 + 800ab5c: ea40 03c3 orrne.w r3, r0, r3, lsl #3 + 800ab60: 60ab strne r3, [r5, #8] + hhash->State = HAL_HASH_STATE_BUSY; + 800ab62: 2302 movs r3, #2 + 800ab64: f884 3035 strb.w r3, [r4, #53] ; 0x35 + 800ab68: e7b9 b.n 800aade + hhash->State = HAL_HASH_STATE_READY; + 800ab6a: f884 5035 strb.w r5, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800ab6e: 2300 movs r3, #0 + 800ab70: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800ab74: e78d b.n 800aa92 + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800ab76: 2114 movs r1, #20 + 800ab78: e7d8 b.n 800ab2c + 800ab7a: 211c movs r1, #28 + 800ab7c: e7d6 b.n 800ab2c + return HAL_BUSY; + 800ab7e: 2502 movs r5, #2 + 800ab80: e787 b.n 800aa92 + return HAL_TIMEOUT; + 800ab82: 2503 movs r5, #3 + 800ab84: e785 b.n 800aa92 + 800ab86: bf00 nop + 800ab88: 50060400 .word 0x50060400 + 800ab8c: 00040080 .word 0x00040080 + +0800ab90 : +{ + 800ab90: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_MD5); + 800ab92: 2480 movs r4, #128 ; 0x80 + 800ab94: 9401 str r4, [sp, #4] + 800ab96: 9c04 ldr r4, [sp, #16] + 800ab98: 9400 str r4, [sp, #0] + 800ab9a: f7ff ff6b bl 800aa74 +} + 800ab9e: b002 add sp, #8 + 800aba0: bd10 pop {r4, pc} + +0800aba2 : + 800aba2: f7ff bff5 b.w 800ab90 + +0800aba6 : +{ + 800aba6: b513 push {r0, r1, r4, lr} + return HASH_Start(hhash, pInBuffer, Size, pOutBuffer, Timeout, HASH_ALGOSELECTION_SHA1); + 800aba8: 2400 movs r4, #0 + 800abaa: 9401 str r4, [sp, #4] + 800abac: 9c04 ldr r4, [sp, #16] + 800abae: 9400 str r4, [sp, #0] + 800abb0: f7ff ff60 bl 800aa74 +} + 800abb4: b002 add sp, #8 + 800abb6: bd10 pop {r4, pc} + +0800abb8 : + 800abb8: f7ff bff5 b.w 800aba6 + +0800abbc : + * @param Size length of the input buffer in bytes, must be a multiple of 4. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Accumulate(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm) +{ + 800abbc: b570 push {r4, r5, r6, lr} + uint8_t *pInBuffer_tmp; /* input data address, input parameter of HASH_WriteData() */ + uint32_t Size_tmp; /* input data size (in bytes), input parameter of HASH_WriteData() */ + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800abbe: f890 5035 ldrb.w r5, [r0, #53] ; 0x35 +{ + 800abc2: 4604 mov r4, r0 + + /* Make sure the input buffer size (in bytes) is a multiple of 4 */ + if ((Size % 4U) != 0U) + 800abc4: 0790 lsls r0, r2, #30 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800abc6: b2ed uxtb r5, r5 + if ((Size % 4U) != 0U) + 800abc8: d13e bne.n 800ac48 + { + return HAL_ERROR; + } + + /* Initiate HASH processing in case of start or resumption */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800abca: 2d01 cmp r5, #1 + 800abcc: d001 beq.n 800abd2 + 800abce: 2d08 cmp r5, #8 + 800abd0: d13c bne.n 800ac4c + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U)) + 800abd2: b101 cbz r1, 800abd6 + 800abd4: b91a cbnz r2, 800abde + { + hhash->State = HAL_HASH_STATE_READY; + 800abd6: 2001 movs r0, #1 + 800abd8: f884 0035 strb.w r0, [r4, #53] ; 0x35 + { + return HAL_BUSY; + } + + +} + 800abdc: bd70 pop {r4, r5, r6, pc} + __HAL_LOCK(hhash); + 800abde: f894 0034 ldrb.w r0, [r4, #52] ; 0x34 + 800abe2: 2801 cmp r0, #1 + 800abe4: d032 beq.n 800ac4c + 800abe6: 2001 movs r0, #1 + 800abe8: f884 0034 strb.w r0, [r4, #52] ; 0x34 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800abec: f894 0035 ldrb.w r0, [r4, #53] ; 0x35 + 800abf0: 2808 cmp r0, #8 + 800abf2: f04f 0002 mov.w r0, #2 + hhash->State = HAL_HASH_STATE_BUSY; + 800abf6: f884 0035 strb.w r0, [r4, #53] ; 0x35 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800abfa: d113 bne.n 800ac24 + pInBuffer_tmp = hhash->pHashInBuffPtr; /* pInBuffer_tmp is set to the input data address */ + 800abfc: 68e1 ldr r1, [r4, #12] + Size_tmp = hhash->HashInCount; /* Size_tmp contains the input data size in bytes */ + 800abfe: 6a22 ldr r2, [r4, #32] + hhash->Status = HASH_WriteData(hhash, pInBuffer_tmp, Size_tmp); + 800ac00: 4620 mov r0, r4 + 800ac02: f7ff fce7 bl 800a5d4 + 800ac06: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800ac0a: 2800 cmp r0, #0 + 800ac0c: d1e6 bne.n 800abdc + if (hhash->State != HAL_HASH_STATE_SUSPENDED) + 800ac0e: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800ac12: 2b08 cmp r3, #8 + hhash->State = HAL_HASH_STATE_READY; + 800ac14: bf1c itt ne + 800ac16: 2301 movne r3, #1 + 800ac18: f884 3035 strbne.w r3, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800ac1c: 2300 movs r3, #0 + 800ac1e: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800ac22: e7db b.n 800abdc + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ac24: f894 002d ldrb.w r0, [r4, #45] ; 0x2d + 800ac28: 2801 cmp r0, #1 + 800ac2a: d109 bne.n 800ac40 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800ac2c: 4e08 ldr r6, [pc, #32] ; (800ac50 ) + 800ac2e: 6830 ldr r0, [r6, #0] + 800ac30: f420 20a0 bic.w r0, r0, #327680 ; 0x50000 + 800ac34: f020 00c4 bic.w r0, r0, #196 ; 0xc4 + 800ac38: 4318 orrs r0, r3 + 800ac3a: f040 0004 orr.w r0, r0, #4 + 800ac3e: 6030 str r0, [r6, #0] + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800ac40: 2302 movs r3, #2 + 800ac42: f884 302d strb.w r3, [r4, #45] ; 0x2d + 800ac46: e7db b.n 800ac00 + return HAL_ERROR; + 800ac48: 2001 movs r0, #1 + 800ac4a: e7c7 b.n 800abdc + return HAL_BUSY; + 800ac4c: 2002 movs r0, #2 + 800ac4e: e7c5 b.n 800abdc + 800ac50: 50060400 .word 0x50060400 + +0800ac54 : + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_MD5); + 800ac54: 2380 movs r3, #128 ; 0x80 + 800ac56: f7ff bfb1 b.w 800abbc + +0800ac5a : + return HASH_Accumulate(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA1); + 800ac5a: 2300 movs r3, #0 + 800ac5c: f7ff bfae b.w 800abbc + +0800ac60 : + * @param Size length of the input buffer in bytes, must be a multiple of 4. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Accumulate_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint32_t Algorithm) +{ + 800ac60: b567 push {r0, r1, r2, r5, r6, lr} + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ac62: f890 5035 ldrb.w r5, [r0, #53] ; 0x35 + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800ac66: 9101 str r1, [sp, #4] + uint32_t SizeVar = Size; + + /* Make sure the input buffer size (in bytes) is a multiple of 4 */ + if ((Size % 4U) != 0U) + 800ac68: 0796 lsls r6, r2, #30 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ac6a: b2ed uxtb r5, r5 + if ((Size % 4U) != 0U) + 800ac6c: d154 bne.n 800ad18 + { + return HAL_ERROR; + } + + /* Initiate HASH processing in case of start or resumption */ + if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800ac6e: 2d01 cmp r5, #1 + 800ac70: d001 beq.n 800ac76 + 800ac72: 2d08 cmp r5, #8 + 800ac74: d152 bne.n 800ad1c + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U)) + 800ac76: b101 cbz r1, 800ac7a + 800ac78: b92a cbnz r2, 800ac86 + { + hhash->State = HAL_HASH_STATE_READY; + 800ac7a: 2301 movs r3, #1 + 800ac7c: f880 3035 strb.w r3, [r0, #53] ; 0x35 + else + { + return HAL_BUSY; + } + +} + 800ac80: 4618 mov r0, r3 + 800ac82: b003 add sp, #12 + 800ac84: bd60 pop {r5, r6, pc} + __HAL_LOCK(hhash); + 800ac86: f890 1034 ldrb.w r1, [r0, #52] ; 0x34 + 800ac8a: 2901 cmp r1, #1 + 800ac8c: d046 beq.n 800ad1c + 800ac8e: 2101 movs r1, #1 + 800ac90: f880 1034 strb.w r1, [r0, #52] ; 0x34 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800ac94: f890 1035 ldrb.w r1, [r0, #53] ; 0x35 + 800ac98: 4d21 ldr r5, [pc, #132] ; (800ad20 ) + 800ac9a: 2908 cmp r1, #8 + 800ac9c: f04f 0102 mov.w r1, #2 + hhash->State = HAL_HASH_STATE_BUSY; + 800aca0: f880 1035 strb.w r1, [r0, #53] ; 0x35 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800aca4: d109 bne.n 800acba + hhash->Accumulation = 1U; + 800aca6: 2301 movs r3, #1 + 800aca8: 6403 str r3, [r0, #64] ; 0x40 + __HAL_UNLOCK(hhash); + 800acaa: 2300 movs r3, #0 + 800acac: f880 3034 strb.w r3, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI); + 800acb0: 6a2a ldr r2, [r5, #32] + 800acb2: f042 0201 orr.w r2, r2, #1 + 800acb6: 622a str r2, [r5, #32] + return HAL_OK; + 800acb8: e7e2 b.n 800ac80 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800acba: f890 602d ldrb.w r6, [r0, #45] ; 0x2d + 800acbe: 2e01 cmp r6, #1 + 800acc0: d11b bne.n 800acfa + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800acc2: 6829 ldr r1, [r5, #0] + 800acc4: f421 21a0 bic.w r1, r1, #327680 ; 0x50000 + 800acc8: f021 01c4 bic.w r1, r1, #196 ; 0xc4 + 800accc: 4319 orrs r1, r3 + 800acce: f041 0104 orr.w r1, r1, #4 + 800acd2: 6029 str r1, [r5, #0] + hhash->HashITCounter = 1; + 800acd4: 6246 str r6, [r0, #36] ; 0x24 + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800acd6: 2302 movs r3, #2 + 800acd8: f880 302d strb.w r3, [r0, #45] ; 0x2d + while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 0U)) + 800acdc: 6a6b ldr r3, [r5, #36] ; 0x24 + 800acde: 07d9 lsls r1, r3, #31 + 800ace0: d400 bmi.n 800ace4 + 800ace2: b96a cbnz r2, 800ad00 + if ((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) || (SizeVar == 0U)) + 800ace4: 6a6b ldr r3, [r5, #36] ; 0x24 + 800ace6: 07db lsls r3, r3, #31 + 800ace8: d500 bpl.n 800acec + 800acea: b98a cbnz r2, 800ad10 + hhash->State = HAL_HASH_STATE_READY; + 800acec: 2301 movs r3, #1 + 800acee: f880 3035 strb.w r3, [r0, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800acf2: 2300 movs r3, #0 + 800acf4: f880 3034 strb.w r3, [r0, #52] ; 0x34 + return HAL_OK; + 800acf8: e7c2 b.n 800ac80 + hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */ + 800acfa: 2303 movs r3, #3 + 800acfc: 6243 str r3, [r0, #36] ; 0x24 + 800acfe: e7ea b.n 800acd6 + HASH->DIN = *(uint32_t*)inputaddr; + 800ad00: 9b01 ldr r3, [sp, #4] + 800ad02: 681b ldr r3, [r3, #0] + 800ad04: 606b str r3, [r5, #4] + inputaddr+=4U; + 800ad06: 9b01 ldr r3, [sp, #4] + 800ad08: 3304 adds r3, #4 + 800ad0a: 9301 str r3, [sp, #4] + SizeVar-=4U; + 800ad0c: 3a04 subs r2, #4 + 800ad0e: e7e5 b.n 800acdc + hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data + 800ad10: 6202 str r2, [r0, #32] + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; /* Points at data which will be fed to the Peripheral at + 800ad12: 9b01 ldr r3, [sp, #4] + 800ad14: 60c3 str r3, [r0, #12] + 800ad16: e7c6 b.n 800aca6 + return HAL_ERROR; + 800ad18: 2301 movs r3, #1 + 800ad1a: e7b1 b.n 800ac80 + return HAL_BUSY; + 800ad1c: 2302 movs r3, #2 + 800ad1e: e7af b.n 800ac80 + 800ad20: 50060400 .word 0x50060400 + +0800ad24 : + return HASH_Accumulate_IT(hhash, pInBuffer, Size,HASH_ALGOSELECTION_MD5); + 800ad24: 2380 movs r3, #128 ; 0x80 + 800ad26: f7ff bf9b b.w 800ac60 + +0800ad2a : + return HASH_Accumulate_IT(hhash, pInBuffer, Size,HASH_ALGOSELECTION_SHA1); + 800ad2a: 2300 movs r3, #0 + 800ad2c: f7ff bf98 b.w 800ac60 + +0800ad30 : + * @param pOutBuffer pointer to the computed digest. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Start_IT(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Algorithm) +{ + 800ad30: b573 push {r0, r1, r4, r5, r6, lr} + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ad32: f890 4035 ldrb.w r4, [r0, #53] ; 0x35 + __IO uint32_t inputaddr = (uint32_t) pInBuffer; + 800ad36: 9101 str r1, [sp, #4] + uint32_t polling_step = 0U; + uint32_t initialization_skipped = 0U; + uint32_t SizeVar = Size; + + /* If State is ready or suspended, start or resume IT-based HASH processing */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800ad38: 2c01 cmp r4, #1 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800ad3a: b2e5 uxtb r5, r4 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800ad3c: d001 beq.n 800ad42 + 800ad3e: 2d08 cmp r5, #8 + 800ad40: d17f bne.n 800ae42 + { + /* Check input parameters */ + if ((pInBuffer == NULL) || (Size == 0U) || (pOutBuffer == NULL)) + 800ad42: b109 cbz r1, 800ad48 + 800ad44: b102 cbz r2, 800ad48 + 800ad46: b92b cbnz r3, 800ad54 + { + hhash->State = HAL_HASH_STATE_READY; + 800ad48: 2201 movs r2, #1 + 800ad4a: f880 2035 strb.w r2, [r0, #53] ; 0x35 + else + { + return HAL_BUSY; + } + +} + 800ad4e: 4610 mov r0, r2 + 800ad50: b002 add sp, #8 + 800ad52: bd70 pop {r4, r5, r6, pc} + __HAL_LOCK(hhash); + 800ad54: f890 4034 ldrb.w r4, [r0, #52] ; 0x34 + 800ad58: 2c01 cmp r4, #1 + 800ad5a: f04f 0402 mov.w r4, #2 + 800ad5e: d072 beq.n 800ae46 + hhash->State = HAL_HASH_STATE_BUSY; + 800ad60: f880 4035 strb.w r4, [r0, #53] ; 0x35 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ad64: f890 402d ldrb.w r4, [r0, #45] ; 0x2d + __HAL_LOCK(hhash); + 800ad68: 2601 movs r6, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ad6a: 42b4 cmp r4, r6 + __HAL_LOCK(hhash); + 800ad6c: f880 6034 strb.w r6, [r0, #52] ; 0x34 + hhash->HashITCounter = 1; + 800ad70: 4c36 ldr r4, [pc, #216] ; (800ae4c ) + 800ad72: 6246 str r6, [r0, #36] ; 0x24 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800ad74: d115 bne.n 800ada2 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_CR_INIT); + 800ad76: 6825 ldr r5, [r4, #0] + 800ad78: 9e06 ldr r6, [sp, #24] + 800ad7a: f425 25a0 bic.w r5, r5, #327680 ; 0x50000 + 800ad7e: f025 05c4 bic.w r5, r5, #196 ; 0xc4 + 800ad82: 4335 orrs r5, r6 + 800ad84: f045 0504 orr.w r5, r5, #4 + 800ad88: 6025 str r5, [r4, #0] + __HAL_HASH_SET_NBVALIDBITS(SizeVar); + 800ad8a: 68a6 ldr r6, [r4, #8] + 800ad8c: f002 0503 and.w r5, r2, #3 + 800ad90: f026 061f bic.w r6, r6, #31 + 800ad94: ea46 05c5 orr.w r5, r6, r5, lsl #3 + 800ad98: 60a5 str r5, [r4, #8] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800ad9a: e9c0 1303 strd r1, r3, [r0, #12] + hhash->HashInCount = SizeVar; /* Counter used to keep track of number of data + 800ad9e: 6202 str r2, [r0, #32] + uint32_t initialization_skipped = 0U; + 800ada0: 2600 movs r6, #0 + hhash->Phase = HAL_HASH_PHASE_PROCESS; + 800ada2: 2102 movs r1, #2 + 800ada4: f880 102d strb.w r1, [r0, #45] ; 0x2d + uint32_t polling_step = 0U; + 800ada8: 2100 movs r1, #0 + while((!(__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS))) && (SizeVar > 3U)) + 800adaa: 6a65 ldr r5, [r4, #36] ; 0x24 + 800adac: 07ed lsls r5, r5, #31 + 800adae: d401 bmi.n 800adb4 + 800adb0: 2a03 cmp r2, #3 + 800adb2: d80d bhi.n 800add0 + if (polling_step == 1U) + 800adb4: b349 cbz r1, 800ae0a + if (SizeVar == 0U) + 800adb6: b9a2 cbnz r2, 800ade2 + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800adb8: 6103 str r3, [r0, #16] + __HAL_HASH_START_DIGEST(); + 800adba: 68a3 ldr r3, [r4, #8] + 800adbc: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800adc0: 60a3 str r3, [r4, #8] + __HAL_UNLOCK(hhash); + 800adc2: f880 2034 strb.w r2, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DCI); + 800adc6: 6a23 ldr r3, [r4, #32] + 800adc8: f043 0302 orr.w r3, r3, #2 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800adcc: 6223 str r3, [r4, #32] + return HAL_OK; + 800adce: e7be b.n 800ad4e + HASH->DIN = *(uint32_t*)inputaddr; + 800add0: 9901 ldr r1, [sp, #4] + 800add2: 6809 ldr r1, [r1, #0] + 800add4: 6061 str r1, [r4, #4] + inputaddr+=4U; + 800add6: 9901 ldr r1, [sp, #4] + 800add8: 3104 adds r1, #4 + 800adda: 9101 str r1, [sp, #4] + SizeVar-=4U; + 800addc: 3a04 subs r2, #4 + polling_step = 1U; /* note that some words are entered before enabling the interrupt */ + 800adde: 2101 movs r1, #1 + 800ade0: e7e3 b.n 800adaa + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800ade2: 6a61 ldr r1, [r4, #36] ; 0x24 + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800ade4: f002 0503 and.w r5, r2, #3 + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800ade8: f011 0101 ands.w r1, r1, #1 + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800adec: ea4f 05c5 mov.w r5, r5, lsl #3 + else if (__HAL_HASH_GET_FLAG(HASH_FLAG_DINIS)) + 800adf0: d012 beq.n 800ae18 + hhash->HashInCount = SizeVar; + 800adf2: 6202 str r2, [r0, #32] + hhash->pHashInBuffPtr = (uint8_t *)inputaddr; + 800adf4: 9a01 ldr r2, [sp, #4] + 800adf6: 60c2 str r2, [r0, #12] + __HAL_HASH_SET_NBVALIDBITS(SizeVar); /* Update the configuration of the number of valid bits in last word of the message */ + 800adf8: 68a2 ldr r2, [r4, #8] + 800adfa: f022 021f bic.w r2, r2, #31 + 800adfe: 432a orrs r2, r5 + 800ae00: 60a2 str r2, [r4, #8] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800ae02: 6103 str r3, [r0, #16] + if (initialization_skipped == 1U) + 800ae04: b10e cbz r6, 800ae0a + hhash->HashITCounter = 3; /* 'cruise-speed' reached during a previous buffer processing */ + 800ae06: 2303 movs r3, #3 + 800ae08: 6243 str r3, [r0, #36] ; 0x24 + __HAL_UNLOCK(hhash); + 800ae0a: 2200 movs r2, #0 + 800ae0c: f880 2034 strb.w r2, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DINI|HASH_IT_DCI); + 800ae10: 6a23 ldr r3, [r4, #32] + 800ae12: f043 0303 orr.w r3, r3, #3 + 800ae16: e7d9 b.n 800adcc + __HAL_HASH_SET_NBVALIDBITS(SizeVar); + 800ae18: 68a2 ldr r2, [r4, #8] + 800ae1a: f022 021f bic.w r2, r2, #31 + 800ae1e: 432a orrs r2, r5 + 800ae20: 60a2 str r2, [r4, #8] + HASH->DIN = *(uint32_t*)inputaddr; + 800ae22: 9a01 ldr r2, [sp, #4] + 800ae24: 6812 ldr r2, [r2, #0] + 800ae26: 6062 str r2, [r4, #4] + hhash->pHashOutBuffPtr = pOutBuffer; /* Points at the computed digest */ + 800ae28: 6103 str r3, [r0, #16] + __HAL_HASH_START_DIGEST(); + 800ae2a: 68a3 ldr r3, [r4, #8] + 800ae2c: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800ae30: 60a3 str r3, [r4, #8] + __HAL_UNLOCK(hhash); + 800ae32: f880 1034 strb.w r1, [r0, #52] ; 0x34 + __HAL_HASH_ENABLE_IT(HASH_IT_DCI); + 800ae36: 6a23 ldr r3, [r4, #32] + 800ae38: f043 0302 orr.w r3, r3, #2 + 800ae3c: 6223 str r3, [r4, #32] + return HAL_OK; + 800ae3e: 460a mov r2, r1 + 800ae40: e785 b.n 800ad4e + return HAL_BUSY; + 800ae42: 2202 movs r2, #2 + 800ae44: e783 b.n 800ad4e + 800ae46: 4622 mov r2, r4 + 800ae48: e781 b.n 800ad4e + 800ae4a: bf00 nop + 800ae4c: 50060400 .word 0x50060400 + +0800ae50 : +{ + 800ae50: b513 push {r0, r1, r4, lr} + return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer,HASH_ALGOSELECTION_MD5); + 800ae52: 2480 movs r4, #128 ; 0x80 + 800ae54: 9400 str r4, [sp, #0] + 800ae56: f7ff ff6b bl 800ad30 +} + 800ae5a: b002 add sp, #8 + 800ae5c: bd10 pop {r4, pc} + +0800ae5e : + 800ae5e: f7ff bff7 b.w 800ae50 + +0800ae62 : +{ + 800ae62: b513 push {r0, r1, r4, lr} + return HASH_Start_IT(hhash, pInBuffer, Size, pOutBuffer,HASH_ALGOSELECTION_SHA1); + 800ae64: 2400 movs r4, #0 + 800ae66: 9400 str r4, [sp, #0] + 800ae68: f7ff ff62 bl 800ad30 +} + 800ae6c: b002 add sp, #8 + 800ae6e: bd10 pop {r4, pc} + +0800ae70 : + 800ae70: f7ff bff7 b.w 800ae62 + +0800ae74 : + * @param pOutBuffer pointer to the computed digest. + * @param Timeout Timeout value. + * @retval HAL status + */ +HAL_StatusTypeDef HASH_Finish(HASH_HandleTypeDef *hhash, uint8_t* pOutBuffer, uint32_t Timeout) +{ + 800ae74: b570 push {r4, r5, r6, lr} + 800ae76: 4613 mov r3, r2 + + if(hhash->State == HAL_HASH_STATE_READY) + 800ae78: f890 2035 ldrb.w r2, [r0, #53] ; 0x35 + 800ae7c: 2a01 cmp r2, #1 +{ + 800ae7e: 4605 mov r5, r0 + 800ae80: 460e mov r6, r1 + if(hhash->State == HAL_HASH_STATE_READY) + 800ae82: b2d4 uxtb r4, r2 + 800ae84: d12f bne.n 800aee6 + { + /* Check parameter */ + if (pOutBuffer == NULL) + 800ae86: b341 cbz r1, 800aeda + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hhash); + 800ae88: f890 2034 ldrb.w r2, [r0, #52] ; 0x34 + 800ae8c: 2a01 cmp r2, #1 + 800ae8e: f04f 0102 mov.w r1, #2 + 800ae92: d028 beq.n 800aee6 + 800ae94: f880 4034 strb.w r4, [r0, #52] ; 0x34 + + /* Change the HASH state to busy */ + hhash->State = HAL_HASH_STATE_BUSY; + 800ae98: f880 1035 strb.w r1, [r0, #53] ; 0x35 + + /* Wait for DCIS flag to be set */ + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800ae9c: 2200 movs r2, #0 + 800ae9e: f7ff fc3b bl 800a718 + 800aea2: 4604 mov r4, r0 + 800aea4: bb08 cbnz r0, 800aeea + { + return HAL_TIMEOUT; + } + + /* Read the message digest */ + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800aea6: 4a12 ldr r2, [pc, #72] ; (800aef0 ) + 800aea8: 4b12 ldr r3, [pc, #72] ; (800aef4 ) + 800aeaa: 6811 ldr r1, [r2, #0] + 800aeac: 4219 tst r1, r3 + 800aeae: d016 beq.n 800aede + 800aeb0: 6811 ldr r1, [r2, #0] + 800aeb2: 4019 ands r1, r3 + 800aeb4: f5b1 2f80 cmp.w r1, #262144 ; 0x40000 + 800aeb8: d013 beq.n 800aee2 + 800aeba: 6812 ldr r2, [r2, #0] + 800aebc: 4393 bics r3, r2 + 800aebe: bf0c ite eq + 800aec0: 2120 moveq r1, #32 + 800aec2: 2110 movne r1, #16 + 800aec4: 4630 mov r0, r6 + 800aec6: f7ff fbc5 bl 800a654 + + /* Change the HASH state to ready */ + hhash->State = HAL_HASH_STATE_READY; + 800aeca: 2301 movs r3, #1 + 800aecc: f885 3035 strb.w r3, [r5, #53] ; 0x35 + + /* Reset HASH state machine */ + hhash->Phase = HAL_HASH_PHASE_READY; + 800aed0: f885 302d strb.w r3, [r5, #45] ; 0x2d + + /* Process UnLock */ + __HAL_UNLOCK(hhash); + 800aed4: 2300 movs r3, #0 + 800aed6: f885 3034 strb.w r3, [r5, #52] ; 0x34 + else + { + return HAL_BUSY; + } + +} + 800aeda: 4620 mov r0, r4 + 800aedc: bd70 pop {r4, r5, r6, pc} + HASH_GetDigest(pOutBuffer, HASH_DIGEST_LENGTH()); + 800aede: 2114 movs r1, #20 + 800aee0: e7f0 b.n 800aec4 + 800aee2: 211c movs r1, #28 + 800aee4: e7ee b.n 800aec4 + return HAL_BUSY; + 800aee6: 2402 movs r4, #2 + 800aee8: e7f7 b.n 800aeda + return HAL_TIMEOUT; + 800aeea: 2403 movs r4, #3 + 800aeec: e7f5 b.n 800aeda + 800aeee: bf00 nop + 800aef0: 50060400 .word 0x50060400 + 800aef4: 00040080 .word 0x00040080 + +0800aef8 : + * @param Timeout Timeout value. + * @param Algorithm HASH algorithm. + * @retval HAL status + */ +HAL_StatusTypeDef HMAC_Start(HASH_HandleTypeDef *hhash, uint8_t *pInBuffer, uint32_t Size, uint8_t* pOutBuffer, uint32_t Timeout, uint32_t Algorithm) +{ + 800aef8: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800aefc: 4604 mov r4, r0 + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800aefe: f890 0035 ldrb.w r0, [r0, #53] ; 0x35 + + /* If State is ready or suspended, start or resume polling-based HASH processing */ +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800af02: 2801 cmp r0, #1 +{ + 800af04: e9dd 7e06 ldrd r7, lr, [sp, #24] + HAL_HASH_StateTypeDef State_tmp = hhash->State; + 800af08: b2c5 uxtb r5, r0 +if((State_tmp == HAL_HASH_STATE_READY) || (State_tmp == HAL_HASH_STATE_SUSPENDED)) + 800af0a: d002 beq.n 800af12 + 800af0c: 2d08 cmp r5, #8 + 800af0e: f040 80df bne.w 800b0d0 + { + /* Check input parameters */ + if ((pInBuffer == NULL) || /*(Size == 0U) ||*/ (hhash->Init.pKey == NULL) || (hhash->Init.KeySize == 0U) || (pOutBuffer == NULL)) + 800af12: b139 cbz r1, 800af24 + 800af14: f8d4 c008 ldr.w ip, [r4, #8] + 800af18: f1bc 0f00 cmp.w ip, #0 + 800af1c: d002 beq.n 800af24 + 800af1e: 6865 ldr r5, [r4, #4] + 800af20: b105 cbz r5, 800af24 + 800af22: b923 cbnz r3, 800af2e + { + hhash->State = HAL_HASH_STATE_READY; + 800af24: 2001 movs r0, #1 + 800af26: f884 0035 strb.w r0, [r4, #53] ; 0x35 + return HMAC_Processing(hhash, Timeout); + + } + else + { + return HAL_BUSY; + 800af2a: 4605 mov r5, r0 + 800af2c: e05b b.n 800afe6 + __HAL_LOCK(hhash); + 800af2e: f894 0034 ldrb.w r0, [r4, #52] ; 0x34 + 800af32: 2801 cmp r0, #1 + 800af34: f04f 0002 mov.w r0, #2 + 800af38: d0f7 beq.n 800af2a + hhash->State = HAL_HASH_STATE_BUSY; + 800af3a: f884 0035 strb.w r0, [r4, #53] ; 0x35 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800af3e: f894 002d ldrb.w r0, [r4, #45] ; 0x2d + __HAL_LOCK(hhash); + 800af42: 2601 movs r6, #1 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800af44: 42b0 cmp r0, r6 + __HAL_LOCK(hhash); + 800af46: f884 6034 strb.w r6, [r4, #52] ; 0x34 + if(hhash->Phase == HAL_HASH_PHASE_READY) + 800af4a: d118 bne.n 800af7e + if(hhash->Init.KeySize > 64U) + 800af4c: 4e61 ldr r6, [pc, #388] ; (800b0d4 ) + 800af4e: f8df 818c ldr.w r8, [pc, #396] ; 800b0dc + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + 800af52: 6830 ldr r0, [r6, #0] + 800af54: ea00 0008 and.w r0, r0, r8 + 800af58: ea40 000e orr.w r0, r0, lr + if(hhash->Init.KeySize > 64U) + 800af5c: 2d40 cmp r5, #64 ; 0x40 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_HMAC_KEYTYPE_LONGKEY | HASH_CR_INIT); + 800af5e: bf88 it hi + 800af60: f440 3080 orrhi.w r0, r0, #65536 ; 0x10000 + MODIFY_REG(HASH->CR, HASH_CR_LKEY|HASH_CR_ALGO|HASH_CR_MODE|HASH_CR_INIT, Algorithm | HASH_ALGOMODE_HMAC | HASH_CR_INIT); + 800af64: f040 0044 orr.w r0, r0, #68 ; 0x44 + 800af68: 6030 str r0, [r6, #0] + hhash->pHashInBuffPtr = pInBuffer; /* Input data address, HMAC_Processing input parameter for Step 2 */ + 800af6a: e9c4 1303 strd r1, r3, [r4, #12] + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + 800af6e: 2003 movs r0, #3 + hhash->HashInCount = Size; /* Input data size, HMAC_Processing input parameter for Step 2 */ + 800af70: 6222 str r2, [r4, #32] + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_1; + 800af72: f884 002d strb.w r0, [r4, #45] ; 0x2d + hhash->HashBuffSize = Size; /* Store the input buffer size for the whole HMAC process */ + 800af76: 61e2 str r2, [r4, #28] + hhash->pHashKeyBuffPtr = hhash->Init.pKey; /* Key address, HMAC_Processing input parameter for Step 1 and Step 3 */ + 800af78: f8c4 c014 str.w ip, [r4, #20] + hhash->HashKeyCount = hhash->Init.KeySize; /* Key size, HMAC_Processing input parameter for Step 1 and Step 3 */ + 800af7c: 62a5 str r5, [r4, #40] ; 0x28 + if ((hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_1) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_2) && (hhash->Phase != HAL_HASH_PHASE_HMAC_STEP_3)) + 800af7e: f894 302d ldrb.w r3, [r4, #45] ; 0x2d + 800af82: 1eda subs r2, r3, #3 + 800af84: 2a02 cmp r2, #2 + 800af86: d906 bls.n 800af96 + hhash->State = HAL_HASH_STATE_READY; + 800af88: 2001 movs r0, #1 + __HAL_UNLOCK(hhash); + 800af8a: 2300 movs r3, #0 + hhash->State = HAL_HASH_STATE_READY; + 800af8c: f884 0035 strb.w r0, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800af90: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_ERROR; + 800af94: e7c9 b.n 800af2a + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_1) + 800af96: 2b03 cmp r3, #3 + 800af98: 4e4e ldr r6, [pc, #312] ; (800b0d4 ) + 800af9a: d155 bne.n 800b048 + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800af9c: 68b3 ldr r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800af9e: 6961 ldr r1, [r4, #20] + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800afa0: f023 031f bic.w r3, r3, #31 + 800afa4: f005 0503 and.w r5, r5, #3 + 800afa8: ea43 05c5 orr.w r5, r3, r5, lsl #3 + 800afac: 60b5 str r5, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800afae: 6aa2 ldr r2, [r4, #40] ; 0x28 + 800afb0: 4620 mov r0, r4 + 800afb2: f7ff fb0f bl 800a5d4 + 800afb6: 4605 mov r5, r0 + 800afb8: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800afbc: b998 cbnz r0, 800afe6 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800afbe: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800afc2: 2b08 cmp r3, #8 + 800afc4: d103 bne.n 800afce + __HAL_UNLOCK(hhash); + 800afc6: 2000 movs r0, #0 + 800afc8: f884 0034 strb.w r0, [r4, #52] ; 0x34 + return HAL_OK; + 800afcc: e7ad b.n 800af2a + __HAL_HASH_START_DIGEST(); + 800afce: 68b3 ldr r3, [r6, #8] + 800afd0: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800afd4: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + 800afd6: 2201 movs r2, #1 + 800afd8: 463b mov r3, r7 + 800afda: 2108 movs r1, #8 + 800afdc: 4620 mov r0, r4 + 800afde: f7ff fb9b bl 800a718 + 800afe2: b118 cbz r0, 800afec + return HAL_TIMEOUT; + 800afe4: 2503 movs r5, #3 + } +} + 800afe6: 4628 mov r0, r5 + 800afe8: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_2; + 800afec: 2304 movs r3, #4 + 800afee: f884 302d strb.w r3, [r4, #45] ; 0x2d + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); + 800aff2: 68b3 ldr r3, [r6, #8] + 800aff4: 69e2 ldr r2, [r4, #28] + hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount); + 800aff6: 68e1 ldr r1, [r4, #12] + __HAL_HASH_SET_NBVALIDBITS(hhash->HashBuffSize); + 800aff8: f002 0203 and.w r2, r2, #3 + 800affc: f023 031f bic.w r3, r3, #31 + 800b000: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 800b004: 60b3 str r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashInBuffPtr, hhash->HashInCount); + 800b006: 6a22 ldr r2, [r4, #32] + 800b008: 4620 mov r0, r4 + 800b00a: f7ff fae3 bl 800a5d4 + 800b00e: 4605 mov r5, r0 + 800b010: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800b014: 2800 cmp r0, #0 + 800b016: d1e6 bne.n 800afe6 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800b018: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800b01c: 2b08 cmp r3, #8 + 800b01e: d0d2 beq.n 800afc6 + __HAL_HASH_START_DIGEST(); + 800b020: 68b3 ldr r3, [r6, #8] + 800b022: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800b026: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_BUSY, SET, Timeout) != HAL_OK) + 800b028: 2201 movs r2, #1 + 800b02a: 463b mov r3, r7 + 800b02c: 2108 movs r1, #8 + 800b02e: 4620 mov r0, r4 + 800b030: f7ff fb72 bl 800a718 + 800b034: 2800 cmp r0, #0 + 800b036: d1d5 bne.n 800afe4 + hhash->Phase = HAL_HASH_PHASE_HMAC_STEP_3; + 800b038: 2305 movs r3, #5 + 800b03a: f884 302d strb.w r3, [r4, #45] ; 0x2d + hhash->pHashKeyBuffPtr = hhash->Init.pKey; + 800b03e: 68a3 ldr r3, [r4, #8] + 800b040: 6163 str r3, [r4, #20] + hhash->HashKeyCount = hhash->Init.KeySize; + 800b042: 6863 ldr r3, [r4, #4] + 800b044: 62a3 str r3, [r4, #40] ; 0x28 + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_3) + 800b046: e001 b.n 800b04c + if (hhash->Phase == HAL_HASH_PHASE_HMAC_STEP_2) + 800b048: 2b04 cmp r3, #4 + 800b04a: d0d2 beq.n 800aff2 + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800b04c: 68b3 ldr r3, [r6, #8] + 800b04e: 6862 ldr r2, [r4, #4] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800b050: 6961 ldr r1, [r4, #20] + __HAL_HASH_SET_NBVALIDBITS(hhash->Init.KeySize); + 800b052: f002 0203 and.w r2, r2, #3 + 800b056: f023 031f bic.w r3, r3, #31 + 800b05a: ea43 03c2 orr.w r3, r3, r2, lsl #3 + 800b05e: 60b3 str r3, [r6, #8] + hhash->Status = HASH_WriteData(hhash, hhash->pHashKeyBuffPtr, hhash->HashKeyCount); + 800b060: 6aa2 ldr r2, [r4, #40] ; 0x28 + 800b062: 4620 mov r0, r4 + 800b064: f7ff fab6 bl 800a5d4 + 800b068: 4605 mov r5, r0 + 800b06a: f884 002c strb.w r0, [r4, #44] ; 0x2c + if (hhash->Status != HAL_OK) + 800b06e: 2800 cmp r0, #0 + 800b070: d1b9 bne.n 800afe6 + if (hhash->State == HAL_HASH_STATE_SUSPENDED) + 800b072: f894 3035 ldrb.w r3, [r4, #53] ; 0x35 + 800b076: 2b08 cmp r3, #8 + 800b078: d0a5 beq.n 800afc6 + __HAL_HASH_START_DIGEST(); + 800b07a: 68b3 ldr r3, [r6, #8] + 800b07c: f443 7380 orr.w r3, r3, #256 ; 0x100 + 800b080: 60b3 str r3, [r6, #8] + if (HASH_WaitOnFlagUntilTimeout(hhash, HASH_FLAG_DCIS, RESET, Timeout) != HAL_OK) + 800b082: 4602 mov r2, r0 + 800b084: 463b mov r3, r7 + 800b086: 2102 movs r1, #2 + 800b088: 4620 mov r0, r4 + 800b08a: f7ff fb45 bl 800a718 + 800b08e: 4605 mov r5, r0 + 800b090: 2800 cmp r0, #0 + 800b092: d1a7 bne.n 800afe4 + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800b094: 6832 ldr r2, [r6, #0] + 800b096: 4b10 ldr r3, [pc, #64] ; (800b0d8 ) + 800b098: 6920 ldr r0, [r4, #16] + 800b09a: 421a tst r2, r3 + 800b09c: d014 beq.n 800b0c8 + 800b09e: 6832 ldr r2, [r6, #0] + 800b0a0: 401a ands r2, r3 + 800b0a2: f5b2 2f80 cmp.w r2, #262144 ; 0x40000 + 800b0a6: d011 beq.n 800b0cc + 800b0a8: 6832 ldr r2, [r6, #0] + 800b0aa: 4393 bics r3, r2 + 800b0ac: bf0c ite eq + 800b0ae: 2120 moveq r1, #32 + 800b0b0: 2110 movne r1, #16 + 800b0b2: f7ff facf bl 800a654 + hhash->Phase = HAL_HASH_PHASE_READY; + 800b0b6: 2301 movs r3, #1 + 800b0b8: f884 302d strb.w r3, [r4, #45] ; 0x2d + hhash->State = HAL_HASH_STATE_READY; + 800b0bc: f884 3035 strb.w r3, [r4, #53] ; 0x35 + __HAL_UNLOCK(hhash); + 800b0c0: 2300 movs r3, #0 + 800b0c2: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800b0c6: e78e b.n 800afe6 + HASH_GetDigest(hhash->pHashOutBuffPtr, HASH_DIGEST_LENGTH()); + 800b0c8: 2114 movs r1, #20 + 800b0ca: e7f2 b.n 800b0b2 + 800b0cc: 211c movs r1, #28 + 800b0ce: e7f0 b.n 800b0b2 + return HAL_BUSY; + 800b0d0: 2502 movs r5, #2 + 800b0d2: e788 b.n 800afe6 + 800b0d4: 50060400 .word 0x50060400 + 800b0d8: 00040080 .word 0x00040080 + 800b0dc: fffaff3b .word 0xfffaff3b + +0800b0e0 : + * @param Tickstart : Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef OSPI_WaitFlagStateUntilTimeout(OSPI_HandleTypeDef *hospi, uint32_t Flag, + FlagStatus State, uint32_t Tickstart, uint32_t Timeout) +{ + 800b0e0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800b0e4: f8dd 8018 ldr.w r8, [sp, #24] + 800b0e8: 4604 mov r4, r0 + 800b0ea: 460e mov r6, r1 + 800b0ec: 4615 mov r5, r2 + 800b0ee: 461f mov r7, r3 + /* Wait until flag is in expected state */ + while((__HAL_OSPI_GET_FLAG(hospi, Flag)) != State) + 800b0f0: 6822 ldr r2, [r4, #0] + 800b0f2: 6a13 ldr r3, [r2, #32] + 800b0f4: 4233 tst r3, r6 + 800b0f6: bf14 ite ne + 800b0f8: 2301 movne r3, #1 + 800b0fa: 2300 moveq r3, #0 + 800b0fc: 42ab cmp r3, r5 + 800b0fe: d101 bne.n 800b104 + + return HAL_ERROR; + } + } + } + return HAL_OK; + 800b100: 2000 movs r0, #0 + 800b102: e012 b.n 800b12a + if (Timeout != HAL_MAX_DELAY) + 800b104: f1b8 3fff cmp.w r8, #4294967295 ; 0xffffffff + 800b108: d0f3 beq.n 800b0f2 + if(((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800b10a: f7fc f967 bl 80073dc + 800b10e: 1bc0 subs r0, r0, r7 + 800b110: 4540 cmp r0, r8 + 800b112: d802 bhi.n 800b11a + 800b114: f1b8 0f00 cmp.w r8, #0 + 800b118: d1ea bne.n 800b0f0 + hospi->State = HAL_OSPI_STATE_ERROR; + 800b11a: f44f 7300 mov.w r3, #512 ; 0x200 + 800b11e: 6463 str r3, [r4, #68] ; 0x44 + hospi->ErrorCode |= HAL_OSPI_ERROR_TIMEOUT; + 800b120: 6ca3 ldr r3, [r4, #72] ; 0x48 + 800b122: f043 0301 orr.w r3, r3, #1 + 800b126: 64a3 str r3, [r4, #72] ; 0x48 + 800b128: 2001 movs r0, #1 +} + 800b12a: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +0800b12e : +} + 800b12e: 4770 bx lr + +0800b130 : +{ + 800b130: b5f0 push {r4, r5, r6, r7, lr} + 800b132: b085 sub sp, #20 + 800b134: 4604 mov r4, r0 + uint32_t tickstart = HAL_GetTick(); + 800b136: f7fc f951 bl 80073dc + 800b13a: 4603 mov r3, r0 + if (hospi == NULL) + 800b13c: 2c00 cmp r4, #0 + 800b13e: d05d beq.n 800b1fc + hospi->ErrorCode = HAL_OSPI_ERROR_NONE; + 800b140: 2000 movs r0, #0 + 800b142: 64a0 str r0, [r4, #72] ; 0x48 + if (hospi->State == HAL_OSPI_STATE_RESET) + 800b144: 6c66 ldr r6, [r4, #68] ; 0x44 + 800b146: 2e00 cmp r6, #0 + 800b148: d156 bne.n 800b1f8 + HAL_OSPI_MspInit(hospi); + 800b14a: 4620 mov r0, r4 + 800b14c: 9303 str r3, [sp, #12] + 800b14e: f7ff ffee bl 800b12e + MODIFY_REG(hospi->Instance->DCR1, + 800b152: 6b20 ldr r0, [r4, #48] ; 0x30 + 800b154: 68e1 ldr r1, [r4, #12] + 800b156: 6825 ldr r5, [r4, #0] + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b158: 9b03 ldr r3, [sp, #12] + MODIFY_REG(hospi->Instance->DCR1, + 800b15a: 68af ldr r7, [r5, #8] + 800b15c: 4301 orrs r1, r0 + 800b15e: 69e0 ldr r0, [r4, #28] + 800b160: 4301 orrs r1, r0 + 800b162: 4827 ldr r0, [pc, #156] ; (800b200 ) + 800b164: 4038 ands r0, r7 + 800b166: 4301 orrs r1, r0 + 800b168: 6920 ldr r0, [r4, #16] + 800b16a: 3801 subs r0, #1 + 800b16c: ea41 4100 orr.w r1, r1, r0, lsl #16 + 800b170: 6960 ldr r0, [r4, #20] + 800b172: 3801 subs r0, #1 + hospi->Timeout = Timeout; + 800b174: f241 3288 movw r2, #5000 ; 0x1388 + MODIFY_REG(hospi->Instance->DCR1, + 800b178: ea41 2100 orr.w r1, r1, r0, lsl #8 + hospi->Timeout = Timeout; + 800b17c: 64e2 str r2, [r4, #76] ; 0x4c + MODIFY_REG(hospi->Instance->DCR1, + 800b17e: 60a9 str r1, [r5, #8] + hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos); + 800b180: 6ae1 ldr r1, [r4, #44] ; 0x2c + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos)); + 800b182: 6860 ldr r0, [r4, #4] + hospi->Instance->DCR3 = (hospi->Init.ChipSelectBoundary << OCTOSPI_DCR3_CSBOUND_Pos); + 800b184: 0409 lsls r1, r1, #16 + 800b186: 6129 str r1, [r5, #16] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold - 1U) << OCTOSPI_CR_FTHRES_Pos)); + 800b188: 6829 ldr r1, [r5, #0] + 800b18a: 3801 subs r0, #1 + 800b18c: f421 51f8 bic.w r1, r1, #7936 ; 0x1f00 + 800b190: ea41 2100 orr.w r1, r1, r0, lsl #8 + 800b194: 6029 str r1, [r5, #0] + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b196: 4620 mov r0, r4 + 800b198: 9200 str r2, [sp, #0] + 800b19a: 2120 movs r1, #32 + 800b19c: 4632 mov r2, r6 + 800b19e: f7ff ff9f bl 800b0e0 + if (status == HAL_OK) + 800b1a2: bb48 cbnz r0, 800b1f8 + MODIFY_REG(hospi->Instance->DCR2, OCTOSPI_DCR2_PRESCALER, ((hospi->Init.ClockPrescaler - 1U) << OCTOSPI_DCR2_PRESCALER_Pos)); + 800b1a4: 6823 ldr r3, [r4, #0] + 800b1a6: 6a22 ldr r2, [r4, #32] + 800b1a8: 68d9 ldr r1, [r3, #12] + 800b1aa: 3a01 subs r2, #1 + 800b1ac: f021 01ff bic.w r1, r1, #255 ; 0xff + 800b1b0: 430a orrs r2, r1 + 800b1b2: 60da str r2, [r3, #12] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_DQM, hospi->Init.DualQuad); + 800b1b4: 681a ldr r2, [r3, #0] + 800b1b6: 68a1 ldr r1, [r4, #8] + 800b1b8: f022 0240 bic.w r2, r2, #64 ; 0x40 + 800b1bc: 430a orrs r2, r1 + 800b1be: 601a str r2, [r3, #0] + MODIFY_REG(hospi->Instance->TCR, (OCTOSPI_TCR_SSHIFT | OCTOSPI_TCR_DHQC), (hospi->Init.SampleShifting | hospi->Init.DelayHoldQuarterCycle)); + 800b1c0: e9d4 2509 ldrd r2, r5, [r4, #36] ; 0x24 + 800b1c4: f8d3 1108 ldr.w r1, [r3, #264] ; 0x108 + 800b1c8: 432a orrs r2, r5 + 800b1ca: f021 41a0 bic.w r1, r1, #1342177280 ; 0x50000000 + 800b1ce: 430a orrs r2, r1 + 800b1d0: f8c3 2108 str.w r2, [r3, #264] ; 0x108 + __HAL_OSPI_ENABLE(hospi); + 800b1d4: 681a ldr r2, [r3, #0] + 800b1d6: f042 0201 orr.w r2, r2, #1 + 800b1da: 601a str r2, [r3, #0] + if (hospi->Init.FreeRunningClock == HAL_OSPI_FREERUNCLK_ENABLE) + 800b1dc: 69a2 ldr r2, [r4, #24] + 800b1de: 2a02 cmp r2, #2 + SET_BIT(hospi->Instance->DCR1, OCTOSPI_DCR1_FRCK); + 800b1e0: bf02 ittt eq + 800b1e2: 689a ldreq r2, [r3, #8] + 800b1e4: f042 0202 orreq.w r2, r2, #2 + 800b1e8: 609a streq r2, [r3, #8] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b1ea: 68e3 ldr r3, [r4, #12] + 800b1ec: f1b3 6f80 cmp.w r3, #67108864 ; 0x4000000 + hospi->State = HAL_OSPI_STATE_HYPERBUS_INIT; + 800b1f0: bf0c ite eq + 800b1f2: 2301 moveq r3, #1 + hospi->State = HAL_OSPI_STATE_READY; + 800b1f4: 2302 movne r3, #2 + 800b1f6: 6463 str r3, [r4, #68] ; 0x44 +} + 800b1f8: b005 add sp, #20 + 800b1fa: bdf0 pop {r4, r5, r6, r7, pc} + status = HAL_ERROR; + 800b1fc: 2001 movs r0, #1 + 800b1fe: e7fb b.n 800b1f8 + 800b200: f8e0f8f4 .word 0xf8e0f8f4 + +0800b204 : +{ + 800b204: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800b208: 4605 mov r5, r0 + 800b20a: b085 sub sp, #20 + 800b20c: 460c mov r4, r1 + 800b20e: 9202 str r2, [sp, #8] + uint32_t tickstart = HAL_GetTick(); + 800b210: f7fc f8e4 bl 80073dc + state = hospi->State; + 800b214: 6c6a ldr r2, [r5, #68] ; 0x44 + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800b216: 2a02 cmp r2, #2 + uint32_t tickstart = HAL_GetTick(); + 800b218: ee07 0a90 vmov s15, r0 + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800b21c: d105 bne.n 800b22a + 800b21e: 68ea ldr r2, [r5, #12] + 800b220: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + 800b224: d107 bne.n 800b236 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b226: 2310 movs r3, #16 + 800b228: e109 b.n 800b43e + if (((state == HAL_OSPI_STATE_READY) && (hospi->Init.MemoryType != HAL_OSPI_MEMTYPE_HYPERBUS)) || + 800b22a: 2a14 cmp r2, #20 + 800b22c: f040 8084 bne.w 800b338 + ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) || + 800b230: 6822 ldr r2, [r4, #0] + 800b232: 2a02 cmp r2, #2 + ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG))) + 800b234: d1f7 bne.n 800b226 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); + 800b236: 9a02 ldr r2, [sp, #8] + 800b238: 9200 str r2, [sp, #0] + 800b23a: ee17 3a90 vmov r3, s15 + 800b23e: 2200 movs r2, #0 + 800b240: 2120 movs r1, #32 + 800b242: 4628 mov r0, r5 + 800b244: edcd 7a03 vstr s15, [sp, #12] + 800b248: f7ff ff4a bl 800b0e0 + if (status == HAL_OK) + 800b24c: eddd 7a03 vldr s15, [sp, #12] + 800b250: 2800 cmp r0, #0 + 800b252: f040 80b9 bne.w 800b3c8 +{ + HAL_StatusTypeDef status = HAL_OK; + __IO uint32_t *ccr_reg, *tcr_reg, *ir_reg, *abr_reg; + + /* Re-initialize the value of the functional mode */ + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); + 800b256: 6829 ldr r1, [r5, #0] + hospi->ErrorCode = HAL_OSPI_ERROR_NONE; + 800b258: 64a8 str r0, [r5, #72] ; 0x48 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, 0U); + 800b25a: 680a ldr r2, [r1, #0] + 800b25c: f022 5240 bic.w r2, r2, #805306368 ; 0x30000000 + 800b260: 600a str r2, [r1, #0] + + /* Configure the flash ID */ + if (hospi->Init.DualQuad == HAL_OSPI_DUALQUAD_DISABLE) + 800b262: 68aa ldr r2, [r5, #8] + 800b264: b92a cbnz r2, 800b272 + { + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FSEL, cmd->FlashId); + 800b266: 680a ldr r2, [r1, #0] + 800b268: 6866 ldr r6, [r4, #4] + 800b26a: f022 0280 bic.w r2, r2, #128 ; 0x80 + 800b26e: 4332 orrs r2, r6 + 800b270: 600a str r2, [r1, #0] + } + + if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) + 800b272: 6822 ldr r2, [r4, #0] + ir_reg = &(hospi->Instance->IR); + abr_reg = &(hospi->Instance->ABR); + } + + /* Configure the CCR register with DQS and SIOO modes */ + *ccr_reg = (cmd->DQSMode | cmd->SIOOMode); + 800b274: e9d4 6712 ldrd r6, r7, [r4, #72] ; 0x48 + if (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG) + 800b278: 2a02 cmp r2, #2 + ccr_reg = &(hospi->Instance->WCCR); + 800b27a: bf0c ite eq + 800b27c: f501 72c0 addeq.w r2, r1, #384 ; 0x180 + ccr_reg = &(hospi->Instance->CCR); + 800b280: f501 7280 addne.w r2, r1, #256 ; 0x100 + *ccr_reg = (cmd->DQSMode | cmd->SIOOMode); + 800b284: ea46 0607 orr.w r6, r6, r7 + 800b288: 6016 str r6, [r2, #0] + + if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) + 800b28a: 6ae6 ldr r6, [r4, #44] ; 0x2c + tcr_reg = &(hospi->Instance->WTCR); + 800b28c: bf03 ittte eq + 800b28e: f501 7cc4 addeq.w ip, r1, #392 ; 0x188 + ir_reg = &(hospi->Instance->WIR); + 800b292: f501 7ec8 addeq.w lr, r1, #400 ; 0x190 + abr_reg = &(hospi->Instance->WABR); + 800b296: f501 78d0 addeq.w r8, r1, #416 ; 0x1a0 + tcr_reg = &(hospi->Instance->TCR); + 800b29a: f501 7c84 addne.w ip, r1, #264 ; 0x108 + ir_reg = &(hospi->Instance->IR); + 800b29e: bf1c itt ne + 800b2a0: f501 7e88 addne.w lr, r1, #272 ; 0x110 + abr_reg = &(hospi->Instance->ABR); + 800b2a4: f501 7890 addne.w r8, r1, #288 ; 0x120 + if (cmd->AlternateBytesMode != HAL_OSPI_ALTERNATE_BYTES_NONE) + 800b2a8: b16e cbz r6, 800b2c6 + { + /* Configure the ABR register with alternate bytes value */ + *abr_reg = cmd->AlternateBytes; + 800b2aa: 6aa6 ldr r6, [r4, #40] ; 0x28 + 800b2ac: f8c8 6000 str.w r6, [r8] + + /* Configure the CCR register with alternate bytes communication parameters */ + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ABMODE | OCTOSPI_CCR_ABDTR | OCTOSPI_CCR_ABSIZE), + 800b2b0: 6ae3 ldr r3, [r4, #44] ; 0x2c + 800b2b2: 6b67 ldr r7, [r4, #52] ; 0x34 + 800b2b4: 6816 ldr r6, [r2, #0] + 800b2b6: 431f orrs r7, r3 + 800b2b8: 6b23 ldr r3, [r4, #48] ; 0x30 + 800b2ba: f426 187c bic.w r8, r6, #4128768 ; 0x3f0000 + 800b2be: 431f orrs r7, r3 + 800b2c0: ea47 0708 orr.w r7, r7, r8 + 800b2c4: 6017 str r7, [r2, #0] + (cmd->AlternateBytesMode | cmd->AlternateBytesDtrMode | cmd->AlternateBytesSize)); + } + + /* Configure the TCR register with the number of dummy cycles */ + MODIFY_REG((*tcr_reg), OCTOSPI_TCR_DCYC, cmd->DummyCycles); + 800b2c6: f8dc 7000 ldr.w r7, [ip] + 800b2ca: 6c66 ldr r6, [r4, #68] ; 0x44 + 800b2cc: f027 071f bic.w r7, r7, #31 + 800b2d0: 433e orrs r6, r7 + 800b2d2: f8cc 6000 str.w r6, [ip] + + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b2d6: f8d4 c038 ldr.w ip, [r4, #56] ; 0x38 + 800b2da: f1bc 0f00 cmp.w ip, #0 + 800b2de: d004 beq.n 800b2ea + { + if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) + 800b2e0: 6827 ldr r7, [r4, #0] + 800b2e2: b917 cbnz r7, 800b2ea + { + /* Configure the DLR register with the number of data */ + hospi->Instance->DLR = (cmd->NbData - 1U); + 800b2e4: 6be7 ldr r7, [r4, #60] ; 0x3c + 800b2e6: 3f01 subs r7, #1 + 800b2e8: 640f str r7, [r1, #64] ; 0x40 + } + } + + if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) + 800b2ea: 68e6 ldr r6, [r4, #12] + { + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b2ec: 69e7 ldr r7, [r4, #28] + if (cmd->InstructionMode != HAL_OSPI_INSTRUCTION_NONE) + 800b2ee: 2e00 cmp r6, #0 + 800b2f0: f000 8082 beq.w 800b3f8 + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + { + /* ---- Command with instruction, address and data ---- */ + + /* Configure the CCR register with all communication parameters */ + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b2f4: e9d4 8904 ldrd r8, r9, [r4, #16] + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b2f8: 2f00 cmp r7, #0 + 800b2fa: d040 beq.n 800b37e + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b2fc: e9d4 ab08 ldrd sl, fp, [r4, #32] + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b300: f1bc 0f00 cmp.w ip, #0 + 800b304: d01e beq.n 800b344 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b306: ea4c 0606 orr.w r6, ip, r6 + 800b30a: 433e orrs r6, r7 + 800b30c: ea46 0909 orr.w r9, r6, r9 + 800b310: ea49 0808 orr.w r8, r9, r8 + 800b314: 6813 ldr r3, [r2, #0] + 800b316: 6c26 ldr r6, [r4, #64] ; 0x40 + 800b318: 4f52 ldr r7, [pc, #328] ; (800b464 ) + 800b31a: ea48 0b0b orr.w fp, r8, fp + 800b31e: ea4b 0b0a orr.w fp, fp, sl + 800b322: ea4b 0606 orr.w r6, fp, r6 + 800b326: 401f ands r7, r3 + 800b328: 433e orrs r6, r7 + + /* The DHQC bit is linked with DDTR bit which should be activated */ + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + (cmd->InstructionDtrMode == HAL_OSPI_INSTRUCTION_DTR_ENABLE)) + { + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b32a: 6016 str r6, [r2, #0] + } + } + + /* Configure the IR register with the instruction value */ + *ir_reg = cmd->Instruction; + 800b32c: 68a2 ldr r2, [r4, #8] + 800b32e: f8ce 2000 str.w r2, [lr] + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), + (cmd->AddressMode | cmd->AddressDtrMode | cmd->AddressSize)); + } + + /* Configure the AR register with the instruction value */ + hospi->Instance->AR = cmd->Address; + 800b332: 69a2 ldr r2, [r4, #24] + 800b334: 648a str r2, [r1, #72] ; 0x48 + if (status == HAL_OK) + 800b336: e038 b.n 800b3aa + ((state == HAL_OSPI_STATE_READ_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_WRITE_CFG)) || + 800b338: 2a24 cmp r2, #36 ; 0x24 + 800b33a: f47f af74 bne.w 800b226 + ((state == HAL_OSPI_STATE_WRITE_CMD_CFG) && (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG))) + 800b33e: 6822 ldr r2, [r4, #0] + 800b340: 2a01 cmp r2, #1 + 800b342: e777 b.n 800b234 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b344: 433e orrs r6, r7 + 800b346: f8d2 c000 ldr.w ip, [r2] + 800b34a: ea46 0609 orr.w r6, r6, r9 + 800b34e: ea46 0608 orr.w r6, r6, r8 + 800b352: ea46 060b orr.w r6, r6, fp + 800b356: f42c 5c7c bic.w ip, ip, #16128 ; 0x3f00 + 800b35a: ea46 060a orr.w r6, r6, sl + 800b35e: f02c 0c3f bic.w ip, ip, #63 ; 0x3f + 800b362: ea46 060c orr.w r6, r6, ip + 800b366: 6016 str r6, [r2, #0] + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + 800b368: 6aae ldr r6, [r5, #40] ; 0x28 + 800b36a: f1b6 5f80 cmp.w r6, #268435456 ; 0x10000000 + 800b36e: d1dd bne.n 800b32c + 800b370: 6966 ldr r6, [r4, #20] + 800b372: 2e08 cmp r6, #8 + 800b374: d1da bne.n 800b32c + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b376: 6816 ldr r6, [r2, #0] + 800b378: f046 6600 orr.w r6, r6, #134217728 ; 0x8000000 + 800b37c: e7d5 b.n 800b32a + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b37e: f1bc 0f00 cmp.w ip, #0 + 800b382: d024 beq.n 800b3ce + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b384: ea4c 0106 orr.w r1, ip, r6 + 800b388: 6817 ldr r7, [r2, #0] + 800b38a: 6c26 ldr r6, [r4, #64] ; 0x40 + 800b38c: ea41 0109 orr.w r1, r1, r9 + 800b390: ea41 0108 orr.w r1, r1, r8 + 800b394: f027 6a70 bic.w sl, r7, #251658240 ; 0xf000000 + 800b398: 4331 orrs r1, r6 + 800b39a: f02a 0a3f bic.w sl, sl, #63 ; 0x3f + 800b39e: ea41 010a orr.w r1, r1, sl + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b3a2: 6011 str r1, [r2, #0] + *ir_reg = cmd->Instruction; + 800b3a4: 68a2 ldr r2, [r4, #8] + 800b3a6: f8ce 2000 str.w r2, [lr] + if (cmd->DataMode == HAL_OSPI_DATA_NONE) + 800b3aa: 6ba2 ldr r2, [r4, #56] ; 0x38 + 800b3ac: 2a00 cmp r2, #0 + 800b3ae: d149 bne.n 800b444 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); + 800b3b0: 9b02 ldr r3, [sp, #8] + 800b3b2: 9300 str r3, [sp, #0] + 800b3b4: 2201 movs r2, #1 + 800b3b6: ee17 3a90 vmov r3, s15 + 800b3ba: 2102 movs r1, #2 + 800b3bc: 4628 mov r0, r5 + 800b3be: f7ff fe8f bl 800b0e0 + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); + 800b3c2: 682b ldr r3, [r5, #0] + 800b3c4: 2202 movs r2, #2 + 800b3c6: 625a str r2, [r3, #36] ; 0x24 +} + 800b3c8: b005 add sp, #20 + 800b3ca: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE), + 800b3ce: 6811 ldr r1, [r2, #0] + 800b3d0: ea46 0609 orr.w r6, r6, r9 + 800b3d4: ea46 0808 orr.w r8, r6, r8 + 800b3d8: f021 063f bic.w r6, r1, #63 ; 0x3f + 800b3dc: ea48 0606 orr.w r6, r8, r6 + 800b3e0: 6016 str r6, [r2, #0] + if ((hospi->Init.DelayHoldQuarterCycle == HAL_OSPI_DHQC_ENABLE) && + 800b3e2: 6aa9 ldr r1, [r5, #40] ; 0x28 + 800b3e4: f1b1 5f80 cmp.w r1, #268435456 ; 0x10000000 + 800b3e8: d1dc bne.n 800b3a4 + 800b3ea: 6961 ldr r1, [r4, #20] + 800b3ec: 2908 cmp r1, #8 + 800b3ee: d1d9 bne.n 800b3a4 + MODIFY_REG((*ccr_reg), OCTOSPI_CCR_DDTR, HAL_OSPI_DATA_DTR_ENABLE); + 800b3f0: 6811 ldr r1, [r2, #0] + 800b3f2: f041 6100 orr.w r1, r1, #134217728 ; 0x8000000 + 800b3f6: e7d4 b.n 800b3a2 + if (cmd->AddressMode != HAL_OSPI_ADDRESS_NONE) + 800b3f8: b307 cbz r7, 800b43c + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_IMODE | OCTOSPI_CCR_IDTR | OCTOSPI_CCR_ISIZE | + 800b3fa: e9d4 9808 ldrd r9, r8, [r4, #32] + if (cmd->DataMode != HAL_OSPI_DATA_NONE) + 800b3fe: f1bc 0f00 cmp.w ip, #0 + 800b402: d011 beq.n 800b428 + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE | + 800b404: f8d2 e000 ldr.w lr, [r2] + 800b408: 6c23 ldr r3, [r4, #64] ; 0x40 + 800b40a: ea4c 0607 orr.w r6, ip, r7 + 800b40e: ea46 0608 orr.w r6, r6, r8 + 800b412: ea46 0609 orr.w r6, r6, r9 + 800b416: f02e 6e70 bic.w lr, lr, #251658240 ; 0xf000000 + 800b41a: 431e orrs r6, r3 + 800b41c: f42e 5e7c bic.w lr, lr, #16128 ; 0x3f00 + 800b420: ea46 060e orr.w r6, r6, lr + MODIFY_REG((*ccr_reg), (OCTOSPI_CCR_ADMODE | OCTOSPI_CCR_ADDTR | OCTOSPI_CCR_ADSIZE), + 800b424: 6016 str r6, [r2, #0] + 800b426: e784 b.n 800b332 + 800b428: f8d2 c000 ldr.w ip, [r2] + 800b42c: ea48 0607 orr.w r6, r8, r7 + 800b430: ea46 0609 orr.w r6, r6, r9 + 800b434: f42c 577c bic.w r7, ip, #16128 ; 0x3f00 + 800b438: 433e orrs r6, r7 + 800b43a: e7f3 b.n 800b424 + } + else + { + /* ---- Invalid command configuration (no instruction, no address) ---- */ + status = HAL_ERROR; + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; + 800b43c: 2308 movs r3, #8 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b43e: 64ab str r3, [r5, #72] ; 0x48 + status = HAL_ERROR; + 800b440: 2001 movs r0, #1 + 800b442: e7c1 b.n 800b3c8 + if (cmd->OperationType == HAL_OSPI_OPTYPE_COMMON_CFG) + 800b444: 6823 ldr r3, [r4, #0] + 800b446: b90b cbnz r3, 800b44c + hospi->State = HAL_OSPI_STATE_CMD_CFG; + 800b448: 2304 movs r3, #4 + 800b44a: e005 b.n 800b458 + else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) + 800b44c: 2b01 cmp r3, #1 + if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG) + 800b44e: 6c6b ldr r3, [r5, #68] ; 0x44 + else if (cmd->OperationType == HAL_OSPI_OPTYPE_READ_CFG) + 800b450: d104 bne.n 800b45c + if (hospi->State == HAL_OSPI_STATE_WRITE_CMD_CFG) + 800b452: 2b24 cmp r3, #36 ; 0x24 + 800b454: d0f8 beq.n 800b448 + hospi->State = HAL_OSPI_STATE_READ_CMD_CFG; + 800b456: 2314 movs r3, #20 + hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG; + 800b458: 646b str r3, [r5, #68] ; 0x44 + 800b45a: e7b5 b.n 800b3c8 + if (hospi->State == HAL_OSPI_STATE_READ_CMD_CFG) + 800b45c: 2b14 cmp r3, #20 + 800b45e: d0f3 beq.n 800b448 + hospi->State = HAL_OSPI_STATE_WRITE_CMD_CFG; + 800b460: 2324 movs r3, #36 ; 0x24 + 800b462: e7f9 b.n 800b458 + 800b464: f0ffc0c0 .word 0xf0ffc0c0 + +0800b468 : +{ + 800b468: b5f0 push {r4, r5, r6, r7, lr} + 800b46a: 4604 mov r4, r0 + 800b46c: b085 sub sp, #20 + 800b46e: 460f mov r7, r1 + 800b470: 4616 mov r6, r2 + uint32_t tickstart = HAL_GetTick(); + 800b472: f7fb ffb3 bl 80073dc + __IO uint32_t *data_reg = &hospi->Instance->DR; + 800b476: 6825 ldr r5, [r4, #0] + uint32_t tickstart = HAL_GetTick(); + 800b478: 4603 mov r3, r0 + uint32_t addr_reg = hospi->Instance->AR; + 800b47a: 6ca8 ldr r0, [r5, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b47c: f8d5 c110 ldr.w ip, [r5, #272] ; 0x110 + if (pData == NULL) + 800b480: b91f cbnz r7, 800b48a + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_PARAM; + 800b482: 2308 movs r3, #8 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b484: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b486: 2001 movs r0, #1 + 800b488: e034 b.n 800b4f4 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b48a: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b48c: 2a04 cmp r2, #4 + 800b48e: d13b bne.n 800b508 + hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; + 800b490: 6c2a ldr r2, [r5, #64] ; 0x40 + hospi->pBuffPtr = pData; + 800b492: 6367 str r7, [r4, #52] ; 0x34 + hospi->XferCount = READ_REG(hospi->Instance->DLR) + 1U; + 800b494: 3201 adds r2, #1 + 800b496: 63e2 str r2, [r4, #60] ; 0x3c + hospi->XferSize = hospi->XferCount; + 800b498: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b49a: 63a2 str r2, [r4, #56] ; 0x38 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b49c: 6829 ldr r1, [r5, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b49e: 68e2 ldr r2, [r4, #12] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b4a0: f021 5140 bic.w r1, r1, #805306368 ; 0x30000000 + 800b4a4: f041 5180 orr.w r1, r1, #268435456 ; 0x10000000 + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b4a8: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FMODE, OSPI_FUNCTIONAL_MODE_INDIRECT_READ); + 800b4ac: 6029 str r1, [r5, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b4ae: d123 bne.n 800b4f8 + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b4b0: 64a8 str r0, [r5, #72] ; 0x48 + status = OSPI_WaitFlagStateUntilTimeout(hospi, (HAL_OSPI_FLAG_FT | HAL_OSPI_FLAG_TC), SET, tickstart, Timeout); + 800b4b2: 9600 str r6, [sp, #0] + 800b4b4: 2201 movs r2, #1 + 800b4b6: 2106 movs r1, #6 + 800b4b8: 4620 mov r0, r4 + 800b4ba: 9303 str r3, [sp, #12] + 800b4bc: f7ff fe10 bl 800b0e0 + if (status != HAL_OK) + 800b4c0: b9c0 cbnz r0, 800b4f4 + *hospi->pBuffPtr = *((__IO uint8_t *)data_reg); + 800b4c2: 6b62 ldr r2, [r4, #52] ; 0x34 + 800b4c4: f895 1050 ldrb.w r1, [r5, #80] ; 0x50 + 800b4c8: 7011 strb r1, [r2, #0] + hospi->pBuffPtr++; + 800b4ca: 6b62 ldr r2, [r4, #52] ; 0x34 + } while(hospi->XferCount > 0U); + 800b4cc: 9b03 ldr r3, [sp, #12] + hospi->pBuffPtr++; + 800b4ce: 3201 adds r2, #1 + 800b4d0: 6362 str r2, [r4, #52] ; 0x34 + hospi->XferCount--; + 800b4d2: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b4d4: 3a01 subs r2, #1 + 800b4d6: 63e2 str r2, [r4, #60] ; 0x3c + } while(hospi->XferCount > 0U); + 800b4d8: 6be2 ldr r2, [r4, #60] ; 0x3c + 800b4da: 2a00 cmp r2, #0 + 800b4dc: d1e9 bne.n 800b4b2 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_TC, SET, tickstart, Timeout); + 800b4de: 9600 str r6, [sp, #0] + 800b4e0: 2201 movs r2, #1 + 800b4e2: 2102 movs r1, #2 + 800b4e4: 4620 mov r0, r4 + 800b4e6: f7ff fdfb bl 800b0e0 + if (status == HAL_OK) + 800b4ea: b918 cbnz r0, 800b4f4 + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TC); + 800b4ec: 6822 ldr r2, [r4, #0] + 800b4ee: 2302 movs r3, #2 + 800b4f0: 6253 str r3, [r2, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_READY; + 800b4f2: 6463 str r3, [r4, #68] ; 0x44 +} + 800b4f4: b005 add sp, #20 + 800b4f6: bdf0 pop {r4, r5, r6, r7, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b4f8: f8d5 2100 ldr.w r2, [r5, #256] ; 0x100 + 800b4fc: f412 6fe0 tst.w r2, #1792 ; 0x700 + 800b500: d1d6 bne.n 800b4b0 + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b502: f8c5 c110 str.w ip, [r5, #272] ; 0x110 + 800b506: e7d4 b.n 800b4b2 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b508: 2310 movs r3, #16 + 800b50a: e7bb b.n 800b484 + +0800b50c : +{ + 800b50c: e92d 41ff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, lr} + 800b510: 4604 mov r4, r0 + 800b512: 4616 mov r6, r2 + 800b514: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800b516: f7fb ff61 bl 80073dc + uint32_t addr_reg = hospi->Instance->AR; + 800b51a: 6822 ldr r2, [r4, #0] + 800b51c: 6c97 ldr r7, [r2, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b51e: f8d2 8110 ldr.w r8, [r2, #272] ; 0x110 + if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE)) + 800b522: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b524: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b526: 4603 mov r3, r0 + if ((hospi->State == HAL_OSPI_STATE_CMD_CFG) && (cfg->AutomaticStop == HAL_OSPI_AUTOMATIC_STOP_ENABLE)) + 800b528: d13c bne.n 800b5a4 + 800b52a: 68ea ldr r2, [r5, #12] + 800b52c: f5b2 0f80 cmp.w r2, #4194304 ; 0x400000 + 800b530: d138 bne.n 800b5a4 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, Timeout); + 800b532: 9003 str r0, [sp, #12] + 800b534: 9600 str r6, [sp, #0] + 800b536: 2200 movs r2, #0 + 800b538: 2120 movs r1, #32 + 800b53a: 4620 mov r0, r4 + 800b53c: f7ff fdd0 bl 800b0e0 + if (status == HAL_OK) + 800b540: bb28 cbnz r0, 800b58e + WRITE_REG (hospi->Instance->PSMAR, cfg->Match); + 800b542: 6822 ldr r2, [r4, #0] + 800b544: 6829 ldr r1, [r5, #0] + 800b546: f8c2 1088 str.w r1, [r2, #136] ; 0x88 + WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); + 800b54a: 6869 ldr r1, [r5, #4] + 800b54c: f8c2 1080 str.w r1, [r2, #128] ; 0x80 + WRITE_REG (hospi->Instance->PIR, cfg->Interval); + 800b550: 6929 ldr r1, [r5, #16] + 800b552: f8c2 1090 str.w r1, [r2, #144] ; 0x90 + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b556: e9d5 1502 ldrd r1, r5, [r5, #8] + 800b55a: 6810 ldr r0, [r2, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b55c: 9b03 ldr r3, [sp, #12] + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b55e: 4329 orrs r1, r5 + 800b560: f020 5043 bic.w r0, r0, #817889280 ; 0x30c00000 + 800b564: 4301 orrs r1, r0 + 800b566: f041 5100 orr.w r1, r1, #536870912 ; 0x20000000 + 800b56a: 6011 str r1, [r2, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b56c: 68e1 ldr r1, [r4, #12] + 800b56e: f1b1 6f80 cmp.w r1, #67108864 ; 0x4000000 + 800b572: d10f bne.n 800b594 + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b574: 6497 str r7, [r2, #72] ; 0x48 + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout); + 800b576: 9600 str r6, [sp, #0] + 800b578: 2201 movs r2, #1 + 800b57a: 2108 movs r1, #8 + 800b57c: 4620 mov r0, r4 + 800b57e: f7ff fdaf bl 800b0e0 + if (status == HAL_OK) + 800b582: b920 cbnz r0, 800b58e + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_SM); + 800b584: 6823 ldr r3, [r4, #0] + 800b586: 2208 movs r2, #8 + 800b588: 625a str r2, [r3, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_READY; + 800b58a: 2302 movs r3, #2 + 800b58c: 6463 str r3, [r4, #68] ; 0x44 +} + 800b58e: b004 add sp, #16 + 800b590: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b594: f8d2 1100 ldr.w r1, [r2, #256] ; 0x100 + 800b598: f411 6fe0 tst.w r1, #1792 ; 0x700 + 800b59c: d1ea bne.n 800b574 + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b59e: f8c2 8110 str.w r8, [r2, #272] ; 0x110 + 800b5a2: e7e8 b.n 800b576 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b5a4: 2310 movs r3, #16 + 800b5a6: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b5a8: 2001 movs r0, #1 + 800b5aa: e7f0 b.n 800b58e + +0800b5ac : +{ + 800b5ac: b5f7 push {r0, r1, r2, r4, r5, r6, r7, lr} + 800b5ae: 4604 mov r4, r0 + 800b5b0: 460f mov r7, r1 + uint32_t tickstart = HAL_GetTick(); + 800b5b2: f7fb ff13 bl 80073dc + uint32_t addr_reg = hospi->Instance->AR; + 800b5b6: 6822 ldr r2, [r4, #0] + 800b5b8: 6c95 ldr r5, [r2, #72] ; 0x48 + uint32_t ir_reg = hospi->Instance->IR; + 800b5ba: f8d2 6110 ldr.w r6, [r2, #272] ; 0x110 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b5be: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b5c0: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b5c2: 4603 mov r3, r0 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b5c4: d132 bne.n 800b62c + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b5c6: 6ce2 ldr r2, [r4, #76] ; 0x4c + 800b5c8: 9200 str r2, [sp, #0] + 800b5ca: 2120 movs r1, #32 + 800b5cc: 2200 movs r2, #0 + 800b5ce: 4620 mov r0, r4 + 800b5d0: f7ff fd86 bl 800b0e0 + if (status == HAL_OK) + 800b5d4: bb00 cbnz r0, 800b618 + WRITE_REG (hospi->Instance->PSMAR, cfg->Match); + 800b5d6: 6823 ldr r3, [r4, #0] + 800b5d8: 683a ldr r2, [r7, #0] + 800b5da: f8c3 2088 str.w r2, [r3, #136] ; 0x88 + WRITE_REG (hospi->Instance->PSMKR, cfg->Mask); + 800b5de: 687a ldr r2, [r7, #4] + 800b5e0: f8c3 2080 str.w r2, [r3, #128] ; 0x80 + WRITE_REG (hospi->Instance->PIR, cfg->Interval); + 800b5e4: 693a ldr r2, [r7, #16] + 800b5e6: f8c3 2090 str.w r2, [r3, #144] ; 0x90 + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_PMM | OCTOSPI_CR_APMS | OCTOSPI_CR_FMODE), + 800b5ea: e9d7 2702 ldrd r2, r7, [r7, #8] + 800b5ee: 6819 ldr r1, [r3, #0] + 800b5f0: 433a orrs r2, r7 + 800b5f2: f021 5143 bic.w r1, r1, #817889280 ; 0x30c00000 + 800b5f6: 430a orrs r2, r1 + 800b5f8: f042 5200 orr.w r2, r2, #536870912 ; 0x20000000 + 800b5fc: 601a str r2, [r3, #0] + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TE | HAL_OSPI_FLAG_SM); + 800b5fe: 2209 movs r2, #9 + 800b600: 625a str r2, [r3, #36] ; 0x24 + hospi->State = HAL_OSPI_STATE_BUSY_AUTO_POLLING; + 800b602: 2248 movs r2, #72 ; 0x48 + 800b604: 6462 str r2, [r4, #68] ; 0x44 + __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_SM | HAL_OSPI_IT_TE); + 800b606: 681a ldr r2, [r3, #0] + 800b608: f442 2210 orr.w r2, r2, #589824 ; 0x90000 + 800b60c: 601a str r2, [r3, #0] + if (hospi->Init.MemoryType == HAL_OSPI_MEMTYPE_HYPERBUS) + 800b60e: 68e2 ldr r2, [r4, #12] + 800b610: f1b2 6f80 cmp.w r2, #67108864 ; 0x4000000 + 800b614: d102 bne.n 800b61c + WRITE_REG(hospi->Instance->AR, addr_reg); + 800b616: 649d str r5, [r3, #72] ; 0x48 +} + 800b618: b003 add sp, #12 + 800b61a: bdf0 pop {r4, r5, r6, r7, pc} + if (READ_BIT(hospi->Instance->CCR, OCTOSPI_CCR_ADMODE) != HAL_OSPI_ADDRESS_NONE) + 800b61c: f8d3 2100 ldr.w r2, [r3, #256] ; 0x100 + 800b620: f412 6fe0 tst.w r2, #1792 ; 0x700 + 800b624: d1f7 bne.n 800b616 + WRITE_REG(hospi->Instance->IR, ir_reg); + 800b626: f8c3 6110 str.w r6, [r3, #272] ; 0x110 + 800b62a: e7f5 b.n 800b618 + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b62c: 2310 movs r3, #16 + 800b62e: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b630: 2001 movs r0, #1 + 800b632: e7f1 b.n 800b618 + +0800b634 : +{ + 800b634: b573 push {r0, r1, r4, r5, r6, lr} + 800b636: 4604 mov r4, r0 + 800b638: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800b63a: f7fb fecf bl 80073dc + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b63e: 6c62 ldr r2, [r4, #68] ; 0x44 + 800b640: 2a04 cmp r2, #4 + uint32_t tickstart = HAL_GetTick(); + 800b642: 4603 mov r3, r0 + if (hospi->State == HAL_OSPI_STATE_CMD_CFG) + 800b644: d121 bne.n 800b68a + status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_BUSY, RESET, tickstart, hospi->Timeout); + 800b646: 6ce2 ldr r2, [r4, #76] ; 0x4c + 800b648: 9200 str r2, [sp, #0] + 800b64a: 2120 movs r1, #32 + 800b64c: 2200 movs r2, #0 + 800b64e: 4620 mov r0, r4 + 800b650: f7ff fd46 bl 800b0e0 + if (status == HAL_OK) + 800b654: b9b8 cbnz r0, 800b686 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b656: 682e ldr r6, [r5, #0] + WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod); + 800b658: 6822 ldr r2, [r4, #0] + hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + 800b65a: 2388 movs r3, #136 ; 0x88 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b65c: 2e08 cmp r6, #8 + hospi->State = HAL_OSPI_STATE_BUSY_MEM_MAPPED; + 800b65e: 6463 str r3, [r4, #68] ; 0x44 + if (cfg->TimeOutActivation == HAL_OSPI_TIMEOUT_COUNTER_ENABLE) + 800b660: d108 bne.n 800b674 + WRITE_REG(hospi->Instance->LPTR, cfg->TimeOutPeriod); + 800b662: 686b ldr r3, [r5, #4] + 800b664: f8c2 3130 str.w r3, [r2, #304] ; 0x130 + __HAL_OSPI_CLEAR_FLAG(hospi, HAL_OSPI_FLAG_TO); + 800b668: 2310 movs r3, #16 + 800b66a: 6253 str r3, [r2, #36] ; 0x24 + __HAL_OSPI_ENABLE_IT(hospi, HAL_OSPI_IT_TO); + 800b66c: 6811 ldr r1, [r2, #0] + 800b66e: f441 1180 orr.w r1, r1, #1048576 ; 0x100000 + 800b672: 6011 str r1, [r2, #0] + MODIFY_REG(hospi->Instance->CR, (OCTOSPI_CR_TCEN | OCTOSPI_CR_FMODE), + 800b674: 6813 ldr r3, [r2, #0] + 800b676: f023 5340 bic.w r3, r3, #805306368 ; 0x30000000 + 800b67a: f023 0308 bic.w r3, r3, #8 + 800b67e: 4333 orrs r3, r6 + 800b680: f043 5340 orr.w r3, r3, #805306368 ; 0x30000000 + 800b684: 6013 str r3, [r2, #0] +} + 800b686: b002 add sp, #8 + 800b688: bd70 pop {r4, r5, r6, pc} + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b68a: 2310 movs r3, #16 + 800b68c: 64a3 str r3, [r4, #72] ; 0x48 + status = HAL_ERROR; + 800b68e: 2001 movs r0, #1 + 800b690: e7f9 b.n 800b686 + +0800b692 : + if ((hospi->State & OSPI_BUSY_STATE_MASK) == 0U) + 800b692: 6c43 ldr r3, [r0, #68] ; 0x44 + 800b694: f013 0308 ands.w r3, r3, #8 + 800b698: d10a bne.n 800b6b0 + hospi->Init.FifoThreshold = Threshold; + 800b69a: 6041 str r1, [r0, #4] + MODIFY_REG(hospi->Instance->CR, OCTOSPI_CR_FTHRES, ((hospi->Init.FifoThreshold-1U) << OCTOSPI_CR_FTHRES_Pos)); + 800b69c: 6800 ldr r0, [r0, #0] + 800b69e: 6802 ldr r2, [r0, #0] + 800b6a0: 3901 subs r1, #1 + 800b6a2: f422 52f8 bic.w r2, r2, #7936 ; 0x1f00 + 800b6a6: ea42 2101 orr.w r1, r2, r1, lsl #8 + 800b6aa: 6001 str r1, [r0, #0] + HAL_StatusTypeDef status = HAL_OK; + 800b6ac: 4618 mov r0, r3 + 800b6ae: 4770 bx lr + hospi->ErrorCode = HAL_OSPI_ERROR_INVALID_SEQUENCE; + 800b6b0: 2310 movs r3, #16 + 800b6b2: 6483 str r3, [r0, #72] ; 0x48 + status = HAL_ERROR; + 800b6b4: 2001 movs r0, #1 +} + 800b6b6: 4770 bx lr + +0800b6b8 : + return ((READ_BIT(hospi->Instance->CR, OCTOSPI_CR_FTHRES) >> OCTOSPI_CR_FTHRES_Pos) + 1U); + 800b6b8: 6803 ldr r3, [r0, #0] + 800b6ba: 6818 ldr r0, [r3, #0] + 800b6bc: f3c0 2004 ubfx r0, r0, #8, #5 +} + 800b6c0: 3001 adds r0, #1 + 800b6c2: 4770 bx lr + +0800b6c4 : + hospi->Timeout = Timeout; + 800b6c4: 64c1 str r1, [r0, #76] ; 0x4c +} + 800b6c6: 2000 movs r0, #0 + 800b6c8: 4770 bx lr + +0800b6ca : + return hospi->ErrorCode; + 800b6ca: 6c80 ldr r0, [r0, #72] ; 0x48 +} + 800b6cc: 4770 bx lr + +0800b6ce : + return hospi->State; + 800b6ce: 6c40 ldr r0, [r0, #68] ; 0x44 +} + 800b6d0: 4770 bx lr + ... + +0800b6d4 : +{ + 800b6d4: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + if (hospi->Instance == OCTOSPI1) + 800b6d8: 6802 ldr r2, [r0, #0] + other_instance = 0U; + 800b6da: 4bbf ldr r3, [pc, #764] ; (800b9d8 ) + * @retval HAL status + */ +static HAL_StatusTypeDef OSPIM_GetConfig(uint8_t instance_nb, OSPIM_CfgTypeDef *cfg) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t reg, value = 0U; + 800b6dc: f8df 8304 ldr.w r8, [pc, #772] ; 800b9e4 + other_instance = 0U; + 800b6e0: 429a cmp r2, r3 +{ + 800b6e2: b08b sub sp, #44 ; 0x2c + } + + /* Get the information about the instance */ + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + { + reg = OCTOSPIM->PCR[index]; + 800b6e4: 4bbd ldr r3, [pc, #756] ; (800b9dc ) + other_instance = 0U; + 800b6e6: bf0b itete eq + 800b6e8: f04f 0a01 moveq.w sl, #1 + 800b6ec: f04f 0a00 movne.w sl, #0 + 800b6f0: 2000 moveq r0, #0 + 800b6f2: 2001 movne r0, #1 + for (index = 0U; index < OSPI_NB_INSTANCE; index++) + 800b6f4: 466a mov r2, sp + instance = 1U; + 800b6f6: 2501 movs r5, #1 + cfg->ClkPort = 0U; + 800b6f8: 2700 movs r7, #0 + cfg->DQSPort = 0U; + 800b6fa: e9c2 7700 strd r7, r7, [r2] + cfg->IOLowPort = 0U; + 800b6fe: e9c2 7702 strd r7, r7, [r2, #8] + uint32_t reg, value = 0U; + 800b702: 2d02 cmp r5, #2 + 800b704: bf0c ite eq + 800b706: 46c4 moveq ip, r8 + 800b708: f04f 0c00 movne.w ip, #0 + cfg->IOHighPort = 0U; + 800b70c: 6117 str r7, [r2, #16] + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + 800b70e: f04f 0e00 mov.w lr, #0 + reg = OCTOSPIM->PCR[index]; + 800b712: eb03 048e add.w r4, r3, lr, lsl #2 + { + /* The clock is enabled on this port */ + if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC)) + { + /* The clock correspond to the instance passed as parameter */ + cfg->ClkPort = index+1U; + 800b716: f10e 0601 add.w r6, lr, #1 + reg = OCTOSPIM->PCR[index]; + 800b71a: 6864 ldr r4, [r4, #4] + if ((reg & OCTOSPIM_PCR_CLKEN) != 0U) + 800b71c: f014 0f01 tst.w r4, #1 + 800b720: d005 beq.n 800b72e + if ((reg & OCTOSPIM_PCR_CLKSRC) == (value & OCTOSPIM_PCR_CLKSRC)) + 800b722: ea84 0e0c eor.w lr, r4, ip + 800b726: f01e 0f02 tst.w lr, #2 + cfg->ClkPort = index+1U; + 800b72a: bf08 it eq + 800b72c: 6016 streq r6, [r2, #0] + } + } + + if ((reg & OCTOSPIM_PCR_DQSEN) != 0U) + 800b72e: f014 0f10 tst.w r4, #16 + 800b732: d005 beq.n 800b740 + { + /* The DQS is enabled on this port */ + if ((reg & OCTOSPIM_PCR_DQSSRC) == (value & OCTOSPIM_PCR_DQSSRC)) + 800b734: ea84 0e0c eor.w lr, r4, ip + 800b738: f01e 0f20 tst.w lr, #32 + { + /* The DQS correspond to the instance passed as parameter */ + cfg->DQSPort = index+1U; + 800b73c: bf08 it eq + 800b73e: 6056 streq r6, [r2, #4] + } + } + + if ((reg & OCTOSPIM_PCR_NCSEN) != 0U) + 800b740: f414 7f80 tst.w r4, #256 ; 0x100 + 800b744: d005 beq.n 800b752 + { + /* The nCS is enabled on this port */ + if ((reg & OCTOSPIM_PCR_NCSSRC) == (value & OCTOSPIM_PCR_NCSSRC)) + 800b746: ea84 0e0c eor.w lr, r4, ip + 800b74a: f41e 7f00 tst.w lr, #512 ; 0x200 + { + /* The nCS correspond to the instance passed as parameter */ + cfg->NCSPort = index+1U; + 800b74e: bf08 it eq + 800b750: 6096 streq r6, [r2, #8] + } + } + + if ((reg & OCTOSPIM_PCR_IOLEN) != 0U) + 800b752: f414 3f80 tst.w r4, #65536 ; 0x10000 + 800b756: d00d beq.n 800b774 + { + /* The IO Low is enabled on this port */ + if ((reg & OCTOSPIM_PCR_IOLSRC_1) == (value & OCTOSPIM_PCR_IOLSRC_1)) + 800b758: ea84 0e0c eor.w lr, r4, ip + 800b75c: f41e 2f80 tst.w lr, #262144 ; 0x40000 + 800b760: d108 bne.n 800b774 + { + /* The IO Low correspond to the instance passed as parameter */ + if ((reg & OCTOSPIM_PCR_IOLSRC_0) == 0U) + 800b762: f414 3f00 tst.w r4, #131072 ; 0x20000 + { + cfg->IOLowPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); + 800b766: bf0c ite eq + 800b768: f446 3e80 orreq.w lr, r6, #65536 ; 0x10000 + } + else + { + cfg->IOLowPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); + 800b76c: f046 7e80 orrne.w lr, r6, #16777216 ; 0x1000000 + 800b770: f8c2 e00c str.w lr, [r2, #12] + } + } + } + + if ((reg & OCTOSPIM_PCR_IOHEN) != 0U) + 800b774: f014 7f80 tst.w r4, #16777216 ; 0x1000000 + 800b778: d00b beq.n 800b792 + { + /* The IO High is enabled on this port */ + if ((reg & OCTOSPIM_PCR_IOHSRC_1) == (value & OCTOSPIM_PCR_IOHSRC_1)) + 800b77a: ea84 0e0c eor.w lr, r4, ip + 800b77e: f01e 6f80 tst.w lr, #67108864 ; 0x4000000 + 800b782: d106 bne.n 800b792 + { + /* The IO High correspond to the instance passed as parameter */ + if ((reg & OCTOSPIM_PCR_IOHSRC_0) == 0U) + 800b784: 01a4 lsls r4, r4, #6 + { + cfg->IOHighPort = (OCTOSPIM_PCR_IOLEN | (index+1U)); + 800b786: bf54 ite pl + 800b788: f446 3480 orrpl.w r4, r6, #65536 ; 0x10000 + } + else + { + cfg->IOHighPort = (OCTOSPIM_PCR_IOHEN | (index+1U)); + 800b78c: f046 7480 orrmi.w r4, r6, #16777216 ; 0x1000000 + 800b790: 6114 str r4, [r2, #16] + for (index = 0U; index < OSPI_IOM_NB_PORTS; index ++) + 800b792: 2e02 cmp r6, #2 + 800b794: f04f 0e01 mov.w lr, #1 + 800b798: d1bb bne.n 800b712 + for (index = 0U; index < OSPI_NB_INSTANCE; index++) + 800b79a: 2d02 cmp r5, #2 + 800b79c: f102 0214 add.w r2, r2, #20 + 800b7a0: f040 8117 bne.w 800b9d2 + if ((OCTOSPI1->CR & OCTOSPI_CR_EN) != 0U) + 800b7a4: 4c8c ldr r4, [pc, #560] ; (800b9d8 ) + 800b7a6: 6825 ldr r5, [r4, #0] + 800b7a8: ea15 050e ands.w r5, r5, lr + CLEAR_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); + 800b7ac: bf1e ittt ne + 800b7ae: 6822 ldrne r2, [r4, #0] + 800b7b0: f022 0201 bicne.w r2, r2, #1 + 800b7b4: 6022 strne r2, [r4, #0] + if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U) + 800b7b6: 4a8a ldr r2, [pc, #552] ; (800b9e0 ) + 800b7b8: 6814 ldr r4, [r2, #0] + ospi_enabled |= 0x1U; + 800b7ba: bf18 it ne + 800b7bc: 4675 movne r5, lr + if ((OCTOSPI2->CR & OCTOSPI_CR_EN) != 0U) + 800b7be: 07e6 lsls r6, r4, #31 + CLEAR_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b7c0: bf42 ittt mi + 800b7c2: 6814 ldrmi r4, [r2, #0] + 800b7c4: f024 0401 bicmi.w r4, r4, #1 + 800b7c8: 6014 strmi r4, [r2, #0] + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b7ca: aa0a add r2, sp, #40 ; 0x28 + 800b7cc: f04f 0414 mov.w r4, #20 + 800b7d0: fb04 2400 mla r4, r4, r0, r2 + ospi_enabled |= 0x2U; + 800b7d4: bf48 it mi + 800b7d6: f045 0b02 orrmi.w fp, r5, #2 + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b7da: f854 2c20 ldr.w r2, [r4, #-32] + 800b7de: f102 32ff add.w r2, r2, #4294967295 ; 0xffffffff + 800b7e2: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b7e6: bf58 it pl + 800b7e8: 46ab movpl fp, r5 + 800b7ea: 6856 ldr r6, [r2, #4] + 800b7ec: f426 7680 bic.w r6, r6, #256 ; 0x100 + 800b7f0: 6056 str r6, [r2, #4] + if (IOM_cfg[instance].ClkPort != 0U) + 800b7f2: f854 2c28 ldr.w r2, [r4, #-40] + 800b7f6: b382 cbz r2, 800b85a + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); + 800b7f8: 3a01 subs r2, #1 + 800b7fa: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b7fe: 6856 ldr r6, [r2, #4] + 800b800: f026 0601 bic.w r6, r6, #1 + 800b804: 6056 str r6, [r2, #4] + if (IOM_cfg[instance].DQSPort != 0U) + 800b806: f854 2c24 ldr.w r2, [r4, #-36] + 800b80a: b132 cbz r2, 800b81a + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); + 800b80c: 3a01 subs r2, #1 + 800b80e: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b812: 6854 ldr r4, [r2, #4] + 800b814: f024 0410 bic.w r4, r4, #16 + 800b818: 6054 str r4, [r2, #4] + if (IOM_cfg[instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b81a: 2214 movs r2, #20 + 800b81c: ac0a add r4, sp, #40 ; 0x28 + 800b81e: fb02 4200 mla r2, r2, r0, r4 + 800b822: f852 2c1c ldr.w r2, [r2, #-28] + 800b826: b142 cbz r2, 800b83a + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN); + 800b828: 3a01 subs r2, #1 + 800b82a: f002 0201 and.w r2, r2, #1 + 800b82e: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b832: 6854 ldr r4, [r2, #4] + 800b834: f424 3480 bic.w r4, r4, #65536 ; 0x10000 + 800b838: 6054 str r4, [r2, #4] + if (IOM_cfg[instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800b83a: 2214 movs r2, #20 + 800b83c: ac0a add r4, sp, #40 ; 0x28 + 800b83e: fb02 4200 mla r2, r2, r0, r4 + 800b842: f852 2c18 ldr.w r2, [r2, #-24] + 800b846: b142 cbz r2, 800b85a + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN); + 800b848: 3a01 subs r2, #1 + 800b84a: f002 0201 and.w r2, r2, #1 + 800b84e: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b852: 6854 ldr r4, [r2, #4] + 800b854: f024 7480 bic.w r4, r4, #16777216 ; 0x1000000 + 800b858: 6054 str r4, [r2, #4] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b85a: aa0a add r2, sp, #40 ; 0x28 + 800b85c: f04f 0914 mov.w r9, #20 + 800b860: fb09 290a mla r9, r9, sl, r2 + 800b864: f8d1 c000 ldr.w ip, [r1] + 800b868: f859 8c28 ldr.w r8, [r9, #-40] + (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) + 800b86c: f859 4c18 ldr.w r4, [r9, #-24] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b870: 45c4 cmp ip, r8 + (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) || + 800b872: e9d1 6e01 ldrd r6, lr, [r1, #4] + (cfg->IOHighPort == IOM_cfg[other_instance].IOHighPort)) + 800b876: e9d1 2103 ldrd r2, r1, [r1, #12] + if ((cfg->ClkPort == IOM_cfg[other_instance].ClkPort) || (cfg->DQSPort == IOM_cfg[other_instance].DQSPort) || + 800b87a: d00d beq.n 800b898 + 800b87c: f859 7c24 ldr.w r7, [r9, #-36] + 800b880: 42b7 cmp r7, r6 + 800b882: d009 beq.n 800b898 + 800b884: f859 7c20 ldr.w r7, [r9, #-32] + 800b888: 45be cmp lr, r7 + 800b88a: d005 beq.n 800b898 + (cfg->NCSPort == IOM_cfg[other_instance].NCSPort) || (cfg->IOLowPort == IOM_cfg[other_instance].IOLowPort) || + 800b88c: f859 7c1c ldr.w r7, [r9, #-28] + 800b890: 4297 cmp r7, r2 + 800b892: d001 beq.n 800b898 + 800b894: 428c cmp r4, r1 + 800b896: d142 bne.n 800b91e + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].ClkPort-1U)], OCTOSPIM_PCR_CLKEN); + 800b898: f108 38ff add.w r8, r8, #4294967295 ; 0xffffffff + 800b89c: eb03 0888 add.w r8, r3, r8, lsl #2 + 800b8a0: f8d8 7004 ldr.w r7, [r8, #4] + 800b8a4: f027 0701 bic.w r7, r7, #1 + 800b8a8: f8c8 7004 str.w r7, [r8, #4] + if (IOM_cfg[other_instance].DQSPort != 0U) + 800b8ac: 2714 movs r7, #20 + 800b8ae: f10d 0828 add.w r8, sp, #40 ; 0x28 + 800b8b2: fb07 870a mla r7, r7, sl, r8 + 800b8b6: f857 7c24 ldr.w r7, [r7, #-36] + 800b8ba: b147 cbz r7, 800b8ce + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].DQSPort-1U)], OCTOSPIM_PCR_DQSEN); + 800b8bc: 3f01 subs r7, #1 + 800b8be: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b8c2: f8d7 8004 ldr.w r8, [r7, #4] + 800b8c6: f028 0810 bic.w r8, r8, #16 + 800b8ca: f8c7 8004 str.w r8, [r7, #4] + CLEAR_BIT(OCTOSPIM->PCR[(IOM_cfg[other_instance].NCSPort-1U)], OCTOSPIM_PCR_NCSEN); + 800b8ce: 2714 movs r7, #20 + 800b8d0: f10d 0828 add.w r8, sp, #40 ; 0x28 + 800b8d4: fb07 8a0a mla sl, r7, sl, r8 + 800b8d8: f85a 7c20 ldr.w r7, [sl, #-32] + 800b8dc: 3f01 subs r7, #1 + 800b8de: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b8e2: f8d7 8004 ldr.w r8, [r7, #4] + 800b8e6: f428 7880 bic.w r8, r8, #256 ; 0x100 + 800b8ea: f8c7 8004 str.w r8, [r7, #4] + if (IOM_cfg[other_instance].IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b8ee: f85a 7c1c ldr.w r7, [sl, #-28] + 800b8f2: b157 cbz r7, 800b90a + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOLowPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOLEN); + 800b8f4: 3f01 subs r7, #1 + 800b8f6: f007 0701 and.w r7, r7, #1 + 800b8fa: eb03 0787 add.w r7, r3, r7, lsl #2 + 800b8fe: f8d7 8004 ldr.w r8, [r7, #4] + 800b902: f428 3880 bic.w r8, r8, #65536 ; 0x10000 + 800b906: f8c7 8004 str.w r8, [r7, #4] + if (IOM_cfg[other_instance].IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800b90a: b144 cbz r4, 800b91e + CLEAR_BIT(OCTOSPIM->PCR[((IOM_cfg[other_instance].IOHighPort-1U)& OSPI_IOM_PORT_MASK)], OCTOSPIM_PCR_IOHEN); + 800b90c: 3c01 subs r4, #1 + 800b90e: f004 0401 and.w r4, r4, #1 + 800b912: eb03 0484 add.w r4, r3, r4, lsl #2 + 800b916: 6867 ldr r7, [r4, #4] + 800b918: f027 7780 bic.w r7, r7, #16777216 ; 0x1000000 + 800b91c: 6067 str r7, [r4, #4] + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b91e: f10e 3eff add.w lr, lr, #4294967295 ; 0xffffffff + 800b922: eb03 0e8e add.w lr, r3, lr, lsl #2 + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b926: f10c 3cff add.w ip, ip, #4294967295 ; 0xffffffff + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b92a: f8de 4004 ldr.w r4, [lr, #4] + 800b92e: f424 7440 bic.w r4, r4, #768 ; 0x300 + 800b932: ea44 2440 orr.w r4, r4, r0, lsl #9 + 800b936: f444 7480 orr.w r4, r4, #256 ; 0x100 + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b93a: eb03 0c8c add.w ip, r3, ip, lsl #2 + MODIFY_REG(OCTOSPIM->PCR[(cfg->NCSPort-1U)], (OCTOSPIM_PCR_NCSEN | OCTOSPIM_PCR_NCSSRC), (OCTOSPIM_PCR_NCSEN | (instance << OCTOSPIM_PCR_NCSSRC_Pos))); + 800b93e: f8ce 4004 str.w r4, [lr, #4] + MODIFY_REG(OCTOSPIM->PCR[(cfg->ClkPort-1U)], (OCTOSPIM_PCR_CLKEN | OCTOSPIM_PCR_CLKSRC), (OCTOSPIM_PCR_CLKEN | (instance << OCTOSPIM_PCR_CLKSRC_Pos))); + 800b942: f8dc 4004 ldr.w r4, [ip, #4] + 800b946: f024 0403 bic.w r4, r4, #3 + 800b94a: ea44 0440 orr.w r4, r4, r0, lsl #1 + 800b94e: f044 0401 orr.w r4, r4, #1 + 800b952: f8cc 4004 str.w r4, [ip, #4] + if (cfg->DQSPort != 0U) + 800b956: b156 cbz r6, 800b96e + MODIFY_REG(OCTOSPIM->PCR[(cfg->DQSPort-1U)], (OCTOSPIM_PCR_DQSEN | OCTOSPIM_PCR_DQSSRC), (OCTOSPIM_PCR_DQSEN | (instance << OCTOSPIM_PCR_DQSSRC_Pos))); + 800b958: 3e01 subs r6, #1 + 800b95a: eb03 0686 add.w r6, r3, r6, lsl #2 + 800b95e: 6874 ldr r4, [r6, #4] + 800b960: f024 0430 bic.w r4, r4, #48 ; 0x30 + 800b964: ea44 1440 orr.w r4, r4, r0, lsl #5 + 800b968: f044 0410 orr.w r4, r4, #16 + 800b96c: 6074 str r4, [r6, #4] + if ((cfg->IOLowPort & OCTOSPIM_PCR_IOLEN) != 0U) + 800b96e: 03d4 lsls r4, r2, #15 + 800b970: d53a bpl.n 800b9e8 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), + 800b972: 3a01 subs r2, #1 + 800b974: f002 0201 and.w r2, r2, #1 + 800b978: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b97c: 6854 ldr r4, [r2, #4] + 800b97e: f424 24e0 bic.w r4, r4, #458752 ; 0x70000 + 800b982: ea44 4480 orr.w r4, r4, r0, lsl #18 + 800b986: f444 3480 orr.w r4, r4, #65536 ; 0x10000 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b98a: 6054 str r4, [r2, #4] + if ((cfg->IOHighPort & OCTOSPIM_PCR_IOLEN) != 0U) + 800b98c: 03ca lsls r2, r1, #15 + 800b98e: d53a bpl.n 800ba06 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOLEN | OCTOSPIM_PCR_IOLSRC), + 800b990: 3901 subs r1, #1 + 800b992: f001 0101 and.w r1, r1, #1 + 800b996: eb03 0381 add.w r3, r3, r1, lsl #2 + 800b99a: 685a ldr r2, [r3, #4] + 800b99c: f422 22e0 bic.w r2, r2, #458752 ; 0x70000 + 800b9a0: ea42 4080 orr.w r0, r2, r0, lsl #18 + 800b9a4: f440 3040 orr.w r0, r0, #196608 ; 0x30000 + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b9a8: 6058 str r0, [r3, #4] + if ((ospi_enabled & 0x1U) != 0U) + 800b9aa: b125 cbz r5, 800b9b6 + SET_BIT(OCTOSPI1->CR, OCTOSPI_CR_EN); + 800b9ac: 4a0a ldr r2, [pc, #40] ; (800b9d8 ) + 800b9ae: 6813 ldr r3, [r2, #0] + 800b9b0: f043 0301 orr.w r3, r3, #1 + 800b9b4: 6013 str r3, [r2, #0] + if ((ospi_enabled & 0x2U) != 0U) + 800b9b6: f01b 0f02 tst.w fp, #2 + SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b9ba: bf1c itt ne + 800b9bc: 4a08 ldrne r2, [pc, #32] ; (800b9e0 ) + 800b9be: 6813 ldrne r3, [r2, #0] +} + 800b9c0: f04f 0000 mov.w r0, #0 + SET_BIT(OCTOSPI2->CR, OCTOSPI_CR_EN); + 800b9c4: bf1c itt ne + 800b9c6: f043 0301 orrne.w r3, r3, #1 + 800b9ca: 6013 strne r3, [r2, #0] +} + 800b9cc: b00b add sp, #44 ; 0x2c + 800b9ce: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + 800b9d2: 4635 mov r5, r6 + 800b9d4: e691 b.n 800b6fa + 800b9d6: bf00 nop + 800b9d8: a0001000 .word 0xa0001000 + 800b9dc: 50061c00 .word 0x50061c00 + 800b9e0: a0001400 .word 0xa0001400 + 800b9e4: 04040222 .word 0x04040222 + else if (cfg->IOLowPort != HAL_OSPIM_IOPORT_NONE) + 800b9e8: 2a00 cmp r2, #0 + 800b9ea: d0cf beq.n 800b98c + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOLowPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800b9ec: 3a01 subs r2, #1 + 800b9ee: f002 0201 and.w r2, r2, #1 + 800b9f2: eb03 0282 add.w r2, r3, r2, lsl #2 + 800b9f6: 6854 ldr r4, [r2, #4] + 800b9f8: f024 64e0 bic.w r4, r4, #117440512 ; 0x7000000 + 800b9fc: ea44 6480 orr.w r4, r4, r0, lsl #26 + 800ba00: f044 7480 orr.w r4, r4, #16777216 ; 0x1000000 + 800ba04: e7c1 b.n 800b98a + else if (cfg->IOHighPort != HAL_OSPIM_IOPORT_NONE) + 800ba06: 2900 cmp r1, #0 + 800ba08: d0cf beq.n 800b9aa + MODIFY_REG(OCTOSPIM->PCR[((cfg->IOHighPort-1U)& OSPI_IOM_PORT_MASK)], (OCTOSPIM_PCR_IOHEN | OCTOSPIM_PCR_IOHSRC), + 800ba0a: 3901 subs r1, #1 + 800ba0c: f001 0101 and.w r1, r1, #1 + 800ba10: eb03 0381 add.w r3, r3, r1, lsl #2 + 800ba14: 685a ldr r2, [r3, #4] + 800ba16: f022 62e0 bic.w r2, r2, #117440512 ; 0x7000000 + 800ba1a: ea42 6080 orr.w r0, r2, r0, lsl #26 + 800ba1e: f040 7040 orr.w r0, r0, #50331648 ; 0x3000000 + 800ba22: e7c1 b.n 800b9a8 + +0800ba24 : + * @arg @ref I2C_GENERATE_START_WRITE Generate Restart for write request. + * @retval None + */ +static void I2C_TransferConfig(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t Size, uint32_t Mode, + uint32_t Request) +{ + 800ba24: b530 push {r4, r5, lr} + 800ba26: 9d03 ldr r5, [sp, #12] + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_TRANSFER_MODE(Mode)); + assert_param(IS_TRANSFER_REQUEST(Request)); + + /* update CR2 register */ + MODIFY_REG(hi2c->Instance->CR2, + 800ba28: 6804 ldr r4, [r0, #0] + 800ba2a: ea45 4202 orr.w r2, r5, r2, lsl #16 + 800ba2e: 431a orrs r2, r3 + 800ba30: 4b05 ldr r3, [pc, #20] ; (800ba48 ) + 800ba32: 6860 ldr r0, [r4, #4] + 800ba34: f3c1 0109 ubfx r1, r1, #0, #10 + 800ba38: ea43 5355 orr.w r3, r3, r5, lsr #21 + 800ba3c: 430a orrs r2, r1 + 800ba3e: ea20 0003 bic.w r0, r0, r3 + 800ba42: 4302 orrs r2, r0 + 800ba44: 6062 str r2, [r4, #4] + ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \ + (I2C_CR2_RD_WRN & (uint32_t)(Request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \ + (uint32_t)(((uint32_t)DevAddress & I2C_CR2_SADD) | + (((uint32_t)Size << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)Mode | (uint32_t)Request)); +} + 800ba46: bd30 pop {r4, r5, pc} + 800ba48: 03ff63ff .word 0x03ff63ff + +0800ba4c : + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800ba4c: 6803 ldr r3, [r0, #0] +{ + 800ba4e: b570 push {r4, r5, r6, lr} + 800ba50: 4604 mov r4, r0 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800ba52: 6998 ldr r0, [r3, #24] + 800ba54: f010 0010 ands.w r0, r0, #16 +{ + 800ba58: 460d mov r5, r1 + 800ba5a: 4616 mov r6, r2 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + 800ba5c: d116 bne.n 800ba8c +} + 800ba5e: bd70 pop {r4, r5, r6, pc} + if (Timeout != HAL_MAX_DELAY) + 800ba60: 1c6a adds r2, r5, #1 + 800ba62: d014 beq.n 800ba8e + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800ba64: f7fb fcba bl 80073dc + 800ba68: 1b80 subs r0, r0, r6 + 800ba6a: 4285 cmp r5, r0 + 800ba6c: d300 bcc.n 800ba70 + 800ba6e: b96d cbnz r5, 800ba8c + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800ba70: 6c63 ldr r3, [r4, #68] ; 0x44 + 800ba72: f043 0320 orr.w r3, r3, #32 + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + 800ba76: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800ba78: 2320 movs r3, #32 + 800ba7a: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800ba7e: 2300 movs r3, #0 + 800ba80: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800ba84: f884 3040 strb.w r3, [r4, #64] ; 0x40 + return HAL_ERROR; + 800ba88: 2001 movs r0, #1 + 800ba8a: e7e8 b.n 800ba5e + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + 800ba8c: 6823 ldr r3, [r4, #0] + 800ba8e: 699a ldr r2, [r3, #24] + 800ba90: 0690 lsls r0, r2, #26 + 800ba92: d5e5 bpl.n 800ba60 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + 800ba94: 2210 movs r2, #16 + 800ba96: 61da str r2, [r3, #28] + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800ba98: 2220 movs r2, #32 + 800ba9a: 61da str r2, [r3, #28] + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) != RESET) + 800ba9c: 699a ldr r2, [r3, #24] + 800ba9e: 0791 lsls r1, r2, #30 + hi2c->Instance->TXDR = 0x00U; + 800baa0: bf44 itt mi + 800baa2: 2200 movmi r2, #0 + 800baa4: 629a strmi r2, [r3, #40] ; 0x28 + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + 800baa6: 699a ldr r2, [r3, #24] + 800baa8: 07d2 lsls r2, r2, #31 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_TXE); + 800baaa: bf5e ittt pl + 800baac: 699a ldrpl r2, [r3, #24] + 800baae: f042 0201 orrpl.w r2, r2, #1 + 800bab2: 619a strpl r2, [r3, #24] + I2C_RESET_CR2(hi2c); + 800bab4: 685a ldr r2, [r3, #4] + 800bab6: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800baba: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800babe: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800bac2: f022 0201 bic.w r2, r2, #1 + 800bac6: 605a str r2, [r3, #4] + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + 800bac8: 6c63 ldr r3, [r4, #68] ; 0x44 + 800baca: f043 0304 orr.w r3, r3, #4 + 800bace: e7d2 b.n 800ba76 + +0800bad0 : +{ + 800bad0: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800bad4: 9f06 ldr r7, [sp, #24] + 800bad6: 4604 mov r4, r0 + 800bad8: 4688 mov r8, r1 + 800bada: 4616 mov r6, r2 + 800badc: 461d mov r5, r3 + while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status) + 800bade: 6822 ldr r2, [r4, #0] + 800bae0: 6993 ldr r3, [r2, #24] + 800bae2: ea38 0303 bics.w r3, r8, r3 + 800bae6: bf0c ite eq + 800bae8: 2301 moveq r3, #1 + 800baea: 2300 movne r3, #0 + 800baec: 42b3 cmp r3, r6 + 800baee: d001 beq.n 800baf4 + return HAL_OK; + 800baf0: 2000 movs r0, #0 + 800baf2: e015 b.n 800bb20 + if (Timeout != HAL_MAX_DELAY) + 800baf4: 1c6b adds r3, r5, #1 + 800baf6: d0f3 beq.n 800bae0 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800baf8: f7fb fc70 bl 80073dc + 800bafc: 1bc0 subs r0, r0, r7 + 800bafe: 42a8 cmp r0, r5 + 800bb00: d801 bhi.n 800bb06 + 800bb02: 2d00 cmp r5, #0 + 800bb04: d1eb bne.n 800bade + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800bb06: 6c63 ldr r3, [r4, #68] ; 0x44 + 800bb08: f043 0320 orr.w r3, r3, #32 + 800bb0c: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bb0e: 2320 movs r3, #32 + 800bb10: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bb14: 2300 movs r3, #0 + 800bb16: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800bb1a: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800bb1e: 2001 movs r0, #1 +} + 800bb20: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + +0800bb24 : +{ + 800bb24: b570 push {r4, r5, r6, lr} + 800bb26: 4604 mov r4, r0 + 800bb28: 460d mov r5, r1 + 800bb2a: 4616 mov r6, r2 + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + 800bb2c: 6823 ldr r3, [r4, #0] + 800bb2e: 699b ldr r3, [r3, #24] + 800bb30: 069b lsls r3, r3, #26 + 800bb32: d501 bpl.n 800bb38 + return HAL_OK; + 800bb34: 2000 movs r0, #0 +} + 800bb36: bd70 pop {r4, r5, r6, pc} + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800bb38: 4632 mov r2, r6 + 800bb3a: 4629 mov r1, r5 + 800bb3c: 4620 mov r0, r4 + 800bb3e: f7ff ff85 bl 800ba4c + 800bb42: b990 cbnz r0, 800bb6a + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800bb44: f7fb fc4a bl 80073dc + 800bb48: 1b80 subs r0, r0, r6 + 800bb4a: 42a8 cmp r0, r5 + 800bb4c: d801 bhi.n 800bb52 + 800bb4e: 2d00 cmp r5, #0 + 800bb50: d1ec bne.n 800bb2c + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800bb52: 6c63 ldr r3, [r4, #68] ; 0x44 + 800bb54: f043 0320 orr.w r3, r3, #32 + 800bb58: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bb5a: 2320 movs r3, #32 + 800bb5c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bb60: 2300 movs r3, #0 + 800bb62: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800bb66: f884 3040 strb.w r3, [r4, #64] ; 0x40 + return HAL_ERROR; + 800bb6a: 2001 movs r0, #1 + 800bb6c: e7e3 b.n 800bb36 + +0800bb6e : +} + 800bb6e: 4770 bx lr + +0800bb70 : +{ + 800bb70: b510 push {r4, lr} + if (hi2c == NULL) + 800bb72: 4604 mov r4, r0 + 800bb74: 2800 cmp r0, #0 + 800bb76: d04a beq.n 800bc0e + if (hi2c->State == HAL_I2C_STATE_RESET) + 800bb78: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 + 800bb7c: f003 02ff and.w r2, r3, #255 ; 0xff + 800bb80: b91b cbnz r3, 800bb8a + hi2c->Lock = HAL_UNLOCKED; + 800bb82: f880 2040 strb.w r2, [r0, #64] ; 0x40 + HAL_I2C_MspInit(hi2c); + 800bb86: f7ff fff2 bl 800bb6e + hi2c->State = HAL_I2C_STATE_BUSY; + 800bb8a: 2324 movs r3, #36 ; 0x24 + 800bb8c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + __HAL_I2C_DISABLE(hi2c); + 800bb90: 6823 ldr r3, [r4, #0] + 800bb92: 681a ldr r2, [r3, #0] + 800bb94: f022 0201 bic.w r2, r2, #1 + 800bb98: 601a str r2, [r3, #0] + hi2c->Instance->TIMINGR = hi2c->Init.Timing & TIMING_CLEAR_MASK; + 800bb9a: 6862 ldr r2, [r4, #4] + 800bb9c: f022 6270 bic.w r2, r2, #251658240 ; 0xf000000 + 800bba0: 611a str r2, [r3, #16] + hi2c->Instance->OAR1 &= ~I2C_OAR1_OA1EN; + 800bba2: 689a ldr r2, [r3, #8] + 800bba4: f422 4200 bic.w r2, r2, #32768 ; 0x8000 + 800bba8: 609a str r2, [r3, #8] + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + 800bbaa: e9d4 2102 ldrd r2, r1, [r4, #8] + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + 800bbae: 2901 cmp r1, #1 + 800bbb0: d124 bne.n 800bbfc + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | hi2c->Init.OwnAddress1); + 800bbb2: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 800bbb6: 609a str r2, [r3, #8] + hi2c->Instance->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK); + 800bbb8: 685a ldr r2, [r3, #4] + 800bbba: f042 7200 orr.w r2, r2, #33554432 ; 0x2000000 + 800bbbe: f442 4200 orr.w r2, r2, #32768 ; 0x8000 + 800bbc2: 605a str r2, [r3, #4] + hi2c->Instance->OAR2 &= ~I2C_DUALADDRESS_ENABLE; + 800bbc4: 68da ldr r2, [r3, #12] + 800bbc6: f422 4200 bic.w r2, r2, #32768 ; 0x8000 + 800bbca: 60da str r2, [r3, #12] + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2 | (hi2c->Init.OwnAddress2Masks << 8)); + 800bbcc: e9d4 2104 ldrd r2, r1, [r4, #16] + 800bbd0: 430a orrs r2, r1 + 800bbd2: 69a1 ldr r1, [r4, #24] + 800bbd4: ea42 2201 orr.w r2, r2, r1, lsl #8 + 800bbd8: 60da str r2, [r3, #12] + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + 800bbda: e9d4 2107 ldrd r2, r1, [r4, #28] + 800bbde: 430a orrs r2, r1 + 800bbe0: 601a str r2, [r3, #0] + __HAL_I2C_ENABLE(hi2c); + 800bbe2: 681a ldr r2, [r3, #0] + 800bbe4: f042 0201 orr.w r2, r2, #1 + 800bbe8: 601a str r2, [r3, #0] + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800bbea: 2000 movs r0, #0 + hi2c->State = HAL_I2C_STATE_READY; + 800bbec: 2320 movs r3, #32 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800bbee: 6460 str r0, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bbf0: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->PreviousState = I2C_STATE_NONE; + 800bbf4: 6320 str r0, [r4, #48] ; 0x30 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bbf6: f884 0042 strb.w r0, [r4, #66] ; 0x42 +} + 800bbfa: bd10 pop {r4, pc} + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + 800bbfc: f442 4204 orr.w r2, r2, #33792 ; 0x8400 + if (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + 800bc00: 2902 cmp r1, #2 + hi2c->Instance->OAR1 = (I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE | hi2c->Init.OwnAddress1); + 800bc02: 609a str r2, [r3, #8] + hi2c->Instance->CR2 = (I2C_CR2_ADD10); + 800bc04: bf04 itt eq + 800bc06: f44f 6200 moveq.w r2, #2048 ; 0x800 + 800bc0a: 605a streq r2, [r3, #4] + 800bc0c: e7d4 b.n 800bbb8 + return HAL_ERROR; + 800bc0e: 2001 movs r0, #1 + 800bc10: e7f3 b.n 800bbfa + +0800bc12 : + 800bc12: 4770 bx lr + +0800bc14 : +{ + 800bc14: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + 800bc18: 4698 mov r8, r3 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bc1a: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 +{ + 800bc1e: 9f0a ldr r7, [sp, #40] ; 0x28 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bc20: 2b20 cmp r3, #32 +{ + 800bc22: 4604 mov r4, r0 + 800bc24: 460e mov r6, r1 + 800bc26: 4691 mov r9, r2 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bc28: f040 80a3 bne.w 800bd72 + __HAL_LOCK(hi2c); + 800bc2c: f890 3040 ldrb.w r3, [r0, #64] ; 0x40 + 800bc30: 2b01 cmp r3, #1 + 800bc32: f000 809e beq.w 800bd72 + 800bc36: f04f 0a01 mov.w sl, #1 + 800bc3a: f880 a040 strb.w sl, [r0, #64] ; 0x40 + tickstart = HAL_GetTick(); + 800bc3e: f7fb fbcd bl 80073dc + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800bc42: 2319 movs r3, #25 + tickstart = HAL_GetTick(); + 800bc44: 4605 mov r5, r0 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800bc46: 9000 str r0, [sp, #0] + 800bc48: 4652 mov r2, sl + 800bc4a: f44f 4100 mov.w r1, #32768 ; 0x8000 + 800bc4e: 4620 mov r0, r4 + 800bc50: f7ff ff3e bl 800bad0 + 800bc54: b118 cbz r0, 800bc5e + return HAL_ERROR; + 800bc56: 2001 movs r0, #1 +} + 800bc58: b002 add sp, #8 + 800bc5a: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hi2c->State = HAL_I2C_STATE_BUSY_TX; + 800bc5e: 2321 movs r3, #33 ; 0x21 + 800bc60: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_MASTER; + 800bc64: 2310 movs r3, #16 + 800bc66: f884 3042 strb.w r3, [r4, #66] ; 0x42 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800bc6a: 6460 str r0, [r4, #68] ; 0x44 + hi2c->XferCount = Size; + 800bc6c: f8a4 802a strh.w r8, [r4, #42] ; 0x2a + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bc70: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->pBuffPtr = pData; + 800bc72: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bc76: b29b uxth r3, r3 + 800bc78: 2bff cmp r3, #255 ; 0xff + hi2c->XferISR = NULL; + 800bc7a: 6360 str r0, [r4, #52] ; 0x34 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bc7c: 4b3e ldr r3, [pc, #248] ; (800bd78 ) + 800bc7e: d927 bls.n 800bcd0 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800bc80: 22ff movs r2, #255 ; 0xff + 800bc82: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE); + 800bc84: 9300 str r3, [sp, #0] + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bc86: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bc8a: 4631 mov r1, r6 + 800bc8c: 4620 mov r0, r4 + 800bc8e: f7ff fec9 bl 800ba24 + while (hi2c->XferCount > 0U) + 800bc92: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bc94: b29b uxth r3, r3 + 800bc96: 2b00 cmp r3, #0 + 800bc98: d13e bne.n 800bd18 + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + 800bc9a: 462a mov r2, r5 + 800bc9c: 4639 mov r1, r7 + 800bc9e: 4620 mov r0, r4 + 800bca0: f7ff ff40 bl 800bb24 + 800bca4: 2800 cmp r0, #0 + 800bca6: d1d6 bne.n 800bc56 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800bca8: 6823 ldr r3, [r4, #0] + 800bcaa: 2120 movs r1, #32 + 800bcac: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800bcae: 685a ldr r2, [r3, #4] + 800bcb0: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800bcb4: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800bcb8: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800bcbc: f022 0201 bic.w r2, r2, #1 + 800bcc0: 605a str r2, [r3, #4] + hi2c->State = HAL_I2C_STATE_READY; + 800bcc2: f884 1041 strb.w r1, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800bcc6: f884 0040 strb.w r0, [r4, #64] ; 0x40 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bcca: f884 0042 strb.w r0, [r4, #66] ; 0x42 + return HAL_OK; + 800bcce: e7c3 b.n 800bc58 + hi2c->XferSize = hi2c->XferCount; + 800bcd0: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE); + 800bcd2: 9300 str r3, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800bcd4: b292 uxth r2, r2 + 800bcd6: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bcd8: f04f 7300 mov.w r3, #33554432 ; 0x2000000 + 800bcdc: b2d2 uxtb r2, r2 + 800bcde: e7d4 b.n 800bc8a + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800bce0: 462a mov r2, r5 + 800bce2: 4639 mov r1, r7 + 800bce4: 4620 mov r0, r4 + 800bce6: f7ff feb1 bl 800ba4c + 800bcea: 2800 cmp r0, #0 + 800bcec: d1b3 bne.n 800bc56 + if (Timeout != HAL_MAX_DELAY) + 800bcee: 1c7a adds r2, r7, #1 + 800bcf0: d012 beq.n 800bd18 + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800bcf2: f7fb fb73 bl 80073dc + 800bcf6: 1b40 subs r0, r0, r5 + 800bcf8: 4287 cmp r7, r0 + 800bcfa: d300 bcc.n 800bcfe + 800bcfc: b967 cbnz r7, 800bd18 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800bcfe: 6c63 ldr r3, [r4, #68] ; 0x44 + 800bd00: f043 0320 orr.w r3, r3, #32 + 800bd04: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800bd06: 2320 movs r3, #32 + 800bd08: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800bd0c: 2300 movs r3, #0 + 800bd0e: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800bd12: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800bd16: e79e b.n 800bc56 + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXIS) == RESET) + 800bd18: 6822 ldr r2, [r4, #0] + 800bd1a: 6993 ldr r3, [r2, #24] + 800bd1c: 079b lsls r3, r3, #30 + 800bd1e: d5df bpl.n 800bce0 + hi2c->Instance->TXDR = *hi2c->pBuffPtr; + 800bd20: 6a63 ldr r3, [r4, #36] ; 0x24 + 800bd22: f813 1b01 ldrb.w r1, [r3], #1 + 800bd26: 6291 str r1, [r2, #40] ; 0x28 + hi2c->pBuffPtr++; + 800bd28: 6263 str r3, [r4, #36] ; 0x24 + hi2c->XferCount--; + 800bd2a: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800bd2c: 8d22 ldrh r2, [r4, #40] ; 0x28 + hi2c->XferCount--; + 800bd2e: 3b01 subs r3, #1 + 800bd30: b29b uxth r3, r3 + 800bd32: 8563 strh r3, [r4, #42] ; 0x2a + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bd34: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800bd36: 3a01 subs r2, #1 + 800bd38: b292 uxth r2, r2 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bd3a: b29b uxth r3, r3 + hi2c->XferSize--; + 800bd3c: 8522 strh r2, [r4, #40] ; 0x28 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bd3e: 2b00 cmp r3, #0 + 800bd40: d0a7 beq.n 800bc92 + 800bd42: 2a00 cmp r2, #0 + 800bd44: d1a5 bne.n 800bc92 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + 800bd46: 9500 str r5, [sp, #0] + 800bd48: 463b mov r3, r7 + 800bd4a: 2180 movs r1, #128 ; 0x80 + 800bd4c: 4620 mov r0, r4 + 800bd4e: f7ff febf bl 800bad0 + 800bd52: 2800 cmp r0, #0 + 800bd54: f47f af7f bne.w 800bc56 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bd58: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bd5a: b29b uxth r3, r3 + 800bd5c: 2bff cmp r3, #255 ; 0xff + 800bd5e: d903 bls.n 800bd68 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800bd60: 22ff movs r2, #255 ; 0xff + 800bd62: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bd64: 9000 str r0, [sp, #0] + 800bd66: e78e b.n 800bc86 + hi2c->XferSize = hi2c->XferCount; + 800bd68: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bd6a: 9000 str r0, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800bd6c: b292 uxth r2, r2 + 800bd6e: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bd70: e7b2 b.n 800bcd8 + return HAL_BUSY; + 800bd72: 2002 movs r0, #2 + 800bd74: e770 b.n 800bc58 + 800bd76: bf00 nop + 800bd78: 80002000 .word 0x80002000 + +0800bd7c : +{ + 800bd7c: e92d 47f3 stmdb sp!, {r0, r1, r4, r5, r6, r7, r8, r9, sl, lr} + 800bd80: 4698 mov r8, r3 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bd82: f890 3041 ldrb.w r3, [r0, #65] ; 0x41 +{ + 800bd86: 9f0a ldr r7, [sp, #40] ; 0x28 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bd88: 2b20 cmp r3, #32 +{ + 800bd8a: 4604 mov r4, r0 + 800bd8c: 460e mov r6, r1 + 800bd8e: 4691 mov r9, r2 + if (hi2c->State == HAL_I2C_STATE_READY) + 800bd90: f040 80be bne.w 800bf10 + __HAL_LOCK(hi2c); + 800bd94: f890 3040 ldrb.w r3, [r0, #64] ; 0x40 + 800bd98: 2b01 cmp r3, #1 + 800bd9a: f000 80b9 beq.w 800bf10 + 800bd9e: f04f 0a01 mov.w sl, #1 + 800bda2: f880 a040 strb.w sl, [r0, #64] ; 0x40 + tickstart = HAL_GetTick(); + 800bda6: f7fb fb19 bl 80073dc + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800bdaa: 2319 movs r3, #25 + tickstart = HAL_GetTick(); + 800bdac: 4605 mov r5, r0 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK) + 800bdae: 9000 str r0, [sp, #0] + 800bdb0: 4652 mov r2, sl + 800bdb2: f44f 4100 mov.w r1, #32768 ; 0x8000 + 800bdb6: 4620 mov r0, r4 + 800bdb8: f7ff fe8a bl 800bad0 + 800bdbc: b118 cbz r0, 800bdc6 + return HAL_ERROR; + 800bdbe: 2001 movs r0, #1 +} + 800bdc0: b002 add sp, #8 + 800bdc2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hi2c->State = HAL_I2C_STATE_BUSY_RX; + 800bdc6: 2322 movs r3, #34 ; 0x22 + 800bdc8: f884 3041 strb.w r3, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_MASTER; + 800bdcc: 2310 movs r3, #16 + 800bdce: f884 3042 strb.w r3, [r4, #66] ; 0x42 + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800bdd2: 6460 str r0, [r4, #68] ; 0x44 + hi2c->XferCount = Size; + 800bdd4: f8a4 802a strh.w r8, [r4, #42] ; 0x2a + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bdd8: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->pBuffPtr = pData; + 800bdda: f8c4 9024 str.w r9, [r4, #36] ; 0x24 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bdde: b29b uxth r3, r3 + 800bde0: 2bff cmp r3, #255 ; 0xff + hi2c->XferISR = NULL; + 800bde2: 6360 str r0, [r4, #52] ; 0x34 + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bde4: 4b4b ldr r3, [pc, #300] ; (800bf14 ) + 800bde6: d909 bls.n 800bdfc + hi2c->XferSize = MAX_NBYTE_SIZE; + 800bde8: 22ff movs r2, #255 ; 0xff + 800bdea: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_READ); + 800bdec: 9300 str r3, [sp, #0] + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bdee: f04f 7380 mov.w r3, #16777216 ; 0x1000000 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bdf2: 4631 mov r1, r6 + 800bdf4: 4620 mov r0, r4 + 800bdf6: f7ff fe15 bl 800ba24 + 800bdfa: e052 b.n 800bea2 + hi2c->XferSize = hi2c->XferCount; + 800bdfc: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ); + 800bdfe: 9300 str r3, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800be00: b292 uxth r2, r2 + 800be02: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800be04: f04f 7300 mov.w r3, #33554432 ; 0x2000000 + 800be08: b2d2 uxtb r2, r2 + 800be0a: e7f2 b.n 800bdf2 + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800be0c: 2120 movs r1, #32 + 800be0e: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800be10: 685a ldr r2, [r3, #4] + 800be12: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800be16: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800be1a: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800be1e: f022 0201 bic.w r2, r2, #1 + 800be22: 605a str r2, [r3, #4] + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + 800be24: 2300 movs r3, #0 + 800be26: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800be28: f884 1041 strb.w r1, [r4, #65] ; 0x41 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800be2c: f884 3042 strb.w r3, [r4, #66] ; 0x42 + __HAL_UNLOCK(hi2c); + 800be30: f884 3040 strb.w r3, [r4, #64] ; 0x40 + 800be34: e7c3 b.n 800bdbe + if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U)) + 800be36: f7fb fad1 bl 80073dc + 800be3a: 1b40 subs r0, r0, r5 + 800be3c: 4287 cmp r7, r0 + 800be3e: d300 bcc.n 800be42 + 800be40: b947 cbnz r7, 800be54 + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + 800be42: 6c63 ldr r3, [r4, #68] ; 0x44 + 800be44: f043 0320 orr.w r3, r3, #32 + 800be48: 6463 str r3, [r4, #68] ; 0x44 + hi2c->State = HAL_I2C_STATE_READY; + 800be4a: 2320 movs r3, #32 + 800be4c: f884 3041 strb.w r3, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800be50: 2300 movs r3, #0 + 800be52: e7ed b.n 800be30 + while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + 800be54: 6823 ldr r3, [r4, #0] + 800be56: 699b ldr r3, [r3, #24] + 800be58: 075b lsls r3, r3, #29 + 800be5a: d410 bmi.n 800be7e + if (I2C_IsAcknowledgeFailed(hi2c, Timeout, Tickstart) != HAL_OK) + 800be5c: 462a mov r2, r5 + 800be5e: 4639 mov r1, r7 + 800be60: 4620 mov r0, r4 + 800be62: f7ff fdf3 bl 800ba4c + 800be66: 2800 cmp r0, #0 + 800be68: d1a9 bne.n 800bdbe + if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + 800be6a: 6823 ldr r3, [r4, #0] + 800be6c: 699a ldr r2, [r3, #24] + 800be6e: 0691 lsls r1, r2, #26 + 800be70: d5e1 bpl.n 800be36 + if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) && (hi2c->XferSize > 0U)) + 800be72: 699a ldr r2, [r3, #24] + 800be74: 0752 lsls r2, r2, #29 + 800be76: d5c9 bpl.n 800be0c + 800be78: 8d22 ldrh r2, [r4, #40] ; 0x28 + 800be7a: 2a00 cmp r2, #0 + 800be7c: d0c6 beq.n 800be0c + *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR; + 800be7e: 6823 ldr r3, [r4, #0] + 800be80: 6a5a ldr r2, [r3, #36] ; 0x24 + 800be82: 6a63 ldr r3, [r4, #36] ; 0x24 + 800be84: 701a strb r2, [r3, #0] + hi2c->pBuffPtr++; + 800be86: 6a63 ldr r3, [r4, #36] ; 0x24 + hi2c->XferSize--; + 800be88: 8d22 ldrh r2, [r4, #40] ; 0x28 + hi2c->pBuffPtr++; + 800be8a: 3301 adds r3, #1 + 800be8c: 6263 str r3, [r4, #36] ; 0x24 + hi2c->XferCount--; + 800be8e: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800be90: 3b01 subs r3, #1 + 800be92: b29b uxth r3, r3 + 800be94: 8563 strh r3, [r4, #42] ; 0x2a + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800be96: 8d63 ldrh r3, [r4, #42] ; 0x2a + hi2c->XferSize--; + 800be98: 3a01 subs r2, #1 + 800be9a: b292 uxth r2, r2 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800be9c: b29b uxth r3, r3 + hi2c->XferSize--; + 800be9e: 8522 strh r2, [r4, #40] ; 0x28 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bea0: b9f3 cbnz r3, 800bee0 + while (hi2c->XferCount > 0U) + 800bea2: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bea4: b29b uxth r3, r3 + 800bea6: 2b00 cmp r3, #0 + 800bea8: d1d4 bne.n 800be54 + if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + 800beaa: 462a mov r2, r5 + 800beac: 4639 mov r1, r7 + 800beae: 4620 mov r0, r4 + 800beb0: f7ff fe38 bl 800bb24 + 800beb4: 2800 cmp r0, #0 + 800beb6: d182 bne.n 800bdbe + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + 800beb8: 6823 ldr r3, [r4, #0] + 800beba: 2120 movs r1, #32 + 800bebc: 61d9 str r1, [r3, #28] + I2C_RESET_CR2(hi2c); + 800bebe: 685a ldr r2, [r3, #4] + 800bec0: f022 72ff bic.w r2, r2, #33423360 ; 0x1fe0000 + 800bec4: f422 328b bic.w r2, r2, #71168 ; 0x11600 + 800bec8: f422 72ff bic.w r2, r2, #510 ; 0x1fe + 800becc: f022 0201 bic.w r2, r2, #1 + 800bed0: 605a str r2, [r3, #4] + hi2c->State = HAL_I2C_STATE_READY; + 800bed2: f884 1041 strb.w r1, [r4, #65] ; 0x41 + __HAL_UNLOCK(hi2c); + 800bed6: f884 0040 strb.w r0, [r4, #64] ; 0x40 + hi2c->Mode = HAL_I2C_MODE_NONE; + 800beda: f884 0042 strb.w r0, [r4, #66] ; 0x42 + return HAL_OK; + 800bede: e76f b.n 800bdc0 + if ((hi2c->XferCount != 0U) && (hi2c->XferSize == 0U)) + 800bee0: 2a00 cmp r2, #0 + 800bee2: d1de bne.n 800bea2 + if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK) + 800bee4: 9500 str r5, [sp, #0] + 800bee6: 463b mov r3, r7 + 800bee8: 2180 movs r1, #128 ; 0x80 + 800beea: 4620 mov r0, r4 + 800beec: f7ff fdf0 bl 800bad0 + 800bef0: 2800 cmp r0, #0 + 800bef2: f47f af64 bne.w 800bdbe + if (hi2c->XferCount > MAX_NBYTE_SIZE) + 800bef6: 8d63 ldrh r3, [r4, #42] ; 0x2a + 800bef8: b29b uxth r3, r3 + 800befa: 2bff cmp r3, #255 ; 0xff + 800befc: d903 bls.n 800bf06 + hi2c->XferSize = MAX_NBYTE_SIZE; + 800befe: 22ff movs r2, #255 ; 0xff + 800bf00: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP); + 800bf02: 9000 str r0, [sp, #0] + 800bf04: e773 b.n 800bdee + hi2c->XferSize = hi2c->XferCount; + 800bf06: 8d62 ldrh r2, [r4, #42] ; 0x2a + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bf08: 9000 str r0, [sp, #0] + hi2c->XferSize = hi2c->XferCount; + 800bf0a: b292 uxth r2, r2 + 800bf0c: 8522 strh r2, [r4, #40] ; 0x28 + I2C_TransferConfig(hi2c, DevAddress, (uint8_t)hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP); + 800bf0e: e779 b.n 800be04 + return HAL_BUSY; + 800bf10: 2002 movs r0, #2 + 800bf12: e755 b.n 800bdc0 + 800bf14: 80002400 .word 0x80002400 + +0800bf18 : + * @param hsd Pointer to SD handle + * @param pSCR pointer to the buffer that will contain the SCR value + * @retval error state + */ +static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) +{ + 800bf18: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + 800bf1c: b086 sub sp, #24 + 800bf1e: 4605 mov r5, r0 + 800bf20: 4688 mov r8, r1 + SDMMC_DataInitTypeDef config; + uint32_t errorstate; + uint32_t tickstart = HAL_GetTick(); + 800bf22: f7fb fa5b bl 80073dc + uint32_t index = 0U; + uint32_t tempscr[2U] = {0UL, 0UL}; + uint32_t *scr = pSCR; + + /* Set Block Size To 8 Bytes */ + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U); + 800bf26: 2108 movs r1, #8 + uint32_t tickstart = HAL_GetTick(); + 800bf28: 4681 mov r9, r0 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8U); + 800bf2a: 6828 ldr r0, [r5, #0] + 800bf2c: f001 f996 bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800bf30: 4604 mov r4, r0 + 800bf32: bb48 cbnz r0, 800bf88 + { + return errorstate; + } + + /* Send CMD55 APP_CMD with argument as card's RCA */ + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16U)); + 800bf34: 6ca9 ldr r1, [r5, #72] ; 0x48 + 800bf36: 6828 ldr r0, [r5, #0] + 800bf38: 0409 lsls r1, r1, #16 + 800bf3a: f001 fac8 bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800bf3e: 4604 mov r4, r0 + 800bf40: bb10 cbnz r0, 800bf88 + { + return errorstate; + } + + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = 8U; + 800bf42: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff + 800bf46: 2308 movs r3, #8 + 800bf48: e9cd 0300 strd r0, r3, [sp] + config.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B; + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800bf4c: 2630 movs r6, #48 ; 0x30 + 800bf4e: 2302 movs r3, #2 + 800bf50: e9cd 6302 strd r6, r3, [sp, #8] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + config.DPSM = SDMMC_DPSM_ENABLE; + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bf54: 4669 mov r1, sp + config.DPSM = SDMMC_DPSM_ENABLE; + 800bf56: 2301 movs r3, #1 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bf58: 6828 ldr r0, [r5, #0] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800bf5a: 9404 str r4, [sp, #16] + config.DPSM = SDMMC_DPSM_ENABLE; + 800bf5c: 9305 str r3, [sp, #20] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800bf5e: f001 f8a1 bl 800d0a4 + + /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ + errorstate = SDMMC_CmdSendSCR(hsd->Instance); + 800bf62: 6828 ldr r0, [r5, #0] + 800bf64: f001 fae7 bl 800d536 + if(errorstate != HAL_SD_ERROR_NONE) + 800bf68: 4604 mov r4, r0 + 800bf6a: b968 cbnz r0, 800bf88 + uint32_t tempscr[2U] = {0UL, 0UL}; + 800bf6c: 4607 mov r7, r0 + 800bf6e: 4606 mov r6, r0 + { + return errorstate; + } + +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DATAEND)) + 800bf70: f240 5a2a movw sl, #1322 ; 0x52a + 800bf74: 6828 ldr r0, [r5, #0] + 800bf76: 6b42 ldr r2, [r0, #52] ; 0x34 + 800bf78: ea12 0f0a tst.w r2, sl + { + if((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) + 800bf7c: 6b42 ldr r2, [r0, #52] ; 0x34 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DATAEND)) + 800bf7e: d007 beq.n 800bf90 + return HAL_SD_ERROR_TIMEOUT; + } + } +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800bf80: 0712 lsls r2, r2, #28 + 800bf82: d519 bpl.n 800bfb8 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800bf84: 2408 movs r4, #8 + + return HAL_SD_ERROR_DATA_CRC_FAIL; + } + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bf86: 6384 str r4, [r0, #56] ; 0x38 + ((tempscr[0] & SDMMC_16TO23BITS) >> 8) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24)); + + } + + return HAL_SD_ERROR_NONE; +} + 800bf88: 4620 mov r0, r4 + 800bf8a: b006 add sp, #24 + 800bf8c: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + if((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) + 800bf90: 0311 lsls r1, r2, #12 + 800bf92: d408 bmi.n 800bfa6 + 800bf94: b93c cbnz r4, 800bfa6 + tempscr[0] = SDMMC_ReadFIFO(hsd->Instance); + 800bf96: f001 f849 bl 800d02c + 800bf9a: 4606 mov r6, r0 + tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); + 800bf9c: 6828 ldr r0, [r5, #0] + 800bf9e: f001 f845 bl 800d02c + index++; + 800bfa2: 2401 movs r4, #1 + tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); + 800bfa4: 4607 mov r7, r0 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800bfa6: f7fb fa19 bl 80073dc + 800bfaa: eba0 0009 sub.w r0, r0, r9 + 800bfae: 3001 adds r0, #1 + 800bfb0: d1e0 bne.n 800bf74 + return HAL_SD_ERROR_TIMEOUT; + 800bfb2: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + 800bfb6: e7e7 b.n 800bf88 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800bfb8: 6b42 ldr r2, [r0, #52] ; 0x34 + 800bfba: 0793 lsls r3, r2, #30 + 800bfbc: d501 bpl.n 800bfc2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800bfbe: 2402 movs r4, #2 + 800bfc0: e7e1 b.n 800bf86 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800bfc2: 6b44 ldr r4, [r0, #52] ; 0x34 + 800bfc4: f014 0420 ands.w r4, r4, #32 + 800bfc8: d001 beq.n 800bfce + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800bfca: 2420 movs r4, #32 + 800bfcc: e7db b.n 800bf86 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800bfce: 4a04 ldr r2, [pc, #16] ; (800bfe0 ) + 800bfd0: 6382 str r2, [r0, #56] ; 0x38 + *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24) | ((tempscr[1] & SDMMC_8TO15BITS) << 8) |\ + 800bfd2: ba3f rev r7, r7 + 800bfd4: ba36 rev r6, r6 + 800bfd6: f8c8 7000 str.w r7, [r8] + *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24) | ((tempscr[0] & SDMMC_8TO15BITS) << 8) |\ + 800bfda: f8c8 6004 str.w r6, [r8, #4] + return HAL_SD_ERROR_NONE; + 800bfde: e7d3 b.n 800bf88 + 800bfe0: 18000f3a .word 0x18000f3a + +0800bfe4 : + * of PLL to have SDMMCCK clock between 50 and 120 MHz + * @param hsd SD handle + * @retval SD Card error state + */ +static uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd) +{ + 800bfe4: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + 800bfe8: 2640 movs r6, #64 ; 0x40 +{ + 800bfea: b096 sub sp, #88 ; 0x58 + 800bfec: 4605 mov r5, r0 + uint32_t SD_hs[16] = {0}; + 800bfee: 4632 mov r2, r6 + 800bff0: 2100 movs r1, #0 + 800bff2: a806 add r0, sp, #24 + 800bff4: f001 fc96 bl 800d924 + uint32_t count, loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + 800bff8: f7fb f9f0 bl 80073dc + + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800bffc: 6deb ldr r3, [r5, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800bffe: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800c000: 2b00 cmp r3, #0 + 800c002: d067 beq.n 800c0d4 + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) && + 800c004: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800c008: d167 bne.n 800c0da + 800c00a: 69af ldr r7, [r5, #24] + 800c00c: 2f01 cmp r7, #1 + 800c00e: d164 bne.n 800c0da + (hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE)) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + 800c010: 6828 ldr r0, [r5, #0] + 800c012: 2300 movs r3, #0 + 800c014: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800c016: 4631 mov r1, r6 + 800c018: f001 f920 bl 800d25c + + if (errorstate != HAL_SD_ERROR_NONE) + 800c01c: 4604 mov r4, r0 + 800c01e: 2800 cmp r0, #0 + 800c020: d13e bne.n 800c0a0 + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800c022: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800c026: e9cd 3600 strd r3, r6, [sp] + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800c02a: e9cd 0704 strd r0, r7, [sp, #16] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800c02e: 2660 movs r6, #96 ; 0x60 + 800c030: 2302 movs r3, #2 + + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800c032: 6828 ldr r0, [r5, #0] + 800c034: 4669 mov r1, sp + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800c036: e9cd 6302 strd r6, r3, [sp, #8] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800c03a: f001 f833 bl 800d0a4 + 800c03e: 2800 cmp r0, #0 + 800c040: d14d bne.n 800c0de + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SDMMC_SDR104_SWITCH_PATTERN); + 800c042: 492a ldr r1, [pc, #168] ; (800c0ec ) + 800c044: 6828 ldr r0, [r5, #0] + 800c046: f001 fa74 bl 800d532 + if(errorstate != HAL_SD_ERROR_NONE) + 800c04a: 4604 mov r4, r0 + 800c04c: bb40 cbnz r0, 800c0a0 + uint32_t count, loop = 0 ; + 800c04e: 4607 mov r7, r0 + { + return errorstate; + } + + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800c050: f240 592a movw r9, #1322 ; 0x52a + 800c054: 682b ldr r3, [r5, #0] + 800c056: 6b5e ldr r6, [r3, #52] ; 0x34 + 800c058: ea16 0609 ands.w r6, r6, r9 + 800c05c: d005 beq.n 800c06a + hsd->State= HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c05e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c060: 0711 lsls r1, r2, #28 + 800c062: d521 bpl.n 800c0a8 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800c064: 2208 movs r2, #8 + 800c066: 639a str r2, [r3, #56] ; 0x38 + + return errorstate; + 800c068: e01a b.n 800c0a0 + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800c06a: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c06c: 0418 lsls r0, r3, #16 + 800c06e: d50b bpl.n 800c088 + 800c070: ab06 add r3, sp, #24 + 800c072: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800c076: 6828 ldr r0, [r5, #0] + 800c078: f000 ffd8 bl 800d02c + for (count = 0U; count < 8U; count++) + 800c07c: 3601 adds r6, #1 + 800c07e: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800c080: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800c084: d1f7 bne.n 800c076 + loop ++; + 800c086: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800c088: f7fb f9a8 bl 80073dc + 800c08c: eba0 0008 sub.w r0, r0, r8 + 800c090: 3001 adds r0, #1 + 800c092: d1df bne.n 800c054 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800c094: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + hsd->State= HAL_SD_STATE_READY; + 800c098: 2301 movs r3, #1 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800c09a: 63ac str r4, [r5, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800c09c: f885 3034 strb.w r3, [r5, #52] ; 0x34 +#endif /* (DLYB_SDMMC1) || (DLYB_SDMMC2) */ + } + } + + return errorstate; +} + 800c0a0: 4620 mov r0, r4 + 800c0a2: b016 add sp, #88 ; 0x58 + 800c0a4: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c0a8: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c0aa: 0792 lsls r2, r2, #30 + 800c0ac: d502 bpl.n 800c0b4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800c0ae: 2402 movs r4, #2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800c0b0: 639c str r4, [r3, #56] ; 0x38 + return errorstate; + 800c0b2: e7f5 b.n 800c0a0 + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800c0b4: 6b5c ldr r4, [r3, #52] ; 0x34 + 800c0b6: f014 0420 ands.w r4, r4, #32 + 800c0ba: d001 beq.n 800c0c0 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800c0bc: 2420 movs r4, #32 + 800c0be: e7f7 b.n 800c0b0 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c0c0: 4a0b ldr r2, [pc, #44] ; (800c0f0 ) + 800c0c2: 639a str r2, [r3, #56] ; 0x38 + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800c0c4: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800c0c8: 079b lsls r3, r3, #30 + 800c0ca: d50b bpl.n 800c0e4 + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800c0cc: 2001 movs r0, #1 + 800c0ce: f7fb f9f5 bl 80074bc + 800c0d2: e7e5 b.n 800c0a0 + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800c0d4: f04f 6480 mov.w r4, #67108864 ; 0x4000000 + 800c0d8: e7e2 b.n 800c0a0 + uint32_t errorstate = HAL_SD_ERROR_NONE; + 800c0da: 2400 movs r4, #0 + 800c0dc: e7e0 b.n 800c0a0 + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + 800c0de: f44f 3480 mov.w r4, #65536 ; 0x10000 + 800c0e2: e7dd b.n 800c0a0 + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + 800c0e4: f04f 5480 mov.w r4, #268435456 ; 0x10000000 + 800c0e8: e7da b.n 800c0a0 + 800c0ea: bf00 nop + 800c0ec: 80ff1f03 .word 0x80ff1f03 + 800c0f0: 18000f3a .word 0x18000f3a + +0800c0f4 : +} + 800c0f4: 4770 bx lr + +0800c0f6 : + 800c0f6: 4770 bx lr + +0800c0f8 : +{ + 800c0f8: b510 push {r4, lr} + if(hsd == NULL) + 800c0fa: 4604 mov r4, r0 + 800c0fc: b198 cbz r0, 800c126 + hsd->State = HAL_SD_STATE_BUSY; + 800c0fe: 2303 movs r3, #3 + 800c100: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c104: 6983 ldr r3, [r0, #24] + 800c106: 2b01 cmp r3, #1 + 800c108: d102 bne.n 800c110 + HAL_SDEx_DriveTransceiver_1_8V_Callback(RESET); + 800c10a: 2000 movs r0, #0 + 800c10c: f7fb f9d6 bl 80074bc + (void)SDMMC_PowerState_OFF(hsd->Instance); + 800c110: 6820 ldr r0, [r4, #0] + 800c112: f000 ffa3 bl 800d05c + HAL_SD_MspDeInit(hsd); + 800c116: 4620 mov r0, r4 + 800c118: f7ff ffed bl 800c0f6 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c11c: 2000 movs r0, #0 + 800c11e: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_RESET; + 800c120: f884 0034 strb.w r0, [r4, #52] ; 0x34 +} + 800c124: bd10 pop {r4, pc} + return HAL_ERROR; + 800c126: 2001 movs r0, #1 + 800c128: e7fc b.n 800c124 + ... + +0800c12c : +{ + 800c12c: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800c130: b087 sub sp, #28 + 800c132: 4604 mov r4, r0 + 800c134: 460e mov r6, r1 + 800c136: 4692 mov sl, r2 + 800c138: 461f mov r7, r3 + uint32_t tickstart = HAL_GetTick(); + 800c13a: f7fb f94f bl 80073dc + 800c13e: 4681 mov r9, r0 + if(NULL == pData) + 800c140: b936 cbnz r6, 800c150 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800c142: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c144: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c148: 63a3 str r3, [r4, #56] ; 0x38 + return HAL_ERROR; + 800c14a: f04f 0801 mov.w r8, #1 + 800c14e: e011 b.n 800c174 + if(hsd->State == HAL_SD_STATE_READY) + 800c150: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800c154: 2b01 cmp r3, #1 + 800c156: fa5f f883 uxtb.w r8, r3 + 800c15a: f040 80c3 bne.w 800c2e4 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c15e: 6d62 ldr r2, [r4, #84] ; 0x54 + 800c160: eb0a 0307 add.w r3, sl, r7 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c164: 2100 movs r1, #0 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c166: 4293 cmp r3, r2 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c168: 63a1 str r1, [r4, #56] ; 0x38 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c16a: d907 bls.n 800c17c + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + 800c16c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c16e: f043 7300 orr.w r3, r3, #33554432 ; 0x2000000 + 800c172: 63a3 str r3, [r4, #56] ; 0x38 +} + 800c174: 4640 mov r0, r8 + 800c176: b007 add sp, #28 + 800c178: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + hsd->State = HAL_SD_STATE_BUSY; + 800c17c: 2303 movs r3, #3 + 800c17e: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c182: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->Instance->DCTRL = 0U; + 800c184: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c186: 2b01 cmp r3, #1 + config.DataTimeOut = SDMMC_DATATIMEOUT; + 800c188: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800c18c: 9300 str r3, [sp, #0] + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800c18e: ea4f 2347 mov.w r3, r7, lsl #9 + 800c192: 9301 str r3, [sp, #4] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800c194: f04f 0502 mov.w r5, #2 + 800c198: f04f 0390 mov.w r3, #144 ; 0x90 + 800c19c: e9cd 3502 strd r3, r5, [sp, #8] + hsd->Instance->DCTRL = 0U; + 800c1a0: 62c1 str r1, [r0, #44] ; 0x2c + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800c1a2: f04f 0300 mov.w r3, #0 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c1a6: 4669 mov r1, sp + config.DPSM = SDMMC_DPSM_DISABLE; + 800c1a8: e9cd 3304 strd r3, r3, [sp, #16] + add *= 512U; + 800c1ac: bf18 it ne + 800c1ae: ea4f 2a4a movne.w sl, sl, lsl #9 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c1b2: f000 ff77 bl 800d0a4 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c1b6: 6820 ldr r0, [r4, #0] + 800c1b8: 68c3 ldr r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c1ba: 2f01 cmp r7, #1 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c1bc: f043 0340 orr.w r3, r3, #64 ; 0x40 + 800c1c0: 60c3 str r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c1c2: d910 bls.n 800c1e6 + hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; + 800c1c4: 6325 str r5, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); + 800c1c6: 4651 mov r1, sl + 800c1c8: f001 f87a bl 800d2c0 + if(errorstate != HAL_SD_ERROR_NONE) + 800c1cc: b188 cbz r0, 800c1f2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c1ce: 6823 ldr r3, [r4, #0] + 800c1d0: 4a46 ldr r2, [pc, #280] ; (800c2ec ) + 800c1d2: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c1d4: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c1d6: 4318 orrs r0, r3 + 800c1d8: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c1da: 2301 movs r3, #1 + 800c1dc: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c1e0: 2300 movs r3, #0 + 800c1e2: 6323 str r3, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c1e4: e7c6 b.n 800c174 + hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK; + 800c1e6: 2301 movs r3, #1 + 800c1e8: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); + 800c1ea: 4651 mov r1, sl + 800c1ec: f001 f84f bl 800d28e + 800c1f0: e7ec b.n 800c1cc + dataremaining = config.DataLength; + 800c1f2: 9d01 ldr r5, [sp, #4] + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800c1f4: 6820 ldr r0, [r4, #0] + 800c1f6: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c1f8: f413 7f95 tst.w r3, #298 ; 0x12a + 800c1fc: d01b beq.n 800c236 + __SDMMC_CMDTRANS_DISABLE( hsd->Instance); + 800c1fe: 68c3 ldr r3, [r0, #12] + 800c200: f023 0340 bic.w r3, r3, #64 ; 0x40 + 800c204: 60c3 str r3, [r0, #12] + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + 800c206: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c208: 05db lsls r3, r3, #23 + 800c20a: d508 bpl.n 800c21e + 800c20c: 2f01 cmp r7, #1 + 800c20e: d906 bls.n 800c21e + if(hsd->SdCard.CardType != CARD_SECURED) + 800c210: 6be3 ldr r3, [r4, #60] ; 0x3c + 800c212: 2b03 cmp r3, #3 + 800c214: d003 beq.n 800c21e + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + 800c216: f001 f91b bl 800d450 + if(errorstate != HAL_SD_ERROR_NONE) + 800c21a: 2800 cmp r0, #0 + 800c21c: d1d7 bne.n 800c1ce + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c21e: 6823 ldr r3, [r4, #0] + 800c220: 6b58 ldr r0, [r3, #52] ; 0x34 + 800c222: f010 0008 ands.w r0, r0, #8 + 800c226: d038 beq.n 800c29a + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c228: 4a30 ldr r2, [pc, #192] ; (800c2ec ) + 800c22a: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + 800c22c: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c22e: f043 0308 orr.w r3, r3, #8 + 800c232: 63a3 str r3, [r4, #56] ; 0x38 + 800c234: e7d1 b.n 800c1da + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U)) + 800c236: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c238: 041a lsls r2, r3, #16 + 800c23a: d518 bpl.n 800c26e + 800c23c: b1bd cbz r5, 800c26e + 800c23e: f106 0a04 add.w sl, r6, #4 + 800c242: f106 0b24 add.w fp, r6, #36 ; 0x24 + data = SDMMC_ReadFIFO(hsd->Instance); + 800c246: 6820 ldr r0, [r4, #0] + 800c248: f000 fef0 bl 800d02c + *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); + 800c24c: 0a02 lsrs r2, r0, #8 + 800c24e: f80a 2c03 strb.w r2, [sl, #-3] + *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); + 800c252: 0c02 lsrs r2, r0, #16 + 800c254: f80a 2c02 strb.w r2, [sl, #-2] + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + 800c258: 0e02 lsrs r2, r0, #24 + *tempbuff = (uint8_t)(data & 0xFFU); + 800c25a: f80a 0c04 strb.w r0, [sl, #-4] + *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); + 800c25e: f80a 2c01 strb.w r2, [sl, #-1] + for(count = 0U; count < 8U; count++) + 800c262: f10a 0a04 add.w sl, sl, #4 + 800c266: 45d3 cmp fp, sl + 800c268: d1ed bne.n 800c246 + tempbuff++; + 800c26a: 3620 adds r6, #32 + dataremaining--; + 800c26c: 3d20 subs r5, #32 + if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) + 800c26e: f7fb f8b5 bl 80073dc + 800c272: 9b10 ldr r3, [sp, #64] ; 0x40 + 800c274: eba0 0009 sub.w r0, r0, r9 + 800c278: 4298 cmp r0, r3 + 800c27a: d3bb bcc.n 800c1f4 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c27c: 6823 ldr r3, [r4, #0] + 800c27e: 4a1b ldr r2, [pc, #108] ; (800c2ec ) + 800c280: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT; + 800c282: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c284: f043 4300 orr.w r3, r3, #2147483648 ; 0x80000000 + 800c288: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800c28a: 2301 movs r3, #1 + 800c28c: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c290: 2300 movs r3, #0 + 800c292: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800c294: f04f 0803 mov.w r8, #3 + 800c298: e76c b.n 800c174 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c29a: 6b59 ldr r1, [r3, #52] ; 0x34 + 800c29c: f011 0102 ands.w r1, r1, #2 + 800c2a0: d00a beq.n 800c2b8 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c2a2: 4a12 ldr r2, [pc, #72] ; (800c2ec ) + 800c2a4: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + 800c2a6: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c2a8: f043 0302 orr.w r3, r3, #2 + 800c2ac: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c2ae: 2301 movs r3, #1 + 800c2b0: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c2b4: 6320 str r0, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c2b6: e75d b.n 800c174 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800c2b8: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c2ba: f012 0220 ands.w r2, r2, #32 + 800c2be: d00a beq.n 800c2d6 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c2c0: 4a0a ldr r2, [pc, #40] ; (800c2ec ) + 800c2c2: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; + 800c2c4: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c2c6: f043 0320 orr.w r3, r3, #32 + 800c2ca: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c2cc: 2301 movs r3, #1 + 800c2ce: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c2d2: 6321 str r1, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c2d4: e74e b.n 800c174 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c2d6: 4906 ldr r1, [pc, #24] ; (800c2f0 ) + 800c2d8: 6399 str r1, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c2da: 2301 movs r3, #1 + 800c2dc: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800c2e0: 4690 mov r8, r2 + 800c2e2: e747 b.n 800c174 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c2e4: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c2e6: f043 5300 orr.w r3, r3, #536870912 ; 0x20000000 + 800c2ea: e72d b.n 800c148 + 800c2ec: 1fe00fff .word 0x1fe00fff + 800c2f0: 18000f3a .word 0x18000f3a + +0800c2f4 : +{ + 800c2f4: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr} + 800c2f8: b089 sub sp, #36 ; 0x24 + 800c2fa: 4604 mov r4, r0 + 800c2fc: 460d mov r5, r1 + 800c2fe: 4692 mov sl, r2 + 800c300: 461f mov r7, r3 + uint32_t tickstart = HAL_GetTick(); + 800c302: f7fb f86b bl 80073dc + 800c306: 4681 mov r9, r0 + if(NULL == pData) + 800c308: b935 cbnz r5, 800c318 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800c30a: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c30c: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c310: 63a3 str r3, [r4, #56] ; 0x38 + return HAL_ERROR; + 800c312: f04f 0801 mov.w r8, #1 + 800c316: e011 b.n 800c33c + if(hsd->State == HAL_SD_STATE_READY) + 800c318: f894 3034 ldrb.w r3, [r4, #52] ; 0x34 + 800c31c: 2b01 cmp r3, #1 + 800c31e: fa5f f883 uxtb.w r8, r3 + 800c322: f040 80b4 bne.w 800c48e + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c326: 6d62 ldr r2, [r4, #84] ; 0x54 + 800c328: eb0a 0307 add.w r3, sl, r7 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c32c: 2100 movs r1, #0 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c32e: 4293 cmp r3, r2 + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800c330: 63a1 str r1, [r4, #56] ; 0x38 + if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) + 800c332: d907 bls.n 800c344 + hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; + 800c334: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c336: f043 7300 orr.w r3, r3, #33554432 ; 0x2000000 + 800c33a: 63a3 str r3, [r4, #56] ; 0x38 +} + 800c33c: 4640 mov r0, r8 + 800c33e: b009 add sp, #36 ; 0x24 + 800c340: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc} + hsd->State = HAL_SD_STATE_BUSY; + 800c344: 2303 movs r3, #3 + 800c346: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c34a: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->Instance->DCTRL = 0U; + 800c34c: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SDHC_SDXC) + 800c34e: 2b01 cmp r3, #1 + config.DataTimeOut = SDMMC_DATATIMEOUT; + 800c350: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + 800c354: 9302 str r3, [sp, #8] + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800c356: ea4f 2347 mov.w r3, r7, lsl #9 + hsd->Instance->DCTRL = 0U; + 800c35a: 62c1 str r1, [r0, #44] ; 0x2c + config.DataLength = NumberOfBlocks * BLOCKSIZE; + 800c35c: 9303 str r3, [sp, #12] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; + 800c35e: f04f 0190 mov.w r1, #144 ; 0x90 + 800c362: f04f 0300 mov.w r3, #0 + 800c366: e9cd 1304 strd r1, r3, [sp, #16] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c36a: a902 add r1, sp, #8 + config.DPSM = SDMMC_DPSM_DISABLE; + 800c36c: e9cd 3306 strd r3, r3, [sp, #24] + add *= 512U; + 800c370: bf18 it ne + 800c372: ea4f 2a4a movne.w sl, sl, lsl #9 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c376: f000 fe95 bl 800d0a4 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c37a: 6820 ldr r0, [r4, #0] + 800c37c: 68c3 ldr r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c37e: 2f01 cmp r7, #1 + __SDMMC_CMDTRANS_ENABLE( hsd->Instance); + 800c380: f043 0340 orr.w r3, r3, #64 ; 0x40 + 800c384: 60c3 str r3, [r0, #12] + if(NumberOfBlocks > 1U) + 800c386: d911 bls.n 800c3ac + hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK; + 800c388: 2320 movs r3, #32 + 800c38a: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); + 800c38c: 4651 mov r1, sl + 800c38e: f000 ffc9 bl 800d324 + if(errorstate != HAL_SD_ERROR_NONE) + 800c392: b188 cbz r0, 800c3b8 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c394: 6823 ldr r3, [r4, #0] + 800c396: 4a40 ldr r2, [pc, #256] ; (800c498 ) + 800c398: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c39a: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c39c: 4318 orrs r0, r3 + 800c39e: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c3a0: 2301 movs r3, #1 + 800c3a2: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c3a6: 2300 movs r3, #0 + 800c3a8: 6323 str r3, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c3aa: e7c7 b.n 800c33c + hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK; + 800c3ac: 2310 movs r3, #16 + 800c3ae: 6323 str r3, [r4, #48] ; 0x30 + errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); + 800c3b0: 4651 mov r1, sl + 800c3b2: f000 ff9e bl 800d2f2 + 800c3b6: e7ec b.n 800c392 + dataremaining = config.DataLength; + 800c3b8: 9e03 ldr r6, [sp, #12] + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800c3ba: 6820 ldr r0, [r4, #0] + 800c3bc: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c3be: f413 7f8d tst.w r3, #282 ; 0x11a + 800c3c2: d01b beq.n 800c3fc + __SDMMC_CMDTRANS_DISABLE( hsd->Instance); + 800c3c4: 68c3 ldr r3, [r0, #12] + 800c3c6: f023 0340 bic.w r3, r3, #64 ; 0x40 + 800c3ca: 60c3 str r3, [r0, #12] + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) + 800c3cc: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c3ce: 05db lsls r3, r3, #23 + 800c3d0: d508 bpl.n 800c3e4 + 800c3d2: 2f01 cmp r7, #1 + 800c3d4: d906 bls.n 800c3e4 + if(hsd->SdCard.CardType != CARD_SECURED) + 800c3d6: 6be3 ldr r3, [r4, #60] ; 0x3c + 800c3d8: 2b03 cmp r3, #3 + 800c3da: d003 beq.n 800c3e4 + errorstate = SDMMC_CmdStopTransfer(hsd->Instance); + 800c3dc: f001 f838 bl 800d450 + if(errorstate != HAL_SD_ERROR_NONE) + 800c3e0: 2800 cmp r0, #0 + 800c3e2: d1d7 bne.n 800c394 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c3e4: 6823 ldr r3, [r4, #0] + 800c3e6: 6b58 ldr r0, [r3, #52] ; 0x34 + 800c3e8: f010 0008 ands.w r0, r0, #8 + 800c3ec: d02a beq.n 800c444 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c3ee: 4a2a ldr r2, [pc, #168] ; (800c498 ) + 800c3f0: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; + 800c3f2: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c3f4: f043 0308 orr.w r3, r3, #8 + 800c3f8: 63a3 str r3, [r4, #56] ; 0x38 + 800c3fa: e7d1 b.n 800c3a0 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U)) + 800c3fc: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c3fe: 045a lsls r2, r3, #17 + 800c400: d50c bpl.n 800c41c + 800c402: b15e cbz r6, 800c41c + 800c404: f105 0b20 add.w fp, r5, #32 + data |= ((uint32_t)(*tempbuff) << 24U); + 800c408: f855 3b04 ldr.w r3, [r5], #4 + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + 800c40c: 6820 ldr r0, [r4, #0] + data |= ((uint32_t)(*tempbuff) << 24U); + 800c40e: 9301 str r3, [sp, #4] + (void)SDMMC_WriteFIFO(hsd->Instance, &data); + 800c410: a901 add r1, sp, #4 + 800c412: f000 fe0e bl 800d032 + for(count = 0U; count < 8U; count++) + 800c416: 45ab cmp fp, r5 + 800c418: d1f6 bne.n 800c408 + dataremaining--; + 800c41a: 3e20 subs r6, #32 + if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) + 800c41c: f7fa ffde bl 80073dc + 800c420: 9b12 ldr r3, [sp, #72] ; 0x48 + 800c422: eba0 0009 sub.w r0, r0, r9 + 800c426: 4298 cmp r0, r3 + 800c428: d3c7 bcc.n 800c3ba + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c42a: 6823 ldr r3, [r4, #0] + 800c42c: 4a1a ldr r2, [pc, #104] ; (800c498 ) + 800c42e: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c430: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c432: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c434: 2301 movs r3, #1 + 800c436: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c43a: 2300 movs r3, #0 + 800c43c: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800c43e: f04f 0803 mov.w r8, #3 + 800c442: e77b b.n 800c33c + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c444: 6b59 ldr r1, [r3, #52] ; 0x34 + 800c446: f011 0102 ands.w r1, r1, #2 + 800c44a: d00a beq.n 800c462 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c44c: 4a12 ldr r2, [pc, #72] ; (800c498 ) + 800c44e: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; + 800c450: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c452: f043 0302 orr.w r3, r3, #2 + 800c456: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c458: 2301 movs r3, #1 + 800c45a: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c45e: 6320 str r0, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c460: e76c b.n 800c33c + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR)) + 800c462: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c464: f012 0210 ands.w r2, r2, #16 + 800c468: d00a beq.n 800c480 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c46a: 4a0b ldr r2, [pc, #44] ; (800c498 ) + 800c46c: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; + 800c46e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c470: f043 0310 orr.w r3, r3, #16 + 800c474: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c476: 2301 movs r3, #1 + 800c478: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800c47c: 6321 str r1, [r4, #48] ; 0x30 + return HAL_ERROR; + 800c47e: e75d b.n 800c33c + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c480: 4906 ldr r1, [pc, #24] ; (800c49c ) + 800c482: 6399 str r1, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c484: 2301 movs r3, #1 + 800c486: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800c48a: 4690 mov r8, r2 + 800c48c: e756 b.n 800c33c + hsd->ErrorCode |= HAL_SD_ERROR_BUSY; + 800c48e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c490: f043 5300 orr.w r3, r3, #536870912 ; 0x20000000 + 800c494: e73c b.n 800c310 + 800c496: bf00 nop + 800c498: 1fe00fff .word 0x1fe00fff + 800c49c: 18000f3a .word 0x18000f3a + +0800c4a0 : + return hsd->State; + 800c4a0: f890 0034 ldrb.w r0, [r0, #52] ; 0x34 +} + 800c4a4: 4770 bx lr + +0800c4a6 : + return hsd->ErrorCode; + 800c4a6: 6b80 ldr r0, [r0, #56] ; 0x38 +} + 800c4a8: 4770 bx lr + +0800c4aa : + 800c4aa: 4770 bx lr + +0800c4ac : + 800c4ac: 4770 bx lr + +0800c4ae : + 800c4ae: 4770 bx lr + +0800c4b0 : + 800c4b0: 4770 bx lr + ... + +0800c4b4 : + pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U); + 800c4b4: 6e03 ldr r3, [r0, #96] ; 0x60 + 800c4b6: 0f9a lsrs r2, r3, #30 + 800c4b8: 700a strb r2, [r1, #0] + pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U); + 800c4ba: f3c3 6283 ubfx r2, r3, #26, #4 + 800c4be: 704a strb r2, [r1, #1] + pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U); + 800c4c0: f3c3 6201 ubfx r2, r3, #24, #2 + 800c4c4: 708a strb r2, [r1, #2] + pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U); + 800c4c6: f3c3 4207 ubfx r2, r3, #16, #8 + 800c4ca: 70ca strb r2, [r1, #3] + pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); + 800c4cc: f3c3 2207 ubfx r2, r3, #8, #8 + pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); + 800c4d0: b2db uxtb r3, r3 + pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); + 800c4d2: 710a strb r2, [r1, #4] + pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); + 800c4d4: 714b strb r3, [r1, #5] + pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U); + 800c4d6: 6e43 ldr r3, [r0, #100] ; 0x64 + 800c4d8: 0d1a lsrs r2, r3, #20 + 800c4da: 80ca strh r2, [r1, #6] + pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U); + 800c4dc: f3c3 4203 ubfx r2, r3, #16, #4 + 800c4e0: 720a strb r2, [r1, #8] + pCSD->PartBlockRead = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U); + 800c4e2: f3c3 32c0 ubfx r2, r3, #15, #1 + 800c4e6: 724a strb r2, [r1, #9] + pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U); + 800c4e8: f3c3 3280 ubfx r2, r3, #14, #1 + 800c4ec: 728a strb r2, [r1, #10] + pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U); + 800c4ee: f3c3 3240 ubfx r2, r3, #13, #1 + 800c4f2: 72ca strb r2, [r1, #11] + pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U); + 800c4f4: f3c3 3200 ubfx r2, r3, #12, #1 + 800c4f8: 730a strb r2, [r1, #12] + pCSD->Reserved2 = 0U; /*!< Reserved */ + 800c4fa: 2200 movs r2, #0 + 800c4fc: 734a strb r2, [r1, #13] + if(hsd->SdCard.CardType == CARD_SDSC) + 800c4fe: 6bc2 ldr r2, [r0, #60] ; 0x3c +{ + 800c500: b510 push {r4, lr} + if(hsd->SdCard.CardType == CARD_SDSC) + 800c502: 2a00 cmp r2, #0 + 800c504: d16c bne.n 800c5e0 + pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U)); + 800c506: 6e82 ldr r2, [r0, #104] ; 0x68 + 800c508: f640 74fc movw r4, #4092 ; 0xffc + 800c50c: ea04 0383 and.w r3, r4, r3, lsl #2 + 800c510: ea43 7392 orr.w r3, r3, r2, lsr #30 + 800c514: 610b str r3, [r1, #16] + pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U); + 800c516: f3c2 63c2 ubfx r3, r2, #27, #3 + 800c51a: 750b strb r3, [r1, #20] + pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U); + 800c51c: f3c2 6302 ubfx r3, r2, #24, #3 + 800c520: 754b strb r3, [r1, #21] + pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U); + 800c522: f3c2 5342 ubfx r3, r2, #21, #3 + 800c526: 758b strb r3, [r1, #22] + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); + 800c528: f3c2 4382 ubfx r3, r2, #18, #3 + pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); + 800c52c: f3c2 32c2 ubfx r2, r2, #15, #3 + pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); + 800c530: 75cb strb r3, [r1, #23] + pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); + 800c532: 760a strb r2, [r1, #24] + hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + 800c534: 690b ldr r3, [r1, #16] + hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + 800c536: 7e0a ldrb r2, [r1, #24] + 800c538: f002 0207 and.w r2, r2, #7 + hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; + 800c53c: 3301 adds r3, #1 + hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); + 800c53e: 3202 adds r2, #2 + 800c540: fa03 f202 lsl.w r2, r3, r2 + 800c544: 64c2 str r2, [r0, #76] ; 0x4c + hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); + 800c546: 7a0b ldrb r3, [r1, #8] + 800c548: f003 040f and.w r4, r3, #15 + 800c54c: 2301 movs r3, #1 + 800c54e: 40a3 lsls r3, r4 + 800c550: 6503 str r3, [r0, #80] ; 0x50 + hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U); + 800c552: 0a5b lsrs r3, r3, #9 + 800c554: 4353 muls r3, r2 + 800c556: 6543 str r3, [r0, #84] ; 0x54 + hsd->SdCard.LogBlockSize = 512U; + 800c558: f44f 7300 mov.w r3, #512 ; 0x200 + hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize; + 800c55c: 6583 str r3, [r0, #88] ; 0x58 + pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U); + 800c55e: 6e83 ldr r3, [r0, #104] ; 0x68 + 800c560: f3c3 3280 ubfx r2, r3, #14, #1 + 800c564: 764a strb r2, [r1, #25] + pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); + 800c566: f3c3 12c6 ubfx r2, r3, #7, #7 + pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); + 800c56a: f003 037f and.w r3, r3, #127 ; 0x7f + pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); + 800c56e: 768a strb r2, [r1, #26] + pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); + 800c570: 76cb strb r3, [r1, #27] + pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U); + 800c572: 6ec3 ldr r3, [r0, #108] ; 0x6c + 800c574: 0fda lsrs r2, r3, #31 + 800c576: 770a strb r2, [r1, #28] + pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U); + 800c578: f3c3 7241 ubfx r2, r3, #29, #2 + 800c57c: 774a strb r2, [r1, #29] + pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U); + 800c57e: f3c3 6282 ubfx r2, r3, #26, #3 + 800c582: 778a strb r2, [r1, #30] + pCSD->MaxWrBlockLen= (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U); + 800c584: f3c3 5283 ubfx r2, r3, #22, #4 + 800c588: 77ca strb r2, [r1, #31] + pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U); + 800c58a: f3c3 5240 ubfx r2, r3, #21, #1 + 800c58e: f881 2020 strb.w r2, [r1, #32] + pCSD->Reserved3 = 0; + 800c592: 2000 movs r0, #0 + pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); + 800c594: f3c3 4200 ubfx r2, r3, #16, #1 + pCSD->Reserved3 = 0; + 800c598: f881 0021 strb.w r0, [r1, #33] ; 0x21 + pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); + 800c59c: f881 2022 strb.w r2, [r1, #34] ; 0x22 + pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U); + 800c5a0: f3c3 32c0 ubfx r2, r3, #15, #1 + 800c5a4: f881 2023 strb.w r2, [r1, #35] ; 0x23 + pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U); + 800c5a8: f3c3 3280 ubfx r2, r3, #14, #1 + 800c5ac: f881 2024 strb.w r2, [r1, #36] ; 0x24 + pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U); + 800c5b0: f3c3 3240 ubfx r2, r3, #13, #1 + 800c5b4: f881 2025 strb.w r2, [r1, #37] ; 0x25 + pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U); + 800c5b8: f3c3 3200 ubfx r2, r3, #12, #1 + 800c5bc: f881 2026 strb.w r2, [r1, #38] ; 0x26 + pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U); + 800c5c0: f3c3 2281 ubfx r2, r3, #10, #2 + 800c5c4: f881 2027 strb.w r2, [r1, #39] ; 0x27 + pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); + 800c5c8: f3c3 2201 ubfx r2, r3, #8, #2 + pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); + 800c5cc: f3c3 0346 ubfx r3, r3, #1, #7 + pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); + 800c5d0: f881 2028 strb.w r2, [r1, #40] ; 0x28 + pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); + 800c5d4: f881 3029 strb.w r3, [r1, #41] ; 0x29 + pCSD->Reserved4 = 1; + 800c5d8: 2301 movs r3, #1 + 800c5da: f881 302a strb.w r3, [r1, #42] ; 0x2a +} + 800c5de: bd10 pop {r4, pc} + else if(hsd->SdCard.CardType == CARD_SDHC_SDXC) + 800c5e0: 2a01 cmp r2, #1 + 800c5e2: d10f bne.n 800c604 + pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U)); + 800c5e4: f8b0 206a ldrh.w r2, [r0, #106] ; 0x6a + 800c5e8: 041b lsls r3, r3, #16 + 800c5ea: f403 137c and.w r3, r3, #4128768 ; 0x3f0000 + 800c5ee: 4313 orrs r3, r2 + 800c5f0: 610b str r3, [r1, #16] + hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U); + 800c5f2: 690b ldr r3, [r1, #16] + 800c5f4: 3301 adds r3, #1 + 800c5f6: 029b lsls r3, r3, #10 + 800c5f8: 64c3 str r3, [r0, #76] ; 0x4c + hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr; + 800c5fa: 6543 str r3, [r0, #84] ; 0x54 + hsd->SdCard.BlockSize = 512U; + 800c5fc: f44f 7300 mov.w r3, #512 ; 0x200 + 800c600: 6503 str r3, [r0, #80] ; 0x50 + 800c602: e7ab b.n 800c55c + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c604: 6803 ldr r3, [r0, #0] + 800c606: 4a05 ldr r2, [pc, #20] ; (800c61c ) + 800c608: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c60a: 6b83 ldr r3, [r0, #56] ; 0x38 + 800c60c: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800c610: 6383 str r3, [r0, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c612: 2301 movs r3, #1 + 800c614: f880 3034 strb.w r3, [r0, #52] ; 0x34 + return HAL_ERROR; + 800c618: 4618 mov r0, r3 + 800c61a: e7e0 b.n 800c5de + 800c61c: 1fe00fff .word 0x1fe00fff + +0800c620 : +{ + 800c620: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr} + Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + 800c624: 2300 movs r3, #0 +{ + 800c626: b099 sub sp, #100 ; 0x64 + 800c628: 4604 mov r4, r0 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800c62a: f44f 2000 mov.w r0, #524288 ; 0x80000 + Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + 800c62e: e9cd 3307 strd r3, r3, [sp, #28] + Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; + 800c632: e9cd 3309 strd r3, r3, [sp, #36] ; 0x24 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800c636: f7fd fb2d bl 8009c94 + if (sdmmc_clk == 0U) + 800c63a: 4605 mov r5, r0 + 800c63c: b948 cbnz r0, 800c652 + hsd->State = HAL_SD_STATE_READY; + 800c63e: 2501 movs r5, #1 + hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + 800c640: f04f 6300 mov.w r3, #134217728 ; 0x8000000 + hsd->State = HAL_SD_STATE_READY; + 800c644: f884 5034 strb.w r5, [r4, #52] ; 0x34 + hsd->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; + 800c648: 63a3 str r3, [r4, #56] ; 0x38 +} + 800c64a: 4628 mov r0, r5 + 800c64c: b019 add sp, #100 ; 0x64 + 800c64e: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc} + Init.Transceiver = hsd->Init.Transceiver; + 800c652: 69a3 ldr r3, [r4, #24] + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c654: 6827 ldr r7, [r4, #0] + Init.Transceiver = hsd->Init.Transceiver; + 800c656: 930c str r3, [sp, #48] ; 0x30 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c658: 2b01 cmp r3, #1 + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c65a: bf08 it eq + 800c65c: 683b ldreq r3, [r7, #0] + Init.ClockDiv = sdmmc_clk / (2U * SD_INIT_FREQ); + 800c65e: 4e99 ldr r6, [pc, #612] ; (800c8c4 ) + 800c660: fbb0 f6f6 udiv r6, r0, r6 + hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; + 800c664: bf04 itt eq + 800c666: f043 0310 orreq.w r3, r3, #16 + 800c66a: 603b streq r3, [r7, #0] + status = SDMMC_Init(hsd->Instance, Init); + 800c66c: 960b str r6, [sp, #44] ; 0x2c + 800c66e: ab0a add r3, sp, #40 ; 0x28 + 800c670: e893 0007 ldmia.w r3, {r0, r1, r2} + 800c674: e88d 0007 stmia.w sp, {r0, r1, r2} + 800c678: ab07 add r3, sp, #28 + 800c67a: cb0e ldmia r3, {r1, r2, r3} + 800c67c: 4638 mov r0, r7 + 800c67e: f000 fcbb bl 800cff8 + if(status != HAL_OK) + 800c682: b108 cbz r0, 800c688 + return HAL_ERROR; + 800c684: 2501 movs r5, #1 + 800c686: e7e0 b.n 800c64a + status = SDMMC_PowerState_ON(hsd->Instance); + 800c688: 6820 ldr r0, [r4, #0] + 800c68a: f000 fcd7 bl 800d03c + if(status != HAL_OK) + 800c68e: 4607 mov r7, r0 + 800c690: 2800 cmp r0, #0 + 800c692: d1f7 bne.n 800c684 + sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv); + 800c694: 0076 lsls r6, r6, #1 + HAL_Delay(1U+ (74U*1000U/(sdmmc_clk))); + 800c696: 488c ldr r0, [pc, #560] ; (800c8c8 ) + sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv); + 800c698: fbb5 f5f6 udiv r5, r5, r6 + HAL_Delay(1U+ (74U*1000U/(sdmmc_clk))); + 800c69c: fbb0 f0f5 udiv r0, r0, r5 + 800c6a0: 3001 adds r0, #1 + 800c6a2: f7f7 f9fc bl 8003a9e + __IO uint32_t count = 0U; + 800c6a6: 9706 str r7, [sp, #24] + uint32_t tickstart = HAL_GetTick(); + 800c6a8: f7fa fe98 bl 80073dc + 800c6ac: 4606 mov r6, r0 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c6ae: 6820 ldr r0, [r4, #0] + 800c6b0: f000 fd18 bl 800d0e4 + if(errorstate != HAL_SD_ERROR_NONE) + 800c6b4: 4605 mov r5, r0 + 800c6b6: b940 cbnz r0, 800c6ca + errorstate = SDMMC_CmdOperCond(hsd->Instance); + 800c6b8: 6820 ldr r0, [r4, #0] + 800c6ba: f001 f8fd bl 800d8b8 + if(errorstate != HAL_SD_ERROR_NONE) + 800c6be: b158 cbz r0, 800c6d8 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c6c0: 6820 ldr r0, [r4, #0] + hsd->SdCard.CardVersion = CARD_V1_X; + 800c6c2: 6425 str r5, [r4, #64] ; 0x40 + errorstate = SDMMC_CmdGoIdleState(hsd->Instance); + 800c6c4: f000 fd0e bl 800d0e4 + if(errorstate != HAL_SD_ERROR_NONE) + 800c6c8: b180 cbz r0, 800c6ec + hsd->State = HAL_SD_STATE_READY; + 800c6ca: 2501 movs r5, #1 + 800c6cc: f884 5034 strb.w r5, [r4, #52] ; 0x34 + hsd->ErrorCode |= errorstate; + 800c6d0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c6d2: 4318 orrs r0, r3 + 800c6d4: 63a0 str r0, [r4, #56] ; 0x38 + return HAL_ERROR; + 800c6d6: e7b8 b.n 800c64a + hsd->SdCard.CardVersion = CARD_V2_X; + 800c6d8: 2301 movs r3, #1 + 800c6da: 6423 str r3, [r4, #64] ; 0x40 + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c6dc: 6820 ldr r0, [r4, #0] + 800c6de: 2100 movs r1, #0 + 800c6e0: f000 fef5 bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800c6e4: b128 cbz r0, 800c6f2 + return HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800c6e6: f04f 5080 mov.w r0, #268435456 ; 0x10000000 + 800c6ea: e7ee b.n 800c6ca + if( hsd->SdCard.CardVersion == CARD_V2_X) + 800c6ec: 6c23 ldr r3, [r4, #64] ; 0x40 + 800c6ee: 2b01 cmp r3, #1 + 800c6f0: d0f4 beq.n 800c6dc + errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); + 800c6f2: f8df 91dc ldr.w r9, [pc, #476] ; 800c8d0 +{ + 800c6f6: 2700 movs r7, #0 + while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) + 800c6f8: f64f 78fe movw r8, #65534 ; 0xfffe + 800c6fc: 9b06 ldr r3, [sp, #24] + 800c6fe: 4543 cmp r3, r8 + 800c700: d800 bhi.n 800c704 + 800c702: b12f cbz r7, 800c710 + if(count >= SDMMC_MAX_VOLT_TRIAL) + 800c704: 9b06 ldr r3, [sp, #24] + 800c706: 4543 cmp r3, r8 + 800c708: d918 bls.n 800c73c + return HAL_SD_ERROR_INVALID_VOLTRANGE; + 800c70a: f04f 7080 mov.w r0, #16777216 ; 0x1000000 + 800c70e: e7dc b.n 800c6ca + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c710: 6820 ldr r0, [r4, #0] + 800c712: 4639 mov r1, r7 + 800c714: f000 fedb bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800c718: 2800 cmp r0, #0 + 800c71a: d1d6 bne.n 800c6ca + errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); + 800c71c: 6820 ldr r0, [r4, #0] + 800c71e: 4649 mov r1, r9 + 800c720: f001 f816 bl 800d750 + if(errorstate != HAL_SD_ERROR_NONE) + 800c724: 2800 cmp r0, #0 + 800c726: d1de bne.n 800c6e6 + response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c728: 4639 mov r1, r7 + 800c72a: 6820 ldr r0, [r4, #0] + 800c72c: f000 fcb7 bl 800d09e + count++; + 800c730: 9b06 ldr r3, [sp, #24] + 800c732: 3301 adds r3, #1 + response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c734: 4605 mov r5, r0 + validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); + 800c736: 0fc7 lsrs r7, r0, #31 + count++; + 800c738: 9306 str r3, [sp, #24] + 800c73a: e7df b.n 800c6fc + if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ + 800c73c: f015 4380 ands.w r3, r5, #1073741824 ; 0x40000000 + 800c740: d04b beq.n 800c7da + hsd->SdCard.CardType = CARD_SDHC_SDXC; + 800c742: 2301 movs r3, #1 + 800c744: 63e3 str r3, [r4, #60] ; 0x3c + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c746: 69a3 ldr r3, [r4, #24] + errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); + 800c748: 6820 ldr r0, [r4, #0] + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800c74a: 2b01 cmp r3, #1 + 800c74c: d12d bne.n 800c7aa + if((response & SD_SWITCH_1_8V_CAPACITY) == SD_SWITCH_1_8V_CAPACITY) + 800c74e: 01ef lsls r7, r5, #7 + 800c750: d52b bpl.n 800c7aa + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + 800c752: f44f 7300 mov.w r3, #512 ; 0x200 + 800c756: 65e3 str r3, [r4, #92] ; 0x5c + hsd->Instance->POWER |= SDMMC_POWER_VSWITCHEN; + 800c758: 6803 ldr r3, [r0, #0] + 800c75a: f043 0308 orr.w r3, r3, #8 + 800c75e: 6003 str r3, [r0, #0] + errorstate = SDMMC_CmdVoltageSwitch(hsd->Instance); + 800c760: f000 ff4e bl 800d600 + if(errorstate != HAL_SD_ERROR_NONE) + 800c764: 2800 cmp r0, #0 + 800c766: d1b0 bne.n 800c6ca + while(( hsd->Instance->STA & SDMMC_FLAG_CKSTOP) != SDMMC_FLAG_CKSTOP) + 800c768: 6823 ldr r3, [r4, #0] + 800c76a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c76c: 0155 lsls r5, r2, #5 + 800c76e: d526 bpl.n 800c7be + hsd->Instance->ICR = SDMMC_FLAG_CKSTOP; + 800c770: f04f 6280 mov.w r2, #67108864 ; 0x4000000 + 800c774: 639a str r2, [r3, #56] ; 0x38 + if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) != SDMMC_FLAG_BUSYD0) + 800c776: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c778: 02d8 lsls r0, r3, #11 + 800c77a: d5b4 bpl.n 800c6e6 + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800c77c: 2001 movs r0, #1 + 800c77e: f7fa fe9d bl 80074bc + hsd->Instance->POWER |= SDMMC_POWER_VSWITCH; + 800c782: 6822 ldr r2, [r4, #0] + 800c784: 6813 ldr r3, [r2, #0] + 800c786: f043 0304 orr.w r3, r3, #4 + 800c78a: 6013 str r3, [r2, #0] + while(( hsd->Instance->STA & SDMMC_FLAG_VSWEND) != SDMMC_FLAG_VSWEND) + 800c78c: 6823 ldr r3, [r4, #0] + 800c78e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c790: 0191 lsls r1, r2, #6 + 800c792: d51c bpl.n 800c7ce + hsd->Instance->ICR = SDMMC_FLAG_VSWEND; + 800c794: f04f 7200 mov.w r2, #33554432 ; 0x2000000 + 800c798: 639a str r2, [r3, #56] ; 0x38 + if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) == SDMMC_FLAG_BUSYD0) + 800c79a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c79c: 02d2 lsls r2, r2, #11 + 800c79e: d4b4 bmi.n 800c70a + hsd->Instance->POWER = 0x13U; + 800c7a0: 2213 movs r2, #19 + 800c7a2: 601a str r2, [r3, #0] + hsd->Instance->ICR = 0xFFFFFFFFU; + 800c7a4: f04f 32ff mov.w r2, #4294967295 ; 0xffffffff + 800c7a8: 639a str r2, [r3, #56] ; 0x38 + uint16_t sd_rca = 1U; + 800c7aa: 2301 movs r3, #1 + if(SDMMC_GetPowerState(hsd->Instance) == 0U) + 800c7ac: 6820 ldr r0, [r4, #0] + uint16_t sd_rca = 1U; + 800c7ae: f8ad 3016 strh.w r3, [sp, #22] + if(SDMMC_GetPowerState(hsd->Instance) == 0U) + 800c7b2: f000 fc59 bl 800d068 + 800c7b6: b990 cbnz r0, 800c7de + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800c7b8: f04f 6080 mov.w r0, #67108864 ; 0x4000000 + 800c7bc: e785 b.n 800c6ca + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c7be: f7fa fe0d bl 80073dc + 800c7c2: 1b80 subs r0, r0, r6 + 800c7c4: 3001 adds r0, #1 + 800c7c6: d1cf bne.n 800c768 + return HAL_SD_ERROR_TIMEOUT; + 800c7c8: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800c7cc: e77d b.n 800c6ca + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c7ce: f7fa fe05 bl 80073dc + 800c7d2: 1b80 subs r0, r0, r6 + 800c7d4: 3001 adds r0, #1 + 800c7d6: d1d9 bne.n 800c78c + 800c7d8: e7f6 b.n 800c7c8 + hsd->SdCard.CardType = CARD_SDSC; + 800c7da: 63e3 str r3, [r4, #60] ; 0x3c + if(errorstate != HAL_SD_ERROR_NONE) + 800c7dc: e7e5 b.n 800c7aa + if(hsd->SdCard.CardType != CARD_SECURED) + 800c7de: 6be3 ldr r3, [r4, #60] ; 0x3c + 800c7e0: 2b03 cmp r3, #3 + 800c7e2: d045 beq.n 800c870 + errorstate = SDMMC_CmdSendCID(hsd->Instance); + 800c7e4: 6820 ldr r0, [r4, #0] + 800c7e6: f000 ff65 bl 800d6b4 + if(errorstate != HAL_SD_ERROR_NONE) + 800c7ea: 2800 cmp r0, #0 + 800c7ec: f47f af6d bne.w 800c6ca + hsd->CID[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c7f0: 4601 mov r1, r0 + 800c7f2: 6820 ldr r0, [r4, #0] + 800c7f4: f000 fc53 bl 800d09e + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c7f8: 2104 movs r1, #4 + hsd->CID[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c7fa: 6720 str r0, [r4, #112] ; 0x70 + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c7fc: 6820 ldr r0, [r4, #0] + 800c7fe: f000 fc4e bl 800d09e + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c802: 2108 movs r1, #8 + hsd->CID[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c804: 6760 str r0, [r4, #116] ; 0x74 + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c806: 6820 ldr r0, [r4, #0] + 800c808: f000 fc49 bl 800d09e + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c80c: 210c movs r1, #12 + hsd->CID[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c80e: 67a0 str r0, [r4, #120] ; 0x78 + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c810: 6820 ldr r0, [r4, #0] + 800c812: f000 fc44 bl 800d09e + if(hsd->SdCard.CardType != CARD_SECURED) + 800c816: 6be3 ldr r3, [r4, #60] ; 0x3c + hsd->CID[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c818: 67e0 str r0, [r4, #124] ; 0x7c + if(hsd->SdCard.CardType != CARD_SECURED) + 800c81a: 2b03 cmp r3, #3 + 800c81c: d028 beq.n 800c870 + errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca); + 800c81e: 6820 ldr r0, [r4, #0] + 800c820: f10d 0116 add.w r1, sp, #22 + 800c824: f001 f804 bl 800d830 + if(errorstate != HAL_SD_ERROR_NONE) + 800c828: 2800 cmp r0, #0 + 800c82a: f47f af4e bne.w 800c6ca + if(hsd->SdCard.CardType != CARD_SECURED) + 800c82e: 6be3 ldr r3, [r4, #60] ; 0x3c + errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c830: 6820 ldr r0, [r4, #0] + if(hsd->SdCard.CardType != CARD_SECURED) + 800c832: 2b03 cmp r3, #3 + 800c834: d01c beq.n 800c870 + hsd->SdCard.RelCardAdd = sd_rca; + 800c836: f8bd 1016 ldrh.w r1, [sp, #22] + 800c83a: 64a1 str r1, [r4, #72] ; 0x48 + errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c83c: 0409 lsls r1, r1, #16 + 800c83e: f000 ff4f bl 800d6e0 + if(errorstate != HAL_SD_ERROR_NONE) + 800c842: 2800 cmp r0, #0 + 800c844: f47f af41 bne.w 800c6ca + hsd->CSD[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c848: 4601 mov r1, r0 + 800c84a: 6820 ldr r0, [r4, #0] + 800c84c: f000 fc27 bl 800d09e + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c850: 2104 movs r1, #4 + hsd->CSD[0U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800c852: 6620 str r0, [r4, #96] ; 0x60 + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c854: 6820 ldr r0, [r4, #0] + 800c856: f000 fc22 bl 800d09e + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c85a: 2108 movs r1, #8 + hsd->CSD[1U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); + 800c85c: 6660 str r0, [r4, #100] ; 0x64 + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c85e: 6820 ldr r0, [r4, #0] + 800c860: f000 fc1d bl 800d09e + hsd->CSD[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c864: 210c movs r1, #12 + hsd->CSD[2U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); + 800c866: 66a0 str r0, [r4, #104] ; 0x68 + hsd->CSD[3U] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); + 800c868: 6820 ldr r0, [r4, #0] + 800c86a: f000 fc18 bl 800d09e + 800c86e: 66e0 str r0, [r4, #108] ; 0x6c + hsd->SdCard.Class = (SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2) >> 20U); + 800c870: 2104 movs r1, #4 + 800c872: 6820 ldr r0, [r4, #0] + 800c874: f000 fc13 bl 800d09e + 800c878: 0d00 lsrs r0, r0, #20 + 800c87a: 6460 str r0, [r4, #68] ; 0x44 + if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK) + 800c87c: a90d add r1, sp, #52 ; 0x34 + 800c87e: 4620 mov r0, r4 + 800c880: f7ff fe18 bl 800c4b4 + 800c884: 4605 mov r5, r0 + 800c886: 2800 cmp r0, #0 + 800c888: f47f af2d bne.w 800c6e6 + errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16U)); + 800c88c: 6ca2 ldr r2, [r4, #72] ; 0x48 + 800c88e: 4603 mov r3, r0 + 800c890: 0412 lsls r2, r2, #16 + 800c892: 6820 ldr r0, [r4, #0] + 800c894: f000 fe02 bl 800d49c + if(errorstate != HAL_SD_ERROR_NONE) + 800c898: 2800 cmp r0, #0 + 800c89a: f47f af16 bne.w 800c6ca + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800c89e: 6820 ldr r0, [r4, #0] + 800c8a0: f44f 7100 mov.w r1, #512 ; 0x200 + 800c8a4: f000 fcda bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800c8a8: 2800 cmp r0, #0 + 800c8aa: f43f aece beq.w 800c64a + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c8ae: 6823 ldr r3, [r4, #0] + 800c8b0: 4a06 ldr r2, [pc, #24] ; (800c8cc ) + 800c8b2: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c8b4: 6ba3 ldr r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c8b6: 2501 movs r5, #1 + hsd->ErrorCode |= errorstate; + 800c8b8: 4318 orrs r0, r3 + 800c8ba: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c8bc: f884 5034 strb.w r5, [r4, #52] ; 0x34 + return HAL_ERROR; + 800c8c0: e6c3 b.n 800c64a + 800c8c2: bf00 nop + 800c8c4: 000c3500 .word 0x000c3500 + 800c8c8: 00012110 .word 0x00012110 + 800c8cc: 1fe00fff .word 0x1fe00fff + 800c8d0: c1100000 .word 0xc1100000 + +0800c8d4 : +{ + 800c8d4: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr} + 800c8d8: b096 sub sp, #88 ; 0x58 + 800c8da: 4604 mov r4, r0 + 800c8dc: 460d mov r5, r1 + uint32_t tickstart = HAL_GetTick(); + 800c8de: f7fa fd7d bl 80073dc + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c8e2: 2100 movs r1, #0 + uint32_t tickstart = HAL_GetTick(); + 800c8e4: 4606 mov r6, r0 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800c8e6: 6820 ldr r0, [r4, #0] + 800c8e8: f000 fbd9 bl 800d09e + 800c8ec: 0183 lsls r3, r0, #6 + 800c8ee: d50b bpl.n 800c908 + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + 800c8f0: f44f 6000 mov.w r0, #2048 ; 0x800 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800c8f4: 6823 ldr r3, [r4, #0] + 800c8f6: 4a54 ldr r2, [pc, #336] ; (800ca48 ) + 800c8f8: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800c8fa: 6ba3 ldr r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c8fc: 2501 movs r5, #1 + hsd->ErrorCode |= errorstate; + 800c8fe: 4318 orrs r0, r3 + 800c900: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800c902: f884 5034 strb.w r5, [r4, #52] ; 0x34 + status = HAL_ERROR; + 800c906: e08a b.n 800ca1e + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800c908: 6820 ldr r0, [r4, #0] + 800c90a: 2140 movs r1, #64 ; 0x40 + 800c90c: f000 fca6 bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800c910: b110 cbz r0, 800c918 + hsd->ErrorCode |= HAL_SD_ERROR_NONE; + 800c912: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800c914: 63a3 str r3, [r4, #56] ; 0x38 + return errorstate; + 800c916: e7ed b.n 800c8f4 + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800c918: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800c91a: 6820 ldr r0, [r4, #0] + 800c91c: 0409 lsls r1, r1, #16 + 800c91e: f000 fdd6 bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800c922: 2800 cmp r0, #0 + 800c924: d1f5 bne.n 800c912 + config.DataLength = 64U; + 800c926: 2340 movs r3, #64 ; 0x40 + 800c928: f04f 37ff mov.w r7, #4294967295 ; 0xffffffff + 800c92c: e9cd 7300 strd r7, r3, [sp] + config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800c930: f04f 0c60 mov.w ip, #96 ; 0x60 + 800c934: 2302 movs r3, #2 + 800c936: e9cd c302 strd ip, r3, [sp, #8] + config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800c93a: 9004 str r0, [sp, #16] + config.DPSM = SDMMC_DPSM_ENABLE; + 800c93c: 2301 movs r3, #1 + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c93e: 6820 ldr r0, [r4, #0] + config.DPSM = SDMMC_DPSM_ENABLE; + 800c940: 9305 str r3, [sp, #20] + (void)SDMMC_ConfigData(hsd->Instance, &config); + 800c942: 4669 mov r1, sp + 800c944: f000 fbae bl 800d0a4 + errorstate = SDMMC_CmdStatusRegister(hsd->Instance); + 800c948: 6820 ldr r0, [r4, #0] + 800c94a: f000 fe40 bl 800d5ce + if(errorstate != HAL_SD_ERROR_NONE) + 800c94e: 2800 cmp r0, #0 + 800c950: d1df bne.n 800c912 + uint32_t *pData = pSDstatus; + 800c952: af06 add r7, sp, #24 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) + 800c954: 6823 ldr r3, [r4, #0] + 800c956: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c958: f412 7f95 tst.w r2, #298 ; 0x12a + 800c95c: d00a beq.n 800c974 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800c95e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c960: 0711 lsls r1, r2, #28 + 800c962: d46f bmi.n 800ca44 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800c964: 6b5a ldr r2, [r3, #52] ; 0x34 + 800c966: 0792 lsls r2, r2, #30 + 800c968: d46a bmi.n 800ca40 + else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800c96a: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c96c: 069b lsls r3, r3, #26 + 800c96e: d51e bpl.n 800c9ae + return HAL_SD_ERROR_RX_OVERRUN; + 800c970: 2020 movs r0, #32 + 800c972: e7bf b.n 800c8f4 + if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800c974: 6b5b ldr r3, [r3, #52] ; 0x34 + 800c976: 0418 lsls r0, r3, #16 + 800c978: d508 bpl.n 800c98c + 800c97a: f107 0820 add.w r8, r7, #32 + *pData = SDMMC_ReadFIFO(hsd->Instance); + 800c97e: 6820 ldr r0, [r4, #0] + 800c980: f000 fb54 bl 800d02c + 800c984: f847 0b04 str.w r0, [r7], #4 + for(count = 0U; count < 8U; count++) + 800c988: 45b8 cmp r8, r7 + 800c98a: d1f8 bne.n 800c97e + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c98c: f7fa fd26 bl 80073dc + 800c990: 1b80 subs r0, r0, r6 + 800c992: 3001 adds r0, #1 + 800c994: d1de bne.n 800c954 + return HAL_SD_ERROR_TIMEOUT; + 800c996: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + if(errorstate != HAL_SD_ERROR_NONE) + 800c99a: e7ab b.n 800c8f4 + *pData = SDMMC_ReadFIFO(hsd->Instance); + 800c99c: f000 fb46 bl 800d02c + 800c9a0: f847 0b04 str.w r0, [r7], #4 + if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800c9a4: f7fa fd1a bl 80073dc + 800c9a8: 1b80 subs r0, r0, r6 + 800c9aa: 3001 adds r0, #1 + 800c9ac: d0f3 beq.n 800c996 + while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DPSMACT))) + 800c9ae: 6820 ldr r0, [r4, #0] + 800c9b0: 6b43 ldr r3, [r0, #52] ; 0x34 + 800c9b2: f413 5380 ands.w r3, r3, #4096 ; 0x1000 + 800c9b6: d1f1 bne.n 800c99c + pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); + 800c9b8: 9906 ldr r1, [sp, #24] + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800c9ba: 4a24 ldr r2, [pc, #144] ; (800ca4c ) + 800c9bc: 6382 str r2, [r0, #56] ; 0x38 + pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); + 800c9be: f3c1 1281 ubfx r2, r1, #6, #2 + 800c9c2: 702a strb r2, [r5, #0] + pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U); + 800c9c4: f3c1 1240 ubfx r2, r1, #5, #1 + 800c9c8: 706a strb r2, [r5, #1] + pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U)); + 800c9ca: 0a0a lsrs r2, r1, #8 + 800c9cc: f022 02ff bic.w r2, r2, #255 ; 0xff + 800c9d0: ea42 6211 orr.w r2, r2, r1, lsr #24 + 800c9d4: b292 uxth r2, r2 + 800c9d6: 806a strh r2, [r5, #2] + pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U) | ((sd_status[1] & 0xFF00U) << 8U) | + 800c9d8: 9a07 ldr r2, [sp, #28] + 800c9da: ba12 rev r2, r2 + 800c9dc: 606a str r2, [r5, #4] + pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU); + 800c9de: 9a08 ldr r2, [sp, #32] + 800c9e0: b2d1 uxtb r1, r2 + 800c9e2: 7229 strb r1, [r5, #8] + pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U); + 800c9e4: f3c2 2107 ubfx r1, r2, #8, #8 + 800c9e8: 7269 strb r1, [r5, #9] + pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U); + 800c9ea: f3c2 5103 ubfx r1, r2, #20, #4 + 800c9ee: 72a9 strb r1, [r5, #10] + pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU)); + 800c9f0: 9909 ldr r1, [sp, #36] ; 0x24 + 800c9f2: 0c12 lsrs r2, r2, #16 + 800c9f4: b2c8 uxtb r0, r1 + 800c9f6: f022 02ff bic.w r2, r2, #255 ; 0xff + 800c9fa: 4302 orrs r2, r0 + 800c9fc: 81aa strh r2, [r5, #12] + pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U); + 800c9fe: f3c1 2285 ubfx r2, r1, #10, #6 + 800ca02: 73aa strb r2, [r5, #14] + pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U); + 800ca04: f3c1 2201 ubfx r2, r1, #8, #2 + 800ca08: 73ea strb r2, [r5, #15] + pStatus->UhsSpeedGrade = (uint8_t)((sd_status[3] & 0x00F0U) >> 4U); + 800ca0a: f3c1 1203 ubfx r2, r1, #4, #4 + 800ca0e: 742a strb r2, [r5, #16] + pStatus->UhsAllocationUnitSize = (uint8_t)(sd_status[3] & 0x000FU) ; + 800ca10: f001 010f and.w r1, r1, #15 + pStatus->VideoSpeedClass = (uint8_t)((sd_status[4] & 0xFF000000U) >> 24U); + 800ca14: f89d 202b ldrb.w r2, [sp, #43] ; 0x2b + pStatus->UhsAllocationUnitSize = (uint8_t)(sd_status[3] & 0x000FU) ; + 800ca18: 7469 strb r1, [r5, #17] + pStatus->VideoSpeedClass = (uint8_t)((sd_status[4] & 0xFF000000U) >> 24U); + 800ca1a: 74aa strb r2, [r5, #18] + HAL_StatusTypeDef status = HAL_OK; + 800ca1c: 461d mov r5, r3 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800ca1e: 6820 ldr r0, [r4, #0] + 800ca20: f44f 7100 mov.w r1, #512 ; 0x200 + 800ca24: f000 fc1a bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800ca28: b130 cbz r0, 800ca38 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800ca2a: 6823 ldr r3, [r4, #0] + 800ca2c: 4a06 ldr r2, [pc, #24] ; (800ca48 ) + 800ca2e: 639a str r2, [r3, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800ca30: 2501 movs r5, #1 + hsd->ErrorCode = errorstate; + 800ca32: 63a0 str r0, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800ca34: f884 5034 strb.w r5, [r4, #52] ; 0x34 +} + 800ca38: 4628 mov r0, r5 + 800ca3a: b016 add sp, #88 ; 0x58 + 800ca3c: e8bd 81f0 ldmia.w sp!, {r4, r5, r6, r7, r8, pc} + return HAL_SD_ERROR_DATA_CRC_FAIL; + 800ca40: 2002 movs r0, #2 + 800ca42: e757 b.n 800c8f4 + return HAL_SD_ERROR_DATA_TIMEOUT; + 800ca44: 2008 movs r0, #8 + 800ca46: e755 b.n 800c8f4 + 800ca48: 1fe00fff .word 0x1fe00fff + 800ca4c: 18000f3a .word 0x18000f3a + +0800ca50 : + pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType); + 800ca50: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800ca52: 600b str r3, [r1, #0] + pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion); + 800ca54: 6c03 ldr r3, [r0, #64] ; 0x40 + 800ca56: 604b str r3, [r1, #4] + pCardInfo->Class = (uint32_t)(hsd->SdCard.Class); + 800ca58: 6c43 ldr r3, [r0, #68] ; 0x44 + 800ca5a: 608b str r3, [r1, #8] + pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd); + 800ca5c: 6c83 ldr r3, [r0, #72] ; 0x48 + 800ca5e: 60cb str r3, [r1, #12] + pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr); + 800ca60: 6cc3 ldr r3, [r0, #76] ; 0x4c + 800ca62: 610b str r3, [r1, #16] + pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize); + 800ca64: 6d03 ldr r3, [r0, #80] ; 0x50 + 800ca66: 614b str r3, [r1, #20] + pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr); + 800ca68: 6d43 ldr r3, [r0, #84] ; 0x54 + 800ca6a: 618b str r3, [r1, #24] + pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize); + 800ca6c: 6d83 ldr r3, [r0, #88] ; 0x58 + 800ca6e: 61cb str r3, [r1, #28] +} + 800ca70: 2000 movs r0, #0 + 800ca72: 4770 bx lr + +0800ca74 : +{ + 800ca74: b530 push {r4, r5, lr} + hsd->State = HAL_SD_STATE_BUSY; + 800ca76: 2303 movs r3, #3 + 800ca78: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->SdCard.CardType != CARD_SECURED) + 800ca7c: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800ca7e: 2b03 cmp r3, #3 +{ + 800ca80: b08b sub sp, #44 ; 0x2c + 800ca82: 4604 mov r4, r0 + 800ca84: 460d mov r5, r1 + if(hsd->SdCard.CardType != CARD_SECURED) + 800ca86: d002 beq.n 800ca8e + if(WideMode == SDMMC_BUS_WIDE_8B) + 800ca88: f5b1 4f00 cmp.w r1, #32768 ; 0x8000 + 800ca8c: d103 bne.n 800ca96 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800ca8e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800ca90: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + 800ca94: e049 b.n 800cb2a + else if(WideMode == SDMMC_BUS_WIDE_4B) + 800ca96: f5b1 4f80 cmp.w r1, #16384 ; 0x4000 + 800ca9a: d123 bne.n 800cae4 + uint32_t scr[2U] = {0UL, 0UL}; + 800ca9c: 2100 movs r1, #0 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800ca9e: 6800 ldr r0, [r0, #0] + uint32_t scr[2U] = {0UL, 0UL}; + 800caa0: e9cd 1104 strd r1, r1, [sp, #16] + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800caa4: f000 fafb bl 800d09e + 800caa8: 0180 lsls r0, r0, #6 + 800caaa: d435 bmi.n 800cb18 + errorstate = SD_FindSCR(hsd, scr); + 800caac: a904 add r1, sp, #16 + 800caae: 4620 mov r0, r4 + 800cab0: f7ff fa32 bl 800bf18 + if(errorstate != HAL_SD_ERROR_NONE) + 800cab4: b960 cbnz r0, 800cad0 + if((scr[1U] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO) + 800cab6: 9b05 ldr r3, [sp, #20] + 800cab8: 0359 lsls r1, r3, #13 + 800caba: d530 bpl.n 800cb1e + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800cabc: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800cabe: 6820 ldr r0, [r4, #0] + 800cac0: 0409 lsls r1, r1, #16 + 800cac2: f000 fd04 bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800cac6: b918 cbnz r0, 800cad0 + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2U); + 800cac8: 2102 movs r1, #2 + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U); + 800caca: 6820 ldr r0, [r4, #0] + 800cacc: f000 fd18 bl 800d500 + hsd->ErrorCode |= errorstate; + 800cad0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cad2: 4318 orrs r0, r3 + 800cad4: 63a0 str r0, [r4, #56] ; 0x38 + if(hsd->ErrorCode != HAL_SD_ERROR_NONE) + 800cad6: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cad8: b34b cbz r3, 800cb2e + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800cada: 6823 ldr r3, [r4, #0] + 800cadc: 4a42 ldr r2, [pc, #264] ; (800cbe8 ) + 800cade: 639a str r2, [r3, #56] ; 0x38 + status = HAL_ERROR; + 800cae0: 2501 movs r5, #1 + 800cae2: e054 b.n 800cb8e + else if(WideMode == SDMMC_BUS_WIDE_1B) + 800cae4: b9f1 cbnz r1, 800cb24 + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800cae6: 6800 ldr r0, [r0, #0] + uint32_t scr[2U] = {0UL, 0UL}; + 800cae8: e9cd 1104 strd r1, r1, [sp, #16] + if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) + 800caec: f000 fad7 bl 800d09e + 800caf0: 0182 lsls r2, r0, #6 + 800caf2: d411 bmi.n 800cb18 + errorstate = SD_FindSCR(hsd, scr); + 800caf4: a904 add r1, sp, #16 + 800caf6: 4620 mov r0, r4 + 800caf8: f7ff fa0e bl 800bf18 + if(errorstate != HAL_SD_ERROR_NONE) + 800cafc: 2800 cmp r0, #0 + 800cafe: d1e7 bne.n 800cad0 + if((scr[1U] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO) + 800cb00: 9b05 ldr r3, [sp, #20] + 800cb02: 03db lsls r3, r3, #15 + 800cb04: d50b bpl.n 800cb1e + errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800cb06: 6ca1 ldr r1, [r4, #72] ; 0x48 + 800cb08: 6820 ldr r0, [r4, #0] + 800cb0a: 0409 lsls r1, r1, #16 + 800cb0c: f000 fcdf bl 800d4ce + if(errorstate != HAL_SD_ERROR_NONE) + 800cb10: 2800 cmp r0, #0 + 800cb12: d1dd bne.n 800cad0 + errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0U); + 800cb14: 4601 mov r1, r0 + 800cb16: e7d8 b.n 800caca + return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; + 800cb18: f44f 6000 mov.w r0, #2048 ; 0x800 + 800cb1c: e7d8 b.n 800cad0 + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800cb1e: f04f 6080 mov.w r0, #67108864 ; 0x4000000 + 800cb22: e7d5 b.n 800cad0 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800cb24: 6b83 ldr r3, [r0, #56] ; 0x38 + 800cb26: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800cb2a: 63a3 str r3, [r4, #56] ; 0x38 + 800cb2c: e7d3 b.n 800cad6 + sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); + 800cb2e: f44f 2000 mov.w r0, #524288 ; 0x80000 + 800cb32: f7fd f8af bl 8009c94 + if (sdmmc_clk != 0U) + 800cb36: 2800 cmp r0, #0 + 800cb38: d051 beq.n 800cbde + Init.ClockEdge = hsd->Init.ClockEdge; + 800cb3a: 6863 ldr r3, [r4, #4] + 800cb3c: 9304 str r3, [sp, #16] + Init.ClockPowerSave = hsd->Init.ClockPowerSave; + 800cb3e: 68a3 ldr r3, [r4, #8] + if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) + 800cb40: 492a ldr r1, [pc, #168] ; (800cbec ) + 800cb42: fbb0 f2f1 udiv r2, r0, r1 + Init.BusWide = WideMode; + 800cb46: e9cd 3505 strd r3, r5, [sp, #20] + Init.HardwareFlowControl = hsd->Init.HardwareFlowControl; + 800cb4a: 6923 ldr r3, [r4, #16] + 800cb4c: 9307 str r3, [sp, #28] + if (hsd->Init.ClockDiv >= (sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ))) + 800cb4e: 6963 ldr r3, [r4, #20] + 800cb50: 4293 cmp r3, r2 + 800cb52: d301 bcc.n 800cb58 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800cb54: 9308 str r3, [sp, #32] + 800cb56: e00d b.n 800cb74 + else if (hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) + 800cb58: 6de5 ldr r5, [r4, #92] ; 0x5c + 800cb5a: f5b5 7f00 cmp.w r5, #512 ; 0x200 + 800cb5e: d0f9 beq.n 800cb54 + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800cb60: f5b5 7f80 cmp.w r5, #256 ; 0x100 + 800cb64: d12e bne.n 800cbc4 + if (hsd->Init.ClockDiv == 0U) + 800cb66: bb3b cbnz r3, 800cbb8 + if (sdmmc_clk > SD_HIGH_SPEED_FREQ) + 800cb68: 4288 cmp r0, r1 + 800cb6a: d923 bls.n 800cbb4 + Init.ClockDiv = sdmmc_clk / (2U * SD_HIGH_SPEED_FREQ); + 800cb6c: 4b20 ldr r3, [pc, #128] ; (800cbf0 ) + 800cb6e: fbb0 f0f3 udiv r0, r0, r3 + 800cb72: 9008 str r0, [sp, #32] + Init.Transceiver = hsd->Init.Transceiver; + 800cb74: 69a3 ldr r3, [r4, #24] + 800cb76: 9309 str r3, [sp, #36] ; 0x24 + (void)SDMMC_Init(hsd->Instance, Init); + 800cb78: ab0a add r3, sp, #40 ; 0x28 + 800cb7a: e913 0007 ldmdb r3, {r0, r1, r2} + 800cb7e: e88d 0007 stmia.w sp, {r0, r1, r2} + 800cb82: ab04 add r3, sp, #16 + 800cb84: cb0e ldmia r3, {r1, r2, r3} + 800cb86: 6820 ldr r0, [r4, #0] + 800cb88: f000 fa36 bl 800cff8 + HAL_StatusTypeDef status = HAL_OK; + 800cb8c: 2500 movs r5, #0 + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800cb8e: 6820 ldr r0, [r4, #0] + 800cb90: f44f 7100 mov.w r1, #512 ; 0x200 + 800cb94: f000 fb62 bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800cb98: b130 cbz r0, 800cba8 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800cb9a: 6823 ldr r3, [r4, #0] + 800cb9c: 4a12 ldr r2, [pc, #72] ; (800cbe8 ) + 800cb9e: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800cba0: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cba2: 4318 orrs r0, r3 + 800cba4: 63a0 str r0, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800cba6: 2501 movs r5, #1 + hsd->State = HAL_SD_STATE_READY; + 800cba8: 2301 movs r3, #1 +} + 800cbaa: 4628 mov r0, r5 + hsd->State = HAL_SD_STATE_READY; + 800cbac: f884 3034 strb.w r3, [r4, #52] ; 0x34 +} + 800cbb0: b00b add sp, #44 ; 0x2c + 800cbb2: bd30 pop {r4, r5, pc} + Init.ClockDiv = hsd->Init.ClockDiv; + 800cbb4: 2300 movs r3, #0 + 800cbb6: e7cd b.n 800cb54 + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_HIGH_SPEED_FREQ) + 800cbb8: 005a lsls r2, r3, #1 + 800cbba: fbb0 f2f2 udiv r2, r0, r2 + 800cbbe: 428a cmp r2, r1 + 800cbc0: d9c8 bls.n 800cb54 + 800cbc2: e7d3 b.n 800cb6c + if (hsd->Init.ClockDiv == 0U) + 800cbc4: 490b ldr r1, [pc, #44] ; (800cbf4 ) + 800cbc6: b91b cbnz r3, 800cbd0 + if (sdmmc_clk > SD_NORMAL_SPEED_FREQ) + 800cbc8: 4288 cmp r0, r1 + 800cbca: d9f3 bls.n 800cbb4 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800cbcc: 9208 str r2, [sp, #32] + 800cbce: e7d1 b.n 800cb74 + if ((sdmmc_clk/(2U * hsd->Init.ClockDiv)) > SD_NORMAL_SPEED_FREQ) + 800cbd0: 005d lsls r5, r3, #1 + 800cbd2: fbb0 f0f5 udiv r0, r0, r5 + Init.ClockDiv = sdmmc_clk / (2U * SD_NORMAL_SPEED_FREQ); + 800cbd6: 4288 cmp r0, r1 + 800cbd8: bf88 it hi + 800cbda: 4613 movhi r3, r2 + 800cbdc: e7ba b.n 800cb54 + hsd->ErrorCode |= SDMMC_ERROR_INVALID_PARAMETER; + 800cbde: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cbe0: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + 800cbe4: 63a3 str r3, [r4, #56] ; 0x38 + 800cbe6: e77b b.n 800cae0 + 800cbe8: 1fe00fff .word 0x1fe00fff + 800cbec: 02faf080 .word 0x02faf080 + 800cbf0: 05f5e100 .word 0x05f5e100 + 800cbf4: 017d7840 .word 0x017d7840 + +0800cbf8 : + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800cbf8: 6c81 ldr r1, [r0, #72] ; 0x48 +{ + 800cbfa: b510 push {r4, lr} + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800cbfc: 0409 lsls r1, r1, #16 +{ + 800cbfe: 4604 mov r4, r0 + errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); + 800cc00: 6800 ldr r0, [r0, #0] + 800cc02: f000 fccb bl 800d59c + if(errorstate != HAL_SD_ERROR_NONE) + 800cc06: 4601 mov r1, r0 + 800cc08: b928 cbnz r0, 800cc16 + *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); + 800cc0a: 6820 ldr r0, [r4, #0] + 800cc0c: f000 fa47 bl 800d09e +} + 800cc10: f3c0 2043 ubfx r0, r0, #9, #4 + 800cc14: bd10 pop {r4, pc} + hsd->ErrorCode |= errorstate; + 800cc16: 6ba0 ldr r0, [r4, #56] ; 0x38 + 800cc18: 4308 orrs r0, r1 + 800cc1a: 63a0 str r0, [r4, #56] ; 0x38 + uint32_t resp1 = 0; + 800cc1c: 2000 movs r0, #0 + 800cc1e: e7f7 b.n 800cc10 + +0800cc20 : +{ + 800cc20: b570 push {r4, r5, r6, lr} + if(hsd == NULL) + 800cc22: 4604 mov r4, r0 +{ + 800cc24: b086 sub sp, #24 + if(hsd == NULL) + 800cc26: b918 cbnz r0, 800cc30 + return HAL_ERROR; + 800cc28: 2501 movs r5, #1 +} + 800cc2a: 4628 mov r0, r5 + 800cc2c: b006 add sp, #24 + 800cc2e: bd70 pop {r4, r5, r6, pc} + if(hsd->State == HAL_SD_STATE_RESET) + 800cc30: f890 3034 ldrb.w r3, [r0, #52] ; 0x34 + 800cc34: f003 02ff and.w r2, r3, #255 ; 0xff + 800cc38: b913 cbnz r3, 800cc40 + hsd->Lock = HAL_UNLOCKED; + 800cc3a: 7702 strb r2, [r0, #28] + HAL_SD_MspInit(hsd); + 800cc3c: f7ff fa5a bl 800c0f4 + hsd->State = HAL_SD_STATE_BUSY; + 800cc40: 2303 movs r3, #3 + 800cc42: f884 3034 strb.w r3, [r4, #52] ; 0x34 + if (HAL_SD_InitCard(hsd) != HAL_OK) + 800cc46: 4620 mov r0, r4 + 800cc48: f7ff fcea bl 800c620 + 800cc4c: 2800 cmp r0, #0 + 800cc4e: d1eb bne.n 800cc28 + if( HAL_SD_GetCardStatus(hsd, &CardStatus) != HAL_OK) + 800cc50: a901 add r1, sp, #4 + 800cc52: 4620 mov r0, r4 + 800cc54: f7ff fe3e bl 800c8d4 + 800cc58: 2800 cmp r0, #0 + 800cc5a: d1e5 bne.n 800cc28 + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800cc5c: 6be1 ldr r1, [r4, #60] ; 0x3c + speedgrade = CardStatus.UhsSpeedGrade; + 800cc5e: f89d 2014 ldrb.w r2, [sp, #20] + unitsize = CardStatus.UhsAllocationUnitSize; + 800cc62: f89d 3015 ldrb.w r3, [sp, #21] + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800cc66: 2901 cmp r1, #1 + speedgrade = CardStatus.UhsSpeedGrade; + 800cc68: b2d2 uxtb r2, r2 + unitsize = CardStatus.UhsAllocationUnitSize; + 800cc6a: b2db uxtb r3, r3 + if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))) + 800cc6c: d11c bne.n 800cca8 + 800cc6e: 4313 orrs r3, r2 + hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; + 800cc70: bf14 ite ne + 800cc72: f44f 7300 movne.w r3, #512 ; 0x200 + hsd->SdCard.CardSpeed = CARD_HIGH_SPEED; + 800cc76: f44f 7380 moveq.w r3, #256 ; 0x100 + 800cc7a: 65e3 str r3, [r4, #92] ; 0x5c + if(HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK) + 800cc7c: 68e1 ldr r1, [r4, #12] + 800cc7e: 4620 mov r0, r4 + 800cc80: f7ff fef8 bl 800ca74 + 800cc84: 4605 mov r5, r0 + 800cc86: 2800 cmp r0, #0 + 800cc88: d1ce bne.n 800cc28 + tickstart = HAL_GetTick(); + 800cc8a: f7fa fba7 bl 80073dc + 800cc8e: 4606 mov r6, r0 + while((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + 800cc90: 4620 mov r0, r4 + 800cc92: f7ff ffb1 bl 800cbf8 + 800cc96: 2804 cmp r0, #4 + 800cc98: d108 bne.n 800ccac + hsd->ErrorCode = HAL_SD_ERROR_NONE; + 800cc9a: 2300 movs r3, #0 + 800cc9c: 63a3 str r3, [r4, #56] ; 0x38 + hsd->Context = SD_CONTEXT_NONE; + 800cc9e: 6323 str r3, [r4, #48] ; 0x30 + hsd->State = HAL_SD_STATE_READY; + 800cca0: 2301 movs r3, #1 + 800cca2: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_OK; + 800cca6: e7c0 b.n 800cc2a + hsd->SdCard.CardSpeed = CARD_NORMAL_SPEED; + 800cca8: 65e0 str r0, [r4, #92] ; 0x5c + 800ccaa: e7e7 b.n 800cc7c + if((HAL_GetTick()-tickstart) >= SDMMC_DATATIMEOUT) + 800ccac: f7fa fb96 bl 80073dc + 800ccb0: 1b80 subs r0, r0, r6 + 800ccb2: 3001 adds r0, #1 + 800ccb4: d1ec bne.n 800cc90 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800ccb6: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800ccba: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800ccbc: 2301 movs r3, #1 + 800ccbe: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->Context = SD_CONTEXT_NONE; + 800ccc2: 2300 movs r3, #0 + 800ccc4: 6323 str r3, [r4, #48] ; 0x30 + return HAL_TIMEOUT; + 800ccc6: 2503 movs r5, #3 + 800ccc8: e7af b.n 800cc2a + ... + +0800cccc : +{ + 800cccc: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + uint32_t SD_hs[16] = {0}; + 800ccd0: 2640 movs r6, #64 ; 0x40 +{ + 800ccd2: b096 sub sp, #88 ; 0x58 + 800ccd4: 4605 mov r5, r0 + uint32_t SD_hs[16] = {0}; + 800ccd6: 4632 mov r2, r6 + 800ccd8: 2100 movs r1, #0 + 800ccda: a806 add r0, sp, #24 + 800ccdc: f000 fe22 bl 800d924 + uint32_t Timeout = HAL_GetTick(); + 800cce0: f7fa fb7c bl 80073dc + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800cce4: 6deb ldr r3, [r5, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800cce6: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800cce8: 2b00 cmp r3, #0 + 800ccea: d066 beq.n 800cdba + if(hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800ccec: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800ccf0: d004 beq.n 800ccfc + uint32_t errorstate = HAL_SD_ERROR_NONE; + 800ccf2: 2400 movs r4, #0 +} + 800ccf4: 4620 mov r0, r4 + 800ccf6: b016 add sp, #88 ; 0x58 + 800ccf8: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + hsd->Instance->DCTRL = 0; + 800ccfc: 6828 ldr r0, [r5, #0] + 800ccfe: 2300 movs r3, #0 + 800cd00: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800cd02: 4631 mov r1, r6 + 800cd04: f000 faaa bl 800d25c + if (errorstate != HAL_SD_ERROR_NONE) + 800cd08: 4604 mov r4, r0 + 800cd0a: 2800 cmp r0, #0 + 800cd0c: d1f2 bne.n 800ccf4 + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800cd0e: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800cd12: e9cd 3600 strd r3, r6, [sp] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800cd16: 2260 movs r2, #96 ; 0x60 + 800cd18: 2302 movs r3, #2 + 800cd1a: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + 800cd1e: 9004 str r0, [sp, #16] + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800cd20: 2301 movs r3, #1 + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800cd22: 6828 ldr r0, [r5, #0] + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800cd24: 9305 str r3, [sp, #20] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800cd26: 4669 mov r1, sp + 800cd28: f000 f9bc bl 800d0a4 + 800cd2c: 2800 cmp r0, #0 + 800cd2e: d147 bne.n 800cdc0 + errorstate = SDMMC_CmdSwitch(hsd->Instance,SDMMC_SDR25_SWITCH_PATTERN); + 800cd30: 4925 ldr r1, [pc, #148] ; (800cdc8 ) + 800cd32: 6828 ldr r0, [r5, #0] + 800cd34: f000 fbfd bl 800d532 + if(errorstate != HAL_SD_ERROR_NONE) + 800cd38: 4604 mov r4, r0 + 800cd3a: 2800 cmp r0, #0 + 800cd3c: d1da bne.n 800ccf4 + uint32_t count, loop = 0 ; + 800cd3e: 4607 mov r7, r0 + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800cd40: f240 592a movw r9, #1322 ; 0x52a + 800cd44: 682b ldr r3, [r5, #0] + 800cd46: 6b5e ldr r6, [r3, #52] ; 0x34 + 800cd48: ea16 0609 ands.w r6, r6, r9 + 800cd4c: d005 beq.n 800cd5a + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800cd4e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cd50: 0710 lsls r0, r2, #28 + 800cd52: d51e bpl.n 800cd92 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800cd54: 2208 movs r2, #8 + 800cd56: 639a str r2, [r3, #56] ; 0x38 + return errorstate; + 800cd58: e7cc b.n 800ccf4 + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800cd5a: 6b5b ldr r3, [r3, #52] ; 0x34 + 800cd5c: 041b lsls r3, r3, #16 + 800cd5e: d50b bpl.n 800cd78 + 800cd60: ab06 add r3, sp, #24 + 800cd62: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cd66: 6828 ldr r0, [r5, #0] + 800cd68: f000 f960 bl 800d02c + for (count = 0U; count < 8U; count++) + 800cd6c: 3601 adds r6, #1 + 800cd6e: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cd70: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800cd74: d1f7 bne.n 800cd66 + loop ++; + 800cd76: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800cd78: f7fa fb30 bl 80073dc + 800cd7c: eba0 0008 sub.w r0, r0, r8 + 800cd80: 3001 adds r0, #1 + 800cd82: d1df bne.n 800cd44 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800cd84: f04f 4400 mov.w r4, #2147483648 ; 0x80000000 + hsd->State= HAL_SD_STATE_READY; + 800cd88: 2301 movs r3, #1 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800cd8a: 63ac str r4, [r5, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800cd8c: f885 3034 strb.w r3, [r5, #52] ; 0x34 + return HAL_SD_ERROR_TIMEOUT; + 800cd90: e7b0 b.n 800ccf4 + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800cd92: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cd94: 0791 lsls r1, r2, #30 + 800cd96: d502 bpl.n 800cd9e + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800cd98: 2402 movs r4, #2 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cd9a: 639c str r4, [r3, #56] ; 0x38 + return errorstate; + 800cd9c: e7aa b.n 800ccf4 + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800cd9e: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cda0: 0692 lsls r2, r2, #26 + 800cda2: d501 bpl.n 800cda8 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cda4: 2420 movs r4, #32 + 800cda6: e7f8 b.n 800cd9a + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800cda8: 4a08 ldr r2, [pc, #32] ; (800cdcc ) + 800cdaa: 639a str r2, [r3, #56] ; 0x38 + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800cdac: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800cdb0: 079b lsls r3, r3, #30 + 800cdb2: d49e bmi.n 800ccf2 + errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; + 800cdb4: f04f 5480 mov.w r4, #268435456 ; 0x10000000 + 800cdb8: e79c b.n 800ccf4 + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + 800cdba: f04f 6480 mov.w r4, #67108864 ; 0x4000000 + 800cdbe: e799 b.n 800ccf4 + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + 800cdc0: f44f 3480 mov.w r4, #65536 ; 0x10000 + 800cdc4: e796 b.n 800ccf4 + 800cdc6: bf00 nop + 800cdc8: 80ffff01 .word 0x80ffff01 + 800cdcc: 18000f3a .word 0x18000f3a + +0800cdd0 : +{ + 800cdd0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} + hsd->State = HAL_SD_STATE_BUSY; + 800cdd4: 2303 movs r3, #3 + 800cdd6: f880 3034 strb.w r3, [r0, #52] ; 0x34 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800cdda: 6983 ldr r3, [r0, #24] + 800cddc: 2b01 cmp r3, #1 +{ + 800cdde: b096 sub sp, #88 ; 0x58 + 800cde0: 4604 mov r4, r0 + if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) + 800cde2: f040 80cf bne.w 800cf84 + switch (SpeedMode) + 800cde6: 2904 cmp r1, #4 + 800cde8: f200 80eb bhi.w 800cfc2 + 800cdec: e8df f011 tbh [pc, r1, lsl #1] + 800cdf0: 00150005 .word 0x00150005 + 800cdf4: 001e00dc .word 0x001e00dc + 800cdf8: 0031 .short 0x0031 + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cdfa: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800cdfc: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ce00: d002 beq.n 800ce08 + 800ce02: 6bc2 ldr r2, [r0, #60] ; 0x3c + 800ce04: 2a01 cmp r2, #1 + 800ce06: d10a bne.n 800ce1e + hsd->Instance->CLKCR |= 0x00100000U; + 800ce08: 6822 ldr r2, [r4, #0] + 800ce0a: 6853 ldr r3, [r2, #4] + 800ce0c: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800ce10: 6053 str r3, [r2, #4] + if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800ce12: 4620 mov r0, r4 + 800ce14: f7ff f8e6 bl 800bfe4 + 800ce18: b920 cbnz r0, 800ce24 + switch (SpeedMode) + 800ce1a: 2500 movs r5, #0 + 800ce1c: e063 b.n 800cee6 + else if (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) + 800ce1e: f5b3 7f80 cmp.w r3, #256 ; 0x100 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800ce22: d1fa bne.n 800ce1a + if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800ce24: 4620 mov r0, r4 + 800ce26: f7ff ff51 bl 800cccc + 800ce2a: e00f b.n 800ce4c + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800ce2c: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800ce2e: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ce32: d003 beq.n 800ce3c + 800ce34: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800ce36: 2b01 cmp r3, #1 + 800ce38: f040 8089 bne.w 800cf4e + hsd->Instance->CLKCR |= 0x00100000U; + 800ce3c: 6822 ldr r2, [r4, #0] + 800ce3e: 6853 ldr r3, [r2, #4] + 800ce40: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800ce44: 6053 str r3, [r2, #4] + if (SD_UltraHighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800ce46: 4620 mov r0, r4 + 800ce48: f7ff f8cc bl 800bfe4 + if (SD_HighSpeed(hsd) != HAL_SD_ERROR_NONE) + 800ce4c: 2800 cmp r0, #0 + 800ce4e: d0e4 beq.n 800ce1a + 800ce50: e07d b.n 800cf4e + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800ce52: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800ce54: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ce58: d002 beq.n 800ce60 + 800ce5a: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800ce5c: 2b01 cmp r3, #1 + 800ce5e: d176 bne.n 800cf4e + hsd->Instance->CLKCR |= 0x00100000U; + 800ce60: 6822 ldr r2, [r4, #0] + 800ce62: 6853 ldr r3, [r2, #4] + */ +static uint32_t SD_DDR_Mode(SD_HandleTypeDef *hsd) +{ + uint32_t errorstate = HAL_SD_ERROR_NONE; + SDMMC_DataInitTypeDef sdmmc_datainitstructure; + uint32_t SD_hs[16] = {0}; + 800ce64: 2540 movs r5, #64 ; 0x40 + hsd->Instance->CLKCR |= 0x00100000U; + 800ce66: f443 1380 orr.w r3, r3, #1048576 ; 0x100000 + 800ce6a: 6053 str r3, [r2, #4] + uint32_t SD_hs[16] = {0}; + 800ce6c: 2100 movs r1, #0 + 800ce6e: 462a mov r2, r5 + 800ce70: a806 add r0, sp, #24 + 800ce72: f000 fd57 bl 800d924 + uint32_t count, loop = 0 ; + uint32_t Timeout = HAL_GetTick(); + 800ce76: f7fa fab1 bl 80073dc + + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800ce7a: 6de3 ldr r3, [r4, #92] ; 0x5c + uint32_t Timeout = HAL_GetTick(); + 800ce7c: 4680 mov r8, r0 + if(hsd->SdCard.CardSpeed == CARD_NORMAL_SPEED) + 800ce7e: 2b00 cmp r3, #0 + 800ce80: d065 beq.n 800cf4e + { + /* Standard Speed Card <= 12.5Mhz */ + return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; + } + + if((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) && + 800ce82: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800ce86: d1c8 bne.n 800ce1a + 800ce88: 69a6 ldr r6, [r4, #24] + 800ce8a: 2e01 cmp r6, #1 + 800ce8c: d1c5 bne.n 800ce1a + (hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE)) + { + /* Initialize the Data control register */ + hsd->Instance->DCTRL = 0; + 800ce8e: 6820 ldr r0, [r4, #0] + 800ce90: 2300 movs r3, #0 + 800ce92: 62c3 str r3, [r0, #44] ; 0x2c + errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64U); + 800ce94: 4629 mov r1, r5 + 800ce96: f000 f9e1 bl 800d25c + + if (errorstate != HAL_SD_ERROR_NONE) + 800ce9a: 2800 cmp r0, #0 + 800ce9c: d157 bne.n 800cf4e + { + return errorstate; + } + + /* Configure the SD DPSM (Data Path State Machine) */ + sdmmc_datainitstructure.DataTimeOut = SDMMC_DATATIMEOUT; + 800ce9e: f04f 33ff mov.w r3, #4294967295 ; 0xffffffff + sdmmc_datainitstructure.DataLength = 64U; + 800cea2: e9cd 3500 strd r3, r5, [sp] + sdmmc_datainitstructure.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B ; + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + sdmmc_datainitstructure.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; + sdmmc_datainitstructure.DPSM = SDMMC_DPSM_ENABLE; + 800cea6: e9cd 0604 strd r0, r6, [sp, #16] + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800ceaa: 2260 movs r2, #96 ; 0x60 + 800ceac: 2302 movs r3, #2 + + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800ceae: 6820 ldr r0, [r4, #0] + 800ceb0: 4669 mov r1, sp + sdmmc_datainitstructure.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; + 800ceb2: e9cd 2302 strd r2, r3, [sp, #8] + if ( SDMMC_ConfigData(hsd->Instance, &sdmmc_datainitstructure) != HAL_OK) + 800ceb6: f000 f8f5 bl 800d0a4 + 800ceba: 4605 mov r5, r0 + 800cebc: 2800 cmp r0, #0 + 800cebe: d146 bne.n 800cf4e + { + return (HAL_SD_ERROR_GENERAL_UNKNOWN_ERR); + } + + errorstate = SDMMC_CmdSwitch(hsd->Instance, SDMMC_DDR50_SWITCH_PATTERN); + 800cec0: 494a ldr r1, [pc, #296] ; (800cfec ) + 800cec2: 6820 ldr r0, [r4, #0] + 800cec4: f000 fb35 bl 800d532 + if(errorstate != HAL_SD_ERROR_NONE) + 800cec8: 4607 mov r7, r0 + 800ceca: 2800 cmp r0, #0 + 800cecc: d13f bne.n 800cf4e + { + return errorstate; + } + + while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND| SDMMC_FLAG_DATAEND )) + 800cece: f240 592a movw r9, #1322 ; 0x52a + 800ced2: 6823 ldr r3, [r4, #0] + 800ced4: 6b5e ldr r6, [r3, #52] ; 0x34 + 800ced6: ea16 0609 ands.w r6, r6, r9 + 800ceda: d01d beq.n 800cf18 + hsd->State= HAL_SD_STATE_READY; + return HAL_SD_ERROR_TIMEOUT; + } + } + + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) + 800cedc: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cede: 0710 lsls r0, r2, #28 + 800cee0: d53b bpl.n 800cf5a + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); + 800cee2: 2208 movs r2, #8 + 800cee4: 639a str r2, [r3, #56] ; 0x38 + tickstart = HAL_GetTick(); + 800cee6: f7fa fa79 bl 80073dc + 800ceea: 4606 mov r6, r0 + while ((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)) + 800ceec: 4620 mov r0, r4 + 800ceee: f7ff fe83 bl 800cbf8 + 800cef2: 2804 cmp r0, #4 + 800cef4: d169 bne.n 800cfca + errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); + 800cef6: 6820 ldr r0, [r4, #0] + 800cef8: f44f 7100 mov.w r1, #512 ; 0x200 + 800cefc: f000 f9ae bl 800d25c + if(errorstate != HAL_SD_ERROR_NONE) + 800cf00: b130 cbz r0, 800cf10 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); + 800cf02: 6823 ldr r3, [r4, #0] + 800cf04: 4a3a ldr r2, [pc, #232] ; (800cff0 ) + 800cf06: 639a str r2, [r3, #56] ; 0x38 + hsd->ErrorCode |= errorstate; + 800cf08: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cf0a: 4318 orrs r0, r3 + 800cf0c: 63a0 str r0, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800cf0e: 2501 movs r5, #1 + hsd->State = HAL_SD_STATE_READY; + 800cf10: 2301 movs r3, #1 + 800cf12: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return status; + 800cf16: e064 b.n 800cfe2 + if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) + 800cf18: 6b5b ldr r3, [r3, #52] ; 0x34 + 800cf1a: 041b lsls r3, r3, #16 + 800cf1c: d50b bpl.n 800cf36 + 800cf1e: ab06 add r3, sp, #24 + 800cf20: eb03 1a47 add.w sl, r3, r7, lsl #5 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cf24: 6820 ldr r0, [r4, #0] + 800cf26: f000 f881 bl 800d02c + for (count = 0U; count < 8U; count++) + 800cf2a: 3601 adds r6, #1 + 800cf2c: 2e08 cmp r6, #8 + SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance); + 800cf2e: f84a 0b04 str.w r0, [sl], #4 + for (count = 0U; count < 8U; count++) + 800cf32: d1f7 bne.n 800cf24 + loop ++; + 800cf34: 3701 adds r7, #1 + if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT) + 800cf36: f7fa fa51 bl 80073dc + 800cf3a: eba0 0008 sub.w r0, r0, r8 + 800cf3e: 3001 adds r0, #1 + 800cf40: d1c7 bne.n 800ced2 + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800cf42: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800cf46: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State= HAL_SD_STATE_READY; + 800cf48: 2301 movs r3, #1 + 800cf4a: f884 3034 strb.w r3, [r4, #52] ; 0x34 + hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; + 800cf4e: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cf50: f043 5380 orr.w r3, r3, #268435456 ; 0x10000000 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800cf54: 63a3 str r3, [r4, #56] ; 0x38 + status = HAL_ERROR; + 800cf56: 2501 movs r5, #1 + break; + 800cf58: e7c5 b.n 800cee6 + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) + 800cf5a: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cf5c: 0791 lsls r1, r2, #30 + 800cf5e: d502 bpl.n 800cf66 + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); + 800cf60: 2202 movs r2, #2 + + return errorstate; + } + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + { + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cf62: 639a str r2, [r3, #56] ; 0x38 + + errorstate = SDMMC_ERROR_RX_OVERRUN; + + return errorstate; + 800cf64: e7f3 b.n 800cf4e + else if (__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) + 800cf66: 6b5a ldr r2, [r3, #52] ; 0x34 + 800cf68: 0692 lsls r2, r2, #26 + 800cf6a: d501 bpl.n 800cf70 + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); + 800cf6c: 2220 movs r2, #32 + 800cf6e: e7f8 b.n 800cf62 + { + /* No error flag set */ + } + + /* Clear all the static flags */ + __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); + 800cf70: 4a20 ldr r2, [pc, #128] ; (800cff4 ) + 800cf72: 639a str r2, [r3, #56] ; 0x38 + + /* Test if the switch mode is ok */ + if ((((uint8_t*)SD_hs)[13] & 2U) != 2U) + 800cf74: f89d 3025 ldrb.w r3, [sp, #37] ; 0x25 + 800cf78: 079b lsls r3, r3, #30 + 800cf7a: d5e8 bpl.n 800cf4e + else + { +#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) + hsd->DriveTransceiver_1_8V_Callback(SET); +#else + HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); + 800cf7c: 2001 movs r0, #1 + 800cf7e: f7fa fa9d bl 80074bc + 800cf82: e7b0 b.n 800cee6 + switch (SpeedMode) + 800cf84: 2901 cmp r1, #1 + 800cf86: f43f af48 beq.w 800ce1a + 800cf8a: 2902 cmp r1, #2 + 800cf8c: d00c beq.n 800cfa8 + 800cf8e: b9c1 cbnz r1, 800cfc2 + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cf90: 6dc3 ldr r3, [r0, #92] ; 0x5c + 800cf92: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cf96: f43f af45 beq.w 800ce24 + 800cf9a: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800cf9e: f43f af41 beq.w 800ce24 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800cfa2: 6bc3 ldr r3, [r0, #60] ; 0x3c + 800cfa4: 2b01 cmp r3, #1 + 800cfa6: e73c b.n 800ce22 + if ((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || + 800cfa8: 6de3 ldr r3, [r4, #92] ; 0x5c + 800cfaa: f5b3 7f00 cmp.w r3, #512 ; 0x200 + 800cfae: f43f af39 beq.w 800ce24 + 800cfb2: f5b3 7f80 cmp.w r3, #256 ; 0x100 + 800cfb6: f43f af35 beq.w 800ce24 + (hsd->SdCard.CardSpeed == CARD_HIGH_SPEED) || + 800cfba: 6be3 ldr r3, [r4, #60] ; 0x3c + 800cfbc: 2b01 cmp r3, #1 + 800cfbe: d1c6 bne.n 800cf4e + 800cfc0: e730 b.n 800ce24 + hsd->ErrorCode |= HAL_SD_ERROR_PARAM; + 800cfc2: 6ba3 ldr r3, [r4, #56] ; 0x38 + 800cfc4: f043 6300 orr.w r3, r3, #134217728 ; 0x8000000 + 800cfc8: e7c4 b.n 800cf54 + if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) + 800cfca: f7fa fa07 bl 80073dc + 800cfce: 1b80 subs r0, r0, r6 + 800cfd0: 3001 adds r0, #1 + 800cfd2: d18b bne.n 800ceec + hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT; + 800cfd4: f04f 4300 mov.w r3, #2147483648 ; 0x80000000 + 800cfd8: 63a3 str r3, [r4, #56] ; 0x38 + hsd->State = HAL_SD_STATE_READY; + 800cfda: 2301 movs r3, #1 + 800cfdc: f884 3034 strb.w r3, [r4, #52] ; 0x34 + return HAL_TIMEOUT; + 800cfe0: 2503 movs r5, #3 +} + 800cfe2: 4628 mov r0, r5 + 800cfe4: b016 add sp, #88 ; 0x58 + 800cfe6: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} + 800cfea: bf00 nop + 800cfec: 80ffff04 .word 0x80ffff04 + 800cff0: 1fe00fff .word 0x1fe00fff + 800cff4: 18000f3a .word 0x18000f3a + +0800cff8 : + * @param SDMMCx Pointer to SDMMC register base + * @param Init SDMMC initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_Init(SDMMC_TypeDef *SDMMCx, SDMMC_InitTypeDef Init) +{ + 800cff8: b084 sub sp, #16 + 800cffa: b510 push {r4, lr} + 800cffc: ac03 add r4, sp, #12 + 800cffe: e884 000e stmia.w r4, {r1, r2, r3} + + /* Set SDMMC configuration parameters */ +#if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) + tmpreg |= Init.ClockBypass; +#endif + tmpreg |= (Init.ClockEdge |\ + 800d002: 9b03 ldr r3, [sp, #12] + Init.HardwareFlowControl |\ + Init.ClockDiv + ); + + /* Write to SDMMC CLKCR */ + MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + 800d004: 6841 ldr r1, [r0, #4] + tmpreg |= (Init.ClockEdge |\ + 800d006: 4313 orrs r3, r2 + Init.ClockPowerSave |\ + 800d008: 9a05 ldr r2, [sp, #20] + 800d00a: 4313 orrs r3, r2 + Init.BusWide |\ + 800d00c: 9a06 ldr r2, [sp, #24] + 800d00e: 4313 orrs r3, r2 + Init.HardwareFlowControl |\ + 800d010: 9a07 ldr r2, [sp, #28] + + return HAL_OK; +} + 800d012: e8bd 4010 ldmia.w sp!, {r4, lr} + Init.HardwareFlowControl |\ + 800d016: 4313 orrs r3, r2 + MODIFY_REG(SDMMCx->CLKCR, CLKCR_CLEAR_MASK, tmpreg); + 800d018: 4a03 ldr r2, [pc, #12] ; (800d028 ) + 800d01a: 400a ands r2, r1 + 800d01c: 4313 orrs r3, r2 + 800d01e: 6043 str r3, [r0, #4] +} + 800d020: b004 add sp, #16 + 800d022: 2000 movs r0, #0 + 800d024: 4770 bx lr + 800d026: bf00 nop + 800d028: ffc02c00 .word 0xffc02c00 + +0800d02c : + * @retval HAL status + */ +uint32_t SDMMC_ReadFIFO(SDMMC_TypeDef *SDMMCx) +{ + /* Read data from Rx FIFO */ + return (SDMMCx->FIFO); + 800d02c: f8d0 0080 ldr.w r0, [r0, #128] ; 0x80 +} + 800d030: 4770 bx lr + +0800d032 : + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_WriteFIFO(SDMMC_TypeDef *SDMMCx, uint32_t *pWriteData) +{ + /* Write data to FIFO */ + SDMMCx->FIFO = *pWriteData; + 800d032: 680b ldr r3, [r1, #0] + 800d034: f8c0 3080 str.w r3, [r0, #128] ; 0x80 + + return HAL_OK; +} + 800d038: 2000 movs r0, #0 + 800d03a: 4770 bx lr + +0800d03c : + * @brief Set SDMMC Power state to ON. + * @param SDMMCx Pointer to SDMMC register base + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_ON(SDMMC_TypeDef *SDMMCx) +{ + 800d03c: b508 push {r3, lr} + /* Set power state to ON */ +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL; + 800d03e: 6803 ldr r3, [r0, #0] + 800d040: f043 0303 orr.w r3, r3, #3 + 800d044: 6003 str r3, [r0, #0] + SDMMCx->POWER = SDMMC_POWER_PWRCTRL; +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + /* 1ms: required power up waiting time before starting the SD initialization + sequence */ + HAL_Delay(2); + 800d046: 2002 movs r0, #2 + 800d048: f7f6 fd29 bl 8003a9e + + return HAL_OK; +} + 800d04c: 2000 movs r0, #0 + 800d04e: bd08 pop {r3, pc} + +0800d050 : + * @retval HAL status + */ +HAL_StatusTypeDef SDMMC_PowerState_Cycle(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to Power Cycle*/ + SDMMCx->POWER |= SDMMC_POWER_PWRCTRL_1; + 800d050: 6803 ldr r3, [r0, #0] + 800d052: f043 0302 orr.w r3, r3, #2 + 800d056: 6003 str r3, [r0, #0] + + return HAL_OK; +} + 800d058: 2000 movs r0, #0 + 800d05a: 4770 bx lr + +0800d05c : + */ +HAL_StatusTypeDef SDMMC_PowerState_OFF(SDMMC_TypeDef *SDMMCx) +{ + /* Set power state to OFF */ +#if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) + SDMMCx->POWER &= ~(SDMMC_POWER_PWRCTRL); + 800d05c: 6803 ldr r3, [r0, #0] + 800d05e: f023 0303 bic.w r3, r3, #3 + 800d062: 6003 str r3, [r0, #0] +#else + SDMMCx->POWER = (uint32_t)0x00000000; +#endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ + + return HAL_OK; +} + 800d064: 2000 movs r0, #0 + 800d066: 4770 bx lr + +0800d068 : + * - 0x02: Power UP + * - 0x03: Power ON + */ +uint32_t SDMMC_GetPowerState(SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->POWER & SDMMC_POWER_PWRCTRL); + 800d068: 6800 ldr r0, [r0, #0] +} + 800d06a: f000 0003 and.w r0, r0, #3 + 800d06e: 4770 bx lr + +0800d070 : + assert_param(IS_SDMMC_RESPONSE(Command->Response)); + assert_param(IS_SDMMC_WAIT(Command->WaitForInterrupt)); + assert_param(IS_SDMMC_CPSM(Command->CPSM)); + + /* Set the SDMMC Argument value */ + SDMMCx->ARG = Command->Argument; + 800d070: 680b ldr r3, [r1, #0] +{ + 800d072: b510 push {r4, lr} + SDMMCx->ARG = Command->Argument; + 800d074: 6083 str r3, [r0, #8] + + /* Set SDMMC command parameters */ + tmpreg |= (uint32_t)(Command->CmdIndex |\ + 800d076: e9d1 3201 ldrd r3, r2, [r1, #4] + 800d07a: 4313 orrs r3, r2 + Command->Response |\ + 800d07c: 68ca ldr r2, [r1, #12] + Command->WaitForInterrupt |\ + Command->CPSM); + + /* Write to SDMMC CMD register */ + MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg); + 800d07e: 68c4 ldr r4, [r0, #12] + Command->Response |\ + 800d080: 4313 orrs r3, r2 + Command->WaitForInterrupt |\ + 800d082: 690a ldr r2, [r1, #16] + 800d084: 4313 orrs r3, r2 + MODIFY_REG(SDMMCx->CMD, CMD_CLEAR_MASK, tmpreg); + 800d086: 4a03 ldr r2, [pc, #12] ; (800d094 ) + 800d088: 4022 ands r2, r4 + 800d08a: 4313 orrs r3, r2 + 800d08c: 60c3 str r3, [r0, #12] + + return HAL_OK; +} + 800d08e: 2000 movs r0, #0 + 800d090: bd10 pop {r4, pc} + 800d092: bf00 nop + 800d094: fffee0c0 .word 0xfffee0c0 + +0800d098 : + * @param SDMMCx Pointer to SDMMC register base + * @retval Command index of the last command response received + */ +uint8_t SDMMC_GetCommandResponse(SDMMC_TypeDef *SDMMCx) +{ + return (uint8_t)(SDMMCx->RESPCMD); + 800d098: 6900 ldr r0, [r0, #16] +} + 800d09a: b2c0 uxtb r0, r0 + 800d09c: 4770 bx lr + +0800d09e : + + /* Check the parameters */ + assert_param(IS_SDMMC_RESP(Response)); + + /* Get the response */ + tmp = (uint32_t)(&(SDMMCx->RESP1)) + Response; + 800d09e: 3014 adds r0, #20 + + return (*(__IO uint32_t *) tmp); + 800d0a0: 5840 ldr r0, [r0, r1] +} + 800d0a2: 4770 bx lr + +0800d0a4 : + assert_param(IS_SDMMC_TRANSFER_DIR(Data->TransferDir)); + assert_param(IS_SDMMC_TRANSFER_MODE(Data->TransferMode)); + assert_param(IS_SDMMC_DPSM(Data->DPSM)); + + /* Set the SDMMC Data TimeOut value */ + SDMMCx->DTIMER = Data->DataTimeOut; + 800d0a4: 680b ldr r3, [r1, #0] +{ + 800d0a6: b510 push {r4, lr} + SDMMCx->DTIMER = Data->DataTimeOut; + 800d0a8: 6243 str r3, [r0, #36] ; 0x24 + + /* Set the SDMMC DataLength value */ + SDMMCx->DLEN = Data->DataLength; + 800d0aa: 684b ldr r3, [r1, #4] + 800d0ac: 6283 str r3, [r0, #40] ; 0x28 + + /* Set the SDMMC data configuration parameters */ + tmpreg |= (uint32_t)(Data->DataBlockSize |\ + 800d0ae: e9d1 3402 ldrd r3, r4, [r1, #8] + 800d0b2: 4323 orrs r3, r4 + Data->TransferDir |\ + 800d0b4: 690c ldr r4, [r1, #16] + Data->TransferMode |\ + Data->DPSM); + + /* Write to SDMMC DCTRL */ + MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + 800d0b6: 6ac2 ldr r2, [r0, #44] ; 0x2c + Data->TransferMode |\ + 800d0b8: 6949 ldr r1, [r1, #20] + Data->TransferDir |\ + 800d0ba: 4323 orrs r3, r4 + Data->TransferMode |\ + 800d0bc: 430b orrs r3, r1 + MODIFY_REG(SDMMCx->DCTRL, DCTRL_CLEAR_MASK, tmpreg); + 800d0be: f022 02ff bic.w r2, r2, #255 ; 0xff + 800d0c2: 4313 orrs r3, r2 + 800d0c4: 62c3 str r3, [r0, #44] ; 0x2c + + return HAL_OK; + +} + 800d0c6: 2000 movs r0, #0 + 800d0c8: bd10 pop {r4, pc} + +0800d0ca : + * @param SDMMCx Pointer to SDMMC register base + * @retval Number of remaining data bytes to be transferred + */ +uint32_t SDMMC_GetDataCounter(SDMMC_TypeDef *SDMMCx) +{ + return (SDMMCx->DCOUNT); + 800d0ca: 6b00 ldr r0, [r0, #48] ; 0x30 +} + 800d0cc: 4770 bx lr + +0800d0ce : + 800d0ce: f8d0 0080 ldr.w r0, [r0, #128] ; 0x80 + 800d0d2: 4770 bx lr + +0800d0d4 : +{ + /* Check the parameters */ + assert_param(IS_SDMMC_READWAIT_MODE(SDMMC_ReadWaitMode)); + + /* Set SDMMC read wait mode */ + MODIFY_REG(SDMMCx->DCTRL, SDMMC_DCTRL_RWMOD, SDMMC_ReadWaitMode); + 800d0d4: 6ac3 ldr r3, [r0, #44] ; 0x2c + 800d0d6: f423 6380 bic.w r3, r3, #1024 ; 0x400 + 800d0da: 4319 orrs r1, r3 + 800d0dc: 62c1 str r1, [r0, #44] ; 0x2c + + return HAL_OK; +} + 800d0de: 2000 movs r0, #0 + 800d0e0: 4770 bx lr + ... + +0800d0e4 : + * @brief Send the Go Idle State command and check the response. + * @param SDMMCx Pointer to SDMMC register base + * @retval HAL status + */ +uint32_t SDMMC_CmdGoIdleState(SDMMC_TypeDef *SDMMCx) +{ + 800d0e4: b510 push {r4, lr} + SDMMC_CmdInitTypeDef sdmmc_cmdinit; + uint32_t errorstate; + + sdmmc_cmdinit.Argument = 0U; + 800d0e6: 2300 movs r3, #0 +{ + 800d0e8: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE; + 800d0ea: e9cd 3301 strd r3, r3, [sp, #4] + sdmmc_cmdinit.Response = SDMMC_RESPONSE_NO; + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d0ee: e9cd 3303 strd r3, r3, [sp, #12] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0f2: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d0f4: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d0f8: 9305 str r3, [sp, #20] +{ + 800d0fa: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d0fc: f7ff ffb8 bl 800d070 + */ +static uint32_t SDMMC_GetCmdError(SDMMC_TypeDef *SDMMCx) +{ + /* 8 is the number of required instructions cycles for the below loop statement. + The SDMMC_CMDTIMEOUT is expressed in ms */ + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d100: 4b0a ldr r3, [pc, #40] ; (800d12c ) + 800d102: f44f 52fa mov.w r2, #8000 ; 0x1f40 + 800d106: 681b ldr r3, [r3, #0] + 800d108: fbb3 f3f2 udiv r3, r3, r2 + 800d10c: f241 3288 movw r2, #5000 ; 0x1388 + 800d110: 4353 muls r3, r2 + + do + { + if (count-- == 0U) + 800d112: 3b01 subs r3, #1 + 800d114: d307 bcc.n 800d126 + { + return SDMMC_ERROR_TIMEOUT; + } + + }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDSENT)); + 800d116: 6b62 ldr r2, [r4, #52] ; 0x34 + 800d118: 0612 lsls r2, r2, #24 + 800d11a: d5fa bpl.n 800d112 + + /* Clear all the static flags */ + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d11c: 4b04 ldr r3, [pc, #16] ; (800d130 ) + 800d11e: 63a3 str r3, [r4, #56] ; 0x38 + + return SDMMC_ERROR_NONE; + 800d120: 2000 movs r0, #0 +} + 800d122: b006 add sp, #24 + 800d124: bd10 pop {r4, pc} + return SDMMC_ERROR_TIMEOUT; + 800d126: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + return errorstate; + 800d12a: e7fa b.n 800d122 + 800d12c: 2009e2ac .word 0x2009e2ac + 800d130: 002000c5 .word 0x002000c5 + +0800d134 : + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800d134: 4b45 ldr r3, [pc, #276] ; (800d24c ) +{ + 800d136: b510 push {r4, lr} + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800d138: 681b ldr r3, [r3, #0] +{ + 800d13a: 4604 mov r4, r0 + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800d13c: f44f 50fa mov.w r0, #8000 ; 0x1f40 + 800d140: fbb3 f3f0 udiv r3, r3, r0 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_BUSYD0END)) == 0U) || + 800d144: 4842 ldr r0, [pc, #264] ; (800d250 ) + uint32_t count = Timeout * (SystemCoreClock / 8U /1000U); + 800d146: 435a muls r2, r3 + if (count-- == 0U) + 800d148: 2a00 cmp r2, #0 + 800d14a: d048 beq.n 800d1de + sta_reg = SDMMCx->STA; + 800d14c: 6b63 ldr r3, [r4, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d14e: 4203 tst r3, r0 + 800d150: d007 beq.n 800d162 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT | SDMMC_FLAG_BUSYD0END)) == 0U) || + 800d152: 049b lsls r3, r3, #18 + 800d154: d405 bmi.n 800d162 + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d156: 6b63 ldr r3, [r4, #52] ; 0x34 + 800d158: 0758 lsls r0, r3, #29 + 800d15a: d504 bpl.n 800d166 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d15c: 2004 movs r0, #4 + 800d15e: 63a0 str r0, [r4, #56] ; 0x38 +} + 800d160: bd10 pop {r4, pc} + 800d162: 3a01 subs r2, #1 + 800d164: e7f0 b.n 800d148 + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d166: 6b60 ldr r0, [r4, #52] ; 0x34 + 800d168: f010 0001 ands.w r0, r0, #1 + 800d16c: d002 beq.n 800d174 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d16e: 2301 movs r3, #1 + 800d170: 63a3 str r3, [r4, #56] ; 0x38 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d172: e7f5 b.n 800d160 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d174: 4b37 ldr r3, [pc, #220] ; (800d254 ) + 800d176: 63a3 str r3, [r4, #56] ; 0x38 + return (uint8_t)(SDMMCx->RESPCMD); + 800d178: 6923 ldr r3, [r4, #16] + if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + 800d17a: b2db uxtb r3, r3 + 800d17c: 4299 cmp r1, r3 + 800d17e: d131 bne.n 800d1e4 + return (*(__IO uint32_t *) tmp); + 800d180: 6963 ldr r3, [r4, #20] + if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO) + 800d182: 4835 ldr r0, [pc, #212] ; (800d258 ) + 800d184: 4018 ands r0, r3 + 800d186: 2800 cmp r0, #0 + 800d188: d0ea beq.n 800d160 + else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE) + 800d18a: 2b00 cmp r3, #0 + 800d18c: db2c blt.n 800d1e8 + else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED) + 800d18e: 005a lsls r2, r3, #1 + 800d190: d42d bmi.n 800d1ee + else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR) + 800d192: 009c lsls r4, r3, #2 + 800d194: d42d bmi.n 800d1f2 + else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR) + 800d196: 00d9 lsls r1, r3, #3 + 800d198: d42d bmi.n 800d1f6 + else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM) + 800d19a: 011a lsls r2, r3, #4 + 800d19c: d42e bmi.n 800d1fc + else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION) + 800d19e: 015c lsls r4, r3, #5 + 800d1a0: d42f bmi.n 800d202 + else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED) + 800d1a2: 01d9 lsls r1, r3, #7 + 800d1a4: d430 bmi.n 800d208 + else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED) + 800d1a6: 021a lsls r2, r3, #8 + 800d1a8: d431 bmi.n 800d20e + else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD) + 800d1aa: 025c lsls r4, r3, #9 + 800d1ac: d432 bmi.n 800d214 + else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED) + 800d1ae: 0299 lsls r1, r3, #10 + 800d1b0: d433 bmi.n 800d21a + else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR) + 800d1b2: 02da lsls r2, r3, #11 + 800d1b4: d434 bmi.n 800d220 + else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN) + 800d1b6: 035c lsls r4, r3, #13 + 800d1b8: d435 bmi.n 800d226 + else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN) + 800d1ba: 0399 lsls r1, r3, #14 + 800d1bc: d436 bmi.n 800d22c + else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE) + 800d1be: 03da lsls r2, r3, #15 + 800d1c0: d437 bmi.n 800d232 + else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP) + 800d1c2: 041c lsls r4, r3, #16 + 800d1c4: d438 bmi.n 800d238 + else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED) + 800d1c6: 0459 lsls r1, r3, #17 + 800d1c8: d439 bmi.n 800d23e + else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET) + 800d1ca: 049a lsls r2, r3, #18 + 800d1cc: d43a bmi.n 800d244 + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + 800d1ce: f013 0f08 tst.w r3, #8 + 800d1d2: bf14 ite ne + 800d1d4: f44f 0000 movne.w r0, #8388608 ; 0x800000 + 800d1d8: f44f 3080 moveq.w r0, #65536 ; 0x10000 + 800d1dc: e7c0 b.n 800d160 + return SDMMC_ERROR_TIMEOUT; + 800d1de: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800d1e2: e7bd b.n 800d160 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d1e4: 2001 movs r0, #1 + 800d1e6: e7bb b.n 800d160 + return SDMMC_ERROR_ADDR_OUT_OF_RANGE; + 800d1e8: f04f 7000 mov.w r0, #33554432 ; 0x2000000 + 800d1ec: e7b8 b.n 800d160 + return SDMMC_ERROR_ADDR_MISALIGNED; + 800d1ee: 2040 movs r0, #64 ; 0x40 + 800d1f0: e7b6 b.n 800d160 + return SDMMC_ERROR_BLOCK_LEN_ERR; + 800d1f2: 2080 movs r0, #128 ; 0x80 + 800d1f4: e7b4 b.n 800d160 + return SDMMC_ERROR_ERASE_SEQ_ERR; + 800d1f6: f44f 7080 mov.w r0, #256 ; 0x100 + 800d1fa: e7b1 b.n 800d160 + return SDMMC_ERROR_BAD_ERASE_PARAM; + 800d1fc: f44f 7000 mov.w r0, #512 ; 0x200 + 800d200: e7ae b.n 800d160 + return SDMMC_ERROR_WRITE_PROT_VIOLATION; + 800d202: f44f 6080 mov.w r0, #1024 ; 0x400 + 800d206: e7ab b.n 800d160 + return SDMMC_ERROR_LOCK_UNLOCK_FAILED; + 800d208: f44f 6000 mov.w r0, #2048 ; 0x800 + 800d20c: e7a8 b.n 800d160 + return SDMMC_ERROR_COM_CRC_FAILED; + 800d20e: f44f 5080 mov.w r0, #4096 ; 0x1000 + 800d212: e7a5 b.n 800d160 + return SDMMC_ERROR_ILLEGAL_CMD; + 800d214: f44f 5000 mov.w r0, #8192 ; 0x2000 + 800d218: e7a2 b.n 800d160 + return SDMMC_ERROR_CARD_ECC_FAILED; + 800d21a: f44f 4080 mov.w r0, #16384 ; 0x4000 + 800d21e: e79f b.n 800d160 + return SDMMC_ERROR_CC_ERR; + 800d220: f44f 4000 mov.w r0, #32768 ; 0x8000 + 800d224: e79c b.n 800d160 + return SDMMC_ERROR_STREAM_READ_UNDERRUN; + 800d226: f44f 3000 mov.w r0, #131072 ; 0x20000 + 800d22a: e799 b.n 800d160 + return SDMMC_ERROR_STREAM_WRITE_OVERRUN; + 800d22c: f44f 2080 mov.w r0, #262144 ; 0x40000 + 800d230: e796 b.n 800d160 + return SDMMC_ERROR_CID_CSD_OVERWRITE; + 800d232: f44f 2000 mov.w r0, #524288 ; 0x80000 + 800d236: e793 b.n 800d160 + return SDMMC_ERROR_WP_ERASE_SKIP; + 800d238: f44f 1080 mov.w r0, #1048576 ; 0x100000 + 800d23c: e790 b.n 800d160 + return SDMMC_ERROR_CARD_ECC_DISABLED; + 800d23e: f44f 1000 mov.w r0, #2097152 ; 0x200000 + 800d242: e78d b.n 800d160 + return SDMMC_ERROR_ERASE_RESET; + 800d244: f44f 0080 mov.w r0, #4194304 ; 0x400000 + 800d248: e78a b.n 800d160 + 800d24a: bf00 nop + 800d24c: 2009e2ac .word 0x2009e2ac + 800d250: 00200045 .word 0x00200045 + 800d254: 002000c5 .word 0x002000c5 + 800d258: fdffe008 .word 0xfdffe008 + +0800d25c : +{ + 800d25c: b530 push {r4, r5, lr} + 800d25e: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d260: 2510 movs r5, #16 + 800d262: f44f 7380 mov.w r3, #256 ; 0x100 + 800d266: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d26a: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d26c: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)BlockSize; + 800d270: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d272: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d274: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d276: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d27a: f7ff fef9 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_BLOCKLEN, SDMMC_CMDTIMEOUT); + 800d27e: f241 3288 movw r2, #5000 ; 0x1388 + 800d282: 4629 mov r1, r5 + 800d284: 4620 mov r0, r4 + 800d286: f7ff ff55 bl 800d134 +} + 800d28a: b007 add sp, #28 + 800d28c: bd30 pop {r4, r5, pc} + +0800d28e : +{ + 800d28e: b530 push {r4, r5, lr} + 800d290: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d292: 2511 movs r5, #17 + 800d294: f44f 7380 mov.w r3, #256 ; 0x100 + 800d298: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d29c: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d29e: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + 800d2a2: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2a4: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2a6: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2a8: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2ac: f7ff fee0 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + 800d2b0: f241 3288 movw r2, #5000 ; 0x1388 + 800d2b4: 4629 mov r1, r5 + 800d2b6: 4620 mov r0, r4 + 800d2b8: f7ff ff3c bl 800d134 +} + 800d2bc: b007 add sp, #28 + 800d2be: bd30 pop {r4, r5, pc} + +0800d2c0 : +{ + 800d2c0: b530 push {r4, r5, lr} + 800d2c2: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d2c4: 2512 movs r5, #18 + 800d2c6: f44f 7380 mov.w r3, #256 ; 0x100 + 800d2ca: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d2ce: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2d0: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)ReadAdd; + 800d2d4: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2d6: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2d8: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d2da: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d2de: f7ff fec7 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_READ_MULT_BLOCK, SDMMC_CMDTIMEOUT); + 800d2e2: f241 3288 movw r2, #5000 ; 0x1388 + 800d2e6: 4629 mov r1, r5 + 800d2e8: 4620 mov r0, r4 + 800d2ea: f7ff ff23 bl 800d134 +} + 800d2ee: b007 add sp, #28 + 800d2f0: bd30 pop {r4, r5, pc} + +0800d2f2 : +{ + 800d2f2: b530 push {r4, r5, lr} + 800d2f4: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d2f6: 2518 movs r5, #24 + 800d2f8: f44f 7380 mov.w r3, #256 ; 0x100 + 800d2fc: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d300: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d302: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + 800d306: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d308: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d30a: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d30c: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d310: f7ff feae bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDMMC_CMDTIMEOUT); + 800d314: f241 3288 movw r2, #5000 ; 0x1388 + 800d318: 4629 mov r1, r5 + 800d31a: 4620 mov r0, r4 + 800d31c: f7ff ff0a bl 800d134 +} + 800d320: b007 add sp, #28 + 800d322: bd30 pop {r4, r5, pc} + +0800d324 : +{ + 800d324: b530 push {r4, r5, lr} + 800d326: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d328: 2519 movs r5, #25 + 800d32a: f44f 7380 mov.w r3, #256 ; 0x100 + 800d32e: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d332: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d334: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)WriteAdd; + 800d338: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d33a: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d33c: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d33e: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d342: f7ff fe95 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_WRITE_MULT_BLOCK, SDMMC_CMDTIMEOUT); + 800d346: f241 3288 movw r2, #5000 ; 0x1388 + 800d34a: 4629 mov r1, r5 + 800d34c: 4620 mov r0, r4 + 800d34e: f7ff fef1 bl 800d134 +} + 800d352: b007 add sp, #28 + 800d354: bd30 pop {r4, r5, pc} + +0800d356 : +{ + 800d356: b530 push {r4, r5, lr} + 800d358: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d35a: 2520 movs r5, #32 + 800d35c: f44f 7380 mov.w r3, #256 ; 0x100 + 800d360: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d364: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d366: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + 800d36a: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d36c: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d36e: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d370: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d374: f7ff fe7c bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + 800d378: f241 3288 movw r2, #5000 ; 0x1388 + 800d37c: 4629 mov r1, r5 + 800d37e: 4620 mov r0, r4 + 800d380: f7ff fed8 bl 800d134 +} + 800d384: b007 add sp, #28 + 800d386: bd30 pop {r4, r5, pc} + +0800d388 : +{ + 800d388: b530 push {r4, r5, lr} + 800d38a: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d38c: 2521 movs r5, #33 ; 0x21 + 800d38e: f44f 7380 mov.w r3, #256 ; 0x100 + 800d392: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d396: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d398: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + 800d39c: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d39e: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3a0: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3a2: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3a6: f7ff fe63 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + 800d3aa: f241 3288 movw r2, #5000 ; 0x1388 + 800d3ae: 4629 mov r1, r5 + 800d3b0: 4620 mov r0, r4 + 800d3b2: f7ff febf bl 800d134 +} + 800d3b6: b007 add sp, #28 + 800d3b8: bd30 pop {r4, r5, pc} + +0800d3ba : +{ + 800d3ba: b530 push {r4, r5, lr} + 800d3bc: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d3be: 2523 movs r5, #35 ; 0x23 + 800d3c0: f44f 7380 mov.w r3, #256 ; 0x100 + 800d3c4: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d3c8: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3ca: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)StartAdd; + 800d3ce: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3d0: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3d2: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3d4: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d3d8: f7ff fe4a bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_START, SDMMC_CMDTIMEOUT); + 800d3dc: f241 3288 movw r2, #5000 ; 0x1388 + 800d3e0: 4629 mov r1, r5 + 800d3e2: 4620 mov r0, r4 + 800d3e4: f7ff fea6 bl 800d134 +} + 800d3e8: b007 add sp, #28 + 800d3ea: bd30 pop {r4, r5, pc} + +0800d3ec : +{ + 800d3ec: b530 push {r4, r5, lr} + 800d3ee: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d3f0: 2524 movs r5, #36 ; 0x24 + 800d3f2: f44f 7380 mov.w r3, #256 ; 0x100 + 800d3f6: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d3fa: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d3fc: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)EndAdd; + 800d400: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d402: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d404: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d406: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d40a: f7ff fe31 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE_GRP_END, SDMMC_CMDTIMEOUT); + 800d40e: f241 3288 movw r2, #5000 ; 0x1388 + 800d412: 4629 mov r1, r5 + 800d414: 4620 mov r0, r4 + 800d416: f7ff fe8d bl 800d134 +} + 800d41a: b007 add sp, #28 + 800d41c: bd30 pop {r4, r5, pc} + +0800d41e : +{ + 800d41e: b530 push {r4, r5, lr} + 800d420: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d422: 2526 movs r5, #38 ; 0x26 + 800d424: f44f 7380 mov.w r3, #256 ; 0x100 + 800d428: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d42c: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d42e: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = EraseType; + 800d432: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d434: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d436: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d438: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d43c: f7ff fe18 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_ERASE, SDMMC_MAXERASETIMEOUT); + 800d440: f24f 6218 movw r2, #63000 ; 0xf618 + 800d444: 4629 mov r1, r5 + 800d446: 4620 mov r0, r4 + 800d448: f7ff fe74 bl 800d134 +} + 800d44c: b007 add sp, #28 + 800d44e: bd30 pop {r4, r5, pc} + +0800d450 : +{ + 800d450: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d452: 2300 movs r3, #0 +{ + 800d454: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d456: 250c movs r5, #12 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d458: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d45c: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION; + 800d460: e9cd 3501 strd r3, r5, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d464: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d468: 9305 str r3, [sp, #20] + __SDMMC_CMDSTOP_ENABLE(SDMMCx); + 800d46a: 68c3 ldr r3, [r0, #12] + 800d46c: f043 0380 orr.w r3, r3, #128 ; 0x80 + 800d470: 60c3 str r3, [r0, #12] + __SDMMC_CMDTRANS_DISABLE(SDMMCx); + 800d472: 68c3 ldr r3, [r0, #12] + 800d474: f023 0340 bic.w r3, r3, #64 ; 0x40 +{ + 800d478: 4604 mov r4, r0 + __SDMMC_CMDTRANS_DISABLE(SDMMCx); + 800d47a: 60c3 str r3, [r0, #12] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d47c: a901 add r1, sp, #4 + 800d47e: f7ff fdf7 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_STOP_TRANSMISSION, SDMMC_STOPTRANSFERTIMEOUT); + 800d482: 4a05 ldr r2, [pc, #20] ; (800d498 ) + 800d484: 4629 mov r1, r5 + 800d486: 4620 mov r0, r4 + 800d488: f7ff fe54 bl 800d134 + __SDMMC_CMDSTOP_DISABLE(SDMMCx); + 800d48c: 68e3 ldr r3, [r4, #12] + 800d48e: f023 0380 bic.w r3, r3, #128 ; 0x80 + 800d492: 60e3 str r3, [r4, #12] +} + 800d494: b007 add sp, #28 + 800d496: bd30 pop {r4, r5, pc} + 800d498: 05f5e100 .word 0x05f5e100 + +0800d49c : +{ + 800d49c: b530 push {r4, r5, lr} + 800d49e: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d4a0: 2507 movs r5, #7 + 800d4a2: f44f 7380 mov.w r3, #256 ; 0x100 + 800d4a6: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d4aa: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4ac: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)Addr; + 800d4b0: 9201 str r2, [sp, #4] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d4b2: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4b4: 2200 movs r2, #0 + 800d4b6: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d4ba: f7ff fdd9 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEL_DESEL_CARD, SDMMC_CMDTIMEOUT); + 800d4be: f241 3288 movw r2, #5000 ; 0x1388 + 800d4c2: 4629 mov r1, r5 + 800d4c4: 4620 mov r0, r4 + 800d4c6: f7ff fe35 bl 800d134 +} + 800d4ca: b007 add sp, #28 + 800d4cc: bd30 pop {r4, r5, pc} + +0800d4ce : +{ + 800d4ce: b530 push {r4, r5, lr} + 800d4d0: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d4d2: 2537 movs r5, #55 ; 0x37 + 800d4d4: f44f 7380 mov.w r3, #256 ; 0x100 + 800d4d8: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d4dc: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4de: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)Argument; + 800d4e2: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4e4: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d4e6: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d4e8: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d4ec: f7ff fdc0 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_CMD, SDMMC_CMDTIMEOUT); + 800d4f0: f241 3288 movw r2, #5000 ; 0x1388 + 800d4f4: 4629 mov r1, r5 + 800d4f6: 4620 mov r0, r4 + 800d4f8: f7ff fe1c bl 800d134 +} + 800d4fc: b007 add sp, #28 + 800d4fe: bd30 pop {r4, r5, pc} + +0800d500 : +{ + 800d500: b530 push {r4, r5, lr} + 800d502: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d504: 2506 movs r5, #6 + 800d506: f44f 7380 mov.w r3, #256 ; 0x100 + 800d50a: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d50e: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d510: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = (uint32_t)BusWidth; + 800d514: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d516: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d518: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d51a: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d51e: f7ff fda7 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDMMC_CMDTIMEOUT); + 800d522: f241 3288 movw r2, #5000 ; 0x1388 + 800d526: 4629 mov r1, r5 + 800d528: 4620 mov r0, r4 + 800d52a: f7ff fe03 bl 800d134 +} + 800d52e: b007 add sp, #28 + 800d530: bd30 pop {r4, r5, pc} + +0800d532 : + 800d532: f7ff bfe5 b.w 800d500 + +0800d536 : +{ + 800d536: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d538: 2300 movs r3, #0 +{ + 800d53a: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d53c: 2533 movs r5, #51 ; 0x33 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d53e: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d542: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR; + 800d546: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d54a: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d54c: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d550: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d552: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d554: f7ff fd8c bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_SEND_SCR, SDMMC_CMDTIMEOUT); + 800d558: f241 3288 movw r2, #5000 ; 0x1388 + 800d55c: 4629 mov r1, r5 + 800d55e: 4620 mov r0, r4 + 800d560: f7ff fde8 bl 800d134 +} + 800d564: b007 add sp, #28 + 800d566: bd30 pop {r4, r5, pc} + +0800d568 : +{ + 800d568: b530 push {r4, r5, lr} + 800d56a: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d56c: 2503 movs r5, #3 + sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U); + 800d56e: 0409 lsls r1, r1, #16 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d570: f44f 7380 mov.w r3, #256 ; 0x100 + 800d574: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d578: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d57a: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = ((uint32_t)RCA << 16U); + 800d57e: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d580: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d582: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d584: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d588: f7ff fd72 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SET_REL_ADDR, SDMMC_CMDTIMEOUT); + 800d58c: f241 3288 movw r2, #5000 ; 0x1388 + 800d590: 4629 mov r1, r5 + 800d592: 4620 mov r0, r4 + 800d594: f7ff fdce bl 800d134 +} + 800d598: b007 add sp, #28 + 800d59a: bd30 pop {r4, r5, pc} + +0800d59c : +{ + 800d59c: b530 push {r4, r5, lr} + 800d59e: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d5a0: 250d movs r5, #13 + 800d5a2: f44f 7380 mov.w r3, #256 ; 0x100 + 800d5a6: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d5aa: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5ac: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = Argument; + 800d5b0: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5b2: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5b4: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5b6: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5ba: f7ff fd59 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SEND_STATUS, SDMMC_CMDTIMEOUT); + 800d5be: f241 3288 movw r2, #5000 ; 0x1388 + 800d5c2: 4629 mov r1, r5 + 800d5c4: 4620 mov r0, r4 + 800d5c6: f7ff fdb5 bl 800d134 +} + 800d5ca: b007 add sp, #28 + 800d5cc: bd30 pop {r4, r5, pc} + +0800d5ce : +{ + 800d5ce: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d5d0: 2300 movs r3, #0 +{ + 800d5d2: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d5d4: 250d movs r5, #13 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d5d6: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d5da: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS; + 800d5de: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d5e2: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5e4: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5e8: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d5ea: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d5ec: f7ff fd40 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_SD_APP_STATUS, SDMMC_CMDTIMEOUT); + 800d5f0: f241 3288 movw r2, #5000 ; 0x1388 + 800d5f4: 4629 mov r1, r5 + 800d5f6: 4620 mov r0, r4 + 800d5f8: f7ff fd9c bl 800d134 +} + 800d5fc: b007 add sp, #28 + 800d5fe: bd30 pop {r4, r5, pc} + +0800d600 : +{ + 800d600: b530 push {r4, r5, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d602: 2300 movs r3, #0 +{ + 800d604: b087 sub sp, #28 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d606: 250b movs r5, #11 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d608: f44f 7280 mov.w r2, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d60c: e9cd 2303 strd r2, r3, [sp, #12] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_VOLTAGE_SWITCH; + 800d610: e9cd 3501 strd r3, r5, [sp, #4] +{ + 800d614: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d616: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d61a: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d61c: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d61e: f7ff fd27 bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_VOLTAGE_SWITCH, SDMMC_CMDTIMEOUT); + 800d622: f241 3288 movw r2, #5000 ; 0x1388 + 800d626: 4629 mov r1, r5 + 800d628: 4620 mov r0, r4 + 800d62a: f7ff fd83 bl 800d134 +} + 800d62e: b007 add sp, #28 + 800d630: bd30 pop {r4, r5, pc} + +0800d632 : +{ + 800d632: b530 push {r4, r5, lr} + 800d634: b087 sub sp, #28 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d636: 2508 movs r5, #8 + 800d638: f44f 7380 mov.w r3, #256 ; 0x100 + 800d63c: e9cd 5302 strd r5, r3, [sp, #8] +{ + 800d640: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d642: f44f 5380 mov.w r3, #4096 ; 0x1000 + sdmmc_cmdinit.Argument = Argument; + 800d646: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d648: 2200 movs r2, #0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d64a: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d64c: e9cd 2304 strd r2, r3, [sp, #16] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d650: f7ff fd0e bl 800d070 + errorstate = SDMMC_GetCmdResp1(SDMMCx, SDMMC_CMD_HS_SEND_EXT_CSD,SDMMC_CMDTIMEOUT); + 800d654: f241 3288 movw r2, #5000 ; 0x1388 + 800d658: 4629 mov r1, r5 + 800d65a: 4620 mov r0, r4 + 800d65c: f7ff fd6a bl 800d134 +} + 800d660: b007 add sp, #28 + 800d662: bd30 pop {r4, r5, pc} + +0800d664 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d664: 4b11 ldr r3, [pc, #68] ; (800d6ac ) + 800d666: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d66a: 681b ldr r3, [r3, #0] + 800d66c: fbb3 f3f1 udiv r3, r3, r1 + 800d670: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d674: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d676: 434b muls r3, r1 + if (count-- == 0U) + 800d678: 3b01 subs r3, #1 + 800d67a: d313 bcc.n 800d6a4 + sta_reg = SDMMCx->STA; + 800d67c: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d67e: f011 0f45 tst.w r1, #69 ; 0x45 + 800d682: d0f9 beq.n 800d678 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d684: 0489 lsls r1, r1, #18 + 800d686: d4f7 bmi.n 800d678 + if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d688: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d68a: 075b lsls r3, r3, #29 + 800d68c: d502 bpl.n 800d694 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d68e: 2004 movs r0, #4 + 800d690: 6390 str r0, [r2, #56] ; 0x38 + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + 800d692: 4770 bx lr + else if (__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d694: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d696: f010 0001 ands.w r0, r0, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d69a: bf0c ite eq + 800d69c: 4b04 ldreq r3, [pc, #16] ; (800d6b0 ) + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d69e: 2301 movne r3, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d6a0: 6393 str r3, [r2, #56] ; 0x38 + return SDMMC_ERROR_NONE; + 800d6a2: 4770 bx lr + return SDMMC_ERROR_TIMEOUT; + 800d6a4: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d6a8: 4770 bx lr + 800d6aa: bf00 nop + 800d6ac: 2009e2ac .word 0x2009e2ac + 800d6b0: 002000c5 .word 0x002000c5 + +0800d6b4 : +{ + 800d6b4: b510 push {r4, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID; + 800d6b6: 2300 movs r3, #0 +{ + 800d6b8: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID; + 800d6ba: 2202 movs r2, #2 + 800d6bc: e9cd 3201 strd r3, r2, [sp, #4] + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + 800d6c0: f44f 7240 mov.w r2, #768 ; 0x300 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d6c4: e9cd 2303 strd r2, r3, [sp, #12] +{ + 800d6c8: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d6ca: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d6ce: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d6d0: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d6d2: f7ff fccd bl 800d070 + errorstate = SDMMC_GetCmdResp2(SDMMCx); + 800d6d6: 4620 mov r0, r4 + 800d6d8: f7ff ffc4 bl 800d664 +} + 800d6dc: b006 add sp, #24 + 800d6de: bd10 pop {r4, pc} + +0800d6e0 : +{ + 800d6e0: b510 push {r4, lr} + 800d6e2: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_LONG; + 800d6e4: 2209 movs r2, #9 + 800d6e6: f44f 7340 mov.w r3, #768 ; 0x300 + 800d6ea: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d6ee: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d6f0: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d6f4: 2100 movs r1, #0 + 800d6f6: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d6fa: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d6fc: a901 add r1, sp, #4 + 800d6fe: f7ff fcb7 bl 800d070 + errorstate = SDMMC_GetCmdResp2(SDMMCx); + 800d702: 4620 mov r0, r4 + 800d704: f7ff ffae bl 800d664 +} + 800d708: b006 add sp, #24 + 800d70a: bd10 pop {r4, pc} + +0800d70c : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d70c: 4b0e ldr r3, [pc, #56] ; (800d748 ) + 800d70e: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d712: 681b ldr r3, [r3, #0] + 800d714: fbb3 f3f1 udiv r3, r3, r1 + 800d718: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d71c: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d71e: 434b muls r3, r1 + if (count-- == 0U) + 800d720: 3b01 subs r3, #1 + 800d722: d30e bcc.n 800d742 + sta_reg = SDMMCx->STA; + 800d724: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d726: f011 0f45 tst.w r1, #69 ; 0x45 + 800d72a: d0f9 beq.n 800d720 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d72c: 0489 lsls r1, r1, #18 + 800d72e: d4f7 bmi.n 800d720 + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d730: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d732: f010 0004 ands.w r0, r0, #4 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d736: bf15 itete ne + 800d738: 2004 movne r0, #4 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d73a: 4b04 ldreq r3, [pc, #16] ; (800d74c ) + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d73c: 6390 strne r0, [r2, #56] ; 0x38 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d73e: 6393 streq r3, [r2, #56] ; 0x38 + return SDMMC_ERROR_NONE; + 800d740: 4770 bx lr + return SDMMC_ERROR_TIMEOUT; + 800d742: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d746: 4770 bx lr + 800d748: 2009e2ac .word 0x2009e2ac + 800d74c: 002000c5 .word 0x002000c5 + +0800d750 : +{ + 800d750: b510 push {r4, lr} + 800d752: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d754: 2229 movs r2, #41 ; 0x29 + 800d756: f44f 7380 mov.w r3, #256 ; 0x100 + 800d75a: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d75e: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d760: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d764: 2100 movs r1, #0 + 800d766: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d76a: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d76c: a901 add r1, sp, #4 + 800d76e: f7ff fc7f bl 800d070 + errorstate = SDMMC_GetCmdResp3(SDMMCx); + 800d772: 4620 mov r0, r4 + 800d774: f7ff ffca bl 800d70c +} + 800d778: b006 add sp, #24 + 800d77a: bd10 pop {r4, pc} + +0800d77c : +{ + 800d77c: b510 push {r4, lr} + 800d77e: b086 sub sp, #24 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d780: 2201 movs r2, #1 + 800d782: f44f 7380 mov.w r3, #256 ; 0x100 + 800d786: e9cd 2302 strd r2, r3, [sp, #8] + sdmmc_cmdinit.Argument = Argument; + 800d78a: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d78c: f44f 5380 mov.w r3, #4096 ; 0x1000 + 800d790: 2100 movs r1, #0 + 800d792: e9cd 1304 strd r1, r3, [sp, #16] +{ + 800d796: 4604 mov r4, r0 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d798: a901 add r1, sp, #4 + 800d79a: f7ff fc69 bl 800d070 + errorstate = SDMMC_GetCmdResp3(SDMMCx); + 800d79e: 4620 mov r0, r4 + 800d7a0: f7ff ffb4 bl 800d70c +} + 800d7a4: b006 add sp, #24 + 800d7a6: bd10 pop {r4, pc} + +0800d7a8 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d7a8: 4b1f ldr r3, [pc, #124] ; (800d828 ) +{ + 800d7aa: b510 push {r4, lr} + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d7ac: 681b ldr r3, [r3, #0] +{ + 800d7ae: 4604 mov r4, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d7b0: f44f 50fa mov.w r0, #8000 ; 0x1f40 + 800d7b4: fbb3 f3f0 udiv r3, r3, r0 + 800d7b8: f241 3088 movw r0, #5000 ; 0x1388 + 800d7bc: 4343 muls r3, r0 + if (count-- == 0U) + 800d7be: 3b01 subs r3, #1 + 800d7c0: d329 bcc.n 800d816 + sta_reg = SDMMCx->STA; + 800d7c2: 6b60 ldr r0, [r4, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d7c4: f010 0f45 tst.w r0, #69 ; 0x45 + 800d7c8: d0f9 beq.n 800d7be + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d7ca: 0480 lsls r0, r0, #18 + 800d7cc: d4f7 bmi.n 800d7be + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d7ce: 6b63 ldr r3, [r4, #52] ; 0x34 + 800d7d0: 0758 lsls r0, r3, #29 + 800d7d2: d502 bpl.n 800d7da + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d7d4: 2004 movs r0, #4 + 800d7d6: 63a0 str r0, [r4, #56] ; 0x38 +} + 800d7d8: bd10 pop {r4, pc} + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d7da: 6b60 ldr r0, [r4, #52] ; 0x34 + 800d7dc: f010 0001 ands.w r0, r0, #1 + 800d7e0: d002 beq.n 800d7e8 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d7e2: 2301 movs r3, #1 + 800d7e4: 63a3 str r3, [r4, #56] ; 0x38 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d7e6: e7f7 b.n 800d7d8 + return (uint8_t)(SDMMCx->RESPCMD); + 800d7e8: 6923 ldr r3, [r4, #16] + if(SDMMC_GetCommandResponse(SDMMCx) != SD_CMD) + 800d7ea: b2db uxtb r3, r3 + 800d7ec: 4299 cmp r1, r3 + 800d7ee: d115 bne.n 800d81c + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_STATIC_CMD_FLAGS); + 800d7f0: 4b0e ldr r3, [pc, #56] ; (800d82c ) + 800d7f2: 63a3 str r3, [r4, #56] ; 0x38 + return (*(__IO uint32_t *) tmp); + 800d7f4: 6963 ldr r3, [r4, #20] + if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO) + 800d7f6: f413 4060 ands.w r0, r3, #57344 ; 0xe000 + 800d7fa: d102 bne.n 800d802 + *pRCA = (uint16_t) (response_r1 >> 16); + 800d7fc: 0c1b lsrs r3, r3, #16 + 800d7fe: 8013 strh r3, [r2, #0] + return SDMMC_ERROR_NONE; + 800d800: e7ea b.n 800d7d8 + else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD) + 800d802: 045a lsls r2, r3, #17 + 800d804: d40c bmi.n 800d820 + return SDMMC_ERROR_GENERAL_UNKNOWN_ERR; + 800d806: f413 4f00 tst.w r3, #32768 ; 0x8000 + 800d80a: bf14 ite ne + 800d80c: f44f 5080 movne.w r0, #4096 ; 0x1000 + 800d810: f44f 3080 moveq.w r0, #65536 ; 0x10000 + 800d814: e7e0 b.n 800d7d8 + return SDMMC_ERROR_TIMEOUT; + 800d816: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 + 800d81a: e7dd b.n 800d7d8 + return SDMMC_ERROR_CMD_CRC_FAIL; + 800d81c: 2001 movs r0, #1 + 800d81e: e7db b.n 800d7d8 + return SDMMC_ERROR_ILLEGAL_CMD; + 800d820: f44f 5000 mov.w r0, #8192 ; 0x2000 + 800d824: e7d8 b.n 800d7d8 + 800d826: bf00 nop + 800d828: 2009e2ac .word 0x2009e2ac + 800d82c: 002000c5 .word 0x002000c5 + +0800d830 : +{ + 800d830: b530 push {r4, r5, lr} + 800d832: b089 sub sp, #36 ; 0x24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d834: 2300 movs r3, #0 +{ + 800d836: 9101 str r1, [sp, #4] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d838: 2503 movs r5, #3 + sdmmc_cmdinit.Response = SDMMC_RESPONSE_SHORT; + 800d83a: f44f 7180 mov.w r1, #256 ; 0x100 + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d83e: e9cd 1305 strd r1, r3, [sp, #20] + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR; + 800d842: e9cd 3503 strd r3, r5, [sp, #12] +{ + 800d846: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d848: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d84c: a903 add r1, sp, #12 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d84e: 9307 str r3, [sp, #28] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d850: f7ff fc0e bl 800d070 + errorstate = SDMMC_GetCmdResp6(SDMMCx, SDMMC_CMD_SET_REL_ADDR, pRCA); + 800d854: 9a01 ldr r2, [sp, #4] + 800d856: 4629 mov r1, r5 + 800d858: 4620 mov r0, r4 + 800d85a: f7ff ffa5 bl 800d7a8 +} + 800d85e: b009 add sp, #36 ; 0x24 + 800d860: bd30 pop {r4, r5, pc} + ... + +0800d864 : + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d864: 4b13 ldr r3, [pc, #76] ; (800d8b4 ) + 800d866: f44f 51fa mov.w r1, #8000 ; 0x1f40 + 800d86a: 681b ldr r3, [r3, #0] + 800d86c: fbb3 f3f1 udiv r3, r3, r1 + 800d870: f241 3188 movw r1, #5000 ; 0x1388 +{ + 800d874: 4602 mov r2, r0 + uint32_t count = SDMMC_CMDTIMEOUT * (SystemCoreClock / 8U /1000U); + 800d876: 434b muls r3, r1 + if (count-- == 0U) + 800d878: 3b01 subs r3, #1 + 800d87a: d317 bcc.n 800d8ac + sta_reg = SDMMCx->STA; + 800d87c: 6b51 ldr r1, [r2, #52] ; 0x34 + ((sta_reg & SDMMC_FLAG_CMDACT) != 0U )); + 800d87e: f011 0f45 tst.w r1, #69 ; 0x45 + 800d882: d0f9 beq.n 800d878 + }while(((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT)) == 0U) || + 800d884: 0488 lsls r0, r1, #18 + 800d886: d4f7 bmi.n 800d878 + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT)) + 800d888: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d88a: 0759 lsls r1, r3, #29 + 800d88c: d502 bpl.n 800d894 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CTIMEOUT); + 800d88e: 2004 movs r0, #4 + 800d890: 6390 str r0, [r2, #56] ; 0x38 + return SDMMC_ERROR_CMD_RSP_TIMEOUT; + 800d892: 4770 bx lr + else if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL)) + 800d894: 6b50 ldr r0, [r2, #52] ; 0x34 + 800d896: f010 0001 ands.w r0, r0, #1 + 800d89a: d002 beq.n 800d8a2 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL); + 800d89c: 2301 movs r3, #1 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND); + 800d89e: 6393 str r3, [r2, #56] ; 0x38 + 800d8a0: 4770 bx lr + if(__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CMDREND)) + 800d8a2: 6b53 ldr r3, [r2, #52] ; 0x34 + 800d8a4: 065b lsls r3, r3, #25 + 800d8a6: d503 bpl.n 800d8b0 + __SDMMC_CLEAR_FLAG(SDMMCx, SDMMC_FLAG_CMDREND); + 800d8a8: 2340 movs r3, #64 ; 0x40 + 800d8aa: e7f8 b.n 800d89e + return SDMMC_ERROR_TIMEOUT; + 800d8ac: f04f 4000 mov.w r0, #2147483648 ; 0x80000000 +} + 800d8b0: 4770 bx lr + 800d8b2: bf00 nop + 800d8b4: 2009e2ac .word 0x2009e2ac + +0800d8b8 : +{ + 800d8b8: b510 push {r4, lr} + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + 800d8ba: f44f 72d5 mov.w r2, #426 ; 0x1aa +{ + 800d8be: b086 sub sp, #24 + sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD; + 800d8c0: 2308 movs r3, #8 + 800d8c2: e9cd 2301 strd r2, r3, [sp, #4] + sdmmc_cmdinit.WaitForInterrupt = SDMMC_WAIT_NO; + 800d8c6: f44f 7180 mov.w r1, #256 ; 0x100 + 800d8ca: 2300 movs r3, #0 + 800d8cc: e9cd 1303 strd r1, r3, [sp, #12] +{ + 800d8d0: 4604 mov r4, r0 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d8d2: f44f 5380 mov.w r3, #4096 ; 0x1000 + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d8d6: a901 add r1, sp, #4 + sdmmc_cmdinit.CPSM = SDMMC_CPSM_ENABLE; + 800d8d8: 9305 str r3, [sp, #20] + (void)SDMMC_SendCommand(SDMMCx, &sdmmc_cmdinit); + 800d8da: f7ff fbc9 bl 800d070 + errorstate = SDMMC_GetCmdResp7(SDMMCx); + 800d8de: 4620 mov r0, r4 + 800d8e0: f7ff ffc0 bl 800d864 +} + 800d8e4: b006 add sp, #24 + 800d8e6: bd10 pop {r4, pc} + +0800d8e8 : + 800d8e8: b510 push {r4, lr} + 800d8ea: 3901 subs r1, #1 + 800d8ec: 4402 add r2, r0 + 800d8ee: 4290 cmp r0, r2 + 800d8f0: d101 bne.n 800d8f6 + 800d8f2: 2000 movs r0, #0 + 800d8f4: e005 b.n 800d902 + 800d8f6: 7803 ldrb r3, [r0, #0] + 800d8f8: f811 4f01 ldrb.w r4, [r1, #1]! + 800d8fc: 42a3 cmp r3, r4 + 800d8fe: d001 beq.n 800d904 + 800d900: 1b18 subs r0, r3, r4 + 800d902: bd10 pop {r4, pc} + 800d904: 3001 adds r0, #1 + 800d906: e7f2 b.n 800d8ee + +0800d908 : + 800d908: 440a add r2, r1 + 800d90a: 4291 cmp r1, r2 + 800d90c: f100 33ff add.w r3, r0, #4294967295 ; 0xffffffff + 800d910: d100 bne.n 800d914 + 800d912: 4770 bx lr + 800d914: b510 push {r4, lr} + 800d916: f811 4b01 ldrb.w r4, [r1], #1 + 800d91a: f803 4f01 strb.w r4, [r3, #1]! + 800d91e: 4291 cmp r1, r2 + 800d920: d1f9 bne.n 800d916 + 800d922: bd10 pop {r4, pc} + +0800d924 : + 800d924: 4402 add r2, r0 + 800d926: 4603 mov r3, r0 + 800d928: 4293 cmp r3, r2 + 800d92a: d100 bne.n 800d92e + 800d92c: 4770 bx lr + 800d92e: f803 1b01 strb.w r1, [r3], #1 + 800d932: e7f9 b.n 800d928 + +0800d934 : + 800d934: 46ec mov ip, sp + 800d936: e8a0 5ff0 stmia.w r0!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} + 800d93a: f04f 0000 mov.w r0, #0 + 800d93e: 4770 bx lr + +0800d940 : + 800d940: e8b0 5ff0 ldmia.w r0!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr} + 800d944: 46e5 mov sp, ip + 800d946: 0008 movs r0, r1 + 800d948: bf08 it eq + 800d94a: 2001 moveq r0, #1 + 800d94c: 4770 bx lr + 800d94e: bf00 nop + +0800d950 : + 800d950: b510 push {r4, lr} + 800d952: 460b mov r3, r1 + 800d954: b162 cbz r2, 800d970 + 800d956: 3a01 subs r2, #1 + 800d958: d008 beq.n 800d96c + 800d95a: f813 4b01 ldrb.w r4, [r3], #1 + 800d95e: f800 4b01 strb.w r4, [r0], #1 + 800d962: 2c00 cmp r4, #0 + 800d964: d1f7 bne.n 800d956 + 800d966: 1a58 subs r0, r3, r1 + 800d968: 3801 subs r0, #1 + 800d96a: bd10 pop {r4, pc} + 800d96c: 2200 movs r2, #0 + 800d96e: 7002 strb r2, [r0, #0] + 800d970: f813 2b01 ldrb.w r2, [r3], #1 + 800d974: 2a00 cmp r2, #0 + 800d976: d1fb bne.n 800d970 + 800d978: e7f5 b.n 800d966 + +0800d97a : + 800d97a: 4603 mov r3, r0 + 800d97c: f813 2b01 ldrb.w r2, [r3], #1 + 800d980: 2a00 cmp r2, #0 + 800d982: d1fb bne.n 800d97c + 800d984: 1a18 subs r0, r3, r0 + 800d986: 3801 subs r0, #1 + 800d988: 4770 bx lr + 800d98a: 0000 movs r0, r0 + 800d98c: 0000 movs r0, r0 + ... + +0800d990 <__flash_burn_veneer>: + 800d990: f85f f000 ldr.w pc, [pc] ; 800d994 <__flash_burn_veneer+0x4> + 800d994: 2009e001 .word 0x2009e001 + +0800d998 <__flash_page_erase_veneer>: + 800d998: f85f f000 ldr.w pc, [pc] ; 800d99c <__flash_page_erase_veneer+0x4> + 800d99c: 2009e08d .word 0x2009e08d + 800d9a0: 6f636e69 .word 0x6f636e69 + 800d9a4: 006e .short 0x006e + 800d9a6: 6944 .short 0x6944 + 800d9a8: 44203a65 .word 0x44203a65 + 800d9ac: 44005546 .word 0x44005546 + 800d9b0: 203a6569 .word 0x203a6569 + 800d9b4: 6e776f44 .word 0x6e776f44 + 800d9b8: 64617267 .word 0x64617267 + 800d9bc: 69440065 .word 0x69440065 + 800d9c0: 42203a65 .word 0x42203a65 + 800d9c4: 6b6e616c .word 0x6b6e616c + 800d9c8: 00687369 .word 0x00687369 + 800d9cc: 3a656944 .word 0x3a656944 + 800d9d0: 69724220 .word 0x69724220 + 800d9d4: 42006b63 .word 0x42006b63 + 800d9d8: 32746f6f .word 0x32746f6f + 800d9dc: 00554644 .word 0x00554644 + 800d9e0: 524c .short 0x524c + 800d9e2: 00 .byte 0x00 + 800d9e3: 65 .byte 0x65 + 800d9e4: 7265746e .word 0x7265746e + 800d9e8: 7566645f .word 0x7566645f + 800d9ec: 2928 .short 0x2928 + 800d9ee: 00 .byte 0x00 + 800d9ef: 0d .byte 0x0d + 800d9f0: 31510a0a .word 0x31510a0a + 800d9f4: 6f6f4220 .word 0x6f6f4220 + 800d9f8: 616f6c74 .word 0x616f6c74 + 800d9fc: 3a726564 .word 0x3a726564 + 800da00: 463e0020 .word 0x463e0020 + 800da04: 57455249 .word 0x57455249 + 800da08: 454c4c41 .word 0x454c4c41 + 800da0c: 70003c44 .word 0x70003c44 + 800da10: 2d726961 .word 0x2d726961 + 800da14: 63697262 .word 0x63697262 + 800da18: 0064656b .word 0x0064656b + 800da1c: 69726556 .word 0x69726556 + 800da20: 203a7966 .word 0x203a7966 + 800da24: 00 .byte 0x00 + 800da25: 54 .byte 0x54 + 800da26: 4145 .short 0x4145 + 800da28: 69742052 .word 0x69742052 + 800da2c: 756f656d .word 0x756f656d + 800da30: 00000074 .word 0x00000074 + 800da34: 00000150 .word 0x00000150 + 800da38: 00000011 .word 0x00000011 + 800da3c: 00000001 .word 0x00000001 + 800da40: 00000001 .word 0x00000001 + 800da44: 00000000 .word 0x00000000 + +0800da48 : + 800da48: 0011627f 01001886 22180080 00188600 .b.........".... + 800da58: 18008001 00117d7f .....}... + +0800da61 : + 800da61: 000f577f 07e00182 1e408100 10018600 .W........@..... + 800da71: 01000200 40810003 0186001e 00020008 .......@........ + 800da81: 81000301 82001e40 00030801 00030181 ....@........... + 800da91: 001e4081 5c08018a 08c1010e 1e40071c .@.....\......@. + 800daa1: 08018a00 21020262 c0082210 018a001e ....b..!."...... + 800dab1: 040241f0 10412011 8a001e40 02400801 .A... A.@.....@. + 800dac1: 41400104 001e4010 4004018a c0010402 ..@A.@.....@.... + 800dad1: 1e40107f 04018a00 01040240 40104020 ..@.....@... @.@ + 800dae1: 018a001e 04024004 10401011 8a001e40 .....@....@.@... + 800daf1: 02400801 21082102 001ec008 40f0018a ..@..!.!.......@ + 800db01: 04c10102 7f40071e 00000f7d ......@.}... + +0800db0d : + 800db0d: 0016237f 00270881 00247f81 ff031f81 .#....'...$..... + 800db1d: 0023c081 e081ff04 07810022 e382ff03 ..#....."....... + 800db2d: 860022e0 ff0fff1f 0022f081 03c03f82 ."........"..?.. + 800db3d: 22f08100 04ff8100 21788100 fc018200 ..."......x!.... + 800db4d: 78810004 03820021 810004f0 83002178 ...x!.......x!.. + 800db5d: 030fe007 21788100 800f8700 0000803f ......x!....?... + 800db6d: 870021f8 80ff001f 21f00000 033e8300 .!.........!..>. + 800db7d: 810003ff 830021f0 03f8077c 21e08100 .....!..|......! + 800db8d: 0ff88700 010000c0 870021e0 00801ff0 .........!...... + 800db9d: 20e00100 e0018300 8200033e 0020e001 ... ....>..... . + 800dbad: 7ce00383 01820003 830020e0 04f8c003 ...|..... ...... + 800dbbd: 20e08100 81078300 810004f0 830020e0 ... ......... .. + 800dbcd: 04e08307 20e08100 030f8300 810004c0 ....... ........ + 800dbdd: 830020f0 04c0070f 20f08100 0f1e8300 . ......... .... + 800dbed: 81000480 820020f0 00050f1e 0020f081 ..... ........ . + 800dbfd: 051f1e82 20f08100 1e1e8200 f0810005 ....... ........ + 800dc0d: 1c820020 8100051e 820020f0 00051c3c ........ ..<... + 800dc1d: 0020f081 053c3c82 20f08100 1c3c8200 .. ..<<.... ..<. + 800dc2d: f0810005 3c810020 e0810006 3c810020 .... ..<.... ..< + 800dc3d: 01820005 810020e0 8200053c 0020e001 ..... ..<..... . + 800dc4d: 00053c81 20e00182 053c8100 c0018200 .<..... ..<..... + 800dc5d: 3c810020 03820005 810020c0 8200053c ..<..... ..<... + 800dc6d: 0020c003 00053c81 20800782 051c8100 .. ..<..... .... + 800dc7d: 80078200 1c810020 0f810005 1c810021 .... .......!... + 800dc8d: 1f810005 1e810021 1e810005 1e810021 ....!.......!... + 800dc9d: 3c810005 1e810021 7c810005 1c810021 ..... + 800dcfd: 22e0ffc3 1f1f8200 8081ff03 1f810022 ..."........"... + 800dd0d: fc81ff03 0f810023 e081ff03 03820023 ....#.......#... + 800dd1d: 810027f8 24297f40 f00f8200 03820008 .'..@.)$........ + 800dd2d: 83001cc0 07200008 20048200 0883001c ...... .... .... + 800dd3d: 00082000 001c1081 000a0881 001c1081 . .............. + 800dd4d: e000088c 08c83d5c 00075cf8 8c001c20 ....\=...\.. ... + 800dd5d: 6220c00f 04882822 40800862 088c001c .. b"(..b..@.... + 800dd6d: 22412000 41048828 1c804010 00088b00 . A"(..A.@...... + 800dd7d: 28224020 1040fc88 8b001d41 40200008 @"(..@.A..... @ + 800dd8d: 04892822 1dc11f40 00088a00 25224020 "(..@....... @"% + 800dd9d: 10400451 088a001e 22402000 40045125 Q.@...... @"%Q.@ + 800ddad: 8b001e10 40200008 0c512520 1d410840 ...... @ %Q.@.A. + 800ddbd: 00088b00 22204020 0740f420 0f4b7f81 .... @ " .@...K. + ... + +0800ddcf : + 800ddcf: 0010237f 00272081 00087081 f8e31f83 .#... '..p...... + 800dddf: 7181001c 3f830008 001bfeff 80730e83 ...q...?......s. + 800ddef: 7f830007 001bfeff 80770f83 fc830007 ..........w..... + 800ddff: 001b9fff 08ff0782 3ef08400 001a800f ...........>.... + 800de0f: 078e0382 f0018500 23800700 e0018500 ...........#.... + 800de1f: 1bc00300 e0078200 03850006 c00300c0 ................ + 800de2f: 0183001a 0006e087 00c00385 0019e001 ................ + 800de3f: c403f883 07850007 e0010080 01840018 ................ + 800de4f: 07ee07fc 803f8500 17fc0100 fb7f8500 ......?......... + 800de5f: 07cf0ffe 80ff8500 16ff0000 ff038700 ................ + 800de6f: 871fdfff 82000580 0003ff01 1580ff82 ................ + 800de7f: ff0f8700 03bf8fff 82000580 0003f803 ................ + 800de8f: 15c00f82 ff3f8500 07fe07ff e0038200 ......?......... + 800de9f: 03820003 850015e0 0303807f 820007fc ................ + 800deaf: 0003c003 15e00182 00fe8500 07f80100 ................ + 800debf: c0038200 01820003 820014e0 0003f801 ................ + 800decf: 0007f881 03e00382 c0038200 03820014 ................ + 800dedf: 810003e0 8200077c 0003f803 14c00f82 ....|........... + 800deef: c0078200 3e810003 01870007 0100c0ff .......>........ + 800deff: 001480ff 78800f86 081f0000 15ff0500 .......x........ + 800df0f: 031f8700 0f0000f8 81000780 81ff033f ............?... + 800df1f: 870015fc 00f8071e 07c00700 031f8100 ................ + 800df2f: 15f881ff 0f3c8700 030000f8 850007c0 ......<......... + 800df3f: feff3f1e 87001578 00801f7c 07c00300 .?..x...|....... + 800df4f: 3f1e8500 1578fce7 3e788200 07820003 ...?..x...x>.... + 800df5f: 850007c0 fce33f1e 82001578 00037c78 .....?..x...x|.. + 800df6f: 06800f82 fe038700 7ffcc31f 820014e0 ................ + 800df7f: 000378f0 00071f81 0fff0387 e07ff881 .x.............. + 800df8f: f0820014 81000378 8700071e 0003ff03 ....x........... + 800df9f: 14c0ff40 f0e08200 1e810003 01820007 @............... + 800dfaf: 820003ff 0013c0ff f0e00183 1e810003 ................ + 800dfbf: 01870007 000080ff 0013c0ff f0e00183 ................ + 800dfcf: 0e810003 01870007 0100c0ff 001380ff ................ + 800dfdf: 70e00183 0f810003 ff860008 ff0300c0 ...p............ + 800dfef: 82001380 0004e001 00080f81 00e0ff85 ................ + 800dfff: 0014ff07 04e00182 080f8100 f87f8500 ................ + 800e00f: 14ff0f00 e0018200 0f810004 ff860008 ................ + 800e01f: ff3f00fc 82001380 0004e001 00070f81 ..?............. + 800e02f: ffff0387 c0ffff80 01820013 810004e0 ................ + 800e03f: 8700070f ff3ff007 13e00ffc e0018200 ......?......... + 800e04f: 0f810004 07870007 f8ff1fc0 0013f003 ................ + 800e05f: 04e00182 070e8100 800f8700 00f8ff1f ................ + 800e06f: 810014f8 810004e0 8700071e 3e1f001f ...............> + 800e07f: 14780078 04f08100 071e8100 001e8700 x.x............. + 800e08f: 00f8800f 8100147c 810004f0 8700071e ....|........... + 800e09f: 810f001e 143c00f8 04f08100 073c8100 ......<.......<. + 800e0af: 003c8700 00f8c10f 8100143c 81000478 ..<.....<...x... + 800e0bf: 8700073c c30f003c 141c00f0 047c8100 <...<.........|. + 800e0cf: 07788100 003c8700 00f0c30f 8100141c ..x...<......... + 800e0df: 8100043c 87000778 c30f003c 141e00f0 <...x...<....... + 800e0ef: 043e8100 07f08100 003c8700 00f0c10f ..>.......<..... + 800e0ff: 8100141e 8200031f 0007f001 07003c87 .............<.. + 800e10f: 1e00f0c1 0f860014 03000080 870007e0 ................ + 800e11f: c107003c 141e00f0 c00f8600 c0070000 <............... + 800e12f: 3c870007 f0810700 00141e00 00e00786 ...<............ + 800e13f: 07800f00 003c8700 00e08107 8500141e ......<......... + 800e14f: 0000f003 8700083f 8107003c 141e00e0 ....?...<....... + 800e15f: fc018500 087e0000 003c8700 00e08007 ......~...<..... + 800e16f: 8400151e fc03007f 3c870008 e0800300 ...........<.... + 800e17f: 00151e00 1ff83f84 870008f8 8003003e .....?......>... + 800e18f: 153c00e0 ff0f8400 0008e0ff ff053f81 ..<..........?.. + 800e19f: 0015fc81 ffff0384 81000880 81ff051f ................ + 800e1af: 820016f8 0009fcff ff050f81 0016f081 ................ + 800e1bf: 000a0381 ff050181 297fc081 01820014 ...........).... + 800e1cf: 840006e0 70000004 04810006 01820015 .......p........ + 800e1df: 87000610 88000004 03010000 15048100 ................ + 800e1ef: 08018200 04870006 00040100 00030100 ................ + 800e1ff: 00150481 06040182 00048700 00000401 ................ + 800e20f: 81000301 93001504 173e0401 5c70d001 ..........>...p\ + 800e21f: 00010004 e0870f41 1504f770 04019300 ....A...p....... + 800e22f: 30821801 00046288 10410001 88880041 ...0.b....A.A... + 800e23f: 93001584 10010401 41041144 00010004 ........D..A.... + 800e24f: 01011041 15848804 04019300 1144103f A...........?.D. + 800e25f: 00044004 10410001 88040101 93001584 .@....A......... + 800e26f: 10410401 40fc1144 00010004 01810f41 ..A.D..@....A... + 800e27f: 15848804 04019300 11441041 00004000 ........A.D..@.. + 800e28f: 00410401 88040141 93001580 10410801 ..A.A.........A. + 800e29f: 40003142 04010000 01410041 15808804 B1.@....A.A..... + 800e2af: 10019300 d0411043 00044084 10238800 ....C.A..@....#. + 800e2bf: 80881041 93001584 103de001 40781040 A.........=.@.x@ + 800e2cf: 70000004 e0800f1d 1a848070 26108100 ...p....p......& + 800e2df: 10048200 02820026 82002620 477fc001 ....&... &.....G + 800e2ef: ... + +0800e2f2 : + 800e2f2: 0013247f 26c00382 ffff8200 0c860023 .$.....&....#... + 800e302: ffff0700 860022e0 ff1f001e 0022f8ff ....."........". + 800e312: 7f001e86 22fe7ffe 001e8600 ff0180ff ......."........ + 800e322: 1e870022 0000fc03 0021c03f f0071e87 ".......?.!..... + 800e332: e00f0000 1e870021 0000c00f 0021f003 ....!.........!. + 800e342: 801f1e87 f8010000 1e820021 8100043f ........!...?... + 800e352: 820021fc 00047e1e 00217e81 00fc1e87 .!...~...~!..... + 800e362: 3f00c003 1e870021 c00300f8 00211f00 ...?!.........!. + 800e372: 00f01f88 0f00c003 88002080 0300e01f ......... ...... + 800e382: 800700c0 1f880020 c00300e0 20c00700 .... .......... + 800e392: c01f8800 00c00300 0020c003 fcff1f88 .......... ..... + 800e3a2: 0100c003 880020e0 03feff1f e00100c0 ..... .......... + 800e3b2: 1f880020 c003feff 20f00100 ff1f8800 .......... .... + 800e3c2: 00c003fc 0023f000 00c00385 0023f000 ......#.......#. + 800e3d2: 00c00385 0023f000 00c00385 00237800 ......#......x#. + 800e3e2: 00c00385 00237800 00c00385 00237800 .....x#......x#. + 800e3f2: 00c00385 00237800 00c00385 00237800 .....x#......x#. + 800e402: 00c00385 00237800 00c00385 00237800 .....x#......x#. + 800e412: 00e00385 00237800 00f80385 00247800 .....x#......x$. + 800e422: 0000fc84 84002478 7800007f 3f840024 ....x$.....x$..? + 800e432: 24f00080 c00f8400 0024f000 00e00784 ...$......$..... + 800e442: 840024f0 f001e001 c0830025 0026e001 .$......%.....&. + 800e452: 26e00182 e0038200 07820026 820026c0 ...&....&....&.. + 800e462: 00268007 26800f82 271f8100 273f8100 ..&....&...'..?' + 800e472: 227e8100 04078100 22fc8100 800f8600 ..~".......".... + 800e482: f8010000 0f860022 030000c0 860022f0 ...."........".. + 800e492: 0000f007 0022e00f 00fc0386 23c03f00 ......"......?.# + 800e4a2: 80ff8400 0024ff01 7ffe7f84 840024fe ......$......$.. + 800e4b2: f8ffff1f 07840024 25e0ffff ffff8200 ....$......%.... + 800e4c2: 01820026 212a7f80 08f08100 00088300 &.....*!........ + 800e4d2: 81001c1e 83000888 1c210008 08848100 ..........!..... + 800e4e2: 00088400 001b8000 00088281 00000884 ................ + 800e4f2: 8c001b80 12100e82 072e3ae0 0138e8c0 .........:....8. + 800e502: 828c001c 10131111 21003146 1c024418 ........F1.!.D.. + 800e512: 20828c00 82081291 08228020 001c0482 ... .... ."..... + 800e522: 9120828c 20820812 8208e207 8c001c08 .. .... ........ + 800e532: 12912082 08208208 08fe0822 828b001c . .... ."....... + 800e542: 08a28a20 22082082 001d8008 8a20848b .... ."...... . + 800e552: 204608a2 80082208 888c001d 08a20a11 ..F .".......... + 800e562: 6108203a 1c084218 0ef08c00 02084204 : .a.B.......B.. + 800e572: e8a00720 0021083c 00270281 00278281 ...<.!...'...'. + 800e582: 00274481 477f3881 .D'..8.G... + +0800e58d : + 800e58d: 0013577f 01001c84 850023c0 02002288 .W.......#...".. + 800e59d: 84002320 02002088 88840024 23020020 #... ..$... ..# + 800e5ad: fc038500 23424020 10018500 23424420 .... @B#.... DB# + 800e5bd: 10018600 c04f44fc 01850022 42442010 .....DO.".... DB + 800e5cd: 07850023 424420f8 02850023 822a2020 #.... DB#... *. + 800e5dd: 02850023 822a2020 02850023 822a2020 #... *.#... *. + 800e5ed: 20830025 7d7f0211 %.. ...}... + +0800e5f8 : + 800e5f8: 0002bc7f 0000fe84 82000801 00198007 ................ + 800e608: 18000185 00060100 04001084 85001940 ............@... + 800e618: 000c0001 84000601 20040010 01850019 ........... .... + 800e628: 01000600 10840006 19100400 00019200 ................ + 800e638: 00010003 c141071c 04007e04 075c7010 ......A..~...p\. + 800e648: 01930016 01800100 c2082200 00100421 ........."..!... + 800e658: 62881004 00158008 00000193 410001c0 ...b...........A + 800e668: 04114410 11040010 40104104 01930015 .D.......A.@.... + 800e678: 01e0ff07 44104100 00100411 41041104 .....A.D.......A + 800e688: 00154010 00000193 410001c0 04114410 .@.........A.D.. + 800e698: 11040010 c01f4104 01920015 01800100 .....A.......... + 800e6a8: 44104100 00100411 41041104 92001610 .A.D.......A.... + 800e6b8: 00030001 08410001 100411c4 04210400 ......A.......!. + 800e6c8: 00161041 06000193 22000100 8c204207 A..........".B . + 800e6d8: 40040011 40084188 01930015 01000c00 ...@.A.@........ + 800e6e8: 41001cfc 000e74c0 41708007 00158007 ...A.t....pA.... + 800e6f8: 18000183 40810005 fe810020 10820005 .......@ ....... + 800e708: 82002640 00268008 147f0781 @&....&........ + +0800e717 : + 800e717: 0014577f 00271081 00271081 00272081 .W....'...'.. '. + 800e727: 00272081 00274081 00274081 00258081 . '..@'..@'...%. + 800e737: 81c01f84 810025fc 81002701 81002701 .....%...'...'.. + 800e747: 81002702 81002702 81002704 147c7f04 .'...'...'....|. + ... + +0800e759 : + 800e759: 0003ba7f 0026c081 26c01082 c3308500 ......&....&..0. + 800e769: 06f00100 00078400 001938e0 80c16085 .........8...`.. + 800e779: 00060801 10810884 85001944 0180c040 ........D...@... + 800e789: 84000604 40004110 c0030019 06040182 .....A.@........ + 800e799: 41108400 00194000 40c0808f 201c0401 ...A.@.....@... + 800e7a9: 0070c121 40004110 80850019 040140c0 !.p..A.@.....@.. + 800e7b9: 21872203 41100088 00184000 c0800190 .".!...A.@...... + 800e7c9: 41080160 04112422 e1471000 900018f8 `..A"$....G..... + 800e7d9: 60c08001 2241f001 00001124 40004110 ...`..A"$....A.@ + 800e7e9: 01900018 0160c080 27224100 100000f1 ......`..A"'.... + 800e7f9: 18400041 80019000 00014000 01441541 A.@......@..A.D. + 800e809: 41100000 00194000 4000808f 15410001 ...A.@.....@..A. + 800e819: 00000144 40004110 c08f0019 0001c000 D....A.@........ + 800e829: 11421522 81080000 00194000 8000408f ".B......@...@.. + 800e839: 081c0001 0000e181 40000107 60830019 ...........@...` + 800e849: 00258001 26033082 0c0c8200 07820026 ..%..0.&....&... + 800e859: 24147ff8 ...$.. + +0800e85f : + 800e85f: 000f277f 00052081 ff040181 001c8081 .'... .......... + 800e86f: 00057081 ff040781 001cf081 0005f881 .p.............. + 800e87f: ff040f81 001cf881 0005fc81 ff041f81 ................ + 800e88f: 001cfc81 00057e81 003c1e86 1cfe0700 .....~....<..... + 800e89f: 053f8100 3c1e8600 bf070000 1f82001c ..?....<........ + 800e8af: 87000480 00003c1e 1b809f07 c00f8200 .....<.......... + 800e8bf: 1e870004 0700003c 001bc08f 04e00782 ....<........... + 800e8cf: 3c1e8700 87070000 82001be0 0004f003 ...<............ + 800e8df: 003c1e87 f0830700 0182001b 870004f8 ..<............. + 800e8ef: 00003c1e 1cf88107 04fc8100 3c1e8700 .<.............< + 800e8ff: 80070000 81001cfc 8700047e 00003c1e ........~....<.. + 800e90f: 1c7c8007 043f8100 3c1e8700 80070000 ..|...?....<.... + 800e91f: 82001c3e 0003801f 003c1e87 1e800700 >.........<..... + 800e92f: 0f82001c 820003c0 ff033f1e 1c0e8082 .........?...... + 800e93f: e0078200 1e820003 82ff031f 001c0f00 ................ + 800e94f: 03f00382 1f1e8200 0082ff03 82001c0f ................ + 800e95f: 0003f801 ff0f1e87 0f00feff fc81001d ................ + 800e96f: 1e810003 0f810005 7e81001d 1e810003 ...........~.... + 800e97f: 0f810005 3f81001d 1e810003 0f810005 .......?........ + 800e98f: 1f85001d 1e000080 0f810005 0f85001d ................ + 800e99f: 1e0000c0 0f810005 078b001d 1e0000e0 ................ + 800e9af: 807f0000 00180f00 f08aff06 001e0000 ................ + 800e9bf: 00e0ff01 0600180f 00f88aff 03001e00 ................ + 800e9cf: 0f00f0ff ff060018 0000f08a fb07001e ................ + 800e9df: 180f00f8 057f8100 00e08aff 07001e00 ................ + 800e9ef: 0f007cc0 0f8b001d 1e0000c0 3e800f00 .|.............> + 800e9ff: 001d0f00 00801f8b 0f001e00 0f001e00 ................ + 800ea0f: 3f81001d 1e870003 1e001e00 001d0f00 ...?............ + 800ea1f: 00037e81 1e001e87 0f000e00 fc81001d .~.............. + 800ea2f: 1e870003 0f001e00 001c0f00 03f80182 ................ + 800ea3f: 001e8700 000f001e 82001c0f 0003f003 ................ + 800ea4f: 1e001e87 0f000e00 0782001c 870003e0 ................ + 800ea5f: 001e001e 1c0f001e c00f8200 1e870003 ................ + 800ea6f: 1e000f00 001c0f00 03801f82 001e8700 ................ + 800ea7f: 003e000f 81001c0f 8700043f c007001e ..>.....?....... + 800ea8f: 1c0f007c 047e8100 001e8700 00f8fb07 |.....~......... + 800ea9f: 81001c0f 870004fc ff03001e 1b0f00f0 ................ + 800eaaf: f8018200 1e870004 e0ff0100 001b0f00 ................ + 800eabf: 04f00382 001e8700 00807f00 82001b0f ................ + 800eacf: 0004e007 00051e81 001b0f81 04c00f82 ................ + 800eadf: 051e8100 1b0f8100 801f8200 1e810004 ................ + 800eaef: 0f810005 3f81001b 1e810005 0e810005 .......?........ + 800eaff: 7e81001b 1e810005 1e810005 fc81001b ...~............ + 800eb0f: 1f810005 fe81ff05 f881001b 0f810005 ................ + 800eb1f: fc81ff05 7081001b 07810005 f881ff05 .......p........ + 800eb2f: 2081001b 01810005 e081ff05 00192d7f ... .........-.. + 800eb3f: 07800f82 031c8100 1a048100 05028100 ................ + 800eb4f: 00018400 00032200 001a0481 00050281 .....".......... + 800eb5f: 00000184 81000341 81001a04 84000502 ....A........... + 800eb6f: 41000001 04810003 028e001a 1cf8c005 ...A............ + 800eb7f: 00e00717 c0850f40 8e001a74 04210602 ....@...t.....!. + 800eb8f: 00811822 46004000 001a8c20 1104028e "....@.F ....... + 800eb9f: 41104100 00400000 1a041144 04028e00 .A.A..@.D....... + 800ebaf: 10410011 40000001 0401c40f 028e001a ..A....@........ + 800ebbf: 7ff81004 00000110 01441040 8e001a04 ........@.D..... + 800ebcf: 04100402 00011040 44104100 001a0401 ....@....A.D.... + 800ebdf: 1004028e 01104004 10410000 1a040144 .....@....A.D... + 800ebef: 04028e00 10210411 22001001 8c00c410 ......!....".... + 800ebff: 0f8e001a 1ef81084 00e00010 00440f1c ..............D. + 800ec0f: 0d4b7f74 t.K... + +0800ec15 : + 800ec15: 0010237f 00272081 00087081 f8e31f83 .#... '..p...... + 800ec25: 7181001c 3f830008 001bfeff 80730e83 ...q...?......s. + 800ec35: 7f830007 001bfeff 80770f83 fc830007 ..........w..... + 800ec45: 001b9fff 08ff0782 3ef08400 001a800f ...........>.... + 800ec55: 078e0382 f0018500 23800700 e0018500 ...........#.... + 800ec65: 1bc00300 e0078200 03850006 c00300c0 ................ + 800ec75: 0183001a 0006e087 00c00385 0019e001 ................ + 800ec85: c403f883 07850007 e0010080 01840018 ................ + 800ec95: 07ee07fc 803f8500 17fc0100 fb7f8500 ......?......... + 800eca5: 07cf0ffe 80ff8500 16ff0000 ff038700 ................ + 800ecb5: 871fdfff 82000580 0003ff01 1580ff82 ................ + 800ecc5: ff0f8700 03bf8fff 82000580 0003f803 ................ + 800ecd5: 15c00f82 ff3f8500 07fe07ff e0038200 ......?......... + 800ece5: 03820003 850015e0 0303807f 820007fc ................ + 800ecf5: 0003c003 15e00182 00fe8500 07f80100 ................ + 800ed05: c0038200 01820003 820014e0 0003f801 ................ + 800ed15: 0007f881 03e00382 c0038200 03820014 ................ + 800ed25: 810003e0 8200077c 0003f803 14c00f82 ....|........... + 800ed35: c0078200 3e810003 01870007 0100c0ff .......>........ + 800ed45: 001480ff 78800f86 081f0000 15ff0500 .......x........ + 800ed55: 031f8700 0f0000f8 81000780 81ff033f ............?... + 800ed65: 870015fc 00f8071e 07c00700 031f8100 ................ + 800ed75: 15f881ff 0f3c8700 030000f8 850007c0 ......<......... + 800ed85: feff3f1e 87001578 00801f7c 07c00300 .?..x...|....... + 800ed95: 3f1e8500 1578fce7 3e788200 07820003 ...?..x...x>.... + 800eda5: 850007c0 fce33f1e 82001578 00037c78 .....?..x...x|.. + 800edb5: 06800f82 fe038700 7ffcc31f 820014e0 ................ + 800edc5: 000378f0 00071f81 0fff0387 e07ff881 .x.............. + 800edd5: f0820014 81000378 8700071e 0003ff03 ....x........... + 800ede5: 14c0ff40 f0e08200 1e810003 01820007 @............... + 800edf5: 820003ff 0013c0ff f0e00183 1e810003 ................ + 800ee05: 01870007 000080ff 0013c0ff f0e00183 ................ + 800ee15: 0e810003 01870007 0100c0ff 001380ff ................ + 800ee25: 70e00183 0f810003 ff860008 ff0300c0 ...p............ + 800ee35: 82001380 0004e001 00080f81 00e0ff85 ................ + 800ee45: 0014ff07 04e00182 080f8100 f87f8500 ................ + 800ee55: 14ff0f00 e0018200 0f810004 ff860008 ................ + 800ee65: ff3f00fc 82001380 0004e001 00070f81 ..?............. + 800ee75: ffff0387 c0ffff80 01820013 810004e0 ................ + 800ee85: 8700070f ff3ff007 13e00ffc e0018200 ......?......... + 800ee95: 0f810004 07870007 f8ff1fc0 0013f003 ................ + 800eea5: 04e00182 070e8100 800f8700 00f8ff1f ................ + 800eeb5: 810014f8 810004e0 8700071e 3e1f001f ...............> + 800eec5: 14780078 04f08100 071e8100 001e8700 x.x............. + 800eed5: 00f8800f 8100147c 810004f0 8700071e ....|........... + 800eee5: 810f001e 143c00f8 04f08100 073c8100 ......<.......<. + 800eef5: 003c8700 00f8c10f 8100143c 81000478 ..<.....<...x... + 800ef05: 8700073c c30f003c 141c00f0 047c8100 <...<.........|. + 800ef15: 07788100 003c8700 00f0c30f 8100141c ..x...<......... + 800ef25: 8100043c 87000778 c30f003c 141e00f0 <...x...<....... + 800ef35: 043e8100 07f08100 003c8700 00f0c10f ..>.......<..... + 800ef45: 8100141e 8200031f 0007f001 07003c87 .............<.. + 800ef55: 1e00f0c1 0f860014 03000080 870007e0 ................ + 800ef65: c107003c 141e00f0 c00f8600 c0070000 <............... + 800ef75: 3c870007 f0810700 00141e00 00e00786 ...<............ + 800ef85: 07800f00 003c8700 00e08107 8500141e ......<......... + 800ef95: 0000f003 8700083f 8107003c 141e00e0 ....?...<....... + 800efa5: fc018500 087e0000 003c8700 00e08007 ......~...<..... + 800efb5: 8400151e fc03007f 3c870008 e0800300 ...........<.... + 800efc5: 00151e00 1ff83f84 870008f8 8003003e .....?......>... + 800efd5: 153c00e0 ff0f8400 0008e0ff ff053f81 ..<..........?.. + 800efe5: 0015fc81 ffff0384 81000880 81ff051f ................ + 800eff5: 820016f8 0009fcff ff050f81 0016f081 ................ + 800f005: 000a0381 ff050181 297fc081 3c810014 ...........)...< + 800f015: 80830007 00080e00 00142081 00072281 ......... ...".. + 800f025: 11008083 20820003 81000304 81001420 ....... .... ... + 800f035: 88000721 80200080 04200000 20810003 !..... ... .... + 800f045: 20820014 87000680 80200080 04200000 ... ...... ... . + 800f055: 14208100 87209400 0e3ae0c2 0080800b .. ... ...:..... + 800f065: 08c20720 82031cfc 001420e0 23802094 ........ ... .# + 800f075: 0c114610 20008040 20082200 10430404 .F..@.. .". ..C. + 800f085: 94001420 08228020 20882082 00200080 ... .".. . .. . + 800f095: 04200822 20082208 20940014 8208e287 ". ..". ... .... + 800f0a5: 80008820 e2072000 08042008 14200822 .... ... ..". . + 800f0b5: 88209400 3f820822 00800088 08220820 .. ."..?.... .". + 800f0c5: 22080420 00142008 22882087 08208208 ..". ... .".. . + 800f0d5: 20890003 20082288 08220804 21870015 ... .". .."....! + 800f0e5: 46082208 00030820 22882089 08042008 .".F .... .". .. + 800f0f5: 00150822 62082294 88103a08 11008000 "....".b.:...... + 800f105: 22186108 08420404 94001420 08a2073c .a."..B. ...<... + 800f115: 00080f02 070e0080 041ce8a0 20088203 ............... + 800f125: 02810018 82810027 44810027 38810027 ....'...'..D'..8 + 800f135: 0019477f .G... + +0800f13a : + 800f13a: 0013247f 26f83f82 feff8200 01840025 .$...?.&....%... + 800f14a: 2480ffff f8038400 0024c03f 07e00784 ...$....?.$..... + 800f15a: 840024e0 f001800f 1f840024 24f80000 .$......$......$ + 800f16a: 001e8400 00247800 00003c84 8600227c .....x$..<..|".. + 800f17a: 003c000e 00223c00 78000f88 003c0000 ..<..<"....x..<. + 800f18a: 880020e0 0078800f e0011e00 07880020 . ....x..... ... + 800f19a: 000078c0 20e0031e e0038800 1e000078 .x..... ....x... + 800f1aa: 0020c007 ff060181 00218081 0022ff06 .. .......!...". + 800f1ba: ff047f81 0022fe81 ff047f81 0022fc81 ......".......". + 800f1ca: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f1da: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f1ea: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f1fa: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f20a: 03007886 223c0080 00788600 3c00c003 .x....<"..x....< + 800f21a: 78860022 00c00300 8600223c c0030078 "..x....<"..x... + 800f22a: 00223c00 03007886 213c00c0 f87f8800 .<"..x....: + 800f3d7: 0013247f 26f83f82 feff8200 01840025 .$...?.&....%... + 800f3e7: 2480ffff f8038400 0024c03f 07e00784 ...$....?.$..... + 800f3f7: 840024e0 f001800f 1f840024 24f80000 .$......$......$ + 800f407: 001e8400 00247800 00003c84 8600227c .....x$..<..|".. + 800f417: 003c000e 00223c00 78000f88 003c0000 ..<..<"....x..<. + 800f427: 880020e0 0078800f e0011e00 07880020 . ....x..... ... + 800f437: 000078c0 20e0031e e0038800 1e000078 .x..... ....x... + 800f447: 0020c007 ff060181 00218081 0022ff06 .. .......!...". + 800f457: ff047f81 0022fe81 ff047f81 0022fc81 ......".......". + 800f467: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f477: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f487: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f497: 00047881 00223c81 00047881 00223c81 .x...<"..x...<". + 800f4a7: 03007886 223c0080 00788600 3c00c003 .x....<"..x....< + 800f4b7: 78860022 00c00300 8600223c c0030078 "..x....<"..x... + 800f4c7: 00223c00 03007886 213c00c0 f87f8800 .<"..x....: + 800f671: 0013247f 26c00182 ffff8200 07840025 .$.....&....%... + 800f681: 24e0ffff ff1f8400 0024f8ff 0ff07f84 ...$......$..... + 800f691: 840024fe ff0000ff 03860023 1f0000f8 .$......#....... + 800f6a1: 860022c0 0000e007 0022e00f 00c00f86 ."........"..... + 800f6b1: 22f00300 031f8100 f8018200 3e810022 ..."........"..> + 800f6c1: 7c810004 7c810022 3e810004 f8860022 ...|"..|...>"... + 800f6d1: 00c00300 8600221f c00300f0 00210f00 ....."........!. + 800f6e1: 00f00188 0f00c003 88002080 0300e001 ......... ...... + 800f6f1: 800700c0 03880020 c00300c0 20c00300 .... .......... + 800f701: c0078800 00c00300 0020c003 00800788 .......... ..... + 800f711: 0100c003 880020e0 03008007 e00100c0 ..... .......... + 800f721: 0f880020 c0030000 20f00000 000f8800 .......... .... + 800f731: 00c00300 0020f000 00000f88 0000c003 ...... ......... + 800f741: 880020f0 0300000e 700000c0 1e880020 . .........p ... + 800f751: c0030000 20780000 001e8800 00c00300 ......x ........ + 800f761: 00207800 00001e88 0000c003 88002078 .x .........x .. + 800f771: 0300001e 780000c0 1e880020 c0030000 .......x ....... + 800f781: 20780000 001e8800 00c00300 00207800 ..x .........x . + 800f791: 00001e88 0000e003 88002078 0300001e ........x ...... + 800f7a1: 780000f0 1e880020 f8030000 20780000 ...x .........x + 800f7b1: 001e8800 00fe0100 00207800 00031e81 .........x ..... + 800f7c1: 00007f84 81002078 8400030e 7000803f ....x ......?..p + 800f7d1: 0f810020 1f840003 20f000e0 030f8100 .......... .... + 800f7e1: e0078400 0020f000 00030f81 00e00384 ...... ......... + 800f7f1: 880020f0 00008007 e001c001 07820020 . .......... ... + 800f801: 82000480 0020e001 04c00782 c0038200 ...... ......... + 800f811: 03820020 820004c0 0020c003 04e00182 ......... ..... + 800f821: 80078200 01820020 820004f0 0021800f .... .........!. + 800f831: 0004f081 00220f81 0004f881 00221e81 ......".......". + 800f841: 00047c81 00223e81 00043e81 00227c81 .|...>"..>...|". + 800f851: 00041f81 0022f881 00c00f86 22f00300 ......"........" + 800f861: e0078600 e0070000 03860022 1f0000f8 ........"....... + 800f871: 840023c0 ff0000ff 7f840024 24fe0ff0 .#......$......$ + 800f881: ff1f8400 0024f8ff ffff0784 820025e0 ......$......%.. + 800f891: 0026ffff 7f800182 8500142a 00f88303 ..&.....*....... + 800f8a1: 8200070e 00090101 09104082 01078300 .........@...... + 800f8b1: 880003c0 00004204 80000011 01860004 .....B.......... + 800f8c1: 00010001 86000480 00104040 00068000 ........@@...... + 800f8d1: 20820883 08880003 20000022 04800080 ... ....".. .... + 800f8e1: 01018600 80000100 40860004 00001040 ...........@@... + 800f8f1: 82000680 00040208 00020888 00002000 ............. .. + 800f901: 82000480 00030101 00058081 00104085 .............@.. + 800f911: 00068000 04020882 0208a400 03200000 .............. . + 800f921: 2e82f083 01010003 f003071f 11100000 ................ + 800f931: 001040c0 2e82f003 3800800b 00040208 .@.........8.... + 800f941: 000204a4 40041000 03318280 00110100 .......@..1..... + 800f951: 00800081 40101100 00001040 0c318280 .......@@.....1. + 800f961: 08440040 a5000402 00f08303 8020080e @.D........... . + 800f971: 00802082 81001101 00008000 40401011 . ............@@ + 800f981: 80000010 20882082 0f3f8200 a30004c0 ..... . ..?..... + 800f991: 01000042 82802008 01008020 00811f11 B.... .. ....... + 800f9a1: 11000080 10404010 82800000 00200820 .....@@..... . . + 800f9b1: 05020882 03228100 e08f9f00 80208280 ......"....... . + 800f9c1: 20290100 00800081 40101100 00001040 ..) .......@@... + 800f9d1: 08208280 08820020 81000502 9f000322 .. . ......."... + 800f9e1: 82800088 00008020 008120aa 0a000080 .... .... ...... + 800f9f1: 104040a0 82800000 00200820 04020882 .@@..... . ..... + 800fa01: 22088a00 88200000 31828000 aa970003 ...".. ....1.... + 800fa11: 80008120 a00a0000 00104040 20828000 .......@@..... + 800fa21: 82002008 00040208 004204ce 20041100 . ........B.... + 800fa31: 032e4688 21440000 30880081 40a00a00 .F....D!...0...@ + 800fa41: 00001040 08204688 08440020 00c00002 @....F . .D..... + 800fa51: f8830300 c0030e00 03203a70 1e440000 ........p: ...D. + 800fa61: 30700081 40400400 00000e38 08203a70 ..p0..@@8...p: . + 800fa71: 08380020 0bc00002 08208100 1e608100 .8....... ...`. + 800fa81: 08208100 1ec08100 27208100 7f208100 .. ....... '.. . + 800fa91: 00001d47 G... + +0800fa95 : + 800fa95: 000e237f 00260881 e0ff0783 1f830025 .#....&.....%... + 800faa5: 0025fcff ffff7f83 01850024 c0ff80ff ..%.....$....... + 800fab5: 1f810005 f881ff03 03850019 e01f00f8 ................ + 800fac5: 7f810005 0019ff04 00e00f85 0005f003 ................ + 800fad5: 8081ff05 1f850018 f8010080 01810004 ................ + 800fae5: c081ff05 3f810018 7c810003 01870004 .......?...|.... + 800faf5: 0000c0e3 0018e07f 00037e81 00043e81 .........~...>.. + 800fb05: c0e30187 f07b0000 78810018 1f810003 ......{....x.... + 800fb15: 01870004 0000c0e3 0018f879 0003f881 ........y....... + 800fb25: 03800f82 e3018700 780000c0 820017fc ...........x.... + 800fb35: 0003f001 03800782 e3018700 780000c0 ...............x + 800fb45: 8200177e 0003e001 03c00382 e3018700 ~............... + 800fb55: 780000c0 8200173f 0003e003 03c00382 ...x?........... + 800fb65: e3018800 780000c0 0016801f 03c00382 .......x........ + 800fb75: e0018200 01880003 0000c0e3 16c00f78 ............x... + 800fb85: c0078200 01820003 880003e0 00c0e301 ................ + 800fb95: c0077800 07820016 81000480 880003f0 .x.............. + 800fba5: 00c0e301 e0037800 07820016 81000480 .....x.......... + 800fbb5: 880003f0 00c0e301 e0017800 07810016 .........x...... + 800fbc5: f0810005 01820003 83ff03e3 16e000f8 ................ + 800fbd5: 050f8100 03708100 e1018200 f083ff03 ......p......... + 800fbe5: 0016f000 00050f81 00037881 03e10182 .........x...... + 800fbf5: 00f083ff 810016f0 8100050f 82000378 ............x... + 800fc05: ff03e001 f000e083 0f810016 78810005 ...............x + 800fc15: 01820003 810005e0 810016f0 8100050f ................ + 800fc25: 82000378 0005e001 0016f081 00050f81 x............... + 800fc35: 00037881 05e00182 16f08100 050f8100 .x.............. + 800fc45: 03788100 e0018200 f0810005 0f810016 ..x............. + 800fc55: 78810005 01820003 810005e0 810016f0 ...x............ + 800fc65: 8100050f 88000370 0700e001 f00000f8 ....p........... + 800fc75: 0f810016 f0810005 01880003 fe1f00e0 ................ + 800fc85: 16f00000 05078100 03f08100 e0018800 ................ + 800fc95: 00ff3f00 0016f000 04800782 03f08100 .?.............. + 800fca5: e0018800 80bf7f00 0016f000 04800782 ................ + 800fcb5: 03f08100 e0018800 c0077c00 0016f000 .........|...... + 800fcc5: 03c00382 e0018200 01880003 03f800e0 ................ + 800fcd5: 16f000e0 c0038200 01820003 880003e0 ................ + 800fce5: f000e001 f000e001 03820016 820003e0 ................ + 800fcf5: 0003c003 01e00188 00e001e0 820016f0 ................ + 800fd05: 0003e001 03c00782 e0018800 e000e001 ................ + 800fd15: 0016f000 03f00182 80078200 01880003 ................ + 800fd25: 00e001e0 17f000f0 03f88100 800f8200 ................ + 800fd35: 01880003 00e001e0 17f000f0 037c8100 ..............|. + 800fd45: 041f8100 e0018800 e000e001 0017f000 ................ + 800fd55: 00033e81 00043e81 01e00188 00e001e0 .>...>.......... + 800fd65: 810017f0 8100033f 8800047f f000e001 ....?........... + 800fd75: f000e001 1f860017 ff0100c0 88000380 ................ + 800fd85: f000e001 f000e003 07860017 f70700e0 ................ + 800fd95: 880003c0 7c00e001 f000c007 03860017 .......|........ + 800fda5: e71f00fc 880003e0 7f00e001 f00080bf ................ + 800fdb5: 01810017 8382ff03 880003f0 3f00e001 ...............? + 800fdc5: f00000ff 7f850018 f801ffff 01880003 ................ + 800fdd5: fe1f00e0 18f00000 ff1f8500 03fc00fc ................ + 800fde5: e0018800 00f80700 0018f000 e0ff0385 ................ + 800fdf5: 00037e00 05e00182 1cf08100 033f8100 .~............?. + 800fe05: e0018200 f0810005 1f86001c 01000080 ................ + 800fe15: 810005e0 86001cf0 0000c00f 0005e001 ................ + 800fe25: 001ce081 00e00786 04e00100 e0018200 ................ + 800fe35: 0385001c 010000f0 e081ff06 0182001c ................ + 800fe45: 060003f8 1dc081ff 03fc8100 057f8100 ................ + 800fe55: 1d8081ff 037e8100 041f8100 1efe81ff ......~......... + 800fe65: 273f8100 271f8100 7f0e8100 8100222a ..?'...'....*".. + 800fe75: 810005e0 82002080 00051001 1f048082 ..... .......... + 800fe85: 08028200 80820005 81001f04 81000602 ................ + 800fe95: 8c002080 1f380002 bce0800b e8800b1c . ....8......... + 800fea5: 018c001c 8c004400 04c21041 1d18410c .....D..A....A.. + 800feb5: 82e08b00 08228800 22080482 8b001d08 ......"....".... + 800fec5: 881f8210 04820002 1d082208 fe088b00 ........."...... + 800fed5: 00028820 22080482 8b001d08 88208008 ......"...... . + 800fee5: 04820002 1c082208 08028c00 02882080 ....."....... .. + 800fef5: 08048208 001c1821 4210018f 10018821 ....!......B!... + 800ff05: 20080482 030c30e8 e08e001a 00881e3c ... .0......<... + 800ff15: 080482e0 0c300820 81002403 82002608 .... .0..$...&.. + 800ff25: 00260802 27100182 7fe08100 00001047 ..&....'....G... + +0800ff35 : + 800ff35: 0001bc7f 00030181 05040182 1c018100 ................ + 800ff45: 00018600 0401c00f 01820005 86001b02 ................ + 800ff55: 40080001 00050401 1b020182 00018600 ...@............ + 800ff65: 0401400c 01810005 0190001c 01400600 .@............@. + 800ff75: 45075c04 0e1df8c0 1874c005 01019000 .\.E......t..... + 800ff85: 0401400f 20c60862 06022304 00188c20 .@..b.. .#.. ... + 800ff95: 99030190 410401c0 04104410 11040241 .......A.D..A... + 800ffa5: 90001804 00f00601 10410401 41fc0044 ..........A.D..A + 800ffb5: 04110402 01900018 0100600c 44104104 .........`...A.D + 800ffc5: 02410401 18041104 08019000 04010000 ..A............. + 800ffd5: 01441041 04024104 00180411 00100190 A.D..A.......... + 800ffe5: 62040100 0401c408 10040241 8100188c ...b....A....... + 800fff5: 8b000401 44075c88 02230c01 18741004 .....\.D..#...t. + 8010005: 04018100 40708b00 f4004400 1004021d ......p@.D...... + 8010015: 81001804 83000501 06400040 18048100 ........@.@..... + 8010025: ff018900 0000e0ff 05401040 04018200 ........@.@..... + 8010035: 4083001e 00068008 001e8881 07074082 ...@.........@.. + 8010045: 7f708100 00001714 ..p..... + +0801004d : + 801004d: 0002b97f 26f80782 0c0c8200 30820026 .......&....&..0 + 801005d: 85002603 01800160 81000404 85001e38 .&..`.......8... + 801006d: 0180c040 84000304 02004480 c003001c @........D...... + 801007d: 03040182 40808400 001c0200 40c08085 .......@.......@ + 801008d: 00040401 001e4081 40c0808f 171c0401 .....@.....@.... + 801009d: 41408003 74c0050e 01900018 0160c080 ..@A...t......`. + 80100ad: 80182204 02414080 188c2006 80019000 ."...@A.. ...... + 80100bd: 040160c0 81401041 040241f8 00180411 .`..A.@..A...... + 80100cd: e0800190 41040160 40800010 11040241 ....`..A...@A... + 80100dd: 8f001904 00403080 00107f88 02414080 .....0@......@A. + 80100ed: 19041104 18808f00 40880040 40800010 ........@..@...@ + 80100fd: 11040241 8f001904 00c000c0 00104050 A...........P@.. + 801010d: 02234080 198c1004 00409300 21500080 .@#.......@...P! + 801011d: 40800010 1004021d 01061874 93001580 ...@....t....... + 801012d: 00800160 00101e20 02014080 18041004 `... ....@...... + 801013d: 15800106 03308200 01810008 04810003 ......0......... + 801014d: 0c820019 8500080c 01000001 82001904 ................ + 801015d: 0008f807 00034281 00238881 00033c81 .....B....#..<.. + 801016d: 147f7081 .p..... + +08010174 : + 8010174: 0014237f 00268081 26c00382 c0038200 .#....&....&.... + 8010184: 03820026 820026c0 0026c003 24c00382 &....&....&....$ + 8010194: c0018500 2303c003 e0038600 c007c003 .......#........ + 80101a4: 07860022 07c003e0 860022e0 c003c00f "........"...... + 80101b4: 0022f003 03001f86 22f800c0 003e8600 .."........"..>. + 80101c4: 7c00c003 7c860022 00c00300 8600223e ...|"..|....>".. + 80101d4: c00300f8 00221f00 0300f086 210f00c0 ......"........! + 80101e4: f0018800 00c00300 0020800f 00e00388 .......... ..... + 80101f4: 0700c003 88002080 0300c003 c00300c0 ..... .......... + 8010204: 07880020 c00300c0 20c00300 80078800 .......... .... + 8010214: 00c00300 0020e001 00800788 0100c003 ...... ......... + 8010224: 880020e0 0300000f f00000c0 0f880020 . .......... ... + 8010234: c0030000 20f00000 000f8800 00c00300 ....... ........ + 8010244: 0020f000 00000e88 0000c003 88002070 .. .........p .. + 8010254: 0300001e 780000c0 1e880020 c0030000 .......x ....... + 8010264: 20780000 001e8800 00c00300 00207800 ..x .........x . + 8010274: 00001e88 0000c003 88002078 0300001e ........x ...... + 8010284: 780000c0 1e880020 c0030000 20780000 ...x .........x + 8010294: 001e8800 00c00300 00207800 00001e88 .........x ..... + 80102a4: 0000c003 88002078 0300001e 780000c0 ....x .........x + 80102b4: 1e810020 78810006 1e810020 78810006 ......x ......x + 80102c4: 1e810020 70810006 0f810020 f0810006 ......p ....... + 80102d4: 0f810020 f0810006 0f810020 f0810006 ....... ....... + 80102e4: 07820020 82000480 0020e001 04800782 ......... ..... + 80102f4: e0018200 07820020 820004c0 0020c003 .... ......... . + 8010304: 04c00382 c0038200 03820020 820004e0 ........ ....... + 8010314: 00208007 04f00182 800f8200 f0810021 .. .........!... + 8010324: 0f810004 f8810022 1f810004 7c810022 ...."......."..| + 8010334: 3e810004 3e810022 7c810004 1f810022 ...>"..>...|"... + 8010344: f8810004 0f860022 030000c0 860022f0 ...."........".. + 8010354: 0000e007 0022e007 00f80386 23c01f00 ......"........# + 8010364: 00ff8400 0024ff00 0ff07f84 840024fe ......$......$.. + 8010374: f8ffff1f 07840024 25e0ffff ffff8200 ....$......%.... + 8010384: 01820026 212a7f80 03388100 00088400 &.....*!..8..... + 8010394: 00044040 001b8081 00034481 40000884 @@.......D.....@ + 80103a4: 81000441 81001b80 84000382 41400008 A.............@A + 80103b4: 80810004 8081001b 08840003 04404000 .............@@. + 80103c4: 1b808100 0e808d00 00e88003 e0024740 ............@G.. + 80103d4: 1b800e38 11408d00 00184104 10034144 8.....@..A..DA.. + 80103e4: 1b801144 20388d00 00082288 08024144 D.....8 ."..DA.. + 80103f4: 1b802082 20048d00 00082288 08024144 . ..... ."..DA.. + 8010404: 1b802082 3f028d00 0008e28f 0802414a . .....?....JA.. + 8010414: 1b8020fe 20028d00 00080208 0802812a . ..... ....*... + 8010424: 1b802080 20828d00 00080208 1003812a . ..... ....*... + 8010434: 1b802080 10448d00 00182184 e0020111 . ....D..!...... + 8010444: 1b801142 0f388d00 00e8c003 00020111 B.....8......... + 8010454: 23800e3c 27028100 27028100 27028100 <..#...'...'...' + 8010464: 7f028100 00001147 65737361 64007472 ....G...assert.d + 8010474: 676e776f 65646172 67697300 69616620 owngrade.sig fai + 8010484: 6f6e006c 72696620 7261776d 61460065 l.no firmware.Fa + 8010494: 726f7463 6f622079 5700746f 3a4e5241 ctory boot.WARN: + 80104a4: 64655220 67696c20 57007468 3a4e5241 Red light.WARN: + 80104b4: 736e5520 656e6769 69662064 61776d72 Unsigned firmwa + 80104c4: 47006572 20646f6f 6d726966 65726177 re.Good firmware + 80104d4: 726f6300 74707572 72696620 7261776d .corrupt firmwar + 80104e4: e. + +080104e6 : + 80104e6: 2641cbb4 f36ce1f7 71b4f28f 0123fb1d ..A&..l....q..#. + 80104f6: 66d6760d 6ca38aa7 f6f9539b 0518587b .v.f...l.S..{X.. + 8010506: e93b0b58 b89fc431 113c0444 470f0896 X.;.1...D.<....G + 8010516: 37ed2581 4a9e237a 3818b7af da0438ba .%.7z#.J...8.8.. + 8010526: 1dc8a2d6 df5e811c 6d290ca6 8d8f57b8 ......^...)m.W.. + 8010536: 9269295e c178d1ce 31d7207b b596a17b ^)i...x.{ .1{... + 8010546: 0c1bef3d c31a79aa c8c45845 ffeb2d8a =....y..EX...-.. + 8010556: 01829bfe bc5e5f87 4fe5a596 9ffe68c7 ....._^....O.h.. + 8010566: 0166ef42 95cfc456 38f0b5f4 c5261164 B.f.V......8d.&. + 8010576: 66c13999 14120632 689c254c bad38c35 .9.f2...L%.h5... + 8010586: 8cde7824 6cdfab52 7809bfb8 3a63bb03 $x..R..l...x..c: + 8010596: 0ed90111 8f737aa4 7f3b18bf c87b0af0 .....zs...;...{. + 80105a6: 56546067 c5ec0c82 0882bc1d ef39c116 g`TV..........9. + 80105b6: 32babff5 e35fce7c d7621e74 4cc5fce9 ...2|._.t.b....L + 80105c6: 8d11e88a 13c2adc3 2a4f2992 a4f8d2ea .........)O*.... + 80105d6: fe7cd5c4 3b450512 07598954 88d7d6da ..|...E;T.Y..... + 80105e6: 37cfb143 1f897cd2 f3acfe5b 95fc33ba C..7.|..[....3.. + 80105f6: dde7d981 14ef9525 bb97efdd a7d8f333 ....%.......3... + 8010606: 977a2b34 73aab3ba 32419de7 17a1fcd8 4+z....s..A2.... + 8010616: fe0bb566 89214063 8e7b92c9 590bdf72 f...c@!...{.r..Y + 8010626: 76dc5cd0 30dd3016 56f180c2 61a85c26 .\.v.0.0...V&\.a + 8010636: 69694fd7 3d57b8e5 582ae235 c69acedd .Oii..W=5.*X.... + 8010646: 2b1ca945 8efc010c 13513fbf 137c7e80 E..+.....?Q..~|. + 8010656: 5e4b4fd5 d59b4c9b e0d81d9e 2246c0ad .OK^.L........F" + 8010666: 20314553 666e6f63 66206769 006c6961 SE1 config fail. + 8010676: 72726f63 20747075 72696170 63657320 corrupt pair sec + 8010686: 75636d00 6c756620 7562006c 66206e72 .mcu full.burn f + 8010696: 3a6c6961 76210020 64696c61 6162003f ail: .!valid?.ba + 80106a6: 61762064 66003f6c 20747361 63697262 d val?.fast bric + 80106b6: 2e2e2e6b 64200020 00656e6f 79706f43 k... . done.Copy + 80106c6: 68676972 30322074 202d3831 43207962 right 2018- by C + 80106d6: 6b6e696f 20657469 2e636e49 206f6e00 oinkite Inc..no + 80106e6: 00726573 66206b77 0016006c 01410800 ser.wk fl.....A. + ... + 8010702: 000000ee 006100e1 218f0000 438f808f ......a....!...C + 8010712: 430080af 20834300 43c343c3 43c343c3 ...C.C. .C.C.C.C + 8010722: 43c343c3 0000438f ffffffff 00000000 .C.C.C.......... + 8010732: ffffffff 00000000 00000000 000000f0 ................ + ... + 801074a: 00001502 003c0000 01bc005c 01bc01fc ......<.\....... + 801075a: 01dc01dc 03dc03d1 03dc03dc 03dc03dc ................ + 801076a: 01dc03dc 0001003c 00120000 00000000 ....<........... + 801077a: 00010000 00080000 02000000 00020000 ................ + 801078a: 00000000 00010000 00070000 .............. + +08010798 : + 8010798: 0d0c0b09 .... + +0801079c : + 801079c: 2e312e31 69742030 323d656d 30353230 1.1.0 time=20250 + 80107ac: 2e353134 36333930 67203133 6d3d7469 415.093631 git=m + 80107bc: 65747361 38324072 61363239 0d006463 aster@28926acd.. + 80107cc: .. + +080107ce : + 80107ce: 33323130 37363534 62613938 66656463 0123456789abcdef + 80107de: 41525350 6166204d 50006c69 203a5253 PSRAM fail.PSR: + 80107ee: 6164616e 52535000 6321203a 6b636568 nada.PSR: !check + 80107fe: 52535000 6576203a 6f697372 fc00006e .PSR: version... + 801080e: 00020000 00000000 00030000 000a0000 ................ + 801081e: 00080000 00100000 6f6c0000 7220676e ..........long r + 801082e: 20646165 6c696166 55464400 72617020 ead fail.DFU par + 801083e: 66206573 006c6961 646f6f67 72696620 se fail.good fir + 801084e: 7261776d 72770065 20676e6f 6c726f77 mware.wrong worl + 801085e: 64730064 64726163 6165735f 3a686372 d.sdcard_search: + 801086e: 64730020 64726163 6f72705f 203a6562 .sdcard_probe: + 801087e: 696e6900 61662074 73006c69 64656570 .init fail.speed + 801088e: 64697700 73620065 3f657a69 006b6f00 .wide.bsize?.ok. + 801089e: 6c696166 61657220 66440064 00655375 fail read.DfuSe. + 80108ae: 6e756f66 20402064 63655200 7265766f found @ .Recover + 80108be: 6f6d2079 002e6564 1f000000 00020000 y mode.......... + 80108ce: 00010000 00030000 000c0000 00040000 ................ + 80108de: 00020000 00010000 00030000 000c0000 ................ + ... + +080108f0 : + 80108f0: 01002008 fffffc2f fffffffe ffffffff . ../........... + 8010900: ffffffff ffffffff ffffffff ffffffff ................ + 8010910: ffffffff d0364141 bfd25e8c af48a03b ....AA6..^..;.H. + 8010920: baaedce6 fffffffe ffffffff ffffffff ................ + 8010930: ffffffff 16f81798 59f2815b 2dce28d9 ........[..Y.(.- + 8010940: 029bfcdb ce870b07 55a06295 f9dcbbac .........b.U.... + 8010950: 79be667e fb10d4b8 9c47d08f a6855419 ~f.y......G..T.. + 8010960: fd17b448 0e1108a8 5da4fbfc 26a3c465 H..........]e..& + 8010970: 483ada77 00000007 00000000 00000000 w.:H............ + ... + 8010994: 0800692d 080061b1 08006387 08005f9d -i...a...c..._.. + +080109a4 : + 80109a4: 01002008 ffffffff ffffffff ffffffff . .............. + ... + 80109c0: 00000001 ffffffff fc632551 f3b9cac2 ........Q%c..... + 80109d0: a7179e84 bce6faad ffffffff ffffffff ................ + 80109e0: 00000000 ffffffff d898c296 f4a13945 ............E9.. + 80109f0: 2deb33a0 77037d81 63a440f2 f8bce6e5 .3.-.}.w.@.c.... + 8010a00: e12c4247 6b17d1f2 37bf51f5 cbb64068 GB,....k.Q.7h@.. + 8010a10: 6b315ece 2bce3357 7c0f9e16 8ee7eb4a .^1kW3.+...|J... + 8010a20: fe1a7f9b 4fe342e2 27d2604b 3bce3c3e .....B.OK`.'><.; + 8010a30: cc53b0f6 651d06b0 769886bc b3ebbd55 ..S....e...vU... + 8010a40: aa3a93e7 5ac635d8 08006a75 080061b1 ..:..5.Zuj...a.. + 8010a50: 08006a1b 08006019 .j...`.. + +08010a58 : + ... + 8010a60: 04030201 09080706 ........ + +08010a68 : + 8010a68: 00000000 04030201 ........ + +08010a70 : + 8010a70: 000186a0 00030d40 00061a80 000c3500 ....@........5.. + 8010a80: 000f4240 001e8480 003d0900 007a1200 @B........=...z. + 8010a90: 00f42400 016e3600 01e84800 02dc6c00 .$...6n..H...l.. + 8010aa0: 20727463 3f746573 00702100 00006000 ctr set?.!p..`.. + 8010ab0: 00000012 00000000 00000003 00000004 ................ + +08010ac0 : + 8010ac0: 00008000 .... + +Disassembly of section .relocate: + +2009e000 : +{ +2009e000: b530 push {r4, r5, lr} + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e002: 4920 ldr r1, [pc, #128] ; (2009e084 ) +2009e004: 690c ldr r4, [r1, #16] +2009e006: 03e5 lsls r5, r4, #15 +2009e008: d4fc bmi.n 2009e004 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e00a: 690d ldr r5, [r1, #16] + if(error) { +2009e00c: 4c1e ldr r4, [pc, #120] ; (2009e088 ) +2009e00e: 4225 tst r5, r4 +2009e010: d104 bne.n 2009e01c + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e012: 690c ldr r4, [r1, #16] +2009e014: 07e4 lsls r4, r4, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e016: bf44 itt mi +2009e018: 2401 movmi r4, #1 +2009e01a: 610c strmi r4, [r1, #16] + FLASH->SR = FLASH->SR & FLASH_FLAG_SR_ERRORS; +2009e01c: 4919 ldr r1, [pc, #100] ; (2009e084 ) +2009e01e: 4d1a ldr r5, [pc, #104] ; (2009e088 ) +2009e020: 690c ldr r4, [r1, #16] +2009e022: 402c ands r4, r5 +2009e024: 610c str r4, [r1, #16] + __HAL_FLASH_DATA_CACHE_DISABLE(); +2009e026: 680c ldr r4, [r1, #0] +2009e028: f424 6480 bic.w r4, r4, #1024 ; 0x400 +2009e02c: 600c str r4, [r1, #0] + CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB)); // added +2009e02e: 694c ldr r4, [r1, #20] +2009e030: f424 64ff bic.w r4, r4, #2040 ; 0x7f8 +2009e034: f024 0407 bic.w r4, r4, #7 +2009e038: 614c str r4, [r1, #20] + SET_BIT(FLASH->CR, FLASH_CR_PG); +2009e03a: 694c ldr r4, [r1, #20] +2009e03c: f044 0401 orr.w r4, r4, #1 +2009e040: 614c str r4, [r1, #20] + *(__IO uint32_t *)(address) = (uint32_t)val; +2009e042: 6002 str r2, [r0, #0] + __ASM volatile ("isb 0xF":::"memory"); +2009e044: f3bf 8f6f isb sy + *(__IO uint32_t *)(address+4) = (uint32_t)(val >> 32); +2009e048: 6043 str r3, [r0, #4] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e04a: 690b ldr r3, [r1, #16] +2009e04c: 03da lsls r2, r3, #15 +2009e04e: d4fc bmi.n 2009e04a + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e050: 6908 ldr r0, [r1, #16] + if(error) { +2009e052: 4028 ands r0, r5 +2009e054: d104 bne.n 2009e060 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e056: 690b ldr r3, [r1, #16] +2009e058: 07db lsls r3, r3, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e05a: bf44 itt mi +2009e05c: 2301 movmi r3, #1 +2009e05e: 610b strmi r3, [r1, #16] + CLEAR_BIT(FLASH->CR, FLASH_CR_PG); +2009e060: 4b08 ldr r3, [pc, #32] ; (2009e084 ) +2009e062: 695a ldr r2, [r3, #20] +2009e064: f022 0201 bic.w r2, r2, #1 +2009e068: 615a str r2, [r3, #20] + __HAL_FLASH_DATA_CACHE_RESET(); +2009e06a: 681a ldr r2, [r3, #0] +2009e06c: f442 5280 orr.w r2, r2, #4096 ; 0x1000 +2009e070: 601a str r2, [r3, #0] +2009e072: 681a ldr r2, [r3, #0] +2009e074: f422 5280 bic.w r2, r2, #4096 ; 0x1000 +2009e078: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); +2009e07a: 681a ldr r2, [r3, #0] +2009e07c: f442 6280 orr.w r2, r2, #1024 ; 0x400 +2009e080: 601a str r2, [r3, #0] +} +2009e082: bd30 pop {r4, r5, pc} +2009e084: 40022000 .word 0x40022000 +2009e088: 0002c3fa .word 0x0002c3fa + +2009e08c : + if(page_num < ((BL_FLASH_SIZE + BL_NVROM_SIZE) / FLASH_ERASE_SIZE)) { +2009e08c: 4b2d ldr r3, [pc, #180] ; (2009e144 ) +2009e08e: 4003 ands r3, r0 +{ +2009e090: b510 push {r4, lr} + if(page_num < ((BL_FLASH_SIZE + BL_NVROM_SIZE) / FLASH_ERASE_SIZE)) { +2009e092: 2b00 cmp r3, #0 +2009e094: d054 beq.n 2009e140 + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e096: 4b2c ldr r3, [pc, #176] ; (2009e148 ) + page_num &= 0xff; +2009e098: f3c0 3207 ubfx r2, r0, #12, #8 + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e09c: 6919 ldr r1, [r3, #16] +2009e09e: 03c9 lsls r1, r1, #15 +2009e0a0: d4fc bmi.n 2009e09c + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e0a2: 691c ldr r4, [r3, #16] + if(error) { +2009e0a4: 4929 ldr r1, [pc, #164] ; (2009e14c ) +2009e0a6: 420c tst r4, r1 +2009e0a8: d104 bne.n 2009e0b4 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e0aa: 6919 ldr r1, [r3, #16] +2009e0ac: 07cc lsls r4, r1, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e0ae: bf44 itt mi +2009e0b0: 2101 movmi r1, #1 +2009e0b2: 6119 strmi r1, [r3, #16] + FLASH->SR = FLASH->SR & 0xffff; +2009e0b4: 4b24 ldr r3, [pc, #144] ; (2009e148 ) +2009e0b6: 6919 ldr r1, [r3, #16] +2009e0b8: b289 uxth r1, r1 +2009e0ba: 6119 str r1, [r3, #16] + __HAL_FLASH_DATA_CACHE_DISABLE(); +2009e0bc: 6819 ldr r1, [r3, #0] +2009e0be: f421 6180 bic.w r1, r1, #1024 ; 0x400 +2009e0c2: 6019 str r1, [r3, #0] + SET_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0c4: 6959 ldr r1, [r3, #20] + if(bank2) { +2009e0c6: f010 6ffe tst.w r0, #133169152 ; 0x7f00000 + SET_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0ca: bf14 ite ne +2009e0cc: f441 6100 orrne.w r1, r1, #2048 ; 0x800 + CLEAR_BIT(FLASH->CR, FLASH_CR_BKER); +2009e0d0: f421 6100 biceq.w r1, r1, #2048 ; 0x800 +2009e0d4: 6159 str r1, [r3, #20] + MODIFY_REG(FLASH->CR, FLASH_CR_PNB, (page_num << POSITION_VAL(FLASH_CR_PNB))); +2009e0d6: 6959 ldr r1, [r3, #20] + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +2009e0d8: f44f 63ff mov.w r3, #2040 ; 0x7f8 +2009e0dc: f421 61ff bic.w r1, r1, #2040 ; 0x7f8 +2009e0e0: fa93 f3a3 rbit r3, r3 + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +2009e0e4: fab3 f383 clz r3, r3 +2009e0e8: 409a lsls r2, r3 +2009e0ea: 4b17 ldr r3, [pc, #92] ; (2009e148 ) +2009e0ec: 430a orrs r2, r1 +2009e0ee: 615a str r2, [r3, #20] + SET_BIT(FLASH->CR, FLASH_CR_PER); +2009e0f0: 695a ldr r2, [r3, #20] +2009e0f2: f042 0202 orr.w r2, r2, #2 +2009e0f6: 615a str r2, [r3, #20] + SET_BIT(FLASH->CR, FLASH_CR_STRT); +2009e0f8: 695a ldr r2, [r3, #20] +2009e0fa: f442 3280 orr.w r2, r2, #65536 ; 0x10000 +2009e0fe: 615a str r2, [r3, #20] + while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { +2009e100: 691a ldr r2, [r3, #16] +2009e102: 03d1 lsls r1, r2, #15 +2009e104: d4fc bmi.n 2009e100 + uint32_t error = (FLASH->SR & FLASH_FLAG_SR_ERRORS); +2009e106: 6918 ldr r0, [r3, #16] +2009e108: 4a10 ldr r2, [pc, #64] ; (2009e14c ) + if(error) { +2009e10a: 4010 ands r0, r2 +2009e10c: d104 bne.n 2009e118 + if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { +2009e10e: 691a ldr r2, [r3, #16] +2009e110: 07d2 lsls r2, r2, #31 + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); +2009e112: bf44 itt mi +2009e114: 2201 movmi r2, #1 +2009e116: 611a strmi r2, [r3, #16] + CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB)); +2009e118: 4b0b ldr r3, [pc, #44] ; (2009e148 ) +2009e11a: 695a ldr r2, [r3, #20] +2009e11c: f422 62ff bic.w r2, r2, #2040 ; 0x7f8 +2009e120: f022 0202 bic.w r2, r2, #2 +2009e124: 615a str r2, [r3, #20] + __HAL_FLASH_DATA_CACHE_RESET(); +2009e126: 681a ldr r2, [r3, #0] +2009e128: f442 5280 orr.w r2, r2, #4096 ; 0x1000 +2009e12c: 601a str r2, [r3, #0] +2009e12e: 681a ldr r2, [r3, #0] +2009e130: f422 5280 bic.w r2, r2, #4096 ; 0x1000 +2009e134: 601a str r2, [r3, #0] + __HAL_FLASH_DATA_CACHE_ENABLE(); +2009e136: 681a ldr r2, [r3, #0] +2009e138: f442 6280 orr.w r2, r2, #1024 ; 0x400 +2009e13c: 601a str r2, [r3, #0] +} +2009e13e: bd10 pop {r4, pc} + return 1; +2009e140: 2001 movs r0, #1 +2009e142: e7fc b.n 2009e13e +2009e144: 07fe0000 .word 0x07fe0000 +2009e148: 40022000 .word 0x40022000 +2009e14c: 0002c3fa .word 0x0002c3fa