OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [ppc/] [hw_shm.c] - Diff between revs 330 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 330 Rev 816
/*  This file is part of the program psim.
/*  This file is part of the program psim.
 
 
    Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>
    Copyright (C) 1997,2008, Joel Sherrill <joel@OARcorp.com>
 
 
    This program is free software; you can redistribute it and/or modify
    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
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    (at your option) any later version.
 
 
    This program is distributed in the hope that it will be useful,
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    GNU General Public License for more details.
 
 
    You should have received a copy of the GNU General Public License
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 
    */
    */
 
 
 
 
#ifndef _HW_SHM_C_
#ifndef _HW_SHM_C_
#define _HW_SHM_C_
#define _HW_SHM_C_
 
 
#include "device_table.h"
#include "device_table.h"
 
 
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
#include <string.h>
#include <string.h>
#else
#else
#ifdef HAVE_STRINGS_H
#ifdef HAVE_STRINGS_H
#include <strings.h>
#include <strings.h>
#endif
#endif
#endif
#endif
 
 
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/shm.h>
 
 
 
 
/* DEVICE
/* DEVICE
 
 
 
 
   shm - map unix shared memory into psim address space
   shm - map unix shared memory into psim address space
 
 
 
 
   DESCRIPTION
   DESCRIPTION
 
 
 
 
   This device implements an area of memory which is mapped into UNIX
   This device implements an area of memory which is mapped into UNIX
   shared memory.
   shared memory.
 
 
 
 
   PROPERTIES
   PROPERTIES
 
 
 
 
   reg = <address> <size> (required)
   reg = <address> <size> (required)
 
 
   Determine where the memory lives in the parents address space.
   Determine where the memory lives in the parents address space.
   The SHM area is assumed to be of the same length.
   The SHM area is assumed to be of the same length.
 
 
   key = <integer> (required)
   key = <integer> (required)
 
 
   This is the key of the unix shared memory area.
   This is the key of the unix shared memory area.
 
 
   EXAMPLES
   EXAMPLES
 
 
 
 
   Enable tracing of the shm:
   Enable tracing of the shm:
 
 
   |  bash$ psim -t shm-device \
   |  bash$ psim -t shm-device \
 
 
 
 
   Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
   Configure a 512 kilobytes of UNIX shared memory with the key 0x12345678
   mapped into psim address space at 0x0c000000.
   mapped into psim address space at 0x0c000000.
 
 
   |  -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
   |  -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
   |  -o '/shm@0x0c000000/key 0x12345678' \
   |  -o '/shm@0x0c000000/key 0x12345678' \
 
 
   sim/ppc/run -o '/#address-cells 1' \
   sim/ppc/run -o '/#address-cells 1' \
         -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
         -o '/shm@0x0c000000/reg 0x0c000000 0x80000' \
         -o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello
         -o '/shm@0x0c000000/key 0x12345678' ../psim-hello/hello
 
 
   BUGS
   BUGS
 
 
   None known.
   None known.
 
 
   */
   */
 
 
