/*  This file is part of the program psim.

    Copyright 1994, 1995, 1996, 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 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
    */


#ifndef _HW_HTAB_C_
#define _HW_HTAB_C_

#include "device_table.h"

#include "bfd.h"


/* DEVICE


   htab - pseudo-device describing a PowerPC hash table

   
   DESCRIPTION
   
   
   During the initialization of the device tree, the pseudo-device
   <<htab>>, in conjunction with any child <<pte>> pseudo-devices,
   will create a PowerPC hash table in memory.  The hash table values
   are written using dma transfers.
   
   The size and address of the hash table are determined by properties
   of the htab node.
    
   By convention, the htab device is made a child of the
   <</openprom/init>> node.
   
   By convention, the real address of the htab is used as the htab
   nodes unit address.
   
   
   PROPERTIES
   

   real-address = <address> (required)

   The physical address of the hash table.  The PowerPC architecture
   places limitations on what is a valid hash table real-address.

   
   nr-bytes = <size> (required)

   The size of the hash table (in bytes) that is to be created at
   <<real-address>>.  The PowerPC architecture places limitations on
   what is a valid hash table size.

   
   claim = <anything> (optional)

   If this property is present, the memory used to construct the hash
   table will be claimed from the memory device.  The memory device
   being specified by the <</chosen/memory>> ihandle property.

   
   EXAMPLES
   
   Enable tracing.
   
   |  $  psim -t htab-device \
   
   
   Create a htab specifying the base address and minimum size.
   
   |    -o '/openprom/init/htab@0x10000/real-address 0x10000' \
   |    -o '/openprom/init/htab@0x10000/claim 0' \
   |    -o '/openprom/init/htab@0x10000/nr-bytes 65536' \
   
   
   BUGS
   
   
   See the <<pte>> device.
   
   
   */

   
/* DEVICE


   pte - pseudo-device describing a htab entry


   DESCRIPTION

   
   The <<pte>> pseudo-device, which must be a child of a <<htabl>>
   node, describes a virtual to physical mapping that is to be entered
   into the parents hash table.
   
   Two alternative specifications of the mapping are allowed.  Either
   a section of physical memory can be mapped to a virtual address, or
   the header of an executible image can be used to define the
   mapping.
   
   By convention, the real address of the map is specified as the pte
   devices unit address.
   
   
   PROPERTIES

   
   real-address = <address> (required)

   The starting physical address that is to be mapped by the hash
   table.

   
   wimg = <int> (required)
   pp = <int> (required)

   The value of hash table protection bits that are to be used when
   creating the virtual to physical address map.

   
   claim = <anything> (optional)

   If this property is present, the real memory that is being mapped by the 
   hash table will be claimed from the memory node (specified by the 
   ihandle <</chosen/memory>>).
   

   virtual-address = <integer> [ <integer> ]  (option A)
   nr-bytes = <size>  (option A)

   Option A - Virtual virtual address (and size) at which the physical
   address is to be mapped.  If multiple values are specified for the
   virtual address then they are concatenated to gether to form a
   longer virtual address.

   
   file-name = <string>  (option B)

   Option B - An executable image that is to be loaded (starting at
   the physical address specified above) and then mapped in using
   informatioin taken from the executables header.  information found
   in the files header.

   
   EXAMPLES
   
   
   Enable tracing (note that both the <<htab>> and <<pte>> device use the 
   same trace option).
   
   |   -t htab-device \
   
   
   Map a block of physical memory into a specified virtual address:
 	
   |  -o '/openprom/init/htab/pte@0x0/real-address 0' \
   |  -o '/openprom/init/htab/pte@0x0/nr-bytes 4096' \
   |  -o '/openprom/init/htab/pte@0x0/virtual-address 0x1000000' \
   |  -o '/openprom/init/htab/pte@0x0/claim 0' \
   |  -o '/openprom/init/htab/pte@0x0/wimg 0x7' \
   |  -o '/openprom/init/htab/pte@0x0/pp 0x2' \
   
   
   Map a file into memory.
   
   |  -o '/openprom/init/htab/pte@0x10000/real-address 0x10000' \
   |  -o '/openprom/init/htab/pte@0x10000/file-name "netbsd.elf' \
   |  -o '/openprom/init/htab/pte@0x10000/wimg 0x7' \
   |  -o '/openprom/init/htab/pte@0x10000/pp 0x2' \
   
   
   BUGS
   
   
   For an ELF executable, the header defines both the virtual and real 
   address at which each file section should be loaded.  At present, the 
   real addresses that are specified in the header are ignored, the file 
   instead being loaded in to physical memory in a linear fashion.
   
   When claiming memory, this device assumes that the #address-cells
   and #size-cells is one.  For future implementations, this may not
   be the case.
   
   */



