static int amd_flash_write_cfibuffer(struct flash_info *info, unsigned long dest, const u8 *cp, int len) { flash_sect_t sector; int cnt; void *src = (void *)cp; void *dst = (void *)dest; cfiword_t cword; sector = find_sector (info, dest); flash_unlock_seq(info); flash_make_cmd (info, AMD_CMD_WRITE_TO_BUFFER, &cword); flash_write_word(info, cword, (void *)dest); if (bankwidth_is_1(info)) { cnt = len; flash_write_cmd(info, sector, 0, (u32)cnt - 1); while (cnt-- > 0) { flash_write8(flash_read8(src), dst); src += 1, dst += 1; } } else if (bankwidth_is_2(info)) { cnt = len >> 1; flash_write_cmd(info, sector, 0, (u32)cnt - 1); while (cnt-- > 0) { flash_write16(flash_read16(src), dst); src += 2, dst += 2; } } else if (bankwidth_is_4(info)) {
static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx) { Flash *s = M25P80(ss); uint32_t r = 0; switch (s->state) { case STATE_PAGE_PROGRAM: DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n", s->cur_addr, (uint8_t)tx); flash_write8(s, s->cur_addr, (uint8_t)tx); s->cur_addr = (s->cur_addr + 1) & (s->size - 1); break; case STATE_READ: r = s->storage[s->cur_addr]; DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr, (uint8_t)r); s->cur_addr = (s->cur_addr + 1) & (s->size - 1); break; case STATE_COLLECTING_DATA: case STATE_COLLECTING_VAR_LEN_DATA: s->data[s->len] = (uint8_t)tx; s->len++; if (s->len == s->needed_bytes) { complete_collecting_data(s); } break; case STATE_READING_DATA: r = s->data[s->pos]; s->pos++; if (s->pos == s->len) { s->pos = 0; s->state = STATE_IDLE; } break; default: case STATE_IDLE: decode_new_cmd(s, (uint8_t)tx); break; } return r; }
static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx) { Flash *s = M25P80(ss); uint32_t r = 0; switch (s->state) { case STATE_PAGE_PROGRAM: DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n", s->cur_addr, (uint8_t)tx); flash_write8(s, s->cur_addr, (uint8_t)tx); s->cur_addr = (s->cur_addr + 1) & (s->size - 1); break; case STATE_READ: r = s->storage[s->cur_addr]; DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr, (uint8_t)r); s->cur_addr = (s->cur_addr + 1) & (s->size - 1); break; case STATE_COLLECTING_DATA: case STATE_COLLECTING_VAR_LEN_DATA: if (s->len >= M25P80_INTERNAL_DATA_BUFFER_SZ) { qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Write overrun internal data buffer. " "SPI controller (QEMU emulator or guest driver) " "is misbehaving\n"); s->len = s->pos = 0; s->state = STATE_IDLE; break; } s->data[s->len] = (uint8_t)tx; s->len++; if (s->len == s->needed_bytes) { complete_collecting_data(s); } break; case STATE_READING_DATA: if (s->pos >= M25P80_INTERNAL_DATA_BUFFER_SZ) { qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Read overrun internal data buffer. " "SPI controller (QEMU emulator or guest driver) " "is misbehaving\n"); s->len = s->pos = 0; s->state = STATE_IDLE; break; } r = s->data[s->pos]; s->pos++; if (s->pos == s->len) { s->pos = 0; if (!s->data_read_loop) { s->state = STATE_IDLE; } } break; default: case STATE_IDLE: decode_new_cmd(s, (uint8_t)tx); break; } return r; }