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