static void
htab_decode_hash_table(device *me,
		       unsigned32 *htaborg,
		       unsigned32 *htabmask)
{
  unsigned_word htab_ra;
  unsigned htab_nr_bytes;
  unsigned n;
  device *parent = device_parent(me);
  /* determine the location/size of the hash table */
  if (parent == NULL
      || strcmp(device_name(parent), "htab") != 0)
    device_error(parent, "must be a htab device");
  htab_ra = device_find_integer_property(parent, "real-address");
  htab_nr_bytes = device_find_integer_property(parent, "nr-bytes");
  if (htab_nr_bytes < 0x10000) {
    device_error(parent, "htab size 0x%x less than 0x1000",
		 htab_nr_bytes);
  }
  for (n = htab_nr_bytes; n > 1; n = n / 2) {
    if (n % 2 != 0)
      device_error(parent, "htab size 0x%x not a power of two",
		   htab_nr_bytes);
  }
  *htaborg = htab_ra;
  /* Position the HTABMASK ready for use against a hashed address and
     not ready for insertion into SDR1.HTABMASK.  */
  *htabmask = MASKED32(htab_nr_bytes - 1, 7, 31-6);
  /* Check that the MASK and ADDRESS do not overlap.  */
  if ((htab_ra & (*htabmask)) != 0) {
    device_error(parent, "htaborg 0x%lx not aligned to htabmask 0x%lx",
		 (unsigned long)*htaborg, (unsigned long)*htabmask);
  }
  DTRACE(htab, ("htab - htaborg=0x%lx htabmask=0x%lx\n",
		(unsigned long)*htaborg, (unsigned long)*htabmask));
}

static void
htab_map_page(device *me,
	      unsigned_word ra,
	      unsigned64 va,
	      unsigned wimg,
	      unsigned pp,
	      unsigned32 htaborg,
	      unsigned32 htabmask)
{
  /* keep everything left shifted so that the numbering is easier */
  unsigned64 vpn = va << 12;
  unsigned32 vsid = INSERTED32(EXTRACTED64(vpn, 0, 23), 0, 23);
  unsigned32 vpage = INSERTED32(EXTRACTED64(vpn, 24, 39), 0, 15);
  unsigned32 hash = INSERTED32(EXTRACTED32(vsid, 5, 23)
			       ^ EXTRACTED32(vpage, 0, 15),
			       7, 31-6);
  int h;
  for (h = 0; h < 2; h++) {
    unsigned32 pteg = (htaborg | (hash & htabmask));
    int pti;
    for (pti = 0; pti < 8; pti++) {
      unsigned32 pte = pteg + 8 * pti;
      unsigned32 current_target_pte0;
      unsigned32 current_pte0;
      if (device_dma_read_buffer(device_parent(me),
				 &current_target_pte0,
				 0, /*space*/
				 pte,
				 sizeof(current_target_pte0)) != 4)
	device_error(me, "failed to read a pte at 0x%lx", (unsigned long)pte);
      current_pte0 = T2H_4(current_target_pte0);
      if (MASKED32(current_pte0, 0, 0)) {
	/* full pte, check it isn't already mapping the same virtual
           address */
	unsigned32 curr_vsid = INSERTED32(EXTRACTED32(current_pte0, 1, 24), 0, 23);
	unsigned32 curr_api = INSERTED32(EXTRACTED32(current_pte0, 26, 31), 0, 5);
	unsigned32 curr_h = EXTRACTED32(current_pte0, 25, 25);
	if (curr_h == h
	    && curr_vsid == vsid
	    && curr_api == MASKED32(vpage, 0, 5))
	  device_error(me, "duplicate map - va=0x%08lx ra=0x%lx vsid=0x%lx h=%d vpage=0x%lx hash=0x%lx pteg=0x%lx+%2d pte0=0x%lx",
		       (unsigned long)va,
		       (unsigned long)ra,
		       (unsigned long)vsid,
		       h,
		       (unsigned long)vpage,
		       (unsigned long)hash,
		       (unsigned long)pteg,
		       pti * 8,
		       (unsigned long)current_pte0);
      }
      else {
	/* empty pte fill it */
	unsigned32 pte0 = (MASK32(0, 0)
			   | INSERTED32(EXTRACTED32(vsid, 0, 23), 1, 24)
			   | INSERTED32(h, 25, 25)
			   | INSERTED32(EXTRACTED32(vpage, 0, 5), 26, 31));
	unsigned32 target_pte0 = H2T_4(pte0);
	unsigned32 pte1 = (INSERTED32(EXTRACTED32(ra, 0, 19), 0, 19)
			   | INSERTED32(wimg, 25, 28)
			   | INSERTED32(pp, 30, 31));
	unsigned32 target_pte1 = H2T_4(pte1);
	if (device_dma_write_buffer(device_parent(me),
				    &target_pte0,
				    0, /*space*/
				    pte,
				    sizeof(target_pte0),
				    1/*ro?*/) != 4
	    || device_dma_write_buffer(device_parent(me),
				       &target_pte1,
				       0, /*space*/
				       pte + 4,
				       sizeof(target_pte1),
				       1/*ro?*/) != 4)
	  device_error(me, "failed to write a pte a 0x%lx", (unsigned long)pte);
	DTRACE(htab, ("map - va=0x%08lx ra=0x%lx vsid=0x%lx h=%d vpage=0x%lx hash=0x%lx pteg=0x%lx+%2d pte0=0x%lx pte1=0x%lx\n",
		      (unsigned long)va,
		      (unsigned long)ra,
		      (unsigned long)vsid,
		      h,
		      (unsigned long)vpage,
		      (unsigned long)hash,
		      (unsigned long)pteg,
		      pti * 8,
		      (unsigned long)pte0,
		      (unsigned long)pte1));
	return;
      }
    }
    /* re-hash */
    hash = MASKED32(~hash, 0, 18);
  }
}

