/*  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"

#include <stdlib.h>
#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_ */
