/*  This file is part of the program psim.

    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>

    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 _DEVICE_TABLE_C_
#define _DEVICE_TABLE_C_

#include "device_table.h"

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <ctype.h>


/* Helper functions */


/* Go through the devices various reg properties for those that
   specify attach addresses */


void
generic_device_init_address(device *me)
{
  static const char *(reg_property_names[]) = {
    "attach-addresses",
    "assigned-addresses",
    "reg",
    "alternate-reg" ,
    NULL
  };
  const char **reg_property_name;
  int nr_valid_reg_properties = 0;
  for (reg_property_name = reg_property_names;
       *reg_property_name != NULL;
       reg_property_name++) {
    if (device_find_property(me, *reg_property_name) != NULL) {
      reg_property_spec reg;
      int reg_entry;
      for (reg_entry = 0;
	   device_find_reg_array_property(me, *reg_property_name, reg_entry,
					  &reg);
	   reg_entry++) {
	unsigned_word attach_address;
	int attach_space;
	unsigned attach_size;
	if (!device_address_to_attach_address(device_parent(me),
					      &reg.address,
					      &attach_space, &attach_address,
					      me))
	  continue;
	if (!device_size_to_attach_size(device_parent(me),
					&reg.size,
					&attach_size, me))
	  continue;
	device_attach_address(device_parent(me),
			      attach_callback,
			      attach_space, attach_address, attach_size,
			      access_read_write_exec,
			      me);
	nr_valid_reg_properties++;
      }
      /* if first option matches don't try for any others */
      if (reg_property_name == reg_property_names)
	break;
    }
  }
}

int
generic_device_unit_decode(device *bus,
			   const char *unit,
			   device_unit *phys)
{
  memset(phys, 0, sizeof(device_unit));
  if (unit == NULL)
    return 0;
  else {
    int nr_cells = 0;
    const int max_nr_cells = device_nr_address_cells(bus);
    while (1) {
      char *end = NULL;
      unsigned long val;
      val = strtoul(unit, &end, 0);
      /* parse error? */
      if (unit == end)
	return -1;
      /* two many cells? */
      if (nr_cells >= max_nr_cells)
	return -1;
      /* save it */
      phys->cells[nr_cells] = val;
      nr_cells++;
      unit = end;
      /* more to follow? */
      if (isspace(*unit) || *unit == '\0')
	break;
      if (*unit != ',')
	return -1;
      unit++;
    }
    if (nr_cells < max_nr_cells) {
      /* shift everything to correct position */
      int i;
      for (i = 1; i <= nr_cells; i++)
	phys->cells[max_nr_cells - i] = phys->cells[nr_cells - i];
      for (i = 0; i < (max_nr_cells - nr_cells); i++)
	phys->cells[i] = 0;
    }
    phys->nr_cells = max_nr_cells;
    return max_nr_cells;
  }
}

int
generic_device_unit_encode(device *bus,
			   const device_unit *phys,
			   char *buf,
			   int sizeof_buf)
{
  int i;
  int len;
  char *pos = buf;
  /* skip leading zero's */
  for (i = 0; i < phys->nr_cells; i++) {
    if (phys->cells[i] != 0)
      break;
  }
  /* don't output anything if empty */
  if (phys->nr_cells == 0) {
    strcpy(pos, "");
    len = 0;
  }
  else if (i == phys->nr_cells) {
    /* all zero */
    strcpy(pos, "0");
    len = 1;
  }
  else {
    for (; i < phys->nr_cells; i++) {
      if (pos != buf) {
	strcat(pos, ",");
	pos = strchr(pos, '\0');
      }
      if (phys->cells[i] < 10)
	sprintf(pos, "%ld", (unsigned long)phys->cells[i]);
      else
	sprintf(pos, "0x%lx", (unsigned long)phys->cells[i]);
      pos = strchr(pos, '\0');
    }
    len = pos - buf;
  }
  if (len >= sizeof_buf)
    error("generic_unit_encode - buffer overflow\n");
  return len;
}

int
generic_device_address_to_attach_address(device *me,
					 const device_unit *address,
					 int *attach_space,
					 unsigned_word *attach_address,
					 device *client)
{
  int i;
  for (i = 0; i < address->nr_cells - 2; i++) {
    if (address->cells[i] != 0)
      device_error(me, "Only 32bit addresses supported");
  }
  if (address->nr_cells >= 2)
    *attach_space = address->cells[address->nr_cells - 2];
  else
    *attach_space = 0;
  *attach_address = address->cells[address->nr_cells - 1];
  return 1;
}

int
generic_device_size_to_attach_size(device *me,
				   const device_unit *size,
				   unsigned *nr_bytes,
				   device *client)
{
  int i;
  for (i = 0; i < size->nr_cells - 1; i++) {
    if (size->cells[i] != 0)
      device_error(me, "Only 32bit sizes supported");
  }
  *nr_bytes = size->cells[0];
  return *nr_bytes;
}


/* ignore/passthrough versions of each function */

void
passthrough_device_address_attach(device *me,
				  attach_type attach,
				  int space,
				  unsigned_word addr,
				  unsigned nr_bytes,
				  access_type access,
				  device *client) /*callback/default*/
{
  device_attach_address(device_parent(me), attach,
			space, addr, nr_bytes,
			access,
			client);
}

void
passthrough_device_address_detach(device *me,
				  attach_type attach,
				  int space,
				  unsigned_word addr,
				  unsigned nr_bytes,
				  access_type access,
				  device *client) /*callback/default*/
{
  device_detach_address(device_parent(me), attach,
			space, addr, nr_bytes, access,
			client);
}

unsigned
passthrough_device_dma_read_buffer(device *me,
				   void *dest,
				   int space,
				   unsigned_word addr,
				   unsigned nr_bytes)
{
  return device_dma_read_buffer(device_parent(me), dest,
				space, addr, nr_bytes);
}

unsigned
passthrough_device_dma_write_buffer(device *me,
			     const void *source,
			     int space,
			     unsigned_word addr,
			     unsigned nr_bytes,
			     int violate_read_only_section)
{
  return device_dma_write_buffer(device_parent(me), source,
				 space, addr,
				 nr_bytes,
				 violate_read_only_section);
}

int
ignore_device_unit_decode(device *me,
			  const char *unit,
			  device_unit *phys)
{
  memset(phys, 0, sizeof(device_unit));
  return 0;
}


static const device_callbacks passthrough_callbacks = {
  { NULL, }, /* init */
  { passthrough_device_address_attach,
    passthrough_device_address_detach, },
  { NULL, }, /* IO */
  { passthrough_device_dma_read_buffer, passthrough_device_dma_write_buffer, },
  { NULL, }, /* interrupt */
  { generic_device_unit_decode,
    generic_device_unit_encode, },
};


static const device_descriptor ob_device_table[] = {
  /* standard OpenBoot devices */
  { "aliases", NULL, &passthrough_callbacks },
  { "options", NULL, &passthrough_callbacks },
  { "chosen", NULL, &passthrough_callbacks },
  { "packages", NULL, &passthrough_callbacks },
  { "cpus", NULL, &passthrough_callbacks },
  { "openprom", NULL, &passthrough_callbacks },
  { "init", NULL, &passthrough_callbacks },
  { NULL },
};

const device_descriptor *const device_table[] = {
  ob_device_table,
#include "hw.c"
  NULL,
};


#endif /* _DEVICE_TABLE_C_ */
