int s3c2440_read_block_data(struct nand_device *nand, uint8_t *data, int data_size) { struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; struct target *target = nand->target; uint32_t nfdata = s3c24xx_info->data; uint32_t tmp; LOG_INFO("%s: reading data: %p, %p, %d", __func__, nand, data, data_size); if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } while (data_size >= 4) { target_read_u32(target, nfdata, &tmp); data[0] = tmp; data[1] = tmp >> 8; data[2] = tmp >> 16; data[3] = tmp >> 24; data_size -= 4; data += 4; } while (data_size > 0) { target_read_u8(target, nfdata, data); data_size -= 1; data += 1; } return ERROR_OK; }
/* read a byte (8bit) from the netx to the pc */ int fn_read_data08(void *pvHandle, unsigned long ulNetxAddress, unsigned char *pucData) { command_context_t *cmd_ctx; target_t *target; int iResult; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; /* get the target from the command context */ target = get_current_target(cmd_ctx); /* read the data from the netX */ iResult = target_read_u8(target, ulNetxAddress, pucData); if( iResult==ERROR_OK ) { iResult = 0; } else { iResult = 1; } wxMilliSleep(1); return iResult; }
/** * Read data directly from the NAND device attached to an AT91SAM9 NAND * controller. * * @param nand NAND device to read from. * @param data Pointer to where the data should be put. * @return Success or failure of reading the data. */ static int at91sam9_read_data(struct nand_device *nand, void *data) { struct at91sam9_nand *info = nand->controller_priv; struct target *target = nand->target; if (!at91sam9_halted(nand->target, "read data")) return ERROR_NAND_OPERATION_FAILED; return target_read_u8(target, info->data, data); }
static int nuc910_nand_read(struct nand_device *nand, void *data) { struct target *target = nand->target; int result; if ((result = validate_target_state(nand)) != ERROR_OK) return result; target_read_u8(target, NUC910_SMDATA, data); return ERROR_OK; }
static int s3c2410_read_data(struct nand_device *nand, void *data) { struct target *target = nand->target; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } target_read_u8(target, S3C2410_NFDATA, data); return ERROR_OK; }
int s3c2410_read_data(struct nand_device_s *device, void *data) { s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; target_t *target = s3c24xx_info->target; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } target_read_u8(target, S3C2410_NFDATA, data); return ERROR_OK; }
int s3c24xx_read_data(struct nand_device *nand, void *data) { struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv; struct target *target = nand->target; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } target_read_u8(target, s3c24xx_info->data, data); return ERROR_OK; }
/* wait up to timeout_ms for controller to not be busy, * then check whether the command passed or failed. * * this function sleeps 1ms between checks (after the first one), * so in some cases may slow things down without a usleep after the first read */ static int aduc702x_check_flash_completion(struct target* target, unsigned int timeout_ms) { uint8_t v = 4; long long endtime = timeval_ms() + timeout_ms; while (1) { target_read_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEESTA, &v); if ((v & 4) == 0) break; alive_sleep(1); if (timeval_ms() >= endtime) break; } if (v & 2) return ERROR_FAIL; // if a command is ignored, both the success and fail bits may be 0 else if ((v & 3) == 0) return ERROR_FAIL; else return ERROR_OK; }
/* All-JTAG, single-access method. Very slow. Used only if there is no * working area available. */ static int aduc702x_write_single(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { uint32_t x; uint8_t b; struct target *target = bank->target; aduc702x_set_write_enable(target, 1); for (x = 0; x < count; x += 2) { /* FEEADR = address */ target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, offset + x); /* set up data */ if ((x + 1) == count) { /* last byte */ target_read_u8(target, offset + x + 1, &b); } else b = buffer[x + 1]; target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, buffer[x] | (b << 8)); /* do single-write command */ target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x02); if (aduc702x_check_flash_completion(target, 1) != ERROR_OK) { LOG_ERROR("single write failed for address 0x%08lX", (unsigned long)(offset + x)); aduc702x_set_write_enable(target, 0); return ERROR_FLASH_OPERATION_FAILED; } } LOG_DEBUG("wrote %d bytes at address 0x%08lX", (int)count, (unsigned long)(offset + x)); aduc702x_set_write_enable(target, 0); return ERROR_OK; }
static int s3c2410_nand_ready(struct nand_device *nand, int timeout) { struct target *target = nand->target; uint8_t status; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } do { target_read_u8(target, S3C2410_NFSTAT, &status); if (status & S3C2410_NFSTAT_BUSY) return 1; alive_sleep(1); } while (timeout-- > 0); return 0; }
int s3c2410_nand_ready(struct nand_device_s *device, int timeout) { s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv; target_t *target = s3c24xx_info->target; u8 status; if (target->state != TARGET_HALTED) { LOG_ERROR("target must be halted to use S3C24XX NAND flash controller"); return ERROR_NAND_OPERATION_FAILED; } do { target_read_u8(target, S3C2410_NFSTAT, &status); if (status & S3C2410_NFSTAT_BUSY) return 1; alive_sleep(1); } while (timeout-- > 0); return 0; }
static int str9x_protect(struct flash_bank *bank, int set, int first, int last) { struct target *target = bank->target; int i; uint32_t adr; uint8_t status; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } for (i = first; i <= last; i++) { /* Level One Protection */ adr = bank->base + bank->sectors[i].offset; target_write_u16(target, adr, 0x60); if (set) target_write_u16(target, adr, 0x01); else target_write_u16(target, adr, 0xD0); /* query status */ target_read_u8(target, adr, &status); /* clear status, also clear read array */ target_write_u16(target, adr, 0x50); /* read array command */ target_write_u16(target, adr, 0xFF); } return ERROR_OK; }
static int str9x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; uint32_t words_remaining = (count / 2); uint32_t bytes_remaining = (count & 0x00000001); uint32_t address = bank->base + offset; uint32_t bytes_written = 0; uint8_t status; int retval; uint32_t check_address = offset; uint32_t bank_adr; int i; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } if (offset & 0x1) { LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset); return ERROR_FLASH_DST_BREAKS_ALIGNMENT; } for (i = 0; i < bank->num_sectors; i++) { uint32_t sec_start = bank->sectors[i].offset; uint32_t sec_end = sec_start + bank->sectors[i].size; /* check if destination falls within the current sector */ if ((check_address >= sec_start) && (check_address < sec_end)) { /* check if destination ends in the current sector */ if (offset + count < sec_end) check_address = offset + count; else check_address = sec_end; } } if (check_address != offset + count) return ERROR_FLASH_DST_OUT_OF_BANK; /* multiple half words (2-byte) to be programmed? */ if (words_remaining > 0) { /* try using a block write */ retval = str9x_write_block(bank, buffer, offset, words_remaining); if (retval != ERROR_OK) { if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { /* if block write failed (no sufficient working area), * we use normal (slow) single dword accesses */ LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } else if (retval == ERROR_FLASH_OPERATION_FAILED) { LOG_ERROR("flash writing failed"); return ERROR_FLASH_OPERATION_FAILED; } } else { buffer += words_remaining * 2; address += words_remaining * 2; words_remaining = 0; } } while (words_remaining > 0) { bank_adr = address & ~0x03; /* write data command */ target_write_u16(target, bank_adr, 0x40); target_write_memory(target, address, 2, 1, buffer + bytes_written); /* get status command */ target_write_u16(target, bank_adr, 0x70); int timeout; for (timeout = 0; timeout < 1000; timeout++) { target_read_u8(target, bank_adr, &status); if (status & 0x80) break; alive_sleep(1); } if (timeout == 1000) { LOG_ERROR("write timed out"); return ERROR_FAIL; } /* clear status reg and read array */ target_write_u16(target, bank_adr, 0x50); target_write_u16(target, bank_adr, 0xFF); if (status & 0x10) return ERROR_FLASH_OPERATION_FAILED; else if (status & 0x02) return ERROR_FLASH_OPERATION_FAILED; bytes_written += 2; words_remaining--; address += 2; } if (bytes_remaining) { uint8_t last_halfword[2] = {0xff, 0xff}; /* copy the last remaining bytes into the write buffer */ memcpy(last_halfword, buffer+bytes_written, bytes_remaining); bank_adr = address & ~0x03; /* write data command */ target_write_u16(target, bank_adr, 0x40); target_write_memory(target, address, 2, 1, last_halfword); /* query status command */ target_write_u16(target, bank_adr, 0x70); int timeout; for (timeout = 0; timeout < 1000; timeout++) { target_read_u8(target, bank_adr, &status); if (status & 0x80) break; alive_sleep(1); } if (timeout == 1000) { LOG_ERROR("write timed out"); return ERROR_FAIL; } /* clear status reg and read array */ target_write_u16(target, bank_adr, 0x50); target_write_u16(target, bank_adr, 0xFF); if (status & 0x10) return ERROR_FLASH_OPERATION_FAILED; else if (status & 0x02) return ERROR_FLASH_OPERATION_FAILED; } return ERROR_OK; }
static int str9x_erase(struct flash_bank *bank, int first, int last) { struct target *target = bank->target; int i; uint32_t adr; uint8_t status; uint8_t erase_cmd; int total_timeout; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } /* Check if we can erase whole bank */ if ((first == 0) && (last == (bank->num_sectors - 1))) { /* Optimize to run erase bank command instead of sector */ erase_cmd = 0x80; /* Add timeout duration since erase bank takes more time */ total_timeout = 1000 * bank->num_sectors; } else { /* Erase sector command */ erase_cmd = 0x20; total_timeout = 1000; } /* this is so the compiler can *know* */ assert(total_timeout > 0); for (i = first; i <= last; i++) { int retval; adr = bank->base + bank->sectors[i].offset; /* erase sectors or block */ retval = target_write_u16(target, adr, erase_cmd); if (retval != ERROR_OK) return retval; retval = target_write_u16(target, adr, 0xD0); if (retval != ERROR_OK) return retval; /* get status */ retval = target_write_u16(target, adr, 0x70); if (retval != ERROR_OK) return retval; int timeout; for (timeout = 0; timeout < total_timeout; timeout++) { retval = target_read_u8(target, adr, &status); if (retval != ERROR_OK) return retval; if (status & 0x80) break; alive_sleep(1); } if (timeout == total_timeout) { LOG_ERROR("erase timed out"); return ERROR_FAIL; } /* clear status, also clear read array */ retval = target_write_u16(target, adr, 0x50); if (retval != ERROR_OK) return retval; /* read array command */ retval = target_write_u16(target, adr, 0xFF); if (retval != ERROR_OK) return retval; if (status & 0x22) { LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } /* If we ran erase bank command, we are finished */ if (erase_cmd == 0x80) break; } for (i = first; i <= last; i++) bank->sectors[i].is_erased = 1; return ERROR_OK; }
static int uCOS_III_update_threads(struct rtos *rtos) { struct uCOS_III_params *params = rtos->rtos_specific_params; int retval; /* free previous thread details */ rtos_free_threadlist(rtos); /* verify RTOS is running */ uint8_t rtos_running; retval = target_read_u8(rtos->target, rtos->symbols[uCOS_III_VAL_OSRunning].address, &rtos_running); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read RTOS running"); return retval; } if (rtos_running != 1 && rtos_running != 0) { LOG_ERROR("uCOS-III: invalid RTOS running value"); return ERROR_FAIL; } if (!rtos_running) { rtos->thread_details = calloc(1, sizeof(struct thread_detail)); if (rtos->thread_details == NULL) { LOG_ERROR("uCOS-III: out of memory"); return ERROR_FAIL; } rtos->thread_count = 1; rtos->thread_details->threadid = 0; rtos->thread_details->exists = true; rtos->current_thread = 0; return ERROR_OK; } /* update thread offsets */ retval = uCOS_III_update_thread_offsets(rtos); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to update thread offsets"); return retval; } /* read current thread address */ symbol_address_t current_thread_address = 0; retval = target_read_memory(rtos->target, rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address, params->pointer_width, 1, (void *)¤t_thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read current thread address"); return retval; } /* read number of tasks */ retval = target_read_u16(rtos->target, rtos->symbols[uCOS_III_VAL_OSTaskQty].address, (void *)&rtos->thread_count); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread count"); return retval; } rtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail)); if (rtos->thread_details == NULL) { LOG_ERROR("uCOS-III: out of memory"); return ERROR_FAIL; } /* * uC/OS-III adds tasks in LIFO order; advance to the end of the * list and work backwards to preserve the intended order. */ symbol_address_t thread_address = 0; retval = uCOS_III_find_last_thread_address(rtos, &thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to find last thread address"); return retval; } for (int i = 0; i < rtos->thread_count; i++) { struct thread_detail *thread_detail = &rtos->thread_details[i]; char thread_str_buffer[UCOS_III_MAX_STRLEN + 1]; /* find or create new threadid */ retval = uCOS_III_find_or_create_thread(rtos, thread_address, &thread_detail->threadid); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to find or create thread"); return retval; } if (thread_address == current_thread_address) rtos->current_thread = thread_detail->threadid; thread_detail->exists = true; /* read thread name */ symbol_address_t thread_name_address = 0; retval = target_read_memory(rtos->target, thread_address + params->thread_name_offset, params->pointer_width, 1, (void *)&thread_name_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to name address"); return retval; } retval = target_read_buffer(rtos->target, thread_name_address, sizeof(thread_str_buffer), (void *)thread_str_buffer); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread name"); return retval; } thread_str_buffer[sizeof(thread_str_buffer) - 1] = '\0'; thread_detail->thread_name_str = strdup(thread_str_buffer); /* read thread extra info */ uint8_t thread_state; uint8_t thread_priority; retval = target_read_u8(rtos->target, thread_address + params->thread_state_offset, &thread_state); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread state"); return retval; } retval = target_read_u8(rtos->target, thread_address + params->thread_priority_offset, &thread_priority); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread priority"); return retval; } const char *thread_state_str; if (thread_state < ARRAY_SIZE(uCOS_III_thread_state_list)) thread_state_str = uCOS_III_thread_state_list[thread_state]; else thread_state_str = "Unknown"; snprintf(thread_str_buffer, sizeof(thread_str_buffer), "State: %s, Priority: %d", thread_state_str, thread_priority); thread_detail->extra_info_str = strdup(thread_str_buffer); /* read previous thread address */ retval = target_read_memory(rtos->target, thread_address + params->thread_prev_offset, params->pointer_width, 1, (void *)&thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read previous thread address"); return retval; } } return ERROR_OK; }
static int str9x_erase(struct flash_bank *bank, int first, int last) { struct target *target = bank->target; int i; uint32_t adr; uint8_t status; uint8_t erase_cmd; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } /*A slower but stable way of erasing*/ /* Erase sector command */ erase_cmd = 0x20; for (i = first; i <= last; i++) { int retval; adr = bank->base + bank->sectors[i].offset; /* erase sectors */ if ((retval = target_write_u16(target, adr, erase_cmd)) != ERROR_OK) { return retval; } if ((retval = target_write_u16(target, adr, 0xD0)) != ERROR_OK) { return retval; } /* get status */ if ((retval = target_write_u16(target, adr, 0x70)) != ERROR_OK) { return retval; } int timeout; for (timeout = 0; timeout < 1000; timeout++) { if ((retval = target_read_u8(target, adr, &status)) != ERROR_OK) { return retval; } if (status & 0x80) break; alive_sleep(1); } if (timeout == 1000) { LOG_ERROR("erase timed out"); return ERROR_FAIL; } /* clear status, also clear read array */ if ((retval = target_write_u16(target, adr, 0x50)) != ERROR_OK) { return retval; } /* read array command */ if ((retval = target_write_u16(target, adr, 0xFF)) != ERROR_OK) { return retval; } if (status & 0x22) { LOG_ERROR("error erasing flash bank, status: 0x%x", status); return ERROR_FLASH_OPERATION_FAILED; } } for (i = first; i <= last; i++) bank->sectors[i].is_erased = 1; return ERROR_OK; }