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

#include "device_table.h"

#include "hw_phb.h"

#include "corefile.h"

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

#include <ctype.h>


/* DEVICE


   phb - PCI Host Bridge


   DESCRIPTION


   PHB implements a model of the PCI-host bridge described in the PPCP
   document.

   For bridge devices, Open Firmware specifies that the <<ranges>>
   property be used to specify the mapping of address spaces between a
   bridges parent and child busses.  This PHB model configures itsself
   according to the information specified in its ranges property.  The
   <<ranges>> property is described in detail in the Open Firmware
   documentation.

   For DMA transfers, any access to a PCI address space which falls
   outside of the mapped memory space is assumed to be a transfer
   intended for the parent bus.


   PROPERTIES


   ranges = <my-phys-addr> <parent-phys-addr> <my-size> ...  (required)
   
   Define a number of mappings from the parent bus to one of this
   devices PCI busses.  The exact format of the <<parent-phys-addr>>
   is parent bus dependant.  The format of <<my-phys-addr>> is
   described in the Open Firmware PCI bindings document (note that the
   address must be non-relocatable).


   #address-cells = 3  (required)

   Number of cells used by an Open Firmware PCI address.  This
   property must be defined before specifying the <<ranges>> property.


   #size-cells = 2  (required)

   Number of cells used by an Open Firmware PCI size.  This property
   must be defined before specifying the <<ranges>> property.


   EXAMPLES
   

   Enable tracing:

   |  $ psim \
   |    -t phb-device \


   Since device tree entries that are specified on the command line
   are added before most of the device tree has been built it is often
   necessary to explictly add certain device properties and thus
   ensure they are already present in the device tree.  For the
   <<phb>> one such property is parent busses <<#address-cells>>.

   |    -o '/#address-cells 1' \


   Create the PHB remembering to include the cell size properties:
   
   |    -o '/phb@0x80000000/#address-cells 3' \
   |    -o '/phb@0x80000000/#size-cells 2' \


   Specify that the memory address range <<0x80000000>> to
   <<0x8fffffff>> should map directly onto the PCI memory address
   space while the processor address range <<0xc0000000>> to
   <<0xc000ffff>> should map onto the PCI I/O address range starting
   at location zero:

   |    -o '/phb@0x80000000/ranges \
   |                nm0,0,0,80000000 0x80000000 0x10000000 \
   |                ni0,0,0,0 0xc0000000 0x10000' \


   Insert a 4k <<nvram>> into slot zero of the PCI bus.  Have it
   directly accessible in both the I/O (address <<0x100>>) and memory
   (address 0x80001000) spaces:

   |    -o '/phb@0x80000000/nvram@0/assigned-addresses \
   |                nm0,0,10,80001000 4096 \
   |                ni0,0,14,100 4096'
   |    -o '/phb@0x80000000/nvram@0/reg \
   |                0 0 \
   |                i0,0,14,0 4096'
   |    -o '/phb@0x80000000/nvram@0/alternate-reg \
   |                0 0 \
   |                m0,0,10,0 4096'

   The <<assigned-address>> property corresponding to what (if it were
   implemented) be found in the config base registers while the
   <<reg>> and <<alternative-reg>> properties indicating the location
   of registers within each address space.

   Of the possible addresses, only the non-relocatable versions are
   used when attaching the device to the bus.


   BUGS
   

   The implementation of the PCI configuration space is left as an
   exercise for the reader.  Such a restriction should only impact on
   systems wanting to dynamically configure devices on the PCI bus.

   The <<CHRP>> document specfies additional (optional) functionality
   of the primary PHB. The implementation of such functionality is
   left as an exercise for the reader.

   The Open Firmware PCI bus bindings document (rev 1.6 and 2.0) is
   unclear on the value of the "ss" bits for a 64bit memory address.
   The correct value, as used by this module, is 0b11.
   
   The Open Firmware PCI bus bindings document (rev 1.6) suggests that
   the register field of non-relocatable PCI address should be zero.
   Unfortunatly, PCI addresses specified in the <<assigned-addresses>>
   property must be both non-relocatable and have non-zero register
   fields.

   The unit-decode method is not inserting a bus number into any
   address that it decodes.  Instead the bus-number is left as zero.

   Support for aliased memory and I/O addresses is left as an exercise
   for the reader.

   Support for interrupt-ack and special cycles are left as an
   exercise for the reader.  One issue to consider when attempting
   this exercise is how to specify the address of the int-ack and
   special cycle register.  Hint: <</8259-interrupt-ackowledge>> is
   the wrong answer.

   Children of this node can only use the client callback interface
   when attaching themselves to the <<phb>>.

   
   REFERENCES


   http://playground.sun.com/1275/home.html#OFDbusPCI


   */

   
