/* Parts of target interface that deal with accessing memory and memory-like
   objects.

   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.

   This file is part of GDB.

   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 3 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 <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "vec.h"
#include "target.h"
#include "memory-map.h"

#include "gdb_assert.h"

#include <stdio.h>
#include <sys/time.h>

static int
compare_block_starting_address (const void *a, const void *b)
{
  const struct memory_write_request *a_req = a;
  const struct memory_write_request *b_req = b;

  if (a_req->begin < b_req->begin)
    return -1;
  else if (a_req->begin == b_req->begin)
    return 0;
  else
    return 1;
}

/* Adds to RESULT all memory write requests from BLOCK that are
   in [BEGIN, END) range.

   If any memory request is only partially in the specified range,
   that part of the memory request will be added.  */

static void
claim_memory (VEC(memory_write_request_s) *blocks,
	      VEC(memory_write_request_s) **result,
	      ULONGEST begin,
	      ULONGEST end)
{
  int i;
  ULONGEST claimed_begin;
  ULONGEST claimed_end;
  struct memory_write_request *r;

  for (i = 0; VEC_iterate (memory_write_request_s, blocks, i, r); ++i)
    {
      /* If the request doesn't overlap [BEGIN, END), skip it.  We
	 must handle END == 0 meaning the top of memory; we don't yet
	 check for R->end == 0, which would also mean the top of
	 memory, but there's an assertion in
	 target_write_memory_blocks which checks for that.  */

      if (begin >= r->end)
	continue;
      if (end != 0 && end <= r->begin)
	continue;

      claimed_begin = max (begin, r->begin);
      if (end == 0)
	claimed_end = r->end;
      else
	claimed_end = min (end, r->end);

      if (claimed_begin == r->begin && claimed_end == r->end)
	VEC_safe_push (memory_write_request_s, *result, r);
      else
	{
	  struct memory_write_request *n =
	    VEC_safe_push (memory_write_request_s, *result, NULL);
	  *n = *r;
	  n->begin = claimed_begin;
	  n->end = claimed_end;
	  n->data += claimed_begin - r->begin;
	}
    }
}

/* Given a vector of struct memory_write_request objects in BLOCKS,
   add memory requests for flash memory into FLASH_BLOCKS, and for
   regular memory to REGULAR_BLOCKS.  */

static void
split_regular_and_flash_blocks (VEC(memory_write_request_s) *blocks,
				VEC(memory_write_request_s) **regular_blocks,
				VEC(memory_write_request_s) **flash_blocks)
{
  struct mem_region *region;
  CORE_ADDR cur_address;

  /* This implementation runs in O(length(regions)*length(blocks)) time.
     However, in most cases the number of blocks will be small, so this does
     not matter.

     Note also that it's extremely unlikely that a memory write request
     will span more than one memory region, however for safety we handle
     such situations.  */

  cur_address = 0;
  while (1)
    {
      VEC(memory_write_request_s) **r;
      region = lookup_mem_region (cur_address);

      r = region->attrib.mode == MEM_FLASH ? flash_blocks : regular_blocks;
      cur_address = region->hi;
      claim_memory (blocks, r, region->lo, region->hi);

      if (cur_address == 0)
	break;
    }
}

/* Given an ADDRESS, if BEGIN is non-NULL this function sets *BEGIN
   to the start of the flash block containing the address.  Similarly,
   if END is non-NULL *END will be set to the address one past the end
   of the block containing the address.  */

static void
block_boundaries (CORE_ADDR address, CORE_ADDR *begin, CORE_ADDR *end)
{
  struct mem_region *region;
  unsigned blocksize;

  region = lookup_mem_region (address);
  gdb_assert (region->attrib.mode == MEM_FLASH);
  blocksize = region->attrib.blocksize;
  if (begin)
    *begin = address / blocksize * blocksize;
  if (end)
    *end = (address + blocksize - 1) / blocksize * blocksize;
}

/* Given the list of memory requests to be WRITTEN, this function
   returns write requests covering each group of flash blocks which must
   be erased.  */