static unsigned_word
claim_memory(device *me,
	     device_instance *memory,
	     unsigned_word ra,
	     unsigned_word size)
{
  unsigned32 args[3];
  unsigned32 results[1];
  int status;
  args[0] = 0; /* alignment */
  args[1] = size;
  args[2] = ra;
  status = device_instance_call_method(memory, "claim", 3, args, 1, results);
  if (status != 0)
    device_error(me, "failed to claim memory");
  return results[0];
}

static void
htab_map_region(device *me,
		device_instance *memory,
		unsigned_word pte_ra,
		unsigned64 pte_va,
		unsigned nr_bytes,
		unsigned wimg,
		unsigned pp,
		unsigned32 htaborg,
		unsigned32 htabmask)
{
  unsigned_word ra;
  unsigned64 va;
  /* claim the memory */
  if (memory != NULL)
    claim_memory(me, memory, pte_ra, nr_bytes);
  /* go through all pages and create a pte for each */
  for (ra = pte_ra, va = pte_va;
       ra < pte_ra + nr_bytes;
       ra += 0x1000, va += 0x1000) {
    htab_map_page(me, ra, va, wimg, pp, htaborg, htabmask);
  }
}
  
typedef struct _htab_binary_sizes {
  unsigned_word text_ra;
  unsigned_word text_base;
  unsigned_word text_bound;
  unsigned_word data_ra;
  unsigned_word data_base;
  unsigned data_bound;
  device *me;
} htab_binary_sizes;

static void
htab_sum_binary(bfd *abfd,
		sec_ptr sec,
		PTR data)
{
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
  unsigned_word size = bfd_get_section_size (sec);
  unsigned_word vma = bfd_get_section_vma (abfd, sec);
  unsigned_word ra = bfd_get_section_lma (abfd, sec);

  /* skip the section if no memory to allocate */
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
    return;

  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY)) {
    if (sizes->text_bound < vma + size)
      sizes->text_bound = ALIGN_PAGE(vma + size);
    if (sizes->text_base > vma)
      sizes->text_base = FLOOR_PAGE(vma);
    if (sizes->text_ra > ra)
      sizes->text_ra = FLOOR_PAGE(ra);
  }
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA)
	   || (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)) {
    if (sizes->data_bound < vma + size)
      sizes->data_bound = ALIGN_PAGE(vma + size);
    if (sizes->data_base > vma)
      sizes->data_base = FLOOR_PAGE(vma);
    if (sizes->data_ra > ra)
      sizes->data_ra = FLOOR_PAGE(ra);
  }
}