typedef struct _phb_space {
  core *map;
  core_map *readable;
  core_map *writeable;
  unsigned_word parent_base;
  int parent_space;
  unsigned_word my_base;
  int my_space;
  unsigned size;	
  const char *name;
} phb_space;

typedef struct _hw_phb_device  {
  phb_space space[nr_hw_phb_spaces];
} hw_phb_device;


static const char *
hw_phb_decode_name(hw_phb_decode level)
{
  switch (level) {
  case hw_phb_normal_decode: return "normal";
  case hw_phb_subtractive_decode: return "subtractive";
  case hw_phb_master_abort_decode: return "master-abort";
  default: return "invalid decode";
  }
}


static void
hw_phb_init_address(device *me)
{
  hw_phb_device *phb = device_data(me);
 
  /* check some basic properties */
  if (device_nr_address_cells(me) != 3)
    device_error(me, "incorrect #address-cells");
  if (device_nr_size_cells(me) != 2)
    device_error(me, "incorrect #size-cells");

  /* (re) initialize each PCI space */
  {
    hw_phb_spaces space_nr;
    for (space_nr = 0; space_nr < nr_hw_phb_spaces; space_nr++) {
      phb_space *pci_space = &phb->space[space_nr];
      core_init(pci_space->map);
      pci_space->size = 0;
    }
  }

  /* decode each of the ranges properties entering the information
     into the space table */
  {
    range_property_spec range;
    int ranges_entry;
    
    for (ranges_entry = 0;
	 device_find_range_array_property(me, "ranges", ranges_entry,
					  &range);
	 ranges_entry++) {
      int my_attach_space;
      unsigned_word my_attach_address;
      int parent_attach_space;
      unsigned_word parent_attach_address;
      unsigned size;
      phb_space *pci_space;
      /* convert the addresses into something meaningful */
      device_address_to_attach_address(me, &range.child_address,
				       &my_attach_space,
				       &my_attach_address,
				       me);
      device_address_to_attach_address(device_parent(me),
				       &range.parent_address,
				       &parent_attach_space,
				       &parent_attach_address,
				       me);
      device_size_to_attach_size(me, &range.size, &size, me);
      if (my_attach_space < 0 || my_attach_space >= nr_hw_phb_spaces)
	device_error(me, "ranges property contains an invalid address space");
      pci_space = &phb->space[my_attach_space];
      if (pci_space->size != 0)
	device_error(me, "ranges property contains duplicate mappings for %s address space",
		     pci_space->name);
      pci_space->parent_base = parent_attach_address;
      pci_space->parent_space = parent_attach_space;
      pci_space->my_base = my_attach_address;
      pci_space->my_space = my_attach_space;
      pci_space->size = size;
      device_attach_address(device_parent(me),
			    attach_callback,
			    parent_attach_space, parent_attach_address, size,
			    access_read_write_exec,
			    me);
      DTRACE(phb, ("map %d:0x%lx to %s:0x%lx (0x%lx bytes)\n",
		   (int)parent_attach_space,
		   (unsigned long)parent_attach_address,
		   pci_space->name,
		   (unsigned long)my_attach_address,
		   (unsigned long)size));
    }
    
    if (ranges_entry == 0) {
      device_error(me, "Missing or empty ranges property");
    }

  }
  
}

static void
hw_phb_attach_address(device *me,
		      attach_type type,
		      int space,
		      unsigned_word addr,
		      unsigned nr_bytes,
		      access_type access,
		      device *client) /*callback/default*/
{
  hw_phb_device *phb = device_data(me);
  phb_space *pci_space;
  /* sanity checks */
  if (space < 0 || space >= nr_hw_phb_spaces)
    device_error(me, "attach space (%d) specified by %s invalid",
		 space, device_path(client));
  pci_space = &phb->space[space];
  if (addr + nr_bytes > pci_space->my_base + pci_space->size
      || addr < pci_space->my_base)
    device_error(me, "attach addr (0x%lx) specified by %s outside of bus address range",
		 (unsigned long)addr, device_path(client));
  if (type != hw_phb_normal_decode
      && type != hw_phb_subtractive_decode)
    device_error(me, "attach type (%d) specified by %s invalid",
		 type, device_path(client));
  /* attach it to the relevent bus */
  DTRACE(phb, ("attach %s - %s %s:0x%lx (0x%lx bytes)\n",
	       device_path(client),
	       hw_phb_decode_name(type),
	       pci_space->name,
	       (unsigned long)addr,
	       (unsigned long)nr_bytes));
  core_attach(pci_space->map,
	      type,
	      space,
	      access,
	      addr,
	      nr_bytes,
	      client);
}


