Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers target_reset_rapid_iot.c Source File

target_reset_rapid_iot.c

00001 /**
00002  * @file    target_reset.c
00003  *
00004  * DAPLink Interface Firmware
00005  * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
00006  * SPDX-License-Identifier: Apache-2.0
00007  *
00008  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00009  * not use this file except in compliance with the License.
00010  * You may obtain a copy of the License at
00011  *
00012  * http://www.apache.org/licenses/LICENSE-2.0
00013  *
00014  * Unless required by applicable law or agreed to in writing, software
00015  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00016  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00017  * See the License for the specific language governing permissions and
00018  * limitations under the License.
00019  */
00020 
00021 #include "swd_host.h"
00022 #include "info.h"
00023 #include "target_config.h"
00024 #include "target_family.h"
00025 
00026 #define MDM_STATUS  0x01000000
00027 #define MDM_CTRL    0x01000004
00028 #define MDM_IDR     0x010000fc
00029 #define MDM_ID_K64  0x001c0000 // K64
00030 #define MDM_ID_KW4  0x001c0020 // KW4
00031 
00032 /* Kinetis series ID */
00033 #define K_SERIES     0
00034 #define KW_SERIES    5
00035 
00036 /* KW4 subfamily defines */
00037 #define KW40         0
00038 #define KW41         1
00039 
00040 static uint8_t target_unlock_sequence(void)
00041 {
00042     uint32_t val;
00043 
00044     // read the device ID
00045     if (!swd_read_ap(MDM_IDR, &val)) {
00046         return 0;
00047     }
00048     /*
00049     // verify the result
00050     if (val != mdm_id) {
00051         return 0;
00052     }
00053     */
00054 
00055     if (!swd_read_ap(MDM_STATUS, &val)) {
00056         return 0;
00057     }
00058 
00059     // flash in secured mode
00060     if (val & (1 << 2)) {
00061         // hold the device in reset
00062         swd_set_target_reset(1);
00063 
00064         // write the mass-erase enable bit
00065         if (!swd_write_ap(MDM_CTRL, 1)) {
00066             return 0;
00067         }
00068 
00069         while (1) {
00070             // wait until mass erase is started
00071             if (!swd_read_ap(MDM_STATUS, &val)) {
00072                 return 0;
00073             }
00074 
00075             if (val & 1) {
00076                 break;
00077             }
00078         }
00079 
00080         // mass erase in progress
00081         while (1) {
00082             // keep reading until procedure is complete
00083             if (!swd_read_ap(MDM_CTRL, &val)) {
00084                 return 0;
00085             }
00086 
00087             if (val == 0) {
00088                 break;
00089             }
00090         }
00091     }
00092 
00093     return 1;
00094 }
00095 
00096 // Check Flash Configuration Field bytes at address 0x400-0x40f to ensure that flash security
00097 // won't be enabled.
00098 //
00099 // FCF bytes:
00100 // [0x0-0x7]=backdoor key
00101 // [0x8-0xb]=flash protection bytes
00102 // [0xc]=FSEC:
00103 //      [7:6]=KEYEN (2'b10 is backdoor key enabled, all others backdoor key disabled)
00104 //      [5:4]=MEEN (2'b10 mass erase disabled, all other mass erase enabled)
00105 //      [3:2]=FSLACC (2'b00 and 2'b11 factory access enabled, 2'b01 and 2'b10 factory access disabled)
00106 //      [1:0]=SEC (2'b10 flash security disabled, all other flash security enabled)
00107 // [0xd]=FOPT
00108 // [0xe]=EEPROM protection bytes (FlexNVM devices only)
00109 // [0xf]=data flash protection bytes (FlexNVM devices only)
00110 //
00111 // This function checks that:
00112 // - FSEC does not disable mass erase or secure the device.
00113 //
00114 static uint8_t security_bits_set(uint32_t addr, uint8_t *data, uint32_t size)
00115 {
00116     const uint32_t fsec_addr = 0x40C;
00117 
00118     if ((addr <= fsec_addr) && (addr + size) > fsec_addr) {
00119         uint8_t fsec = data[fsec_addr - addr];
00120 
00121         // make sure we can unsecure the device or dont program at all
00122         if ((fsec & 0x30) == 0x20) {
00123             // Dont allow programming mass-erase disabled state
00124             return 1;
00125         }
00126 
00127         // Security is OK long as we can mass-erase (comment the following out to enable target security)
00128         if ((fsec & 0x03) != 0x02) {
00129             return 1;
00130         }
00131     }
00132 
00133     return 0;
00134 }
00135 
00136 
00137 const target_family_descriptor_t g_nxp_rapid_iot = {
00138     .family_id  = kNXP_RapidIot_FamilyID,
00139     .default_reset_type = kHardwareReset,
00140     .target_unlock_sequence = target_unlock_sequence,
00141     .security_bits_set = security_bits_set,
00142 };