/*  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 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_HTAB_C_
#define _HW_HTAB_C_

#include "device_table.h"
#include "device.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_section_size (sec);
  unsigned_word vma = bfd_section_vma (sec);
  unsigned_word ra = bfd_section_lma (sec);

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

  if ((bfd_section_flags (sec) & SEC_CODE)
      || (bfd_section_flags (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_section_flags (sec) & SEC_DATA)
	   || (bfd_section_flags (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_section_flags (sec) & SEC_ALLOC))
    return;

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

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

  /* find where it is to go */
  section_vma = bfd_section_vma (sec);
  section_ra = 0;
  if ((bfd_section_flags (sec) & SEC_CODE)
      || (bfd_section_flags (sec) & SEC_READONLY))
    section_ra = (section_vma - sizes->text_base + sizes->text_ra);
  else if ((bfd_section_flags (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_section_name (sec),
	  (long)section_vma,
	  (long)section_size,
	  (long)section_ra,
	  (long)bfd_section_flags (sec),
	  bfd_section_flags (sec) & SEC_LOAD ? " LOAD" : "",
	  bfd_section_flags (sec) & SEC_CODE ? " CODE" : "",
	  bfd_section_flags (sec) & SEC_DATA ? " DATA" : "",
	  bfd_section_flags (sec) & SEC_ALLOC ? " ALLOC" : "",
	  bfd_section_flags (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.text_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_ */