static VEC(memory_write_request_s) *
blocks_to_erase (VEC(memory_write_request_s) *written)
{
  unsigned i;
  struct memory_write_request *ptr;

  VEC(memory_write_request_s) *result = NULL;

  for (i = 0; VEC_iterate (memory_write_request_s, written, i, ptr); ++i)
    {
      CORE_ADDR begin, end;

      block_boundaries (ptr->begin, &begin, 0);
      block_boundaries (ptr->end - 1, 0, &end);

      if (!VEC_empty (memory_write_request_s, result)
	  && VEC_last (memory_write_request_s, result)->end >= begin)
	{
	  VEC_last (memory_write_request_s, result)->end = end;
	}
      else
	{
	  struct memory_write_request *n =
	    VEC_safe_push (memory_write_request_s, result, NULL);
	  memset (n, 0, sizeof (struct memory_write_request));
	  n->begin = begin;
	  n->end = end;
	}
    }

  return result;
}

/* Given ERASED_BLOCKS, a list of blocks that will be erased with
   flash erase commands, and WRITTEN_BLOCKS, the list of memory
   addresses that will be written, compute the set of memory addresses
   that will be erased but not rewritten (e.g. padding within a block
   which is only partially filled by "load").  */

static VEC(memory_write_request_s) *
compute_garbled_blocks (VEC(memory_write_request_s) *erased_blocks,
			VEC(memory_write_request_s) *written_blocks)
{
  VEC(memory_write_request_s) *result = NULL;

  unsigned i, j;
  unsigned je = VEC_length (memory_write_request_s, written_blocks);
  struct memory_write_request *erased_p;

  /* Look at each erased memory_write_request in turn, and
     see what part of it is subsequently written to.

     This implementation is O(length(erased) * length(written)).  If
     the lists are sorted at this point it could be rewritten more
     efficiently, but the complexity is not generally worthwhile.  */

  for (i = 0;
       VEC_iterate (memory_write_request_s, erased_blocks, i, erased_p);
       ++i)
    {
      /* Make a deep copy -- it will be modified inside the loop, but
	 we don't want to modify original vector.  */
      struct memory_write_request erased = *erased_p;

      for (j = 0; j != je;)
	{
	  struct memory_write_request *written
	    = VEC_index (memory_write_request_s,
			 written_blocks, j);

	  /* Now try various cases.  */

	  /* If WRITTEN is fully to the left of ERASED, check the next
	     written memory_write_request.  */
	  if (written->end <= erased.begin)
	    {
	      ++j;
	      continue;
	    }

	  /* If WRITTEN is fully to the right of ERASED, then ERASED
	     is not written at all.  WRITTEN might affect other
	     blocks.  */
	  if (written->begin >= erased.end)
	    {
	      VEC_safe_push (memory_write_request_s, result, &erased);
	      goto next_erased;
	    }

	  /* If all of ERASED is completely written, we can move on to
	     the next erased region.  */
	  if (written->begin <= erased.begin
	      && written->end >= erased.end)
	    {
	      goto next_erased;
	    }

	  /* If there is an unwritten part at the beginning of ERASED,
	     then we should record that part and try this inner loop
	     again for the remainder.  */
	  if (written->begin > erased.begin)
	    {
	      struct memory_write_request *n =
		VEC_safe_push (memory_write_request_s, result, NULL);
	      memset (n, 0, sizeof (struct memory_write_request));
	      n->begin = erased.begin;
	      n->end = written->begin;
	      erased.begin = written->begin;
	      continue;
	    }

	  /* If there is an unwritten part at the end of ERASED, we
	     forget about the part that was written to and wait to see
	     if the next write request writes more of ERASED.  We can't
	     push it yet.  */
	  if (written->end < erased.end)
	    {
	      erased.begin = written->end;
	      ++j;
	      continue;
	    }
	}

      /* If we ran out of write requests without doing anything about
	 ERASED, then that means it's really erased.  */
      VEC_safe_push (memory_write_request_s, result, &erased);

    next_erased:
      ;
    }

  return result;
}

static void
cleanup_request_data (void *p)
{
  VEC(memory_write_request_s) **v = p;
  struct memory_write_request *r;
  int i;

  for (i = 0; VEC_iterate (memory_write_request_s, *v, i, r); ++i)
    xfree (r->data);
}

static void
cleanup_write_requests_vector (void *p)
{
  VEC(memory_write_request_s) **v = p;
  VEC_free (memory_write_request_s, *v);
}