typedef struct _hw_shm_device {
typedef struct _hw_shm_device {
  unsigned_word physical_address;
  unsigned_word physical_address;
  char *shm_address;
  char *shm_address;
  unsigned sizeof_memory;
  unsigned sizeof_memory;
  key_t key;
  key_t key;
  int id;
  int id;
} hw_shm_device;
} hw_shm_device;
 
 
static void
static void
hw_shm_init_data(device *me)
hw_shm_init_data(device *me)
{
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  const device_unit *d;
  const device_unit *d;
  reg_property_spec reg;
  reg_property_spec reg;
  int i;
  int i;
 
 
  /* Obtain the Key Value */
  /* Obtain the Key Value */
  if (device_find_property(me, "key") == NULL)
  if (device_find_property(me, "key") == NULL)
    error("shm_init_data() required key property is missing\n");
    error("shm_init_data() required key property is missing\n");
 
 
  shm->key = (key_t) device_find_integer_property(me, "key");
  shm->key = (key_t) device_find_integer_property(me, "key");
  DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
  DTRACE(shm, ("shm key (0x%08x)\n", shm->key) );
 
 
  /* Figure out where this memory is in address space and how long it is */
  /* Figure out where this memory is in address space and how long it is */
  if ( !device_find_reg_array_property(me, "reg", 0, &reg) )
  if ( !device_find_reg_array_property(me, "reg", 0, &reg) )
    error("hw_shm_init_data() no address registered\n");
    error("hw_shm_init_data() no address registered\n");
 
 
  /* Determine the address and length being as paranoid as possible */
  /* Determine the address and length being as paranoid as possible */
  shm->physical_address = 0xffffffff;
  shm->physical_address = 0xffffffff;
  shm->sizeof_memory = 0xffffffff;
  shm->sizeof_memory = 0xffffffff;
 
 
  for ( i=0 ; i<reg.address.nr_cells; i++ ) {
  for ( i=0 ; i<reg.address.nr_cells; i++ ) {
    if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
    if (reg.address.cells[0] == 0 && reg.size.cells[0] == 0)
      continue;
      continue;
 
 
    if ( shm->physical_address != 0xffffffff )
    if ( shm->physical_address != 0xffffffff )
      device_error(me, "Only single celled address ranges supported\n");
      device_error(me, "Only single celled address ranges supported\n");
 
 
    shm->physical_address = reg.address.cells[i];
    shm->physical_address = reg.address.cells[i];
    DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));
    DTRACE(shm, ("shm physical_address=0x%x\n", shm->physical_address));
 
 
    shm->sizeof_memory = reg.size.cells[i];
    shm->sizeof_memory = reg.size.cells[i];
    DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
    DTRACE(shm, ("shm length=0x%x\n", shm->sizeof_memory));
  }
  }
 
 
  if ( shm->physical_address == 0xffffffff )
  if ( shm->physical_address == 0xffffffff )
    device_error(me, "Address not specified\n" );
    device_error(me, "Address not specified\n" );
 
 
  if ( shm->sizeof_memory == 0xffffffff )
  if ( shm->sizeof_memory == 0xffffffff )
    device_error(me, "Length not specified\n" );
    device_error(me, "Length not specified\n" );
 
 
  /* Now actually attach to or create the shared memory area */
  /* Now actually attach to or create the shared memory area */
  shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
  shm->id = shmget(shm->key, shm->sizeof_memory, IPC_CREAT | 0660);
  if (shm->id == -1)
  if (shm->id == -1)
    error("hw_shm_init_data() shmget failed\n");
    error("hw_shm_init_data() shmget failed\n");
 
 
  shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
  shm->shm_address = shmat(shm->id, (char *)0, SHM_RND);
  if (shm->shm_address == (void *)-1)
  if (shm->shm_address == (void *)-1)
    error("hw_shm_init_data() shmat failed\n");
    error("hw_shm_init_data() shmat failed\n");
}
}
 
 
static void
static void
hw_shm_attach_address_callback(device *me,
hw_shm_attach_address_callback(device *me,
                                attach_type attach,
                                attach_type attach,
                                int space,
                                int space,
                                unsigned_word addr,
                                unsigned_word addr,
                                unsigned nr_bytes,
                                unsigned nr_bytes,
                                access_type access,
                                access_type access,
                                device *client) /*callback/default*/
                                device *client) /*callback/default*/
{
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
 
 
  if (space != 0)
  if (space != 0)
    error("shm_attach_address_callback() invalid address space\n");
    error("shm_attach_address_callback() invalid address space\n");
 
 
  if (nr_bytes == 0)
  if (nr_bytes == 0)
    error("shm_attach_address_callback() invalid size\n");
    error("shm_attach_address_callback() invalid size\n");
}
}
 
 
 
 
static unsigned
static unsigned
hw_shm_io_read_buffer(device *me,
hw_shm_io_read_buffer(device *me,
                         void *dest,
                         void *dest,
                         int space,
                         int space,
                         unsigned_word addr,
                         unsigned_word addr,
                         unsigned nr_bytes,
                         unsigned nr_bytes,
                         cpu *processor,
                         cpu *processor,
                         unsigned_word cia)
                         unsigned_word cia)
{
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
 
 
  /* do we need to worry about out of range addresses? */
  /* do we need to worry about out of range addresses? */
 
 
  DTRACE(shm, ("read %p %x %x %x\n", \
  DTRACE(shm, ("read %p %x %x %x\n", \
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
 
 
  memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
  memcpy(dest, &shm->shm_address[addr - shm->physical_address], nr_bytes);
  return nr_bytes;
  return nr_bytes;
}
}
 
 
 
 
static unsigned
static unsigned
hw_shm_io_write_buffer(device *me,
hw_shm_io_write_buffer(device *me,
                          const void *source,
                          const void *source,
                          int space,
                          int space,
                          unsigned_word addr,
                          unsigned_word addr,
                          unsigned nr_bytes,
                          unsigned nr_bytes,
                          cpu *processor,
                          cpu *processor,
                          unsigned_word cia)
                          unsigned_word cia)
{
{
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
  hw_shm_device *shm = (hw_shm_device*)device_data(me);
 
 
  /* do we need to worry about out of range addresses? */
  /* do we need to worry about out of range addresses? */
 
 
  DTRACE(shm, ("write %p %x %x %x\n", \
  DTRACE(shm, ("write %p %x %x %x\n", \
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
     shm->shm_address, shm->physical_address, addr, nr_bytes) );
 
 
  memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
  memcpy(&shm->shm_address[addr - shm->physical_address], source, nr_bytes);
  return nr_bytes;
  return nr_bytes;
}
}
 
 
static device_callbacks const hw_shm_callbacks = {
static device_callbacks const hw_shm_callbacks = {
  { generic_device_init_address, hw_shm_init_data },
  { generic_device_init_address, hw_shm_init_data },
  { hw_shm_attach_address_callback, }, /* address */
  { hw_shm_attach_address_callback, }, /* address */
  { hw_shm_io_read_buffer,
  { hw_shm_io_read_buffer,
    hw_shm_io_write_buffer }, /* IO */
    hw_shm_io_write_buffer }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  { NULL, }, /* unit */
  NULL,
  NULL,
};
};
 
 
static void *
static void *
hw_shm_create(const char *name,
hw_shm_create(const char *name,
                 const device_unit *unit_address,
                 const device_unit *unit_address,
                 const char *args)
                 const char *args)
{
{
  hw_shm_device *shm = ZALLOC(hw_shm_device);
  hw_shm_device *shm = ZALLOC(hw_shm_device);
  return shm;
  return shm;
}
}
 
 
 
 
 
 
const device_descriptor hw_shm_device_descriptor[] = {
const device_descriptor hw_shm_device_descriptor[] = {
  { "shm", hw_shm_create, &hw_shm_callbacks },
  { "shm", hw_shm_create, &hw_shm_callbacks },
  { NULL },
  { NULL },
};
};
 
 
#endif /* _HW_SHM_C_ */
#endif /* _HW_SHM_C_ */
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.