/*  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_SEM_C_
#define _HW_SEM_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/sem.h>

#include <errno.h>

/* DEVICE


   sem - provide access to a unix semaphore


   DESCRIPTION


   This device implements an interface to a unix semaphore.


   PROPERTIES


   reg = <address> <size> (required)

   Determine where the memory lives in the parents address space.

   key = <integer> (required)

   This is the key of the unix semaphore.

   EXAMPLES


   Enable tracing of the sem:

   |  bash$ psim -t sem-device \


   Configure a UNIX semaphore using key 0x12345678 mapped into psim
   address space at 0xfff00000:

   |  -o '/sem@0xfff00000/reg 0xfff00000 0x80000' \
   |  -o '/sem@0xfff00000/key 0x12345678' \

   sim/ppc/run -o '/#address-cells 1' \
         -o '/sem@0xfff00000/reg 0xfff00000 12' \
         -o '/sem@0xfff00000/key 0x12345678' ../psim-hello/hello

   REGISTERS

   offset 0 - lock count
   offset 4 - lock operation
   offset 8 - unlock operation

   All reads return the current or resulting count.

   BUGS

   None known.

   */

typedef struct _hw_sem_device {
  unsigned_word physical_address;
  key_t key;
  int id;
  int initial;
  int count;
} hw_sem_device;

#ifndef HAVE_UNION_SEMUN
union semun {
  int val;
  struct semid_ds *buf;
  unsigned short int *array;
#if defined(__linux__)
  struct seminfo *__buf;
#endif
};
#endif

static void
hw_sem_init_data(device *me)
{
  hw_sem_device *sem = (hw_sem_device*)device_data(me);
  const device_unit *d;
  int status;
  union semun help;

  /* initialize the properties of the sem */

  if (device_find_property(me, "key") == NULL)
    error("sem_init_data() required key property is missing\n");

  if (device_find_property(me, "value") == NULL)
    error("sem_init_data() required value property is missing\n");

  sem->key = (key_t) device_find_integer_property(me, "key");
  DTRACE(sem, ("semaphore key (%d)\n", sem->key) );

  sem->initial = (int) device_find_integer_property(me, "value");
  DTRACE(sem, ("semaphore initial value (%d)\n", sem->initial) );

  d = device_unit_address(me);
  sem->physical_address = d->cells[ d->nr_cells-1 ];
  DTRACE(sem, ("semaphore physical_address=0x%x\n", sem->physical_address));

  /* Now to initialize the semaphore */

  if ( sem->initial != -1 ) {

    sem->id = semget(sem->key, 1, IPC_CREAT | 0660);
    if (sem->id == -1)
      error("hw_sem_init_data() semget failed\n");

    help.val = sem->initial;
    status = semctl( sem->id, 0, SETVAL, help );
    if (status == -1)
      error("hw_sem_init_data() semctl -- set value failed\n");

  } else {
    sem->id = semget(sem->key, 1, 0660);
    if (sem->id == -1)
      error("hw_sem_init_data() semget failed\n");
  }

  sem->count = semctl( sem->id, 0, GETVAL, help );
  if (sem->count == -1)
    error("hw_sem_init_data() semctl -- get value failed\n");
  DTRACE(sem, ("semaphore OS value (%d)\n", sem->count) );
}

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

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

  if (nr_bytes == 12)
    error("sem_attach_address_callback() invalid size\n");

  sem->physical_address = addr;
  DTRACE(sem, ("semaphore physical_address=0x%x\n", addr));
}

static unsigned
hw_sem_io_read_buffer(device *me,
			 void *dest,
			 int space,
			 unsigned_word addr,
			 unsigned nr_bytes,
			 cpu *processor,
			 unsigned_word cia)
{
  hw_sem_device *sem = (hw_sem_device*)device_data(me);
  struct sembuf sb;
  int status;
  unsigned32 u32;
  union semun help;

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

  DTRACE(sem, ("semaphore read addr=0x%x length=%d\n", addr, nr_bytes));

  if (!(addr >= sem->physical_address && addr <= sem->physical_address + 11))
    error("hw_sem_io_read_buffer() invalid address - out of range\n");

  if ((addr % 4) != 0)
    error("hw_sem_io_read_buffer() invalid address - alignment\n");

  if (nr_bytes != 4)
    error("hw_sem_io_read_buffer() invalid length\n");

  switch ( (addr - sem->physical_address) / 4 ) {

    case 0:  /* OBTAIN CURRENT VALUE */
      break; 

    case 1:  /* LOCK */
      sb.sem_num = 0;
      sb.sem_op  = -1;
      sb.sem_flg = 0;

      status = semop(sem->id, &sb, 1);
      if (status == -1) {
        perror( "hw_sem.c: lock" );
        error("hw_sem_io_read_buffer() sem lock\n");
      }

      DTRACE(sem, ("semaphore lock %d\n", sem->count));
      break; 

    case 2: /* UNLOCK */
      sb.sem_num = 0;
      sb.sem_op  = 1;
      sb.sem_flg = 0;

      status = semop(sem->id, &sb, 1);
      if (status == -1) {
        perror( "hw_sem.c: unlock" );
        error("hw_sem_io_read_buffer() sem unlock\n");
      }
      DTRACE(sem, ("semaphore unlock %d\n", sem->count));
      break; 

    default:
      error("hw_sem_io_read_buffer() invalid address - unknown error\n");
      break; 
  }

  /* assume target is big endian */
  u32 = H2T_4(semctl( sem->id, 0, GETVAL, help ));

  DTRACE(sem, ("semaphore OS value (%d)\n", u32) );
  if (u32 == 0xffffffff) {
    perror( "hw_sem.c: getval" );
    error("hw_sem_io_read_buffer() semctl -- get value failed\n");
  }

  memcpy(dest, &u32, nr_bytes);
  return nr_bytes;

}

static device_callbacks const hw_sem_callbacks = {
  { generic_device_init_address, hw_sem_init_data },
  { hw_sem_attach_address_callback, }, /* address */
  { hw_sem_io_read_buffer, NULL }, /* IO */
  { NULL, }, /* DMA */
  { NULL, }, /* interrupt */
  { NULL, }, /* unit */
  NULL,
};

static void *
hw_sem_create(const char *name,
		 const device_unit *unit_address,
		 const char *args)
{
  hw_sem_device *sem = ZALLOC(hw_sem_device);
  return sem;
}

const device_descriptor hw_sem_device_descriptor[] = {
  { "sem", hw_sem_create, &hw_sem_callbacks },
  { NULL },
};

#endif /* _HW_SEM_C_ */
