+ LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
+ nvm_size, pf_size, ee_size, fcfg2_pflsh);
+
+ num_blocks = kinetis_flash_params[granularity].num_blocks;
+ num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
+ first_nvm_bank = num_pflash_blocks;
+ num_nvm_blocks = num_blocks - num_pflash_blocks;
+
+ LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
+ num_blocks, num_pflash_blocks, num_nvm_blocks);
+
+ /*
+ * If the flash class is already assigned, verify the
+ * parameters.
+ */
+ if (kinfo->flash_class != FC_AUTO) {
+ if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
+ LOG_WARNING("Flash ordinal/bank number mismatch");
+ reassign = 1;
+ } else if (kinfo->granularity != granularity) {
+ LOG_WARNING("Flash granularity mismatch");
+ reassign = 1;
+ } else {
+ switch (kinfo->flash_class) {
+ case FC_PFLASH:
+ if (kinfo->bank_ordinal >= first_nvm_bank) {
+ LOG_WARNING("Class mismatch, bank %d is not PFlash",
+ bank->bank_number);
+ reassign = 1;
+ } else if (bank->size != (pf_size / num_pflash_blocks)) {
+ LOG_WARNING("PFlash size mismatch");
+ reassign = 1;
+ } else if (bank->base !=
+ (0x00000000 + bank->size * kinfo->bank_ordinal)) {
+ LOG_WARNING("PFlash address range mismatch");
+ reassign = 1;
+ } else if (kinfo->sector_size !=
+ kinetis_flash_params[granularity].pflash_sector_size_bytes) {
+ LOG_WARNING("PFlash sector size mismatch");
+ reassign = 1;
+ } else {
+ LOG_DEBUG("PFlash bank %d already configured okay",
+ kinfo->bank_ordinal);
+ }
+ break;
+ case FC_FLEX_NVM:
+ if ((kinfo->bank_ordinal >= num_blocks) ||
+ (kinfo->bank_ordinal < first_nvm_bank)) {
+ LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
+ bank->bank_number);
+ reassign = 1;
+ } else if (bank->size != (nvm_size / num_nvm_blocks)) {
+ LOG_WARNING("FlexNVM size mismatch");
+ reassign = 1;
+ } else if (bank->base !=
+ (0x10000000 + bank->size * kinfo->bank_ordinal)) {
+ LOG_WARNING("FlexNVM address range mismatch");
+ reassign = 1;
+ } else if (kinfo->sector_size !=
+ kinetis_flash_params[granularity].nvm_sector_size_bytes) {
+ LOG_WARNING("FlexNVM sector size mismatch");
+ reassign = 1;
+ } else {
+ LOG_DEBUG("FlexNVM bank %d already configured okay",
+ kinfo->bank_ordinal);
+ }
+ break;
+ case FC_FLEX_RAM:
+ if (kinfo->bank_ordinal != num_blocks) {
+ LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
+ bank->bank_number);
+ reassign = 1;
+ } else if (bank->size != ee_size) {
+ LOG_WARNING("FlexRAM size mismatch");
+ reassign = 1;
+ } else if (bank->base != 0x14000000) {
+ LOG_WARNING("FlexRAM address mismatch");
+ reassign = 1;
+ } else if (kinfo->sector_size !=
+ kinetis_flash_params[granularity].nvm_sector_size_bytes) {
+ LOG_WARNING("FlexRAM sector size mismatch");
+ reassign = 1;
+ } else {
+ LOG_DEBUG("FlexRAM bank %d already configured okay",
+ kinfo->bank_ordinal);
+ }
+ break;
+
+ default:
+ LOG_WARNING("Unknown or inconsistent flash class");
+ reassign = 1;
+ break;
+ }
+ }
+ } else {
+ LOG_INFO("Probing flash info for bank %d", bank->bank_number);
+ reassign = 1;
+ }
+
+ if (!reassign)
+ return ERROR_OK;
+
+ kinfo->granularity = granularity;
+
+ if ((unsigned)bank->bank_number < num_pflash_blocks) {
+ /* pflash, banks start at address zero */
+ kinfo->flash_class = FC_PFLASH;
+ bank->size = (pf_size / num_pflash_blocks);
+ bank->base = 0x00000000 + bank->size * bank->bank_number;
+ kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
+ kinfo->protection_size = pf_size / 32;
+ } else if ((unsigned)bank->bank_number < num_blocks) {
+ /* nvm, banks start at address 0x10000000 */
+ kinfo->flash_class = FC_FLEX_NVM;
+ bank->size = (nvm_size / num_nvm_blocks);
+ bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
+ kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
+ kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
+ } else if ((unsigned)bank->bank_number == num_blocks) {
+ LOG_ERROR("FlexRAM support not yet implemented");
+ return ERROR_FLASH_OPER_UNSUPPORTED;
+ } else {
+ LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
+ bank->bank_number, num_blocks);
+ return ERROR_FLASH_BANK_INVALID;