/*  This file is part of the program psim.
    
    Copyright 1994, 1997, 2003, 2004 Andrew Cagney
    
    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/>.
    
    */


#ifndef _HW_INIT_C_
#define _HW_INIT_C_

#include "device_table.h"
#include "bfd.h"
#include "psim.h"


/* DMA a file into memory */
static int
dma_file(device *me,
	 const char *file_name,
	 unsigned_word addr)
{
  int count;
  int inc;
  FILE *image;
  char buf[1024];

  /* get it open */
  image = fopen(file_name, "r");
  if (image == NULL)
    return -1;

  /* read it in slowly */
  count = 0;
  while (1) {
    inc = fread(buf, 1, sizeof(buf), image);
    if (inc <= 0)
      break;
    if (device_dma_write_buffer(device_parent(me),
				buf,
				0 /*address-space*/,
				addr+count,
				inc /*nr-bytes*/,
				1 /*violate ro*/) != inc) {
      fclose(image);
      return -1;
    }
    count += inc;
  }

  /* close down again */
  fclose(image);

  return count;
}


/* DEVICE

   file - load a file into memory

   DESCRIPTION

   Loads the entire contents of <file-name> into memory at starting at
   <<real-address>>.  Assumes that memory exists for the load.

   PROPERTIES

   file-name = <string>

   Name of the file to be loaded into memory

   real-address = <integer>

   Real address at which the file is to be loaded */

static void
hw_file_init_data_callback(device *me)
{
  int count;
  const char *file_name = device_find_string_property(me, "file-name");
  unsigned_word addr = device_find_integer_property(me, "real-address");
  /* load the file */
  count = dma_file(me, file_name, addr);
  if (count < 0)
    device_error(me, "Problem loading file %s\n", file_name);
}


