/*
    Copyright 2001 (c) by Authors,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/IO/sa1100/Drivers/Attic/IXPUtil.c,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2936 $
    Last Date of Change:   $Date: 2007-03-21 15:23:42 +0100 (Mit, 21 Mär 2007) $  by: $Author: baderma $
 
*/

#include "types.h"
#include "cpu.h"

// this code is based upon parts of vera from Princeton

/*****************************************************************************/
/*    Project: IXP1200 Runtime Library (libIXP1200.a)                        */
/*    File: ixp_util_p.h                                                     */
/*    Name: Yitzchak M. Gottlieb                                             */
/*                                                                           */
/*****************************************************************************/


/*****************************************************************************/
/*                                                                           */
/* Function Name: getBits                                                    */
/* Parameters:                                                               */
/*	uint32 	value    	What to mask				                                   */
/*	int 	bitOffset       From the least significant bit                     */
/*	int 	bitCount        How many bits are valid                            */
/* Returns: Given a "value", discard all but "bitCount" bits "bitOffset" from*/
/*	    the LSB. The remaining bits are left in LS position.  This is        */
/*	    the read access routine for bitfields wintin larger values.          */
/* Effects: <none>                                                           */
/*                                                                           */
/*****************************************************************************/

inline uint32 getBits(uint32 value, int bitOffset, int bitCount)
{
  uint32 mask;

  mask = (0xFFFFFFFFUL >> (32 - bitCount)) << bitOffset;
  return (value & mask) >> bitOffset;
}


/*****************************************************************************/
/*                                                                           */
/* Function Name: putBits                                                    */
/* Parameters:                                                               */
/*    	uint32 value	What to mask				                                   */
/*    	int bitOffset 	From the least significant bit                       */
/*    	int bitCount	How many bits are valid                                */
/* Returns: Given a "value", ensure it is "bitCount" wide and shift it       */
/*          "bitOffset" bits away from the LSB.  This is the write access    */
/*          routine for bitfields within larger values.                      */
/* Effects:                                                                  */
/*                                                                           */
/*****************************************************************************/

inline uint32 putBits(uint32 value, int bitOffset, int bitCount)
{
  uint32 mask;

  mask = (0xFFFFFFFFUL >> (32 - bitCount));
  return (value & mask) << bitOffset;
}

/*****************************************************************************/
/*                                                                           */
/* Function Name: delay                                                      */
/* Parameters: int  count   Length of the delay.                             */
/* Returns: <none>                                                           */
/* Effects: Delays processing for count interations of a for loop.           */
/*                                                                           */
/*****************************************************************************/

inline void delay(int count)
{
  int i = 0;

  for(i = count; i != 0; i--)
  {
    // Wait
  }
}

/*****************************************************************************
 *                                                                           *
 * Function Name: led                                                        *
 * Parameters: uint8 cal    Value to be displayed on the IXP board display   *
 * Returns: <none>                                                           *
 * Effects: displays th value on the 7 segment display on the IXP board      *
 *                                                                           *
 *****************************************************************************/

// Slow Port needs to be directly mapped fort this to work
inline void led(uint8  val)
{

  //WRITEB(val, LED_ADDR + 3L);
  // write big endian word directly since Leds can be accessed in
  // big endian mode (high order byte contains val)
  WRITEW((uint32)val, LED_ADDR);
}

/*****************************************************************************/
/*                                                                           */
/* Function Name: findFirstBitSet                                            */
/* Parameters: uint32  data    The value to query.                           */
/* Returns: uint8, the position of the least significant bit set in data.    */
/*              >31 is error.                                                */
/* Effects: <none>                                                           */
/*                                                                           */
/*****************************************************************************/

inline uint8 findFirstBitSet(uint32 data)
{
  uint8 i = 0;

  for (i = 0; i < 32; i++)
  {
    if (data & (1 << i))
      break;
  }

  return i;
}