int
target_write_memory_blocks (VEC(memory_write_request_s) *requests,
			    enum flash_preserve_mode preserve_flash_p,
			    void (*progress_cb) (ULONGEST, void *))
{
  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
  VEC(memory_write_request_s) *blocks = VEC_copy (memory_write_request_s,
						  requests);
  unsigned i;
  int err = 0;
  struct memory_write_request *r;
  VEC(memory_write_request_s) *regular = NULL;
  VEC(memory_write_request_s) *flash = NULL;
  VEC(memory_write_request_s) *erased, *garbled;

  /* END == 0 would represent wraparound: a write to the very last
     byte of the address space.  This file was not written with that
     possibility in mind.  This is fixable, but a lot of work for a
     rare problem; so for now, fail noisily here instead of obscurely
     later.  */
  for (i = 0; VEC_iterate (memory_write_request_s, requests, i, r); ++i)
    gdb_assert (r->end != 0);

  make_cleanup (cleanup_write_requests_vector, &blocks);

  /* Sort the blocks by their start address.  */
  qsort (VEC_address (memory_write_request_s, blocks),
	 VEC_length (memory_write_request_s, blocks),
	 sizeof (struct memory_write_request), compare_block_starting_address);

  /* Split blocks into list of regular memory blocks,
     and list of flash memory blocks. */
  make_cleanup (cleanup_write_requests_vector, &regular);
  make_cleanup (cleanup_write_requests_vector, &flash);
  split_regular_and_flash_blocks (blocks, &regular, &flash);

  /* If a variable is added to forbid flash write, even during "load",
     it should be checked here.  Similarly, if this function is used
     for other situations besides "load" in which writing to flash
     is undesirable, that should be checked here.  */

  /* Find flash blocks to erase.  */
  erased = blocks_to_erase (flash);
  make_cleanup (cleanup_write_requests_vector, &erased);

  /* Find what flash regions will be erased, and not overwritten; then
     either preserve or discard the old contents.  */
  garbled = compute_garbled_blocks (erased, flash);
  make_cleanup (cleanup_request_data, &garbled);
  make_cleanup (cleanup_write_requests_vector, &garbled);

  if (!VEC_empty (memory_write_request_s, garbled))
    {
      if (preserve_flash_p == flash_preserve)
	{
	  struct memory_write_request *r;

	  /* Read in regions that must be preserved and add them to
	     the list of blocks we read.  */
	  for (i = 0; VEC_iterate (memory_write_request_s, garbled, i, r); ++i)
	    {
	      gdb_assert (r->data == NULL);
	      r->data = xmalloc (r->end - r->begin);
	      err = target_read_memory (r->begin, r->data, r->end - r->begin);
	      if (err != 0)
		goto out;

	      VEC_safe_push (memory_write_request_s, flash, r);
	    }

	  qsort (VEC_address (memory_write_request_s, flash),
		 VEC_length (memory_write_request_s, flash),
		 sizeof (struct memory_write_request), compare_block_starting_address);
	}
    }

  /* We could coalesce adjacent memory blocks here, to reduce the
     number of write requests for small sections.  However, we would
     have to reallocate and copy the data pointers, which could be
     large; large sections are more common in loadable objects than
     large numbers of small sections (although the reverse can be true
     in object files).  So, we issue at least one write request per
     passed struct memory_write_request.  The remote stub will still
     have the opportunity to batch flash requests.  */

  /* Write regular blocks.  */
  for (i = 0; VEC_iterate (memory_write_request_s, regular, i, r); ++i)
    {
      LONGEST len;

      len = target_write_with_progress (current_target.beneath,
					TARGET_OBJECT_MEMORY, NULL,
					r->data, r->begin, r->end - r->begin,
					progress_cb, r->baton);
      if (len < (LONGEST) (r->end - r->begin))
	{
	  /* Call error?  */
	  err = -1;
	  goto out;
	}
    }

  if (!VEC_empty (memory_write_request_s, erased))
    {
      /* Erase all pages.  */
      for (i = 0; VEC_iterate (memory_write_request_s, erased, i, r); ++i)
	target_flash_erase (r->begin, r->end - r->begin);

      /* Write flash data.  */
      for (i = 0; VEC_iterate (memory_write_request_s, flash, i, r); ++i)
	{
	  LONGEST len;

	  len = target_write_with_progress (&current_target,
					    TARGET_OBJECT_FLASH, NULL,
					    r->data, r->begin, r->end - r->begin,
					    progress_cb, r->baton);
	  if (len < (LONGEST) (r->end - r->begin))
	    error (_("Error writing data to flash"));
	}

      target_flash_done ();
    }

 out:
  do_cleanups (back_to);

  return err;
}
