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

#include <stdlib.h>
#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 ((hw_phb_decode)type != hw_phb_normal_decode
      && (hw_phb_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, (unsigned long)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, (unsigned long)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_ */