/* Extract/set various fields from a PCI unit address.

   Note: only the least significant 32 bits of each cell is used.

   Note: for PPC MSB is 0 while for PCI it is 31. */


/* relocatable bit n */

static unsigned
extract_n(const device_unit *address)
{
  return EXTRACTED32(address->cells[0], 0, 0);
}

static void
set_n(device_unit *address)
{
  BLIT32(address->cells[0], 0, 1);
}


/* prefetchable bit p */

static unsigned
extract_p(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 1, 1);
}

static void
set_p(device_unit *address)
{
  BLIT32(address->cells[0], 1, 1);
}


/* aliased bit t */

static unsigned
extract_t(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 2, 2);
}

static void
set_t(device_unit *address)
{
  BLIT32(address->cells[0], 2, 1);
}


/* space code ss */

typedef enum {
  ss_config_code = 0,
  ss_io_code = 1,
  ss_32bit_memory_code = 2,
  ss_64bit_memory_code = 3,
} ss_type;

static ss_type
extract_ss(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 6, 7);
}

static void
set_ss(device_unit *address, ss_type val)
{
  MBLIT32(address->cells[0], 6, 7, val);
}


/* bus number bbbbbbbb */

#if 0
static unsigned
extract_bbbbbbbb(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 8, 15);
}
#endif

#if 0
static void
set_bbbbbbbb(device_unit *address, unsigned val)
{
  MBLIT32(address->cells[0], 8, 15, val);
}
#endif


/* device number ddddd */

static unsigned
extract_ddddd(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 16, 20);
}

static void
set_ddddd(device_unit *address, unsigned val)
{
  MBLIT32(address->cells[0], 16, 20, val);
}


/* function number fff */

static unsigned
extract_fff(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 21, 23);
}

static void
set_fff(device_unit *address, unsigned val)
{
  MBLIT32(address->cells[0], 21, 23, val);
}


/* register number rrrrrrrr */

static unsigned
extract_rrrrrrrr(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return EXTRACTED32(address->cells[0], 24, 31);
}

static void
set_rrrrrrrr(device_unit *address, unsigned val)
{
  MBLIT32(address->cells[0], 24, 31, val);
}


/* MSW of 64bit address hh..hh */

static unsigned
extract_hh_hh(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return address->cells[1];
}

static void
set_hh_hh(device_unit *address, unsigned val)
{
  address->cells[2] = val;
}


/* LSW of 64bit address ll..ll */

static unsigned
extract_ll_ll(const device_unit *address)
{
  ASSERT(address->nr_cells == 3);
  return address->cells[2];
}

static void
set_ll_ll(device_unit *address, unsigned val)
{
  address->cells[2] = val;
}


/* Convert PCI textual bus address into a device unit */

