/*  This file is part of the program psim.

    Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>

    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
    */


#ifndef _HW_SHM_C_
#define _HW_SHM_C_

#include "device_table.h"

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif

#include <sys/ipc.h>
#include <sys/shm.h>


/* DEVICE


   shm - map unix shared memory into psim address space


   DESCRIPTION


   This device implements an area of memory which is mapped into UNIX
   shared memory.


   PROPERTIES


   reg = <address> <size> (required)

   Determine where the memory lives in the parents address space.
   The SHM area is assumed to be of the same length.

   key = <integer> (required)

   This is the key of the unix shared memory area.

   EXAMPLES


   Enable tracing of the shm:

   |  bash$ psim -t shm-device \


   Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
   mapped into psim address space at 0x0c000000.

   |  -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
   |  -o '/shm@0x0c000000/key 0x12345678' \

   sim/ppc/run -o '/#address-cells 1' \
         -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
         -o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello

   BUGS

   None known.

   */

typedef struct _hw_shm_device {
  unsigned_word physical_address;
  char *shm_address;
  unsigned sizeof_memory;
  key_t key;
  int id;
} hw_shm_device;

static void
hw_shm_init_data(device *me)
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  const device_unit *d;
  reg_property_spec reg;
  int i;

  /* Obtain the Key Value */
  if (device_find_property(me, "key") == NULL)
    error("shm_init_data() required key property is missing\n");

  shm->key = (key_t) device_find_integer_property(me, "key");
  DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
  
  /* Figure out where this memory is in address space and how long it is */
  if ( !device_find_reg_array_property(me, "reg", 0, &reg) )
    error("hw_shm_init_data() no address registered\n");

  /* Determine the address and length being as paranoid as possible */
  shm->physical_address = 0xffffffff;
  shm->sizeof_memory = 0xffffffff;

  for ( i=0 ; i<reg.address.nr_cells; i++ ) {
    if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
      continue;

    if ( shm->physical_address != 0xffffffff )
      device_error(me, "Only single celled address ranges supported\n");

    shm->physical_address = reg.address.cells[i];
    DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));

    shm->sizeof_memory = reg.size.cells[i];
    DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
  }

  if ( shm->physical_address == 0xffffffff )
    device_error(me, "Address not specified\n" );

  if ( shm->sizeof_memory == 0xffffffff )
    device_error(me, "Length not specified\n" );

  /* Now actually attach to or create the shared memory area */
  shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
  if (shm->id == -1)
    error("hw_shm_init_data() shmget failed\n");

  shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
  if (shm->shm_address == (void *)-1)
    error("hw_shm_init_data() shmat failed\n");
}

static void
hw_shm_attach_address_callback(device *me,
				attach_type attach,
				int space,
				unsigned_word addr,
				unsigned nr_bytes,
				access_type access,
				device *client) /*callback/default*/
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);

  if (space != 0)
    error("shm_attach_address_callback() invalid address space\n");

  if (nr_bytes == 0)
    error("shm_attach_address_callback() invalid size\n");
}


static unsigned
hw_shm_io_read_buffer(device *me,
			 void *dest,
			 int space,
			 unsigned_word addr,
			 unsigned nr_bytes,
			 cpu *processor,
			 unsigned_word cia)
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);

  /* do we need to worry about out of range addresses? */

  DTRACE(shm, ("read %p %x %x %x\n", \
     shm->shm_address, shm->physical_address, addr, nr_bytes) );

  memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
  return nr_bytes;
}


static unsigned
hw_shm_io_write_buffer(device *me,
			  const void *source,
			  int space,
			  unsigned_word addr,
			  unsigned nr_bytes,
			  cpu *processor,
			  unsigned_word cia)
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);

  /* do we need to worry about out of range addresses? */

  DTRACE(shm, ("write %p %x %x %x\n", \
     shm->shm_address, shm->physical_address, addr, nr_bytes) );

  memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
  return nr_bytes;
}

static device_callbacks const hw_shm_callbacks = {
  { generic_device_init_address, hw_shm_init_data },
  { hw_shm_attach_address_callback, }, /* address */
  { hw_shm_io_read_buffer,
    hw_shm_io_write_buffer }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  NULL,
};

static void *
hw_shm_create(const char *name,
		 const device_unit *unit_address,
		 const char *args)
{
  hw_shm_device *shm = ZALLOC(hw_shm_device);
  return shm;
}



const device_descriptor hw_shm_device_descriptor[] = {
  { "shm", hw_shm_create, &hw_shm_callbacks },
  { NULL },
};

#endif /* _HW_SHM_C_ */