static void
htab_dma_binary(bfd *abfd,
		sec_ptr sec,
		PTR data)
{
  htab_binary_sizes *sizes = (htab_binary_sizes*)data;
  void *section_init;
  unsigned_word section_vma;
  unsigned_word section_size;
  unsigned_word section_ra;
  device *me = sizes->me;

  /* skip the section if no memory to allocate */
  if (! (bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
    return;

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

  /* if nothing to load, ignore this one */
  if (! (bfd_get_section_flags(abfd, sec) & SEC_LOAD))
    return;

  /* find where it is to go */
  section_vma = bfd_get_section_vma(abfd, sec);
  section_ra = 0;
  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE)
      || (bfd_get_section_flags (abfd, sec) & SEC_READONLY))
    section_ra = (section_vma - sizes->text_base + sizes->text_ra);
  else if ((bfd_get_section_flags (abfd, sec) & SEC_DATA))
    section_ra = (section_vma - sizes->data_base + sizes->data_ra);
  else 
    return; /* just ignore it */

  DTRACE(htab,
	 ("load - name=%-7s vma=0x%.8lx size=%6ld ra=0x%.8lx flags=%3lx(%s%s%s%s%s )\n",
	  bfd_get_section_name(abfd, sec),
	  (long)section_vma,
	  (long)section_size,
	  (long)section_ra,
	  (long)bfd_get_section_flags(abfd, sec),
	  bfd_get_section_flags(abfd, sec) & SEC_LOAD ? " LOAD" : "",
	  bfd_get_section_flags(abfd, sec) & SEC_CODE ? " CODE" : "",
	  bfd_get_section_flags(abfd, sec) & SEC_DATA ? " DATA" : "",
	  bfd_get_section_flags(abfd, sec) & SEC_ALLOC ? " ALLOC" : "",
	  bfd_get_section_flags(abfd, sec) & SEC_READONLY ? " READONLY" : ""
	  ));

  /* dma in the sections data */
  section_init = zalloc(section_size);
  if (!bfd_get_section_contents(abfd,
				sec,
				section_init, 0,
				section_size)) {
    bfd_perror("devices/pte");
    device_error(me, "no data loaded");
  }
  if (device_dma_write_buffer(device_parent(me),
			      section_init,
			      0 /*space*/,
			      section_ra,
			      section_size,
			      1 /*violate_read_only*/)
      != section_size)
    device_error(me, "broken dma transfer");
  free(section_init); /* only free if load */
}

/* create a memory map from a binaries virtual addresses to a copy of
   the binary laid out linearly in memory */

