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

« Back to documentation index

Show/hide line numbers target_reset_Lseries.c Source File

target_reset_Lseries.c

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