static int
hw_phb_unit_decode(device *me,
		   const char *unit,
		   device_unit *address)
{
  char *end = NULL;
  const char *chp = unit;
  unsigned long val;

  if (device_nr_address_cells(me) != 3)
    device_error(me, "PCI bus should have #address-cells == 3");
  memset(address, 0, sizeof(*address));

  if (unit == NULL)
    return 0;

  address->nr_cells = 3;

  if (isxdigit(*chp)) {
    set_ss(address, ss_config_code);
  }
  else {

    /* non-relocatable? */
    if (*chp == 'n') {
      set_n(address);
      chp++;
    }

    /* address-space? */
    if (*chp == 'i') {
      set_ss(address, ss_io_code);
      chp++;
    }
    else if (*chp == 'm') {
      set_ss(address, ss_32bit_memory_code);
      chp++;
    }
    else if (*chp == 'x') {
      set_ss(address, ss_64bit_memory_code);
      chp++;
    }
    else
      device_error(me, "Problem parsing PCI address %s", unit);

    /* possible alias */
    if (*chp == 't') {
      if (extract_ss(address) == ss_64bit_memory_code)
	device_error(me, "Invalid alias bit in PCI address %s", unit);
      set_t(address);
      chp++;
    }

    /* possible p */
    if (*chp == 'p') {
      if (extract_ss(address) != ss_32bit_memory_code)
	device_error(me, "Invalid prefetchable bit (p) in PCI address %s",
		     unit);
      set_p(address);
      chp++;
    }

  }

  /* required DD */
  if (!isxdigit(*chp))
    device_error(me, "Missing device number in PCI address %s", unit);
  val = strtoul(chp, &end, 16);
  if (chp == end)
    device_error(me, "Problem parsing device number in PCI address %s", unit);
  if ((val & 0x1f) != val)
    device_error(me, "Device number (0x%lx) out of range (0..0x1f) in PCI address %s",
		 val, unit);
  set_ddddd(address, val);
  chp = end;

  /* For config space, the F is optional */
  if (extract_ss(address) == ss_config_code
      && (isspace(*chp) || *chp == '\0'))
    return chp - unit;

  /* function number F */
  if (*chp != ',')
    device_error(me, "Missing function number in PCI address %s", unit);
  chp++;
  val = strtoul(chp, &end, 10);
  if (chp == end)
    device_error(me, "Problem parsing function number in PCI address %s",
		 unit);
  if ((val & 7) != val)
    device_error(me, "Function number (%ld) out of range (0..7) in PCI address %s",
		 (long)val, unit);
  set_fff(address, val);
  chp = end;

  /* for config space, must be end */
  if (extract_ss(address) == ss_config_code) {
    if (!isspace(*chp) && *chp != '\0')
      device_error(me, "Problem parsing PCI config address %s",
		   unit);
    return chp - unit;
  }

  /* register number RR */
  if (*chp != ',')
    device_error(me, "Missing register number in PCI address %s", unit);
  chp++;
  val = strtoul(chp, &end, 16);
  if (chp == end)
    device_error(me, "Problem parsing register number in PCI address %s",
		 unit);
  switch (extract_ss(address)) {
  case ss_io_code:
#if 0
    if (extract_n(address) && val != 0)
      device_error(me, "non-relocatable I/O register must be zero in PCI address %s", unit);
    else if (!extract_n(address)
	     && val != 0x10 && val != 0x14 && val != 0x18
	     && val != 0x1c && val != 0x20 && val != 0x24)
      device_error(me, "I/O register invalid in PCI address %s", unit);
#endif
    break;
  case ss_32bit_memory_code:
#if 0
    if (extract_n(address) && val != 0)
      device_error(me, "non-relocatable memory register must be zero in PCI address %s", unit);
    else if (!extract_n(address)
	     && val != 0x10 && val != 0x14 && val != 0x18
	     && val != 0x1c && val != 0x20 && val != 0x24 && val != 0x30)
      device_error(me, "I/O register (0x%lx) invalid in PCI address %s",
		   val, unit);
#endif
    break;
  case ss_64bit_memory_code:
    if (extract_n(address) && val != 0)
      device_error(me, "non-relocatable 32bit memory register must be zero in PCI address %s", unit);
    else if (!extract_n(address)
	     && val != 0x10 && val != 0x18 && val != 0x20)
      device_error(me, "Register number (0x%lx) invalid in 64bit PCI address %s",
		   val, unit);
  case ss_config_code:
    device_error(me, "internal error");
  }
  if ((val & 0xff) != val)
    device_error(me, "Register number (0x%lx) out of range (0..0xff) in PCI address %s",
		 val, unit);
  set_rrrrrrrr(address, val);
  chp = end;

  /* address */
  if (*chp != ',')
    device_error(me, "Missing address in PCI address %s", unit);
  chp++;
  switch (extract_ss(address)) {
  case ss_io_code:
  case ss_32bit_memory_code:
    val = strtoul(chp, &end, 16);
    if (chp == end)
      device_error(me, "Problem parsing address in PCI address %s", unit);
    switch (extract_ss(address)) {
    case ss_io_code:
      if (extract_n(address) && extract_t(address)
	  && (val & 1024) != val)
	device_error(me, "10bit aliased non-relocatable address (0x%lx) out of range in PCI address %s",
		     val, unit);
      if (!extract_n(address) && extract_t(address)
	  && (val & 0xffff) != val)
	device_error(me, "64k relocatable address (0x%lx) out of range in PCI address %s",
		     val, unit);
      break;
    case ss_32bit_memory_code:
      if (extract_t(address) && (val & 0xfffff) != val)
	device_error(me, "1mb memory address (0x%lx) out of range in PCI address %s",
		     val, unit);
      if (!extract_t(address) && (val & 0xffffffff) != val)
	device_error(me, "32bit memory address (0x%lx) out of range in PCI address %s",
		     val, unit);
      break;
    case ss_64bit_memory_code:
    case ss_config_code:
      device_error(me, "internal error");
    }
    set_ll_ll(address, val);
    chp = end;
    break;
  case ss_64bit_memory_code:
    device_error(me, "64bit addresses unimplemented");
    set_hh_hh(address, val);
    set_ll_ll(address, val);
    break;
  case ss_config_code:
    device_error(me, "internal error");
    break;
  }

  /* finished? */
  if (!isspace(*chp) && *chp != '\0')
    device_error(me, "Problem parsing PCI address %s", unit);

  return chp - unit;
}