static device_callbacks const hw_file_callbacks = {
  { NULL, hw_file_init_data_callback, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
};


/* DEVICE


   data - initialize a memory location with specified data


   DESCRIPTION


   The pseudo device <<data>> provides a mechanism specifying the
   initialization of a small section of memory.

   Normally, the data would be written using a dma operation.
   However, for some addresses this will not result in the desired
   result.  For instance, to initialize an address in an eeprom,
   instead of a simple dma of the data, a sequence of writes (and then
   real delays) that program the eeprom would be required.

   For dma write initialization, the data device will write the
   specified <<data>> to <<real-address>> using a normal dma.

   For instance write initialization, the specified <<instance>> is
   opened.  Then a seek to the <<real-address>> is performed followed
   by a write of the data.


   Integer properties are stored using the target's endian mode.


   PROPERTIES


   data = <any-valid-property> (required)

   Data to be loaded into memory.  The property type determines how it
   is loaded.


   real-address = <integer> (required)

   Start address at which the data is to be stored.


   instance = <string> (optional)

   Instance specification of the device that is to be opened so that
   the specified data can be written to it.


   EXAMPLES


   The examples below illustrate the two alternative mechanisms that
   can be used to store the value 0x12345678 at address 0xfff00c00,
   which is normally part of the 512k system eeprom.


   If the eeprom is being modeled by ram (<<memory>> device) then the
   standard dma initialization can be used.  By convention: the data
   devices are uniquely identified by argumenting them with the
   destinations real address; and all data devices are put under the
   node <</openprom/init>>.

   | /openprom/memory@0xfff00000/reg 0xfff00000 0x80000
   | /openprom/init/data@0x1000/data 0x12345678
   | /openprom/init/data@0x1000/real-address 0x1000


   If instead a real eeprom was being used the instance write method
   would instead need to be used (storing just a single byte in an
   eeprom requires a complex sequence of accesses).  The
   <<real-address>> is specified as <<0x0c00>> which is the offset
   into the eeprom.  For brevity, most of the eeprom properties have
   been omited.

   | /iobus/eeprom@0xfff00000/reg 0xfff00000 0x80000
   | /openprom/init/data@0xfff00c00/real-address 0x0c00
   | /openprom/init/data@0xfff00c00/data 0x12345667
   | /openprom/init/data@0xfff00c00/instance /iobus/eeprom@0xfff00000/reg


   BUGS


   At present, only <<integer>> properties can be specified for an
   initial data value.

   */


static void
hw_data_init_data_callback(device *me)
{
  unsigned_word addr = device_find_integer_property(me, "real-address");
  const device_property *data = device_find_property(me, "data");
  const char *instance_spec = (device_find_property(me, "instance") != NULL
			       ? device_find_string_property(me, "instance")
			       : NULL);
  device_instance *instance = NULL;
  if (data == NULL)
    device_error(me, "missing property <data>\n");
  if (instance_spec != NULL)
    instance = tree_instance(me, instance_spec);
  switch (data->type) {
  case integer_property:
    {
      unsigned_cell buf = device_find_integer_property(me, "data");
      H2T(buf);
      if (instance == NULL) {
	if (device_dma_write_buffer(device_parent(me),
				    &buf,
				    0 /*address-space*/,
				    addr,
				    sizeof(buf), /*nr-bytes*/
				    1 /*violate ro*/) != sizeof(buf))
	  device_error(me, "Problem storing integer 0x%x at 0x%lx\n",
		       (unsigned)buf, (unsigned long)addr);
      }
      else {
	if (device_instance_seek(instance, 0, addr) < 0
	    || device_instance_write(instance, &buf, sizeof(buf)) != sizeof(buf))
	  device_error(me, "Problem storing integer 0x%x at 0x%lx of instance %s\n",
		       (unsigned)buf, (unsigned long)addr, instance_spec);
      }
    }
    break;
  default:
    device_error(me, "Write of this data is not yet implemented\n");
    break;
  }
  if (instance != NULL)
    device_instance_delete(instance);
}


static device_callbacks const hw_data_callbacks = {
  { NULL, hw_data_init_data_callback, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
};


/* DEVICE


   load-binary - load binary segments into memory


   DESCRIPTION

   Each loadable segment of the specified binary is loaded into memory
   at its required address.  It is assumed that the memory at those
   addresses already exists.

   This device is normally used to load an executable into memory as
   part of real mode simulation.


   PROPERTIES


   file-name = <string>

   Name of the binary to be loaded.


   claim = <anything> (optional)

   If this property is present, the real memory that is to be used by
   the image being loaded will be claimed from the memory node
   (specified by the ihandle <</chosen/memory>>).


   BUGS

   
   When loading the binary the bfd virtual-address is used.  It should
   be using the bfd load-address.

   */

/* DEVICE

   map-binary - map the binary into the users address space

   DESCRIPTION
   
   Similar to load-binary except that memory for each segment is
   created before the corresponding data for the segment is loaded.

   This device is normally used to load an executable into a user mode
   simulation.

   PROPERTIES

   file-name = <string>

   Name of the binary to be loaded.

   */

static void
update_for_binary_section(bfd *abfd,
			  asection *the_section,
			  void *obj)
{
  unsigned_word section_vma;
  unsigned_word section_size;
  access_type access;
  device *me = (device*)obj;

  /* skip the section if no memory to allocate */
  if (! (bfd_section_flags (the_section) & SEC_ALLOC))
    return;

  /* check/ignore any sections of size zero */
  section_size = bfd_section_size (the_section);
  if (section_size == 0)
    return;

  /* find where it is to go */
  section_vma = bfd_section_vma (the_section);

  DTRACE(binary,
	 ("name=%-7s, vma=0x%.8lx, size=%6ld, flags=%3lx(%s%s%s%s%s )\n",
	  bfd_section_name (the_section),
	  (long)section_vma,
	  (long)section_size,
	  (long)bfd_section_flags (the_section),
	  bfd_section_flags (the_section) & SEC_LOAD ? " LOAD" : "",
	  bfd_section_flags (the_section) & SEC_CODE ? " CODE" : "",
	  bfd_section_flags (the_section) & SEC_DATA ? " DATA" : "",
	  bfd_section_flags (the_section) & SEC_ALLOC ? " ALLOC" : "",
	  bfd_section_flags (the_section) & SEC_READONLY ? " READONLY" : ""
	  ));

  /* If there is an .interp section, it means it needs a shared library interpreter.  */
  if (strcmp(".interp", bfd_section_name (the_section)) == 0)
    error("Shared libraries are not yet supported.\n");

  /* determine the devices access */
  access = access_read;
  if (bfd_section_flags (the_section) & SEC_CODE)
    access |= access_exec;
  if (!(bfd_section_flags (the_section) & SEC_READONLY))
    access |= access_write;

  /* if claim specified, allocate region from the memory device */
  if (device_find_property(me, "claim") != NULL) {
    device_instance *memory = tree_find_ihandle_property(me, "/chosen/memory");
    unsigned_cell mem_in[3];
    unsigned_cell mem_out[1];
    mem_in[0] = 0; /*alignment - top-of-stack*/
    mem_in[1] = section_size;
    mem_in[2] = section_vma;
    if (device_instance_call_method(memory, "claim", 3, mem_in, 1, mem_out) < 0)
      device_error(me, "failed to claim memory for section at 0x%lx (0x%lx",
		   (unsigned long)section_vma,
		   (unsigned long)section_size);
    if (mem_out[0] != section_vma)
      device_error(me, "section address not as requested");
  }

  /* if a map, pass up a request to create the memory in core */
  if (strncmp(device_name(me), "map-binary", strlen("map-binary")) == 0)
    device_attach_address(device_parent(me),
			  attach_raw_memory,
			  0 /*address space*/,
			  section_vma,
			  section_size,
			  access,
			  me);

  /* if a load dma in the required data */
  if (bfd_section_flags (the_section) & SEC_LOAD) {
    void *section_init = zalloc(section_size);
    if (!bfd_get_section_contents(abfd,
				  the_section,
				  section_init, 0,
				  section_size)) {
      bfd_perror("binary");
      device_error(me, "load of data failed");
      return;
    }
    if (device_dma_write_buffer(device_parent(me),
				section_init,
				0 /*space*/,
				section_vma,
				section_size,
				1 /*violate_read_only*/)
	!= section_size)
      device_error(me, "broken transfer\n");
    free(section_init); /* only free if load */
  }
}

static void
hw_binary_init_data_callback(device *me)
{
  /* get the file name */
  const char *file_name = device_find_string_property(me, "file-name");
  bfd *image;

  /* open the file */
  image = bfd_openr(file_name, NULL);
  if (image == NULL) {
    bfd_perror("binary");
    device_error(me, "Failed to open file %s\n", file_name);
  }

  /* check it is valid */
  if (!bfd_check_format(image, bfd_object)) {
    bfd_close(image);
    device_error(me, "The file %s has an invalid binary format\n", file_name);
  }

  /* and the data sections */
  bfd_map_over_sections(image,
			update_for_binary_section,
			me);

  bfd_close(image);
}


static device_callbacks const hw_binary_callbacks = {
  { NULL, hw_binary_init_data_callback, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
};


/* DEVICE

   stack - create an initial stack frame in memory

   DESCRIPTION

   Creates a stack frame of the specified type in memory.

   Due to the startup sequence gdb uses when commencing a simulation,
   it is not possible for the data to be placed on the stack to be
   specified as part of the device tree.  Instead the arguments to be
   pushed onto the stack are specified using an IOCTL call.

   The IOCTL takes the additional arguments:

   | unsigned_word stack_end -- where the stack should come down from
   | char **argv -- ...
   | char **envp -- ...

   PROPERTIES

   stack-type = <string>

   The form of the stack frame that is to be created.

   */

static int
sizeof_argument_strings(char **arg)
{
  int sizeof_strings = 0;

  /* robust */
  if (arg == NULL)
    return 0;

  /* add up all the string sizes (padding as we go) */
  for (; *arg != NULL; arg++) {
    int len = strlen(*arg) + 1;
    sizeof_strings += ALIGN_8(len);
  }

  return sizeof_strings;
}

static int
number_of_arguments(char **arg)
{
  int nr;
  if (arg == NULL)
    return 0;
  for (nr = 0; *arg != NULL; arg++, nr++);
  return nr;
}

static int
sizeof_arguments(char **arg)
{
  return ALIGN_8((number_of_arguments(arg) + 1) * sizeof(unsigned_word));
}

static void
write_stack_arguments(device *me,
		      char **arg,
		      unsigned_word start_block,
		      unsigned_word end_block,
		      unsigned_word start_arg,
		      unsigned_word end_arg)
{
  DTRACE(stack,
	("write_stack_arguments(device=%s, arg=%p, start_block=0x%lx, end_block=0x%lx, start_arg=0x%lx, end_arg=0x%lx)\n",
	 device_name(me), arg, (long)start_block, (long)end_block, (long)start_arg, (long)end_arg));
  if (arg == NULL)
    device_error(me, "Attempt to write a null array onto the stack\n");
  /* only copy in arguments, memory is already zero */
  for (; *arg != NULL; arg++) {
    int len = strlen(*arg)+1;
    unsigned_word target_start_block;
    DTRACE(stack,
	  ("write_stack_arguments() write %s=%s at %s=0x%lx %s=0x%lx %s=0x%lx\n",
	   "**arg", *arg, "start_block", (long)start_block,
	   "len", (long)len, "start_arg", (long)start_arg));
    if (psim_write_memory(device_system(me), 0, *arg,
			  start_block, len,
			  0/*violate_readonly*/) != len)
      device_error(me, "Write of **arg (%s) at 0x%lx of stack failed\n",
		   *arg, (unsigned long)start_block);
    target_start_block = H2T_word(start_block);
    if (psim_write_memory(device_system(me), 0, &target_start_block,
			  start_arg, sizeof(target_start_block),
			  0) != sizeof(target_start_block))
      device_error(me, "Write of *arg onto stack failed\n");
    start_block += ALIGN_8(len);
    start_arg += sizeof(start_block);
  }
  start_arg += sizeof(start_block); /*the null at the end*/
  if (start_block != end_block
      || ALIGN_8(start_arg) != end_arg)
    device_error(me, "Probable corrpution of stack arguments\n");
  DTRACE(stack, ("write_stack_arguments() = void\n"));
}

static void
create_ppc_elf_stack_frame(device *me,
			   unsigned_word bottom_of_stack,
			   char **argv,
			   char **envp)
{
  /* fixme - this is over aligned */

  /* information block */
  const unsigned sizeof_envp_block = sizeof_argument_strings(envp);
  const unsigned_word start_envp_block = bottom_of_stack - sizeof_envp_block;
  const unsigned sizeof_argv_block = sizeof_argument_strings(argv);
  const unsigned_word start_argv_block = start_envp_block - sizeof_argv_block;

  /* auxiliary vector - contains only one entry */
  const unsigned sizeof_aux_entry = 2*sizeof(unsigned_word); /* magic */
  const unsigned_word start_aux = start_argv_block - ALIGN_8(sizeof_aux_entry);

  /* environment points (including null sentinal) */
  const unsigned sizeof_envp = sizeof_arguments(envp);
  const unsigned_word start_envp = start_aux - sizeof_envp;

  /* argument pointers (including null sentinal) */
  const int argc = number_of_arguments(argv);
  const unsigned sizeof_argv = sizeof_arguments(argv);
  const unsigned_word start_argv = start_envp - sizeof_argv;

  /* link register save address - aligned to a 16byte boundary */
  const unsigned_word top_of_stack = ((start_argv
				       - 2 * sizeof(unsigned_word))
				      & ~0xf);

  /* install arguments on stack */
  write_stack_arguments(me, envp,
			start_envp_block, bottom_of_stack,
			start_envp, start_aux);
  write_stack_arguments(me, argv,
			start_argv_block, start_envp_block,
			start_argv, start_envp);

  /* set up the registers */
  ASSERT (psim_write_register(device_system(me), -1,
			      &top_of_stack, "sp", cooked_transfer) > 0);
  ASSERT (psim_write_register(device_system(me), -1,
			      &argc, "r3", cooked_transfer) > 0);
  ASSERT (psim_write_register(device_system(me), -1,
			      &start_argv, "r4", cooked_transfer) > 0);
  ASSERT (psim_write_register(device_system(me), -1,
			      &start_envp, "r5", cooked_transfer) > 0);
  ASSERT (psim_write_register(device_system(me), -1,
			      &start_aux, "r6", cooked_transfer) > 0);
}

static void
create_ppc_aix_stack_frame(device *me,
			   unsigned_word bottom_of_stack,
			   char **argv,
			   char **envp)
{
  unsigned_word core_envp;
  unsigned_word core_argv;
  unsigned_word core_argc;
  unsigned_word core_aux;
  unsigned_word top_of_stack;

  /* cheat - create an elf stack frame */
  create_ppc_elf_stack_frame(me, bottom_of_stack, argv, envp);
  
  /* extract argument addresses from registers */
  ASSERT (psim_read_register(device_system(me), 0,
			     &top_of_stack, "r1", cooked_transfer) > 0);
  ASSERT (psim_read_register(device_system(me), 0,
			     &core_argc, "r3", cooked_transfer) > 0);
  ASSERT (psim_read_register(device_system(me), 0,
			     &core_argv, "r4", cooked_transfer) > 0);
  ASSERT (psim_read_register(device_system(me), 0,
			     &core_envp, "r5", cooked_transfer) > 0);
  ASSERT (psim_read_register(device_system(me), 0,
			     &core_aux, "r6", cooked_transfer) > 0);

  /* extract arguments from registers */
  device_error(me, "Unfinished procedure create_ppc_aix_stack_frame\n");
}


static void
create_ppc_chirp_bootargs(device *me,
			  char **argv)
{
  /* concat the arguments */
  char args[1024];
  char **chp = argv + 1;
  args[0] = '\0';
  while (*chp != NULL) {
    if (strlen(args) > 0)
      strcat(args, " ");
    if (strlen(args) + strlen(*chp) >= sizeof(args))
      device_error(me, "buffer overflow");
    strcat(args, *chp);
    chp++;
  }

  /* set the arguments property */
  tree_parse(me, "/chosen/bootargs \"%s", args);
}


static int
hw_stack_ioctl(device *me,
	       cpu *processor,
	       unsigned_word cia,
	       device_ioctl_request request,
	       va_list ap)
{
  switch (request) {
  case device_ioctl_create_stack:
    {
      unsigned_word stack_pointer = va_arg(ap, unsigned_word);
      char **argv = va_arg(ap, char **);
      char **envp = va_arg(ap, char **);
      const char *stack_type;
      DTRACE(stack,
	     ("stack_ioctl_callback(me=%p:%s processor=%p cia=0x%lx argv=%p envp=%p)\n",
	      me, device_name(me),
	      processor,
	      (long)cia,
	      argv,
	      envp));
      stack_type = device_find_string_property(me, "stack-type");
      if (strcmp(stack_type, "ppc-elf") == 0)
	create_ppc_elf_stack_frame(me, stack_pointer, argv, envp);
      else if (strcmp(stack_type, "ppc-xcoff") == 0)
	create_ppc_aix_stack_frame(me, stack_pointer, argv, envp);
      else if (strcmp(stack_type, "chirp") == 0)
	create_ppc_chirp_bootargs(me, argv);
      else if (strcmp(stack_type, "none") != 0)
	device_error(me, "Unknown initial stack frame type %s", stack_type);
      DTRACE(stack, 
	     ("stack_ioctl_callback() = void\n"));
      break;
    }
  default:
    device_error(me, "Unsupported ioctl requested");
    break;
  }
  return 0;
}

static device_callbacks const hw_stack_callbacks = {
  { NULL, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  NULL, /* instance */
  hw_stack_ioctl,
};

const device_descriptor hw_init_device_descriptor[] = {
  { "file", NULL, &hw_file_callbacks },
  { "data", NULL, &hw_data_callbacks },
  { "load-binary", NULL, &hw_binary_callbacks },
  { "map-binary", NULL, &hw_binary_callbacks },
  { "stack", NULL, &hw_stack_callbacks },
  { NULL },
};

#endif /* _HW_INIT_C_ */
