/*
    TMClock.h, Copyright 18.3.97: (c) by C. Conrad & G. Fankhauser,
    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.
*/
/*
 	PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
	
	File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Threads/mips/TMClock.h,v $
 	Author(s):             C. Conrad & G. Fankhauser
 	Affiliation:           ETH Zuerich, TIK
 	Version:               $Revision: 2935 $
 	Creation Date:         18.3.97: 1997/03/18 16:33:01 $
	
*/

#ifndef __TMCLOCK_H
#define __TMCLOCK_H

#include "tm-include.h"
#include "cpu.h"
#include "Configuration.h"

#ifndef SIMOS

/* 82C54 Programmable Timer */
#ifdef TOPSY_BIG_ENDIAN
#define TIMERBASE          (0x1f800000+K1SEG_BASE+3)
#else
#define TIMERBASE          (0x1f800000+K1SEG_BASE)
#endif
#define COUNTER0           (TIMERBASE+0x0)
#define COUNTER1           (TIMERBASE+0x4)
#define COUNTER2           (TIMERBASE+0x8)
#define TIMERCTRLREGISTER  (TIMERBASE+0xc)
#define RESETCINT0         (TIMERBASE+0x10)
#define RESETCINT1         (TIMERBASE+0x14)

#define MODE2_COUNTER0  0x34     /* specific control word */
#define MODE2_COUNTER1  0x74     /* specific control word */
#define MODE2_COUNTER2  0xb4     /* specific control word */

#define MODE4_COUNTER0  0x38     /* specific control word */
#define MODE4_COUNTER1  0x78     /* specific control word */
#define MODE4_COUNTER2  0xb8     /* specific control word */

#define MODE5_COUNTER0  0x3a     /* specific control word */
#define MODE5_COUNTER1  0x7a     /* specific control word */
#define MODE5_COUNTER2  0xba     /* specific control word */

#else /* SIMOS */

/* MAGIC chipset emulated by SimOS. We use only few of these registers.
 * Although, strictly speaking, these constants do not belong in here,
 * the interval timer is the only place where they are used, so, oh well,
 * it's all an evil game anyway *grin* 
 */

#define magic_control ((volatile int *)0xa0100000)

/* These constants are multiplied by 2 because magic_control is really an
 * array of long longs and not ints. However, because long longs don't work
 * in mips2 xgcc, and we don't really need the top 32 bits anyway, I just
 * treat it as an array of ints, with an int of padding between registers. 
 */