static void
htab_map_binary(device *me,
		device_instance *memory,
		unsigned_word ra,
		unsigned wimg,
		unsigned pp,
		const char *file_name,
		unsigned32 htaborg,
		unsigned32 htabmask)
{
  htab_binary_sizes sizes;
  bfd *image;
  sizes.text_ra = -1;
  sizes.data_ra = -1;
  sizes.text_base = -1;
  sizes.data_base = -1;
  sizes.text_bound = 0;
  sizes.data_bound = 0;
  sizes.me = me;

  /* open the file */
  image = bfd_openr(file_name, NULL);
  if (image == NULL) {
    bfd_perror("devices/pte");
    device_error(me, "the file %s not loaded", 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", file_name);
  }

  /* determine the size of each of the files regions */
  bfd_map_over_sections (image, htab_sum_binary, (PTR) &sizes);

  /* if needed, determine the real addresses of the sections */
  if (ra != -1) {
    sizes.text_ra = ra;
    sizes.data_ra = ALIGN_PAGE(sizes.text_ra + 
			       (sizes.text_bound - sizes.text_base));
  }

  DTRACE(htab, ("text map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
		(unsigned long)sizes.text_base,
		(unsigned long)sizes.text_bound,
		(unsigned long)sizes.text_ra));
  DTRACE(htab, ("data map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
		(unsigned long)sizes.data_base,
		(unsigned long)sizes.data_bound,
		(unsigned long)sizes.data_ra));

  /* check for and fix a botched image (text and data segments
     overlap) */
  if ((sizes.text_base <= sizes.data_base
       && sizes.text_bound >= sizes.data_bound)
      || (sizes.data_base <= sizes.text_base
	  && sizes.data_bound >= sizes.data_bound)
      || (sizes.text_bound > sizes.data_base
	  && sizes.text_bound <= sizes.data_bound)
      || (sizes.text_base >= sizes.data_base
	  && sizes.text_base < sizes.data_bound)) {
    DTRACE(htab, ("text and data segment overlaped - using just data segment\n"));
    /* check va->ra linear */
    if ((sizes.text_base - sizes.text_ra)
	!= (sizes.data_base - sizes.data_ra))
      device_error(me, "overlapping but missaligned text and data segments");
    /* enlarge the data segment */
    if (sizes.text_base < sizes.data_base)
      sizes.data_base = sizes.text_base;
    if (sizes.text_bound > sizes.data_bound)
      sizes.data_bound = sizes.text_bound;
    if (sizes.text_ra < sizes.data_ra)
      sizes.data_ra = sizes.text_ra;
    /* zap the text segment */
    sizes.text_base = 0;
    sizes.text_bound = 0;
    sizes.text_ra = 0;
    DTRACE(htab, ("common map - base=0x%lx bound=0x%lx-1 ra=0x%lx\n",
		  (unsigned long)sizes.data_base,
		  (unsigned long)sizes.data_bound,
		  (unsigned long)sizes.data_ra));
  }

  /* set up virtual memory maps for each of the regions */
  if (sizes.text_bound - sizes.text_base > 0) {
    htab_map_region(me, memory, sizes.text_ra, sizes.text_base,
		    sizes.text_bound - sizes.text_base,
		    wimg, pp,
		    htaborg, htabmask);
  }

  htab_map_region(me, memory, sizes.data_ra, sizes.data_base,
		  sizes.data_bound - sizes.data_base,
		  wimg, pp,
		  htaborg, htabmask);

  /* dma the sections into physical memory */
  bfd_map_over_sections (image, htab_dma_binary, (PTR) &sizes);
}

static void
htab_init_data_callback(device *me)
{
  device_instance *memory = NULL;
  if (WITH_TARGET_WORD_BITSIZE != 32)
    device_error(me, "only 32bit targets currently suported");

  /* find memory device */
  if (device_find_property(me, "claim") != NULL)
    memory = tree_find_ihandle_property(me, "/chosen/memory");

  /* for the htab, just allocate space for it */
  if (strcmp(device_name(me), "htab") == 0) {
    unsigned_word address = device_find_integer_property(me, "real-address");
    unsigned_word length = device_find_integer_property(me, "nr-bytes");
    unsigned_word base = claim_memory(me, memory, address, length);
    if (base == -1 || base != address)
      device_error(me, "cannot allocate hash table");
  }

  /* for the pte, do all the real work */
  if (strcmp(device_name(me), "pte") == 0) {
    unsigned32 htaborg;
    unsigned32 htabmask;

    htab_decode_hash_table(me, &htaborg, &htabmask);

    if (device_find_property(me, "file-name") != NULL) {
      /* map in a binary */
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
      unsigned pte_pp = device_find_integer_property(me, "pp");
      const char *file_name = device_find_string_property(me, "file-name");
      if (device_find_property(me, "real-address") != NULL) {
	unsigned32 pte_ra = device_find_integer_property(me, "real-address");
	DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, file-name=%s\n",
		      (unsigned long)pte_ra,
		      (unsigned long)pte_wimg,
		      (long)pte_pp,
		      file_name));
	htab_map_binary(me, memory, pte_ra, pte_wimg, pte_pp, file_name,
			htaborg, htabmask);
      }
      else {
	DTRACE(htab, ("pte - wimg=%ld, pp=%ld, file-name=%s\n",
		      (unsigned long)pte_wimg,
		      (long)pte_pp,
		      file_name));
	htab_map_binary(me, memory, -1, pte_wimg, pte_pp, file_name,
			htaborg, htabmask);
      }
    }
    else {
      /* handle a normal mapping definition */
      unsigned64 pte_va = 0;
      unsigned32 pte_ra = device_find_integer_property(me, "real-address");
      unsigned pte_nr_bytes = device_find_integer_property(me, "nr-bytes");
      unsigned pte_wimg = device_find_integer_property(me, "wimg");
      unsigned pte_pp = device_find_integer_property(me, "pp");
      signed_cell partial_va;
      int i;
      for (i = 0;
	   device_find_integer_array_property(me, "virtual-address", i, &partial_va);
	   i++) {
	pte_va = (pte_va << WITH_TARGET_WORD_BITSIZE) | (unsigned_cell)partial_va;
      }
      DTRACE(htab, ("pte - ra=0x%lx, wimg=%ld, pp=%ld, va=0x%lx, nr_bytes=%ld\n",
		    (unsigned long)pte_ra,
		    (long)pte_wimg,
		    (long)pte_pp,
		    (unsigned long)pte_va,
		    (long)pte_nr_bytes));
      htab_map_region(me, memory, pte_ra, pte_va, pte_nr_bytes, pte_wimg, pte_pp,
		      htaborg, htabmask);
    }
  }
}


static device_callbacks const htab_callbacks = {
  { NULL, htab_init_data_callback, },
  { NULL, }, /* address */
  { NULL, }, /* IO */
  { passthrough_device_dma_read_buffer,
    passthrough_device_dma_write_buffer, },
  { NULL, }, /* interrupt */
  { generic_device_unit_decode,
    generic_device_unit_encode, },
};

const device_descriptor hw_htab_device_descriptor[] = {
  { "htab", NULL, &htab_callbacks },
  { "pte", NULL, &htab_callbacks }, /* yep - uses htab's table */
  { NULL },
};

#endif /* _HW_HTAB_C_ */