/* Convert PCI device unit into its corresponding textual
   representation */

static int
hw_phb_unit_encode(device *me,
		   const device_unit *unit_address,
		   char *buf,
		   int sizeof_buf)
{
  if (unit_address->nr_cells != 3)
    device_error(me, "Incorrect number of cells in PCI unit address");
  if (device_nr_address_cells(me) != 3)
    device_error(me, "PCI bus should have #address-cells == 3");
  if (extract_ss(unit_address) == ss_config_code
      && extract_fff(unit_address) == 0
      && extract_rrrrrrrr(unit_address) == 0
      && extract_hh_hh(unit_address) == 0
      && extract_ll_ll(unit_address) == 0) {
    /* DD - Configuration Space address */
    sprintf(buf, "%x",
	    extract_ddddd(unit_address));
  }
  else if (extract_ss(unit_address) == ss_config_code
	   && extract_fff(unit_address) != 0
	   && extract_rrrrrrrr(unit_address) == 0
	   && extract_hh_hh(unit_address) == 0
	   && extract_ll_ll(unit_address) == 0) {
    /* DD,F - Configuration Space */
    sprintf(buf, "%x,%d",
	    extract_ddddd(unit_address),
	    extract_fff(unit_address));
  }
  else if (extract_ss(unit_address) == ss_io_code
	   && extract_hh_hh(unit_address) == 0) {
    /* [n]i[t]DD,F,RR,NNNNNNNN - 32bit I/O space */
    sprintf(buf, "%si%s%x,%d,%x,%x",
	    extract_n(unit_address) ? "n" : "",
	    extract_t(unit_address) ? "t" : "",
	    extract_ddddd(unit_address),
	    extract_fff(unit_address),
	    extract_rrrrrrrr(unit_address),
	    extract_ll_ll(unit_address));
  }
  else if (extract_ss(unit_address) == ss_32bit_memory_code
	   && extract_hh_hh(unit_address) == 0) {
    /* [n]m[t][p]DD,F,RR,NNNNNNNN - 32bit memory space */
    sprintf(buf, "%sm%s%s%x,%d,%x,%x",
	    extract_n(unit_address) ? "n" : "",
	    extract_t(unit_address) ? "t" : "",
	    extract_p(unit_address) ? "p" : "",
	    extract_ddddd(unit_address),
	    extract_fff(unit_address),
	    extract_rrrrrrrr(unit_address),
	    extract_ll_ll(unit_address));
  }
  else if (extract_ss(unit_address) == ss_32bit_memory_code) {
    /* [n]x[p]DD,F,RR,NNNNNNNNNNNNNNNN - 64bit memory space */
    sprintf(buf, "%sx%s%x,%d,%x,%x%08x",
	    extract_n(unit_address) ? "n" : "",
	    extract_p(unit_address) ? "p" : "",
	    extract_ddddd(unit_address),
	    extract_fff(unit_address),
	    extract_rrrrrrrr(unit_address),
	    extract_hh_hh(unit_address),
	    extract_ll_ll(unit_address));
  }
  else {
    device_error(me, "Invalid PCI unit address 0x%08lx 0x%08lx 0x%08lx",
		 (unsigned long)unit_address->cells[0],
		 (unsigned long)unit_address->cells[1],
		 (unsigned long)unit_address->cells[2]);
  }
  if (strlen(buf) > sizeof_buf)
    error("buffer overflow");
  return strlen(buf);
}