#define MAGIC_PPR_IECHIGH            (0x0000*2)    /* r */
#define MAGIC_PPR_ACKINTERNAL        (0x0001*2)    /* w */
#define MAGIC_PPR_IECENABLE          (0x0002*2)    /* r/w */
#define MAGIC_PPR_SENDIPI            (0x0003*2)    /* w */
#define MAGIC_PPR_OPSPACE            (0x0004*2)    /* r/w */
#define MAGIC_PPR_ASID               (0x0005*2)    /* r/w */
#define MAGIC_PPR_TLBINVAL           (0x0006*2)    /* w */
#define MAGIC_PPR_TLBINUSE           (0x0007*2)    /* r */
#define MAGIC_PPR_MSGTAG             (0x0008*2)    /* r/w */
#define MAGIC_PPR_STALLOSPC          (0x0009*2)    /* r/w */
#define MAGIC_PPR_CYCLECOUNT         (0x000a*2)    /* r */
#define MAGIC_PPR_NETMSGTIME         (0x000b*2)    /* r */
#define MAGIC_PPR_SIPSLOACK          (0x000c*2)    /* r */
#define MAGIC_PPR_SIPSHIACK          (0x000d*2)    /* r */
#define MAGIC_PPR_IECPENDING         (0x000e*2)    /* r/w */
#define MAGIC_PPR_RTC                (0x000f*2)    /* r */
#define MAGIC_PPR_UNUSED10           (0x0010*2)    /* r */
#define MAGIC_PPR_PROTVERSION        (0x0011*2)    /* r */
#define MAGIC_PPR_HWVERSION          (0x0012*2)    /* r */
#define MAGIC_PPR_REMAPMASK          (0x0013*2)    /* r/w */
#define MAGIC_PPR_PROTCONTROL        (0x0014*2)    /* r/w */
#define MAGIC_PPR_RESERVED_15        (0x0015*2)    /* */
#define MAGIC_PPR_RESERVED_16        (0x0016*2)    /* */
#define MAGIC_PPR_RESERVED_17        (0x0017*2)    /* */
#define MAGIC_PPR_OUTOFRANGE         (0x0018*2)    /* r */
#define MAGIC_PPR_INTERVAL           (0x0019*2)    /* r/w */
#define MAGIC_PPR_SLOTMAP            (0x001a*2)    /* r/w */
#define MAGIC_SLOTMAP_SLOT0_OFFS         0
#define MAGIC_SLOTMAP_SLOT1_OFFS         8
#define MAGIC_SLOTMAP_SLOT2_OFFS         16
#define MAGIC_SLOTMAP_SLOT3_OFFS         24
#define MAGIC_PPR_FWSHIFT            (0x001b*2)    /* r/w */
#define MAGIC_PPR_REPORT_DIAG_RESULT (0x001d*2)    /* w */
#define MAGIC_REPORT_PASS_DIAG           0         /* other values indicate fail */
#define MAGIC_PPR_RESERVED_1E        (0x001e*2)    /* w */
#define MAGIC_PPR_DRAIN_POLL         (0x001f*2)    /* r */

#define DEV_IEC_SCSI                0x08    /* scsi disk controller */
#define DEV_IEC_ETHER               0x09    /* ether controller */
#define DEV_IEC_OSPC_LO             0x0a    /* low-priority SIPS */
#define DEV_IEC_VEC_REQ             0x0b    /* vector packet request */
#define DEV_IEC_KEYBDMOUSE          0x10    /* console */
#define DEV_IEC_DUART               0x11    /* serial line on FLASH board */
#define DEV_IEC_OSPC_HI             0x12    /* high-priority SIPS */
#define DEV_IEC_RECOVERY            0x13    /* recov int (posted by MAGIC) */
#define DEV_IEC_VEC_REPLY           0x14    /* vector packet reply */
#define DEV_IEC_MIG_REP             0x17    /* page migration hot page */
#define DEV_IEC_CLOCK               0x18    /* clock */
#define DEV_IEC_IPI                 0x20    /* inter-processor interrupt (level 0)*/
#define DEV_IEC_DEBUG               0x21    /* ??? */
#define DEV_IEC_IPI1                 0x22    /* inter-processor interrupt (level 1)*/
#define DEV_IEC_IPI2                 0x23    /* inter-processor interrupt (level 2)*/
#define DEV_IEC_PROFTIM             0x28    /* prof timer (currently unused) */
#define DEV_IEC_MAGICWARN           0x29    /* ??? */
#define DEV_IEC_MAGICERR            0x31    /* ??? */
#define DEV_IEC_POWERFAIL           0x38    /* ??? */

#define DEV_IEC_MAX                 0x3f    /* 64 bits */

#endif /* SimOS */

/* The 2 timers of the 82C54 programmable interval timer */
typedef enum { CLOCK0, CLOCK1 } ClockId;

/* Used modes for the 82C54, currently a single mode */
typedef enum { RATEGENERATOR, SWTRIGGER } ClockMode;

/* Configuration of the 82C54 (each counter separately) */
Error setClockValue( ClockId cId, int period, ClockMode cMode);

void tmResetClockInterrupt( ClockId cId);

/* RTC routines
 * Seconds difference from January 1st 1998, 00:00, UTC
 */
unsigned long tmRTClockGetSeconds(void);
void tmRTClockSetSeconds(unsigned long seconds, unsigned long microSeconds);

#endif
