/*************************************************************************** * Copyright (C) 2010 by Oleksandr Tymoshenko * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "target.h" #include "jtag/jtag.h" #include "avr32_jtag.h" #include "avr32_mem.h" int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, uint32_t addr, int count, uint32_t *buffer) { int i, retval; uint32_t data; for (i = 0; i < count; i++) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i*4, &data); if (retval != ERROR_OK) return retval; /* XXX: Assume AVR32 is BE */ buffer[i] = be_to_h_u32((uint8_t *)&data); } return ERROR_OK; } int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, uint32_t addr, int count, uint16_t *buffer) { int i, retval; uint32_t data; i = 0; /* any unaligned half-words? */ if (addr & 3) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, &data); if (retval != ERROR_OK) return retval; /* XXX: Assume AVR32 is BE */ data = be_to_h_u32((uint8_t *)&data); buffer[i] = (data >> 16) & 0xffff; i++; } /* read all complete words */ for (; i < (count & ~1); i += 2) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, &data); if (retval != ERROR_OK) return retval; /* XXX: Assume AVR32 is BE */ data = be_to_h_u32((uint8_t *)&data); buffer[i] = data & 0xffff; buffer[i+1] = (data >> 16) & 0xffff; } /* last halfword */ if (i < count) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, &data); if (retval != ERROR_OK) return retval; /* XXX: Assume AVR32 is BE */ data = be_to_h_u32((uint8_t *)&data); buffer[i] = data & 0xffff; } return ERROR_OK; } int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, uint32_t addr, int count, uint8_t *buffer) { int i, j, retval; uint8_t data[4]; i = 0; /* Do we have non-aligned bytes? */ if (addr & 3) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i, (uint32_t *)(void *)data); if (retval != ERROR_OK) return retval; for (j = addr & 3; (j < 4) && (i < count); j++, i++) buffer[i] = data[3-j]; } /* read all complete words */ for (; i < (count & ~3); i += 4) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i, (uint32_t *)(void *)data); if (retval != ERROR_OK) return retval; for (j = 0; j < 4; j++) buffer[i+j] = data[3-j]; } /* remaining bytes */ if (i < count) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i, (uint32_t *)(void *)data); if (retval != ERROR_OK) return retval; for (j = 0; i + j < count; j++) buffer[i+j] = data[3-j]; } return ERROR_OK; } int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, uint32_t addr, int count, const uint32_t *buffer) { int i, retval; uint32_t data; for (i = 0; i < count; i++) { /* XXX: Assume AVR32 is BE */ h_u32_to_be((uint8_t *)&data, buffer[i]); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr + i*4, data); if (retval != ERROR_OK) return retval; } return ERROR_OK; } int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, uint32_t addr, int count, const uint16_t *buffer) { int i, retval; uint32_t data; uint32_t data_out; i = 0; /* * Do we have any non-aligned half-words? */ if (addr & 3) { /* * mwa_read will read whole world, no nead to fiddle * with address. It will be truncated in set_addr */ retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr, &data); if (retval != ERROR_OK) return retval; data = be_to_h_u32((uint8_t *)&data); data = (buffer[i] << 16) | (data & 0xffff); h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr, data_out); if (retval != ERROR_OK) return retval; i++; } /* write all complete words */ for (; i < (count & ~1); i += 2) { /* XXX: Assume AVR32 is BE */ data = (buffer[i+1] << 16) | buffer[i]; h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, data_out); if (retval != ERROR_OK) return retval; } /* last halfword */ if (i < count) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, &data); if (retval != ERROR_OK) return retval; data = be_to_h_u32((uint8_t *)&data); data &= ~0xffff; data |= buffer[i]; h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr + i*2, data_out); if (retval != ERROR_OK) return retval; } return ERROR_OK; } int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, uint32_t addr, int count, const uint8_t *buffer) { int i, j, retval; uint32_t data; uint32_t data_out; i = 0; /* * Do we have any non-aligned bytes? */ if (addr & 3) { /* * mwa_read will read whole world, no nead to fiddle * with address. It will be truncated in set_addr */ retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr, &data); if (retval != ERROR_OK) return retval; data = be_to_h_u32((uint8_t *)&data); for (j = addr & 3; (j < 4) && (i < count); j++, i++) { data &= ~(0xff << j*8); data |= (buffer[i] << j*8); } h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr, data_out); if (retval != ERROR_OK) return retval; } /* write all complete words */ for (; i < (count & ~3); i += 4) { data = 0; for (j = 0; j < 4; j++) data |= (buffer[j+i] << j*8); h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr + i, data_out); if (retval != ERROR_OK) return retval; } /* * Write trailing bytes */ if (i < count) { retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, addr + i, &data); if (retval != ERROR_OK) return retval; data = be_to_h_u32((uint8_t *)&data); for (j = 0; i < count; j++, i++) { data &= ~(0xff << j*8); data |= (buffer[j+i] << j*8); } h_u32_to_be((uint8_t *)&data_out, data); retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, addr+i, data_out); if (retval != ERROR_OK) return retval; } return ERROR_OK; }