static bool kl_gen_command(target *t, uint8_t cmd, uint32_t addr, const uint8_t data[8]) { uint8_t fstat; /* clear errors unconditionally, so we can start a new operation */ target_mem_write8(t,FTFA_FSTAT,(FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL)); /* Wait for CCIF to be high */ do { fstat = target_mem_read8(t, FTFA_FSTAT); } while (!(fstat & FTFA_FSTAT_CCIF)); /* Write command to FCCOB */ addr &= 0xffffff; addr |= (uint32_t)cmd << 24; target_mem_write32(t, FTFA_FCCOB_0, addr); if (data) { target_mem_write32(t, FTFA_FCCOB_1, *(uint32_t*)&data[0]); target_mem_write32(t, FTFA_FCCOB_2, *(uint32_t*)&data[4]); } /* Enable execution by clearing CCIF */ target_mem_write8(t, FTFA_FSTAT, FTFA_FSTAT_CCIF); /* Wait for execution to complete */ do { fstat = target_mem_read8(t, FTFA_FSTAT); /* Check ACCERR and FPVIOL are zero in FSTAT */ if (fstat & (FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL)) return false; } while (!(fstat & FTFA_FSTAT_CCIF)); return true; }
uint32_t generic_crc32(target *t, uint32_t base, int len) { uint32_t data; uint32_t crc; size_t i; CRC_CR |= CRC_CR_RESET; while (len > 3) { data = target_mem_read32(t, base); CRC_DR = __builtin_bswap32(data); base += 4; len -= 4; } crc = CRC_DR; while (len--) { data = target_mem_read8(t, base++); crc ^= data << 24; for (i = 0; i < 8; i++) { if (crc & 0x80000000) crc = (crc << 1) ^ 0x4C11DB7; else crc <<= 1; } } return crc; }
static int kl_gen_flash_done(struct target_flash *f) { struct kinetis_flash *kf = (struct kinetis_flash *)f; if (unsafe_enabled) return 0; if (target_mem_read8(f->t, FLASH_SECURITY_BYTE_ADDRESS) == FLASH_SECURITY_BYTE_UNSECURED) return 0; /* Load the security byte based on the alignment (determine 8 byte phrases * vs 4 byte phrases). */ if (kf->write_len == 8) { uint32_t vals[2]; vals[0] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS-4); vals[1] = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS); vals[1] = (vals[1] & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED; kl_gen_command(f->t, FTFE_CMD_PROGRAM_PHRASE, FLASH_SECURITY_BYTE_ADDRESS - 4, (uint8_t*)vals); } else { uint32_t val = target_mem_read32(f->t, FLASH_SECURITY_BYTE_ADDRESS); val = (val & 0xffffff00) | FLASH_SECURITY_BYTE_UNSECURED; kl_gen_command(f->t, FTFA_CMD_PROGRAM_LONGWORD, FLASH_SECURITY_BYTE_ADDRESS, (uint8_t*)&val); } return 0; }
uint32_t generic_crc32(target *t, uint32_t base, int len) { uint32_t crc = -1; uint8_t byte; while (len--) { byte = target_mem_read8(t, base); crc = crc32_calc(crc, byte); base++; } return crc; }
/** * Reads the EFM32 Part Family */ uint8_t efm32_read_part_family(target *t) { return target_mem_read8(t, EFM32_DI_PART_FAMILY); }