static int
hw_phb_address_to_attach_address(device *me,
				 const device_unit *address,
				 int *attach_space,
				 unsigned_word *attach_address,
				 device *client)
{
  if (address->nr_cells != 3)
    device_error(me, "attach address has incorrect number of cells");
  if (address->cells[1] != 0)
    device_error(me, "64bit attach address unsupported");

  /* directly decode the address/space */
  *attach_address = address->cells[2];
  switch (extract_ss(address)) {
  case ss_config_code:
    *attach_space = hw_phb_config_space;
    break;
  case ss_io_code:
    *attach_space = hw_phb_io_space;
    break;
  case ss_32bit_memory_code:
  case ss_64bit_memory_code:
    *attach_space = hw_phb_memory_space;
    break;
  }

  /* if non-relocatable finished */
  if (extract_n(address))
    return 1;

  /* make memory and I/O addresses absolute */
  if (*attach_space == hw_phb_io_space
      || *attach_space == hw_phb_memory_space) {
    int reg_nr;
    reg_property_spec assigned;
    if (extract_ss(address) == ss_64bit_memory_code)
      device_error(me, "64bit memory address not unsuported");
    for (reg_nr = 0;
	 device_find_reg_array_property(client, "assigned-addresses", reg_nr,
					&assigned);
	 reg_nr++) {
      if (!extract_n(&assigned.address)
	  || extract_rrrrrrrr(&assigned.address) == 0)
	device_error(me, "client %s has invalid assigned-address property",
		     device_path(client));
      if (extract_rrrrrrrr(address) == extract_rrrrrrrr(&assigned.address)) {
	/* corresponding base register */
	if (extract_ss(address) != extract_ss(&assigned.address))
	  device_error(me, "client %s has conflicting types for base register 0x%lx",
		       device_path(client),
		       (unsigned long)extract_rrrrrrrr(address));
	*attach_address += assigned.address.cells[2];
	return 0;
      }
    }
    device_error(me, "client %s missing base address register 0x%lx in assigned-addresses property",
		 device_path(client),
		 (unsigned long)extract_rrrrrrrr(address));
  }
  
  return 0;
}


static int
hw_phb_size_to_attach_size(device *me,
			   const device_unit *size,
			   unsigned *nr_bytes,
			   device *client)
{
  if (size->nr_cells != 2)
    device_error(me, "size has incorrect number of cells");
  if (size->cells[0] != 0)
    device_error(me, "64bit size unsupported");
  *nr_bytes = size->cells[1];
  return size->cells[1];
}


static const phb_space *
find_phb_space(hw_phb_device *phb,
	       unsigned_word addr,
	       unsigned nr_bytes)
{
  hw_phb_spaces space;
  /* find the space that matches the address */
  for (space = 0; space < nr_hw_phb_spaces; space++) {
    phb_space *pci_space = &phb->space[space];
    if (addr >= pci_space->parent_base
	&& (addr + nr_bytes) <= (pci_space->parent_base + pci_space->size)) {
      return pci_space;
    }
  }
  return NULL;
}


static unsigned_word
map_phb_addr(const phb_space *space,
	     unsigned_word addr)
{
  return addr - space->parent_base + space->my_base;
}



static unsigned
hw_phb_io_read_buffer(device *me,
		      void *dest,
		      int space,
		      unsigned_word addr,
		      unsigned nr_bytes,
		      cpu *processor,
		      unsigned_word cia)
{
  hw_phb_device *phb = (hw_phb_device*)device_data(me);
  const phb_space *pci_space = find_phb_space(phb, addr, nr_bytes);
  unsigned_word bus_addr;
  if (pci_space == NULL)
    return 0;
  bus_addr = map_phb_addr(pci_space, addr);
  DTRACE(phb, ("io read - %d:0x%lx -> %s:0x%lx (%u bytes)\n",
	       space, (unsigned long)addr, pci_space->name, (unsigned long)bus_addr,
	       nr_bytes));
  return core_map_read_buffer(pci_space->readable,
			      dest, bus_addr, nr_bytes);
}


static unsigned
hw_phb_io_write_buffer(device *me,
		       const void *source,
		       int space,
		       unsigned_word addr,
		       unsigned nr_bytes,
		       cpu *processor,
		       unsigned_word cia)
{
  hw_phb_device *phb = (hw_phb_device*)device_data(me);
  const phb_space *pci_space = find_phb_space(phb, addr, nr_bytes);
  unsigned_word bus_addr;
  if (pci_space == NULL)
    return 0;
  bus_addr = map_phb_addr(pci_space, addr);
  DTRACE(phb, ("io write - %d:0x%lx -> %s:0x%lx (%u bytes)\n",
	       space, (unsigned long)addr, pci_space->name, (unsigned long)bus_addr,
	       nr_bytes));
  return core_map_write_buffer(pci_space->writeable, source,
			       bus_addr, nr_bytes);
}


static unsigned
hw_phb_dma_read_buffer(device *me,
		       void *dest,
		       int space,
		       unsigned_word addr,
		       unsigned nr_bytes)
{
  hw_phb_device *phb = (hw_phb_device*)device_data(me);
  const phb_space *pci_space;
  /* find the space */
  if (space != hw_phb_memory_space)
    device_error(me, "invalid dma address space %d", space);
  pci_space = &phb->space[space];
  /* check out the address */
  if ((addr >= pci_space->my_base
       && addr <= pci_space->my_base + pci_space->size)
      || (addr + nr_bytes >= pci_space->my_base
	  && addr + nr_bytes <= pci_space->my_base + pci_space->size))
    device_error(me, "Do not support DMA into own bus");
  /* do it */
  DTRACE(phb, ("dma read - %s:0x%lx (%d bytes)\n",
	       pci_space->name, addr, nr_bytes));
  return device_dma_read_buffer(device_parent(me),
				dest, pci_space->parent_space,
				addr, nr_bytes);
}


static unsigned
hw_phb_dma_write_buffer(device *me,
			const void *source,
			int space,
			unsigned_word addr,
			unsigned nr_bytes,
			int violate_read_only_section)
{
  hw_phb_device *phb = (hw_phb_device*)device_data(me);
  const phb_space *pci_space;
  /* find the space */
  if (space != hw_phb_memory_space)
    device_error(me, "invalid dma address space %d", space);
  pci_space = &phb->space[space];
  /* check out the address */
  if ((addr >= pci_space->my_base
       && addr <= pci_space->my_base + pci_space->size)
      || (addr + nr_bytes >= pci_space->my_base
	  && addr + nr_bytes <= pci_space->my_base + pci_space->size))
    device_error(me, "Do not support DMA into own bus");
  /* do it */
  DTRACE(phb, ("dma write - %s:0x%lx (%d bytes)\n",
	       pci_space->name, addr, nr_bytes));
  return device_dma_write_buffer(device_parent(me),
				 source, pci_space->parent_space,
				 addr, nr_bytes,
				 violate_read_only_section);
}


static device_callbacks const hw_phb_callbacks = {
  { hw_phb_init_address, },
  { hw_phb_attach_address, },
  { hw_phb_io_read_buffer, hw_phb_io_write_buffer },
  { hw_phb_dma_read_buffer, hw_phb_dma_write_buffer },
  { NULL, }, /* interrupt */
  { hw_phb_unit_decode,
    hw_phb_unit_encode,
    hw_phb_address_to_attach_address,
    hw_phb_size_to_attach_size }
};


static void *
hw_phb_create(const char *name,
	      const device_unit *unit_address,
	      const char *args)
{
  /* create the descriptor */
  hw_phb_device *phb = ZALLOC(hw_phb_device);

  /* create the core maps now */
  hw_phb_spaces space_nr;
  for (space_nr = 0; space_nr < nr_hw_phb_spaces; space_nr++) {
    phb_space *pci_space = &phb->space[space_nr];
    pci_space->map = core_create();
    pci_space->readable = core_readable(pci_space->map);
    pci_space->writeable = core_writeable(pci_space->map);
    switch (space_nr) {
    case hw_phb_memory_space:
      pci_space->name = "memory";
      break;
    case hw_phb_io_space:
      pci_space->name = "I/O";
      break;
    case hw_phb_config_space:
      pci_space->name = "config";
      break;
    case hw_phb_special_space:
      pci_space->name = "special";
      break;
    default:
      error ("internal error");
      break;
    }
  }

  return phb;
}


const device_descriptor hw_phb_device_descriptor[] = {
  { "phb", hw_phb_create, &hw_phb_callbacks },
  { "pci", NULL, &hw_phb_callbacks },
  { NULL, },
};

#endif /* _HW_PHB_ */
